Fix the toggle status for show sensitive content switches

We need to make the show sensitive content switch checked by default.
The old implementation misses calling to super.updateState(), which
caused lacking of UI refreshment.
This change also added validation to the preference id that is used
to construct the LockScreenNotificationShowSensitiveController, which
avoids misusage.
Added unit tests to verify that the UI is also updated upon Settings
change, and the preference IDs are verified.

Fix: 392621932
Flag: com.android.server.notification.notification_lock_screen_settings
Test: manual
Change-Id: I31fe602d5b5439515e5fdf5c706b420edaf79042
This commit is contained in:
Yining Liu
2025-01-27 14:13:34 -08:00
parent 7e6cc163d9
commit 1436bcff72
2 changed files with 47 additions and 3 deletions

View File

@@ -81,6 +81,13 @@ public class LockScreenNotificationShowSensitiveController
public LockScreenNotificationShowSensitiveController(@NonNull Context context, public LockScreenNotificationShowSensitiveController(@NonNull Context context,
@NonNull String preferenceKey) { @NonNull String preferenceKey) {
super(context, preferenceKey); super(context, preferenceKey);
// This prevents unexpected controller usages.
if (!KEY_SHOW_SENSITIVE.equals(preferenceKey)
&& !KEY_SHOW_SENSITIVE_WORK_PROFILE.equals(preferenceKey)) {
throw new IllegalArgumentException("Invalid preference key: " + preferenceKey);
}
mContentResolver = context.getContentResolver(); mContentResolver = context.getContentResolver();
mUserManager = context.getSystemService(UserManager.class); mUserManager = context.getSystemService(UserManager.class);
@@ -138,13 +145,18 @@ public class LockScreenNotificationShowSensitiveController
} }
private int getUserId() { private int getUserId() {
return KEY_SHOW_SENSITIVE.equals(getPreferenceKey()) return switch (getPreferenceKey()) {
? UserHandle.myUserId() : mWorkProfileUserId; case KEY_SHOW_SENSITIVE -> UserHandle.myUserId();
case KEY_SHOW_SENSITIVE_WORK_PROFILE -> mWorkProfileUserId;
default -> throw new IllegalArgumentException(
"Invalid preference key: " + getPreferenceKey());
};
} }
@Override @Override
public void updateState(@Nullable Preference preference) { public void updateState(@Nullable Preference preference) {
if (preference == null) return; if (preference == null) return;
super.updateState(preference);
setChecked(showSensitiveContentWhenLocked()); setChecked(showSensitiveContentWhenLocked());
preference.setVisible(isAvailable()); preference.setVisible(isAvailable());
} }
@@ -195,7 +207,7 @@ public class LockScreenNotificationShowSensitiveController
if (!isLockScreenSecure()) return true; if (!isLockScreenSecure()) return true;
if (getEnforcedAdmin(userId) != null) return false; if (getEnforcedAdmin(userId) != null) return false;
return Settings.Secure.getIntForUser(mContext.getContentResolver(), return Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, ON, userId) == ON; Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, ON, userId) != OFF;
} }
@Override @Override

View File

@@ -131,6 +131,14 @@ public class LockScreenNotificationShowSensitiveControllerTest {
assertThat(mWorkController.mWorkProfileUserId).isEqualTo(10); assertThat(mWorkController.mWorkProfileUserId).isEqualTo(10);
} }
@Test(expected = IllegalArgumentException.class)
public void validatePreferenceId() {
new LockScreenNotificationShowSensitiveController(
mMockContext,
"Illegal Key"
);
}
@Test @Test
public void getAvailabilityStatus_noSecureLockscreen() { public void getAvailabilityStatus_noSecureLockscreen() {
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false); when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false);
@@ -266,34 +274,58 @@ public class LockScreenNotificationShowSensitiveControllerTest {
@Test @Test
public void isChecked() { public void isChecked() {
// Given: screen is secure
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true); when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
// When: disable LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS
// then updateState, this mocks the mWorkController.mContentObserver.onChange()
Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.putIntForUser(mContext.getContentResolver(),
LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
0, 0); 0, 0);
mController.updateState(mPreference);
// Then: the toggle is unchecked
assertThat(mController.isChecked()).isFalse(); assertThat(mController.isChecked()).isFalse();
assertThat(mPreference.isChecked()).isFalse();
// When: enable LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS
// then updateState, this mocks the mWorkController.mContentObserver.onChange()
Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.putIntForUser(mContext.getContentResolver(),
LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
1, 0); 1, 0);
mController.updateState(mPreference);
// Then: the toggle is checked
assertThat(mController.isChecked()).isTrue(); assertThat(mController.isChecked()).isTrue();
assertThat(mPreference.isChecked()).isTrue();
} }
@Test @Test
public void isChecked_work() { public void isChecked_work() {
// Given: screen is secure
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true); when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
// When: disable LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS for work profile
// then updateState, this mocks the mWorkController.mContentObserver.onChange()
Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.putIntForUser(mContext.getContentResolver(),
LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
0, 10); 0, 10);
mWorkController.updateState(mWorkPreference);
// Then: the toggle is unchecked
assertThat(mWorkController.isChecked()).isFalse(); assertThat(mWorkController.isChecked()).isFalse();
assertThat(mWorkPreference.isChecked()).isFalse();
// When: enable LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS for work profile
// then updateState, this mocks the mWorkController.mContentObserver.onChange()
Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.putIntForUser(mContext.getContentResolver(),
LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
1, 10); 1, 10);
mWorkController.updateState(mWorkPreference);
// Then: the toggle is checked
assertThat(mWorkController.isChecked()).isTrue(); assertThat(mWorkController.isChecked()).isTrue();
assertThat(mWorkPreference.isChecked()).isTrue();
} }
@Test @Test