Settings: don't try to allow NLSes with too-long component names
* NotificationAccessConfirmationActivity (triggered through CompanionDeviceManager) -> Don't show the dialog, bail out early similarly to other invalid inputs.
* NotificationAccessSettings (from Special App Access) -> No changes, but use the canonical constant now.
* ApprovalPreferenceController (used in NotificationAccessDetails) -> Disable the toggle, unless the NLS was previously approved (in which case it can still be removed).
Fixes: 260570119
Fixes: 286043036
Test: atest + manually
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:b88fbf932a1631792a422f8ac34e83e1d6ae74d7)
Merged-In: Ifc048311746c027e3683cdcf65f1079d04cf7c56
Change-Id: Ifc048311746c027e3683cdcf65f1079d04cf7c56
diff --git a/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java b/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java
index 0767e65..6bee62c 100644
--- a/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java
+++ b/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceController.java
@@ -81,6 +81,8 @@
final RestrictedSwitchPreference preference =
(RestrictedSwitchPreference) pref;
final CharSequence label = mPkgInfo.applicationInfo.loadLabel(mPm);
+ final boolean isAllowedCn = mCn.flattenToShortString().length()
+ <= NotificationManager.MAX_SERVICE_COMPONENT_NAME_LENGTH;
final boolean isEnabled = isServiceEnabled(mCn);
preference.setChecked(isEnabled);
preference.setOnPreferenceChangeListener((p, newValue) -> {
@@ -105,7 +107,8 @@
return false;
}
});
- preference.updateState(mCn.getPackageName(), mPkgInfo.applicationInfo.uid, isEnabled);
+ preference.updateState(
+ mCn.getPackageName(), mPkgInfo.applicationInfo.uid, isAllowedCn, isEnabled);
}
public void disable(final ComponentName cn) {
diff --git a/src/com/android/settings/notification/NotificationAccessConfirmationActivity.java b/src/com/android/settings/notification/NotificationAccessConfirmationActivity.java
index dfe6df2..a6b565a 100644
--- a/src/com/android/settings/notification/NotificationAccessConfirmationActivity.java
+++ b/src/com/android/settings/notification/NotificationAccessConfirmationActivity.java
@@ -67,7 +67,9 @@
mUserId = getIntent().getIntExtra(EXTRA_USER_ID, UserHandle.USER_NULL);
CharSequence mAppLabel;
- if (mComponentName == null || mComponentName.getPackageName() == null) {
+ if (mComponentName == null || mComponentName.getPackageName() == null
+ || mComponentName.flattenToString().length()
+ > NotificationManager.MAX_SERVICE_COMPONENT_NAME_LENGTH) {
finish();
return;
}
diff --git a/src/com/android/settings/notification/NotificationAccessSettings.java b/src/com/android/settings/notification/NotificationAccessSettings.java
index 369c4f6..e2ef0dd 100644
--- a/src/com/android/settings/notification/NotificationAccessSettings.java
+++ b/src/com/android/settings/notification/NotificationAccessSettings.java
@@ -66,7 +66,6 @@
private static final String TAG = "NotifAccessSettings";
static final String ALLOWED_KEY = "allowed";
static final String NOT_ALLOWED_KEY = "not_allowed";
- private static final int MAX_CN_LENGTH = 500;
private static final ManagedServiceSettings.Config CONFIG =
new ManagedServiceSettings.Config.Builder()
@@ -150,7 +149,8 @@
for (ServiceInfo service : services) {
final ComponentName cn = new ComponentName(service.packageName, service.name);
boolean isAllowed = mNm.isNotificationListenerAccessGranted(cn);
- if (!isAllowed && cn.flattenToString().length() > MAX_CN_LENGTH) {
+ if (!isAllowed && cn.flattenToString().length()
+ > NotificationManager.MAX_SERVICE_COMPONENT_NAME_LENGTH) {
continue;
}
diff --git a/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java
index 249b713..4601a1c 100644
--- a/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/applications/specialaccess/notificationaccess/ApprovalPreferenceControllerTest.java
@@ -84,6 +84,36 @@
}
@Test
+ public void updateState_enabled() {
+ when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(), anyString())).thenReturn(
+ AppOpsManager.MODE_ALLOWED);
+ when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(
+ mContext);
+ pref.setAppOps(mAppOpsManager);
+
+ mController.updateState(pref);
+
+ assertThat(pref.isEnabled()).isTrue();
+ }
+
+ @Test
+ public void updateState_invalidCn_disabled() {
+ ComponentName longCn = new ComponentName("com.example.package",
+ com.google.common.base.Strings.repeat("Blah", 150));
+ mController.setCn(longCn);
+ when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(), anyString())).thenReturn(
+ AppOpsManager.MODE_ALLOWED);
+ RestrictedSwitchPreference pref = new RestrictedSwitchPreference(
+ mContext);
+ pref.setAppOps(mAppOpsManager);
+
+ mController.updateState(pref);
+
+ assertThat(pref.isEnabled()).isFalse();
+ }
+
+ @Test
public void updateState_checked() {
when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(), anyString())).thenReturn(
AppOpsManager.MODE_ALLOWED);