Update non-framework emergency location request notification
- Incorporate notification text feedback in b/116328114 so that
it translates well in different locales.
- Implement PWG recommendation to always notify user of non-framework
location requests and not make it configurable. Remove es_notify_int
configuration parameter.
Bug: 116328114
Bug: 130892418
Test: Manual plus existing tests pass.
Change-Id: Iad972eb1a6fe6c6ed5646edb00c1ea483a077553
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index 04e7bab..e890514 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -360,7 +360,7 @@
/**
* Posts a notification in the status bar using the contents in {@code notif} object.
*/
- public synchronized void setNiNotification(GpsNiNotification notif) {
+ private synchronized void setNiNotification(GpsNiNotification notif) {
NotificationManager notificationManager = (NotificationManager) mContext
.getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager == null) {
@@ -541,35 +541,26 @@
*/
static private String decodeString(String original, boolean isHex, int coding)
{
- if (coding == GPS_ENC_NONE) {
+ if (coding == GPS_ENC_NONE || coding == GPS_ENC_UNKNOWN) {
return original;
}
- String decoded = original;
byte[] input = stringToByteArray(original, isHex);
switch (coding) {
- case GPS_ENC_SUPL_GSM_DEFAULT:
- decoded = decodeGSMPackedString(input);
- break;
+ case GPS_ENC_SUPL_GSM_DEFAULT:
+ return decodeGSMPackedString(input);
- case GPS_ENC_SUPL_UTF8:
- decoded = decodeUTF8String(input);
- break;
+ case GPS_ENC_SUPL_UTF8:
+ return decodeUTF8String(input);
- case GPS_ENC_SUPL_UCS2:
- decoded = decodeUCS2String(input);
- break;
+ case GPS_ENC_SUPL_UCS2:
+ return decodeUCS2String(input);
- case GPS_ENC_UNKNOWN:
- decoded = original;
- break;
-
- default:
- Log.e(TAG, "Unknown encoding " + coding + " for NI text " + original);
- break;
+ default:
+ Log.e(TAG, "Unknown encoding " + coding + " for NI text " + original);
+ return original;
}
- return decoded;
}
// change this to configure notification display
diff --git a/services/core/java/com/android/server/location/GnssConfiguration.java b/services/core/java/com/android/server/location/GnssConfiguration.java
index aa51aec..86a84e3 100644
--- a/services/core/java/com/android/server/location/GnssConfiguration.java
+++ b/services/core/java/com/android/server/location/GnssConfiguration.java
@@ -70,7 +70,6 @@
private static final String CONFIG_GPS_LOCK = "GPS_LOCK";
private static final String CONFIG_ES_EXTENSION_SEC = "ES_EXTENSION_SEC";
public static final String CONFIG_NFW_PROXY_APPS = "NFW_PROXY_APPS";
- public static final String CONFIG_ES_NOTIFY_INT = "ES_NOTIFY_INT";
// Limit on NI emergency mode time extension after emergency sessions ends
private static final int MAX_EMERGENCY_MODE_EXTENSION_SECONDS = 300; // 5 minute maximum
@@ -200,14 +199,6 @@
}
/**
- * Returns the value of config parameter ES_NOTIFY_INT or {@code defaulEsNotify} if no
- * value is provided or if there is an error parsing the configured value.
- */
- int getEsNotify(int defaulEsNotify) {
- return getIntConfig(CONFIG_ES_NOTIFY_INT, defaulEsNotify);
- }
-
- /**
* Updates the GNSS HAL satellite blacklist.
*/
void setSatelliteBlacklist(int[] constellations, int[] svids) {
diff --git a/services/core/java/com/android/server/location/GnssVisibilityControl.java b/services/core/java/com/android/server/location/GnssVisibilityControl.java
index c49d900..b7e0a0f 100644
--- a/services/core/java/com/android/server/location/GnssVisibilityControl.java
+++ b/services/core/java/com/android/server/location/GnssVisibilityControl.java
@@ -18,6 +18,9 @@
import android.annotation.SuppressLint;
import android.app.AppOpsManager;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -35,6 +38,7 @@
import com.android.internal.R;
import com.android.internal.location.GpsNetInitiatedHandler;
+import com.android.internal.notification.SystemNotificationChannels;
import java.util.Arrays;
import java.util.List;
@@ -58,11 +62,6 @@
// Max wait time for synchronous method onGpsEnabledChanged() to run.
private static final long ON_GPS_ENABLED_CHANGED_TIMEOUT_MILLIS = 3 * 1000;
- // Valid values for config parameter es_notify_int for posting notification in the status
- // bar for non-framework location requests in user-initiated emergency use cases.
- private static final int ES_NOTIFY_NONE = 0;
- private static final int ES_NOTIFY_ALL = 1;
-
// Wakelocks
private static final String WAKELOCK_KEY = TAG;
private static final long WAKELOCK_TIMEOUT_MILLIS = 60 * 1000;
@@ -74,9 +73,9 @@
private final Handler mHandler;
private final Context mContext;
private final GpsNetInitiatedHandler mNiHandler;
+ private final Notification mEmergencyLocationUserNotification;
private boolean mIsGpsEnabled;
- private boolean mEsNotify;
// Number of non-framework location access proxy apps is expected to be small (< 5).
private static final int ARRAY_MAP_INITIAL_CAPACITY_PROXY_APP_TO_LOCATION_PERMISSIONS = 7;
@@ -94,6 +93,7 @@
mNiHandler = niHandler;
mAppOps = mContext.getSystemService(AppOpsManager.class);
mPackageManager = mContext.getPackageManager();
+ mEmergencyLocationUserNotification = createEmergencyLocationUserNotification(mContext);
// Complete initialization as the first event to run in mHandler thread. After that,
// all object state read/update events run in the mHandler thread.
@@ -135,22 +135,7 @@
void onConfigurationUpdated(GnssConfiguration configuration) {
// The configuration object must be accessed only in the caller thread and not in mHandler.
List<String> nfwLocationAccessProxyApps = configuration.getProxyApps();
- int esNotify = configuration.getEsNotify(ES_NOTIFY_NONE);
- runOnHandler(() -> {
- setEsNotify(esNotify);
- handleUpdateProxyApps(nfwLocationAccessProxyApps);
- });
- }
-
- private void setEsNotify(int esNotify) {
- if (esNotify != ES_NOTIFY_NONE && esNotify != ES_NOTIFY_ALL) {
- Log.e(TAG, "Config parameter " + GnssConfiguration.CONFIG_ES_NOTIFY_INT
- + " is set to invalid value: " + esNotify
- + ". Using default value: " + ES_NOTIFY_NONE);
- esNotify = ES_NOTIFY_NONE;
- }
-
- mEsNotify = (esNotify == ES_NOTIFY_ALL);
+ runOnHandler(() -> handleUpdateProxyApps(nfwLocationAccessProxyApps));
}
private void handleInitialize() {
@@ -278,9 +263,6 @@
private static final byte NFW_RESPONSE_TYPE_ACCEPTED_NO_LOCATION_PROVIDED = 1;
private static final byte NFW_RESPONSE_TYPE_ACCEPTED_LOCATION_PROVIDED = 2;
- // This must match with NfwProtocolStack enum in IGnssVisibilityControlCallback.hal.
- private static final byte NFW_PROTOCOL_STACK_SUPL = 1;
-
private final String mProxyAppPackageName;
private final byte mProtocolStack;
private final String mOtherProtocolStackName;
@@ -341,10 +323,6 @@
private boolean isEmergencyRequestNotification() {
return mInEmergencyMode && !isRequestAttributedToProxyApp();
}
-
- private boolean isRequestTypeSupl() {
- return mProtocolStack == NFW_PROTOCOL_STACK_SUPL;
- }
}
private void handlePermissionsChanged(int uid) {
@@ -517,27 +495,44 @@
logEvent(nfwNotification, isPermissionMismatched);
- if (mEsNotify && nfwNotification.isLocationProvided()) {
- // Emulate deprecated IGnssNi.hal user notification of emergency NI requests.
- GpsNetInitiatedHandler.GpsNiNotification notification =
- new GpsNetInitiatedHandler.GpsNiNotification();
- notification.notificationId = 0;
- notification.niType = nfwNotification.isRequestTypeSupl()
- ? GpsNetInitiatedHandler.GPS_NI_TYPE_EMERGENCY_SUPL
- : GpsNetInitiatedHandler.GPS_NI_TYPE_UMTS_CTRL_PLANE;
- notification.needNotify = true;
- notification.needVerify = false;
- notification.privacyOverride = false;
- notification.timeout = 0;
- notification.defaultResponse = GpsNetInitiatedHandler.GPS_NI_RESPONSE_NORESP;
- notification.requestorId = nfwNotification.mRequestorId;
- notification.requestorIdEncoding = GpsNetInitiatedHandler.GPS_ENC_NONE;
- notification.text = mContext.getString(R.string.global_action_emergency);
- notification.textEncoding = GpsNetInitiatedHandler.GPS_ENC_NONE;
- mNiHandler.setNiNotification(notification);
+ if (nfwNotification.isLocationProvided()) {
+ postEmergencyLocationUserNotification(nfwNotification);
}
}
+ private void postEmergencyLocationUserNotification(NfwNotification nfwNotification) {
+ // Emulate deprecated IGnssNi.hal user notification of emergency NI requests.
+ NotificationManager notificationManager = (NotificationManager) mContext
+ .getSystemService(Context.NOTIFICATION_SERVICE);
+ if (notificationManager == null) {
+ Log.w(TAG, "Could not notify user of emergency location request. Notification: "
+ + nfwNotification);
+ return;
+ }
+
+ notificationManager.notifyAsUser(/* tag= */ null, /* notificationId= */ 0,
+ mEmergencyLocationUserNotification, UserHandle.ALL);
+ }
+
+ private static Notification createEmergencyLocationUserNotification(Context context) {
+ String firstLineText = context.getString(R.string.gpsNotifTitle);
+ String secondLineText = context.getString(R.string.global_action_emergency);
+ String accessibilityServicesText = firstLineText + " (" + secondLineText + ")";
+ return new Notification.Builder(context, SystemNotificationChannels.NETWORK_ALERTS)
+ .setSmallIcon(com.android.internal.R.drawable.stat_sys_gps_on)
+ .setWhen(0)
+ .setOngoing(true)
+ .setAutoCancel(true)
+ .setColor(context.getColor(
+ com.android.internal.R.color.system_notification_accent_color))
+ .setDefaults(0)
+ .setTicker(accessibilityServicesText)
+ .setContentTitle(firstLineText)
+ .setContentText(secondLineText)
+ .setContentIntent(PendingIntent.getBroadcast(context, 0, new Intent(), 0))
+ .build();
+ }
+
private void logEvent(NfwNotification notification, boolean isPermissionMismatched) {
StatsLog.write(StatsLog.GNSS_NFW_NOTIFICATION_REPORTED,
notification.mProxyAppPackageName,
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 6ba359b..5175c1d 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2794,14 +2794,6 @@
*/
public static final String KEY_NFW_PROXY_APPS_STRING = KEY_PREFIX + "nfw_proxy_apps";
- /**
- * Specify whether to post a notification on the status bar whenever device location is
- * provided for non-framework location requests in user-initiated emergency use cases.
- * 0 - Do not post notification. This is default.
- * 1 - Post notification for all request types.
- */
- public static final String KEY_ES_NOTIFY_INT = KEY_PREFIX + "es_notify_int";
-
private static PersistableBundle getDefaults() {
PersistableBundle defaults = new PersistableBundle();
defaults.putBoolean(KEY_PERSIST_LPP_MODE_BOOL, true);
@@ -2816,7 +2808,6 @@
defaults.putString(KEY_GPS_LOCK_STRING, "3");
defaults.putString(KEY_ES_EXTENSION_SEC_STRING, "0");
defaults.putString(KEY_NFW_PROXY_APPS_STRING, "");
- defaults.putInt(KEY_ES_NOTIFY_INT, 0);
return defaults;
}
}