From a024c10517bdeaf98c33102f7e92e30c4e1cb499 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Fri, 29 Oct 2021 08:19:10 -0400 Subject: [PATCH] Migrate to using fixed permissions When deciding which app/group/channel level fields are editable. If an app has a fixed notification permission, no importance type fields (including blocking, importance, minimizing, popping on screen, or prioirty conversions) can be edited. Test: Robotests Bug: 194833441 Change-Id: Idc198ea05cd2ab6e43387ae4e8290f446ccfa0c6 --- .../notification/NotificationBackend.java | 33 ++++-- .../app/BlockPreferenceController.java | 5 +- ...versationPriorityPreferenceController.java | 4 +- .../HighImportancePreferenceController.java | 2 +- .../app/ImportancePreferenceController.java | 4 +- .../MinImportancePreferenceController.java | 2 +- .../app/NotificationPreferenceController.java | 62 ++++++++++- .../notification/NotificationBackendTest.java | 50 +++++++++ .../AllowSoundPreferenceControllerTest.java | 14 --- .../app/BadgePreferenceControllerTest.java | 14 --- .../app/BlockPreferenceControllerTest.java | 52 ++------- .../app/BubblePreferenceControllerTest.java | 15 --- ...ationPriorityPreferenceControllerTest.java | 22 +--- .../app/DndPreferenceControllerTest.java | 2 +- ...ighImportancePreferenceControllerTest.java | 22 +--- .../ImportancePreferenceControllerTest.java | 22 +--- .../app/LightsPreferenceControllerTest.java | 13 --- ...MinImportancePreferenceControllerTest.java | 23 +--- .../NotificationPreferenceControllerTest.java | 105 ++++++++++++++++++ .../app/SoundPreferenceControllerTest.java | 14 --- .../VibrationPreferenceControllerTest.java | 3 +- 21 files changed, 272 insertions(+), 211 deletions(-) diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java index cf8801fdb83..1af8867acd5 100644 --- a/src/com/android/settings/notification/NotificationBackend.java +++ b/src/com/android/settings/notification/NotificationBackend.java @@ -20,6 +20,7 @@ import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_CACHED; import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC; import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER; +import static android.os.UserHandle.USER_SYSTEM; import android.app.INotificationManager; import android.app.NotificationChannel; @@ -44,6 +45,7 @@ import android.graphics.drawable.Drawable; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; +import android.provider.Settings; import android.service.notification.ConversationChannelWrapper; import android.service.notification.NotificationListenerFilter; import android.text.format.DateUtils; @@ -112,15 +114,25 @@ public class NotificationBackend { void recordCanBeBlocked(Context context, PackageManager pm, RoleManager rm, PackageInfo app, AppRow row) { - row.systemApp = Utils.isSystemPackage(context.getResources(), pm, app); - List roles = rm.getHeldRolesFromController(app.packageName); - if (roles.contains(RoleManager.ROLE_DIALER) - || roles.contains(RoleManager.ROLE_EMERGENCY)) { - row.systemApp = true; + if (Settings.Secure.getIntForUser(context.getContentResolver(), + Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 0, USER_SYSTEM) != 0) { + try { + row.systemApp = row.lockedImportance = + sINM.isPermissionFixed(app.packageName, row.userId); + } catch (RemoteException e) { + Log.w(TAG, "Error calling NMS", e); + } + } else { + row.systemApp = Utils.isSystemPackage(context.getResources(), pm, app); + List roles = rm.getHeldRolesFromController(app.packageName); + if (roles.contains(RoleManager.ROLE_DIALER) + || roles.contains(RoleManager.ROLE_EMERGENCY)) { + row.systemApp = true; + } + final String[] nonBlockablePkgs = context.getResources().getStringArray( + com.android.internal.R.array.config_nonBlockableNotificationPackages); + markAppRowWithBlockables(nonBlockablePkgs, row, app.packageName); } - final String[] nonBlockablePkgs = context.getResources().getStringArray( - com.android.internal.R.array.config_nonBlockableNotificationPackages); - markAppRowWithBlockables(nonBlockablePkgs, row, app.packageName); } @VisibleForTesting static void markAppRowWithBlockables(String[] nonBlockablePkgs, AppRow row, @@ -653,6 +665,11 @@ public class NotificationBackend { return false; } + @VisibleForTesting + void setNm(INotificationManager inm) { + sINM = inm; + } + /** * NotificationsSentState contains how often an app sends notifications and how recently it sent * one. diff --git a/src/com/android/settings/notification/app/BlockPreferenceController.java b/src/com/android/settings/notification/app/BlockPreferenceController.java index d5d516eaf73..f4e213298a7 100644 --- a/src/com/android/settings/notification/app/BlockPreferenceController.java +++ b/src/com/android/settings/notification/app/BlockPreferenceController.java @@ -80,7 +80,7 @@ public class BlockPreferenceController extends NotificationPreferenceController } bar.setDisabledByAdmin(mAdmin); - if (mChannel != null && !isChannelBlockable()) { + if (mChannel != null && (!isChannelBlockable() || !isChannelConfigurable(mChannel))) { bar.setSwitchBarEnabled(false); } @@ -88,8 +88,7 @@ public class BlockPreferenceController extends NotificationPreferenceController bar.setSwitchBarEnabled(false); } - if (mChannel == null && mAppRow.systemApp - && (!mAppRow.banned || mAppRow.lockedImportance)) { + if (mChannel == null && !isAppBlockable()) { bar.setSwitchBarEnabled(false); } diff --git a/src/com/android/settings/notification/app/ConversationPriorityPreferenceController.java b/src/com/android/settings/notification/app/ConversationPriorityPreferenceController.java index 9730104d303..ae169282484 100644 --- a/src/com/android/settings/notification/app/ConversationPriorityPreferenceController.java +++ b/src/com/android/settings/notification/app/ConversationPriorityPreferenceController.java @@ -62,9 +62,9 @@ public class ConversationPriorityPreferenceController extends NotificationPrefer public void updateState(Preference preference) { if (mAppRow != null) { - preference.setEnabled(mAdmin == null && !mChannel.isImportanceLockedByOEM()); + preference.setEnabled(mAdmin == null && isChannelConfigurable(mChannel)); ConversationPriorityPreference pref = (ConversationPriorityPreference) preference; - pref.setConfigurable(!mChannel.isImportanceLockedByOEM()); + pref.setConfigurable(isChannelConfigurable(mChannel)); pref.setImportance(mChannel.getImportance()); pref.setOriginalImportance(mChannel.getOriginalImportance()); pref.setPriorityConversation(mChannel.isImportantConversation()); diff --git a/src/com/android/settings/notification/app/HighImportancePreferenceController.java b/src/com/android/settings/notification/app/HighImportancePreferenceController.java index 67fb2ff1be5..d60668b9abe 100644 --- a/src/com/android/settings/notification/app/HighImportancePreferenceController.java +++ b/src/com/android/settings/notification/app/HighImportancePreferenceController.java @@ -68,7 +68,7 @@ public class HighImportancePreferenceController extends NotificationPreferenceCo @Override public void updateState(Preference preference) { if (mAppRow != null && mChannel != null) { - preference.setEnabled(mAdmin == null && !mChannel.isImportanceLockedByOEM()); + preference.setEnabled(mAdmin == null && isChannelConfigurable(mChannel)); RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference; pref.setChecked(mChannel.getImportance() >= IMPORTANCE_HIGH); diff --git a/src/com/android/settings/notification/app/ImportancePreferenceController.java b/src/com/android/settings/notification/app/ImportancePreferenceController.java index ed3410c1459..3c32ca4b0bc 100644 --- a/src/com/android/settings/notification/app/ImportancePreferenceController.java +++ b/src/com/android/settings/notification/app/ImportancePreferenceController.java @@ -66,9 +66,9 @@ public class ImportancePreferenceController extends NotificationPreferenceContro @Override public void updateState(Preference preference) { if (mAppRow!= null && mChannel != null) { - preference.setEnabled(mAdmin == null && !mChannel.isImportanceLockedByOEM()); + preference.setEnabled(mAdmin == null && isChannelConfigurable(mChannel)); ImportancePreference pref = (ImportancePreference) preference; - pref.setConfigurable(!mChannel.isImportanceLockedByOEM()); + pref.setConfigurable(isChannelConfigurable(mChannel)); pref.setImportance(mChannel.getImportance()); pref.setDisplayInStatusBar(mBackend.showSilentInStatusBar(mContext.getPackageName())); pref.setDisplayOnLockscreen(Settings.Secure.getInt(mContext.getContentResolver(), diff --git a/src/com/android/settings/notification/app/MinImportancePreferenceController.java b/src/com/android/settings/notification/app/MinImportancePreferenceController.java index 90f56b295d3..f8257636615 100644 --- a/src/com/android/settings/notification/app/MinImportancePreferenceController.java +++ b/src/com/android/settings/notification/app/MinImportancePreferenceController.java @@ -68,7 +68,7 @@ public class MinImportancePreferenceController extends NotificationPreferenceCon @Override public void updateState(Preference preference) { if (mAppRow != null && mChannel != null) { - preference.setEnabled(mAdmin == null && !mChannel.isImportanceLockedByOEM()); + preference.setEnabled(mAdmin == null && isChannelConfigurable(mChannel)); RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference; pref.setChecked(mChannel.getImportance() == IMPORTANCE_MIN); diff --git a/src/com/android/settings/notification/app/NotificationPreferenceController.java b/src/com/android/settings/notification/app/NotificationPreferenceController.java index e2eb453a780..289f1edfc3c 100644 --- a/src/com/android/settings/notification/app/NotificationPreferenceController.java +++ b/src/com/android/settings/notification/app/NotificationPreferenceController.java @@ -17,6 +17,7 @@ package com.android.settings.notification.app; import static android.app.NotificationManager.IMPORTANCE_NONE; +import static android.os.UserHandle.USER_SYSTEM; import android.annotation.Nullable; import android.app.NotificationChannel; @@ -27,6 +28,7 @@ import android.content.pm.PackageManager; import android.content.pm.ShortcutInfo; import android.graphics.drawable.Drawable; import android.os.UserManager; +import android.provider.Settings; import android.util.Log; import androidx.preference.Preference; @@ -62,6 +64,12 @@ public abstract class NotificationPreferenceController extends AbstractPreferenc @Nullable protected ShortcutInfo mConversationInfo; protected List mPreferenceFilter; + boolean mMigratedPermission; + + boolean overrideCanBlock; + boolean overrideCanConfigure; + boolean overrideCanBlockValue; + boolean overrideCanConfigureValue; public NotificationPreferenceController(Context context, NotificationBackend backend) { super(context); @@ -70,6 +78,8 @@ public abstract class NotificationPreferenceController extends AbstractPreferenc mBackend = backend; mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE); mPm = mContext.getPackageManager(); + mMigratedPermission = Settings.Secure.getIntForUser(context.getContentResolver(), + Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 0, USER_SYSTEM) != 0; } /** @@ -138,10 +148,18 @@ public abstract class NotificationPreferenceController extends AbstractPreferenc } protected boolean isChannelBlockable(NotificationChannel channel) { + if (overrideCanBlock) { + return overrideCanBlockValue; + } + if (overrideCanConfigure) { + return overrideCanConfigureValue; + } if (channel != null && mAppRow != null) { - if (channel.isImportanceLockedByCriticalDeviceFunction() - || channel.isImportanceLockedByOEM()) { - return channel.getImportance() == IMPORTANCE_NONE; + boolean locked = mMigratedPermission ? mAppRow.lockedImportance + : channel.isImportanceLockedByCriticalDeviceFunction() + || channel.isImportanceLockedByOEM(); + if (locked) { + return channel.isBlockable() || channel.getImportance() == IMPORTANCE_NONE; } return channel.isBlockable() || !mAppRow.systemApp @@ -150,9 +168,27 @@ public abstract class NotificationPreferenceController extends AbstractPreferenc return false; } + protected boolean isAppBlockable() { + if (overrideCanBlock) { + return overrideCanBlockValue; + } + if (overrideCanConfigure) { + return overrideCanConfigureValue; + } + if (mAppRow != null) { + return !mAppRow.systemApp && !mAppRow.lockedImportance; + } + return true; + } + protected boolean isChannelConfigurable(NotificationChannel channel) { + if (overrideCanConfigure) { + return overrideCanConfigureValue; + } if (channel != null && mAppRow != null) { - return !channel.isImportanceLockedByOEM(); + boolean locked = mMigratedPermission ? mAppRow.lockedImportance + : channel.isImportanceLockedByOEM(); + return !locked || channel.isBlockable(); } return false; } @@ -162,8 +198,14 @@ public abstract class NotificationPreferenceController extends AbstractPreferenc } protected boolean isChannelGroupBlockable(NotificationChannelGroup group) { + if (overrideCanBlock) { + return overrideCanBlockValue; + } + if (overrideCanConfigure) { + return overrideCanConfigureValue; + } if (group != null && mAppRow != null) { - if (!mAppRow.systemApp) { + if (!mAppRow.systemApp && !mAppRow.lockedImportance) { return true; } @@ -183,6 +225,16 @@ public abstract class NotificationPreferenceController extends AbstractPreferenc return Objects.equals(NotificationChannel.DEFAULT_CHANNEL_ID, mChannel.getId()); } + protected final void setOverrideCanBlock(boolean canBlock) { + overrideCanBlock = true; + overrideCanBlockValue = canBlock; + } + + protected final void setOverrideCanConfigure(boolean canConfigure) { + overrideCanConfigure = true; + overrideCanConfigureValue = canConfigure; + } + public static final Comparator CHANNEL_GROUP_COMPARATOR = new Comparator() { @Override diff --git a/tests/robotests/src/com/android/settings/notification/NotificationBackendTest.java b/tests/robotests/src/com/android/settings/notification/NotificationBackendTest.java index 17471b5d90c..063be35fe77 100644 --- a/tests/robotests/src/com/android/settings/notification/NotificationBackendTest.java +++ b/tests/robotests/src/com/android/settings/notification/NotificationBackendTest.java @@ -16,6 +16,9 @@ package com.android.settings.notification; +import static android.os.UserHandle.USER_SYSTEM; +import static android.provider.Settings.*; + import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertFalse; @@ -24,6 +27,7 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import android.app.INotificationManager; import android.app.role.RoleManager; import android.app.usage.UsageEvents; import android.bluetooth.BluetoothAdapter; @@ -33,6 +37,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Parcel; +import android.provider.Settings; import com.android.settings.notification.NotificationBackend.AppRow; import com.android.settingslib.bluetooth.CachedBluetoothDevice; @@ -63,11 +68,16 @@ public class NotificationBackendTest { @Mock CachedBluetoothDeviceManager mCbm; ComponentName mCn = new ComponentName("a", "b"); + @Mock + INotificationManager mInm; + NotificationBackend mNotificationBackend; @Before public void setUp() { MockitoAnnotations.initMocks(this); when(mBm.getCachedDeviceManager()).thenReturn(mCbm); + mNotificationBackend = new NotificationBackend(); + mNotificationBackend.setNm(mInm); } @Test @@ -101,6 +111,46 @@ public class NotificationBackendTest { assertTrue(appRow.systemApp); } + @Test + public void testMarkAppRow_fixedPermission() throws Exception { + Secure.putIntForUser(RuntimeEnvironment.application.getContentResolver(), + Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 1, USER_SYSTEM); + + PackageInfo pi = new PackageInfo(); + pi.packageName = "test"; + pi.applicationInfo = new ApplicationInfo(); + pi.applicationInfo.packageName = "test"; + pi.applicationInfo.uid = 123; + + when(mInm.isPermissionFixed(pi.packageName, 0)).thenReturn(true); + + AppRow appRow = new NotificationBackend().loadAppRow(RuntimeEnvironment.application, + mock(PackageManager.class), mock(RoleManager.class), pi); + + assertTrue(appRow.systemApp); + assertTrue(appRow.lockedImportance); + } + + @Test + public void testMarkAppRow_notFixedPermission() throws Exception { + Secure.putIntForUser(RuntimeEnvironment.application.getContentResolver(), + Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 1, USER_SYSTEM); + + PackageInfo pi = new PackageInfo(); + pi.packageName = "test"; + pi.applicationInfo = new ApplicationInfo(); + pi.applicationInfo.packageName = "test"; + pi.applicationInfo.uid = 123; + + when(mInm.isPermissionFixed(pi.packageName, 0)).thenReturn(false); + + AppRow appRow = new NotificationBackend().loadAppRow(RuntimeEnvironment.application, + mock(PackageManager.class), mock(RoleManager.class), pi); + + assertFalse(appRow.systemApp); + assertFalse(appRow.lockedImportance); + } + @Test public void testMarkAppRow_notDefaultPackage() { PackageInfo pi = new PackageInfo(); diff --git a/tests/robotests/src/com/android/settings/notification/app/AllowSoundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/AllowSoundPreferenceControllerTest.java index be663d8f8c8..5260ff64c1d 100644 --- a/tests/robotests/src/com/android/settings/notification/app/AllowSoundPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/AllowSoundPreferenceControllerTest.java @@ -165,20 +165,6 @@ public class AllowSoundPreferenceControllerTest { assertFalse(pref.isEnabled()); } - @Test - public void testUpdateState_notBlockable_oem() { - NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - NotificationChannel channel = mock(NotificationChannel.class); - when(channel.getId()).thenReturn(""); - when(channel.isImportanceLockedByOEM()).thenReturn(true); - mController.onResume(appRow, channel, null, null, null, null, null); - - Preference pref = new RestrictedSwitchPreference(mContext); - mController.updateState(pref); - - assertTrue(pref.isEnabled()); - } - @Test public void testUpdateState_configurable() { NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); diff --git a/tests/robotests/src/com/android/settings/notification/app/BadgePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/BadgePreferenceControllerTest.java index 9cdf64dc79d..d8717764111 100644 --- a/tests/robotests/src/com/android/settings/notification/app/BadgePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/BadgePreferenceControllerTest.java @@ -217,20 +217,6 @@ public class BadgePreferenceControllerTest { assertFalse(pref.isEnabled()); } - @Test - public void testUpdateState_channelNotBlockable() { - NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - NotificationChannel channel = mock(NotificationChannel.class); - when(channel.getId()).thenReturn(""); - when(channel.isImportanceLockedByOEM()).thenReturn(true); - mController.onResume(appRow, channel, null, null, null, null, null); - - Preference pref = new RestrictedSwitchPreference(mContext); - mController.updateState(pref); - - assertTrue(pref.isEnabled()); - } - @Test public void testUpdateState_channel() { NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); diff --git a/tests/robotests/src/com/android/settings/notification/app/BlockPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/BlockPreferenceControllerTest.java index d65f91dd0b1..0c2eebe8070 100644 --- a/tests/robotests/src/com/android/settings/notification/app/BlockPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/BlockPreferenceControllerTest.java @@ -200,68 +200,40 @@ public class BlockPreferenceControllerTest { } @Test - public void testIsEnabled_lockedApp() { + public void testIsEnabled_cannotBlockAppOrGroupOrChannel() { + mController.setOverrideCanBlock(false); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.lockedImportance = true; - appRow.systemApp = true; mController.onResume(appRow, null, null, null, null, null, null); mController.updateState(mPreference); assertFalse(mPreference.getSwitchBar().isEnabled()); } @Test - public void testIsEnabled_GroupNotBlockable() { + public void testIsEnabled_importanceLocked_app() { + mController.setOverrideCanConfigure(false); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.systemApp = true; - mController.onResume(appRow, null, mock(NotificationChannelGroup.class), null, null, null, - null); - mController.updateState(mPreference); - assertFalse(mPreference.getSwitchBar().isEnabled()); - } - - @Test - public void testIsEnabled_systemAppNotBlockable() { - NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.systemApp = true; mController.onResume(appRow, null, null, null, null, null, null); mController.updateState(mPreference); assertFalse(mPreference.getSwitchBar().isEnabled()); } @Test - public void testIsEnabled_systemAppBlockable() { + public void testIsEnabled_importanceLocked_group() { + mController.setOverrideCanConfigure(false); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.systemApp = true; - NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT); - channel.setBlockable(true); - mController.onResume(appRow, channel, null, null, null, null, null); + mController.onResume( + appRow, null, new NotificationChannelGroup("a", "a"), null, null, null, null); mController.updateState(mPreference); - assertTrue(mPreference.getSwitchBar().isEnabled()); - } - - @Test - public void testIsEnabled_lockedChannel() { - NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByOEM()).thenReturn(true); - when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); - mController.onResume(appRow, channel, null, null, null, null, null); - - mController.updateState(mPreference); - assertFalse(mPreference.getSwitchBar().isEnabled()); } @Test - public void testIsEnabled_defaultAppChannel() { + public void testIsEnabled_importanceLocked_channel() { + mController.setOverrideCanConfigure(false); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByCriticalDeviceFunction()).thenReturn(true); - when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); - mController.onResume(appRow, channel, null, null, null, null, null); - + mController.onResume(appRow, new NotificationChannel("a", "a", IMPORTANCE_LOW), null, null, + null, null, null); mController.updateState(mPreference); - assertFalse(mPreference.getSwitchBar().isEnabled()); } diff --git a/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java index e04402cd97a..09f6b7d634a 100644 --- a/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java @@ -297,21 +297,6 @@ public class BubblePreferenceControllerTest { assertFalse(pref.isEnabled()); } - @Test - public void updateState_channel_channelNotBlockable() { - Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON); - NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.pkg = "a"; - NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByCriticalDeviceFunction()).thenReturn(true); - mController.onResume(appRow, channel, null, null, null, null, null); - - Preference pref = new RestrictedSwitchPreference(mContext); - mController.updateState(pref); - - assertTrue(pref.isEnabled()); - } - @Test public void updateState_channel() { Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON); diff --git a/tests/robotests/src/com/android/settings/notification/app/ConversationPriorityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/ConversationPriorityPreferenceControllerTest.java index 692a4b18b5c..9bd2f153c05 100644 --- a/tests/robotests/src/com/android/settings/notification/app/ConversationPriorityPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/ConversationPriorityPreferenceControllerTest.java @@ -146,9 +146,9 @@ public class ConversationPriorityPreferenceControllerTest { @Test public void testUpdateState_notConfigurable() { + mController.setOverrideCanConfigure(false); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByOEM()).thenReturn(true); when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); mController.onResume(appRow, channel, null, null, null, null, null); @@ -159,26 +159,10 @@ public class ConversationPriorityPreferenceControllerTest { } @Test - public void testUpdateState_systemButConfigurable() { + public void testUpdateState_Configurable() { + mController.setOverrideCanConfigure(true); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.systemApp = true; NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByOEM()).thenReturn(false); - when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); - mController.onResume(appRow, channel, null, null, null, null, null); - - Preference pref = new ConversationPriorityPreference(mContext, null); - mController.updateState(pref); - - assertTrue(pref.isEnabled()); - } - - @Test - public void testUpdateState_defaultApp() { - NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.systemApp = true; - NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByCriticalDeviceFunction()).thenReturn(true); when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); mController.onResume(appRow, channel, null, null, null, null, null); diff --git a/tests/robotests/src/com/android/settings/notification/app/DndPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/DndPreferenceControllerTest.java index 22a7b0946bc..7357bb3f12f 100644 --- a/tests/robotests/src/com/android/settings/notification/app/DndPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/DndPreferenceControllerTest.java @@ -138,8 +138,8 @@ public class DndPreferenceControllerTest { @Test public void testUpdateState_notBlockable() { NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.lockedImportance = true; NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByOEM()).thenReturn(true); mController.onResume(appRow, channel, null, null, null, null, null); Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application); diff --git a/tests/robotests/src/com/android/settings/notification/app/HighImportancePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/HighImportancePreferenceControllerTest.java index 0db46789d19..5189beb6fbb 100644 --- a/tests/robotests/src/com/android/settings/notification/app/HighImportancePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/HighImportancePreferenceControllerTest.java @@ -166,9 +166,9 @@ public class HighImportancePreferenceControllerTest { @Test public void testUpdateState_notConfigurable() { + mController.setOverrideCanConfigure(false); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByOEM()).thenReturn(true); when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); mController.onResume(appRow, channel, null, null, null, null, null); @@ -179,26 +179,10 @@ public class HighImportancePreferenceControllerTest { } @Test - public void testUpdateState_systemButConfigurable() { + public void testUpdateState_Configurable() { + mController.setOverrideCanConfigure(true); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.systemApp = true; NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByOEM()).thenReturn(false); - when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); - mController.onResume(appRow, channel, null, null, null, null, null); - - Preference pref = new RestrictedSwitchPreference(mContext, null); - mController.updateState(pref); - - assertTrue(pref.isEnabled()); - } - - @Test - public void testUpdateState_defaultApp() { - NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.systemApp = true; - NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByCriticalDeviceFunction()).thenReturn(true); when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); mController.onResume(appRow, channel, null, null, null, null, null); diff --git a/tests/robotests/src/com/android/settings/notification/app/ImportancePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/ImportancePreferenceControllerTest.java index 223fa23324b..34f777a5cbd 100644 --- a/tests/robotests/src/com/android/settings/notification/app/ImportancePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/ImportancePreferenceControllerTest.java @@ -183,9 +183,9 @@ public class ImportancePreferenceControllerTest { @Test public void testUpdateState_notConfigurable() { + mController.setOverrideCanConfigure(false); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByOEM()).thenReturn(true); when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); mController.onResume(appRow, channel, null, null, null, null, null); @@ -196,26 +196,10 @@ public class ImportancePreferenceControllerTest { } @Test - public void testUpdateState_systemButConfigurable() { + public void testUpdateState_Configurable() { + mController.setOverrideCanConfigure(true); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.systemApp = true; NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByOEM()).thenReturn(false); - when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); - mController.onResume(appRow, channel, null, null, null, null, null); - - Preference pref = new ImportancePreference(mContext, null); - mController.updateState(pref); - - assertTrue(pref.isEnabled()); - } - - @Test - public void testUpdateState_defaultApp() { - NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.systemApp = true; - NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByCriticalDeviceFunction()).thenReturn(true); when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); mController.onResume(appRow, channel, null, null, null, null, null); diff --git a/tests/robotests/src/com/android/settings/notification/app/LightsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/LightsPreferenceControllerTest.java index e51a9e003ba..d977d8b091c 100644 --- a/tests/robotests/src/com/android/settings/notification/app/LightsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/LightsPreferenceControllerTest.java @@ -181,19 +181,6 @@ public class LightsPreferenceControllerTest { assertFalse(pref.isEnabled()); } - @Test - public void testUpdateState_notBlockable() { - NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByOEM()).thenReturn(true); - mController.onResume(appRow, channel, null, null, null, null, null); - - Preference pref = new RestrictedSwitchPreference(mContext); - mController.updateState(pref); - - assertTrue(pref.isEnabled()); - } - @Test public void testUpdateState_lightsOn() { NotificationChannel channel = mock(NotificationChannel.class); diff --git a/tests/robotests/src/com/android/settings/notification/app/MinImportancePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/MinImportancePreferenceControllerTest.java index 3907db22f92..b3d5cf01d81 100644 --- a/tests/robotests/src/com/android/settings/notification/app/MinImportancePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/MinImportancePreferenceControllerTest.java @@ -166,9 +166,9 @@ public class MinImportancePreferenceControllerTest { @Test public void testUpdateState_notConfigurable() { + mController.setOverrideCanConfigure(false); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByOEM()).thenReturn(true); when(channel.getImportance()).thenReturn(IMPORTANCE_LOW); mController.onResume(appRow, channel, null, null, null, null, null); @@ -179,26 +179,11 @@ public class MinImportancePreferenceControllerTest { } @Test - public void testUpdateState_systemButConfigurable() { + public void testUpdateState_Configurable() { + mController.setOverrideCanConfigure(true); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.systemApp = true; NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByOEM()).thenReturn(false); - when(channel.getImportance()).thenReturn(IMPORTANCE_LOW); - mController.onResume(appRow, channel, null, null, null, null, null); - - Preference pref = new RestrictedSwitchPreference(mContext, null); - mController.updateState(pref); - - assertTrue(pref.isEnabled()); - } - - @Test - public void testUpdateState_defaultApp() { - NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.systemApp = true; - NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByCriticalDeviceFunction()).thenReturn(true); + when(channel.isBlockable()).thenReturn(true); when(channel.getImportance()).thenReturn(IMPORTANCE_LOW); mController.onResume(appRow, channel, null, null, null, null, null); diff --git a/tests/robotests/src/com/android/settings/notification/app/NotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/NotificationPreferenceControllerTest.java index 1fb9942fcb2..8d31fe53354 100644 --- a/tests/robotests/src/com/android/settings/notification/app/NotificationPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/NotificationPreferenceControllerTest.java @@ -22,6 +22,7 @@ import static android.app.NotificationManager.IMPORTANCE_LOW; import static android.app.NotificationManager.IMPORTANCE_MIN; import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; +import static android.os.UserHandle.USER_SYSTEM; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -38,6 +39,7 @@ import android.app.NotificationChannelGroup; import android.app.NotificationManager; import android.content.Context; import android.os.UserManager; +import android.provider.Settings; import androidx.preference.Preference; @@ -221,6 +223,109 @@ public class NotificationPreferenceControllerTest { verify(mBackend, times(1)).updateChannel(any(), anyInt(), any()); } + @Test + public void testIsChannelBlockable_postMigration_locked() { + Settings.Secure.putIntForUser(RuntimeEnvironment.application.getContentResolver(), + Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 1, USER_SYSTEM); + + mController = new TestPreferenceController(mContext, mBackend); + + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.lockedImportance = true; + NotificationChannel channel = mock(NotificationChannel.class); + when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); + mController.onResume(appRow, channel, null, null, null, null, null); + assertFalse(mController.isChannelBlockable()); + } + + @Test + public void testIsChannelBlockable_postMigration_locked_butChannelOff() { + Settings.Secure.putIntForUser(RuntimeEnvironment.application.getContentResolver(), + Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 1, USER_SYSTEM); + + mController = new TestPreferenceController(mContext, mBackend); + + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.lockedImportance = true; + NotificationChannel channel = mock(NotificationChannel.class); + when(channel.getImportance()).thenReturn(IMPORTANCE_NONE); + mController.onResume(appRow, channel, null, null, null, null, null); + assertTrue(mController.isChannelBlockable()); + } + + @Test + public void testIsChannelBlockable_postMigration_locked_butChannelBlockable() { + Settings.Secure.putIntForUser(RuntimeEnvironment.application.getContentResolver(), + Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 1, USER_SYSTEM); + + mController = new TestPreferenceController(mContext, mBackend); + + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.lockedImportance = true; + NotificationChannel channel = mock(NotificationChannel.class); + when(channel.isBlockable()).thenReturn(true); + when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); + mController.onResume(appRow, channel, null, null, null, null, null); + assertTrue(mController.isChannelBlockable()); + } + + @Test + public void testIsChannelGroupBlockable_postMigration_locked() { + Settings.Secure.putIntForUser(RuntimeEnvironment.application.getContentResolver(), + Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 1, USER_SYSTEM); + + mController = new TestPreferenceController(mContext, mBackend); + + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.lockedImportance = true; + NotificationChannelGroup channelGroup = mock(NotificationChannelGroup.class); + mController.onResume(appRow, null, channelGroup, null, null, null, null); + assertFalse(mController.isChannelGroupBlockable()); + } + + @Test + public void testIsChannelGroupBlockable_postMigration_locked_butChannelGroupOff() { + Settings.Secure.putIntForUser(RuntimeEnvironment.application.getContentResolver(), + Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 1, USER_SYSTEM); + + mController = new TestPreferenceController(mContext, mBackend); + + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.lockedImportance = true; + NotificationChannelGroup channelGroup = mock(NotificationChannelGroup.class); + when(channelGroup.isBlocked()).thenReturn(true); + mController.onResume(appRow, null, channelGroup, null, null, null, null); + assertTrue(mController.isChannelGroupBlockable()); + } + + @Test + public void testIsAppBlockable_postMigration_locked() { + Settings.Secure.putIntForUser(RuntimeEnvironment.application.getContentResolver(), + Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 1, USER_SYSTEM); + + mController = new TestPreferenceController(mContext, mBackend); + + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.lockedImportance = true; + appRow.banned = false; + mController.onResume(appRow, null, null, null, null, null, null); + assertFalse(mController.isAppBlockable()); + } + + @Test + public void testIsAppBlockable_postMigration_locked_butAppOff() { + Settings.Secure.putIntForUser(RuntimeEnvironment.application.getContentResolver(), + Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 1, USER_SYSTEM); + + mController = new TestPreferenceController(mContext, mBackend); + + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.lockedImportance = true; + appRow.banned = true; + mController.onResume(appRow, null, null, null, null, null, null); + assertFalse(mController.isAppBlockable()); + } + @Test public void testIsBlockable_oemAllowlist() { NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); diff --git a/tests/robotests/src/com/android/settings/notification/app/SoundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/SoundPreferenceControllerTest.java index c79b97d3ba2..273bcdbe213 100644 --- a/tests/robotests/src/com/android/settings/notification/app/SoundPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/SoundPreferenceControllerTest.java @@ -182,20 +182,6 @@ public class SoundPreferenceControllerTest { assertFalse(pref.isEnabled()); } - @Test - public void testUpdateState_notBlockable() { - NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByOEM()).thenReturn(true); - mController.onResume(appRow, channel, null, null, null, null, null); - - AttributeSet attributeSet = Robolectric.buildAttributeSet().build(); - Preference pref = new NotificationSoundPreference(mContext, attributeSet); - mController.updateState(pref); - - assertTrue(pref.isEnabled()); - } - @Test public void testUpdateState_configurable() { Uri sound = Settings.System.DEFAULT_ALARM_ALERT_URI; diff --git a/tests/robotests/src/com/android/settings/notification/app/VibrationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/VibrationPreferenceControllerTest.java index 0fb5e72eb51..ad6df604654 100644 --- a/tests/robotests/src/com/android/settings/notification/app/VibrationPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/VibrationPreferenceControllerTest.java @@ -162,10 +162,9 @@ public class VibrationPreferenceControllerTest { } @Test - public void testUpdateState_notBlockable() { + public void testUpdateState_blockable() { NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); NotificationChannel channel = mock(NotificationChannel.class); - when(channel.isImportanceLockedByOEM()).thenReturn(true); mController.onResume(appRow, channel, null, null, null, null, null); Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);