script-astra/Android/Sdk/sources/android-35/com/android/internal/location/GpsNetInitiatedHandler.java
localadmin 4380f00a78 init
2025-01-20 18:15:20 +03:00

167 lines
6.7 KiB
Java

/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.location;
import android.Manifest;
import android.annotation.RequiresPermission;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.os.SystemClock;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
import android.telephony.emergency.EmergencyNumber;
import android.util.Log;
import com.android.internal.telephony.flags.Flags;
import java.util.concurrent.TimeUnit;
/**
* A GPS Network-initiated Handler class used by LocationManager.
*
* {@hide}
*/
public class GpsNetInitiatedHandler {
private static final String TAG = "GpsNetInitiatedHandler";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private final Context mContext;
private final TelephonyManager mTelephonyManager;
// parent gps location provider
private final LocationManager mLocationManager;
// Set to true if the phone is having emergency call.
private volatile boolean mIsInEmergencyCall;
// End time of emergency call, and extension, if set
private volatile long mCallEndElapsedRealtimeMillis = 0;
private volatile long mEmergencyExtensionMillis = 0;
/** Callbacks for Emergency call events. */
public interface EmergencyCallCallback {
/** Callback invoked when an emergency call starts */
void onEmergencyCallStart(int subId);
/** Callback invoked when an emergency call ends */
void onEmergencyCallEnd();
}
private class EmergencyCallListener extends TelephonyCallback implements
TelephonyCallback.OutgoingEmergencyCallListener,
TelephonyCallback.CallStateListener {
@Override
@RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
public void onOutgoingEmergencyCall(EmergencyNumber placedEmergencyNumber,
int subscriptionId) {
mIsInEmergencyCall = true;
if (DEBUG) Log.d(TAG, "onOutgoingEmergencyCall(): inEmergency = " + getInEmergency());
mEmergencyCallCallback.onEmergencyCallStart(subscriptionId);
}
@Override
@RequiresPermission(Manifest.permission.READ_PHONE_STATE)
public void onCallStateChanged(int state) {
if (DEBUG) Log.d(TAG, "onCallStateChanged(): state is " + state);
// listening for emergency call ends
if (state == TelephonyManager.CALL_STATE_IDLE) {
if (mIsInEmergencyCall) {
mCallEndElapsedRealtimeMillis = SystemClock.elapsedRealtime();
mIsInEmergencyCall = false;
mEmergencyCallCallback.onEmergencyCallEnd();
}
}
}
}
// The internal implementation of TelephonyManager uses WeakReference so we have to keep a
// reference here.
private final EmergencyCallListener mEmergencyCallListener = new EmergencyCallListener();
private final EmergencyCallCallback mEmergencyCallCallback;
public GpsNetInitiatedHandler(Context context,
EmergencyCallCallback emergencyCallCallback,
boolean isSuplEsEnabled) {
mContext = context;
mEmergencyCallCallback = emergencyCallCallback;
mLocationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
mTelephonyManager =
(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
mTelephonyManager.registerTelephonyCallback(mContext.getMainExecutor(),
mEmergencyCallListener);
}
/**
* Determines whether device is in user-initiated emergency session based on the following
* 1. If the user is making an emergency call, this is provided by actively
* monitoring the outgoing phone number;
* 2. If the user has recently ended an emergency call, and the device is in a configured time
* window after the end of that call.
* 3. If the device is in a emergency callback state, this is provided by querying
* TelephonyManager.
* 4. If the user has recently sent an Emergency SMS and telephony reports that it is in
* emergency SMS mode, this is provided by querying TelephonyManager.
* @return true if is considered in user initiated emergency mode for NI purposes
*/
public boolean getInEmergency() {
return getInEmergency(mEmergencyExtensionMillis);
}
/**
* Determines whether device is in user-initiated emergency session with the given extension
* time.
*
* @return true if is considered in user initiated emergency mode for NI purposes within the
* given extension time.
*
* @see {@link #getInEmergency()}
*/
public boolean getInEmergency(long emergencyExtensionMillis) {
boolean isInEmergencyExtension =
(mCallEndElapsedRealtimeMillis > 0)
&& ((SystemClock.elapsedRealtime() - mCallEndElapsedRealtimeMillis)
< emergencyExtensionMillis);
boolean isInEmergencyCallback = false;
boolean isInEmergencySmsMode = false;
if (!Flags.enforceTelephonyFeatureMappingForPublicApis()) {
isInEmergencyCallback = mTelephonyManager.getEmergencyCallbackMode();
isInEmergencySmsMode = mTelephonyManager.isInEmergencySmsMode();
} else {
PackageManager pm = mContext.getPackageManager();
if (pm != null && pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CALLING)) {
isInEmergencyCallback = mTelephonyManager.getEmergencyCallbackMode();
}
if (pm != null && pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)) {
isInEmergencySmsMode = mTelephonyManager.isInEmergencySmsMode();
}
}
return mIsInEmergencyCall || isInEmergencyCallback || isInEmergencyExtension
|| isInEmergencySmsMode;
}
public void setEmergencyExtensionSeconds(int emergencyExtensionSeconds) {
mEmergencyExtensionMillis = TimeUnit.SECONDS.toMillis(emergencyExtensionSeconds);
}
}