167 lines
6.7 KiB
Java
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);
|
|
}
|
|
}
|