Layout improvements for notification pages

Changes for upcoming theming changes in Settings:
- replacing some margins with padding
- merging some (switch pref + info pref) combos into a single preference.
I flagged the one that was already launched, but changed the other directly
- added some section headers (unflagged)
- moved all app wide notification settings to a single section (unflagged)
- changed two plain text prefs into TopIntroPreference, the dedicated pref
type for that sort of UI
- fixed some UI issues with 'Show more categories' appearing too often
- removed a duplicate notifcation channel label (unflagged)
- replaced a button layout preference with ButtonPreference (unflagged)

Test: manual review with is_expressive_design_enabled on and off
Test: atest com.android.settings.notification.app
Flag: EXEMPT this feature is not using aconfig for flagging
Bug: 349652992
Change-Id: I2acd7b2eb9dbcf6929143bfde99cd67163f1f95d
This commit is contained in:
Julia Reynolds
2024-11-20 10:32:59 -05:00
parent b7e1cc472e
commit 41896428ea
30 changed files with 261 additions and 215 deletions

View File

@@ -38,6 +38,8 @@ import android.content.Context;
import android.os.UserManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import com.android.settings.notification.NotificationBackend;
@@ -68,7 +70,6 @@ public class AllowSoundPreferenceControllerTest {
private NotificationManager mNm;
@Mock
private UserManager mUm;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceScreen mScreen;
@Mock
@@ -83,6 +84,7 @@ public class AllowSoundPreferenceControllerTest {
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
mContext = RuntimeEnvironment.application;
mScreen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
mController =
spy(new AllowSoundPreferenceController(mContext, mDependentFieldListener, mBackend));
}
@@ -160,6 +162,7 @@ public class AllowSoundPreferenceControllerTest {
RestrictedLockUtils.EnforcedAdmin.class), null);
Preference pref = new RestrictedSwitchPreference(mContext);
mScreen.addPreference(pref);
mController.updateState(pref);
assertFalse(pref.isEnabled());
@@ -173,6 +176,7 @@ public class AllowSoundPreferenceControllerTest {
mController.onResume(appRow, channel, null, null, null, null, null);
Preference pref = new RestrictedSwitchPreference(mContext);
mScreen.addPreference(pref);
mController.updateState(pref);
assertTrue(pref.isEnabled());
@@ -186,6 +190,7 @@ public class AllowSoundPreferenceControllerTest {
null);
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
mScreen.addPreference(pref);
mController.updateState(pref);
assertTrue(pref.isChecked());
}
@@ -198,6 +203,7 @@ public class AllowSoundPreferenceControllerTest {
null);
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
mScreen.addPreference(pref);
mController.updateState(pref);
assertTrue(pref.isChecked());
}
@@ -210,6 +216,7 @@ public class AllowSoundPreferenceControllerTest {
null);
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
mScreen.addPreference(pref);
mController.updateState(pref);
assertFalse(pref.isChecked());
}
@@ -222,7 +229,7 @@ public class AllowSoundPreferenceControllerTest {
null);
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mScreen.addPreference(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
pref.setChecked(true);
@@ -240,7 +247,7 @@ public class AllowSoundPreferenceControllerTest {
null);
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mScreen.addPreference(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);

View File

@@ -37,6 +37,7 @@ import android.permission.PermissionManager.PERMISSION_HARD_DENIED
import android.permission.PermissionManager.PERMISSION_SOFT_DENIED
import android.permission.PermissionManager.PermissionResult
import androidx.preference.Preference
import androidx.preference.PreferenceManager
import androidx.preference.PreferenceScreen
import androidx.test.core.app.ApplicationProvider
import com.android.settings.notification.NotificationBackend
@@ -80,7 +81,6 @@ class FullScreenIntentPermissionPreferenceControllerTest {
private lateinit var preference: RestrictedSwitchPreference
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private lateinit var screen: PreferenceScreen
private lateinit var controller: FullScreenIntentPermissionPreferenceController
@@ -94,7 +94,8 @@ class FullScreenIntentPermissionPreferenceControllerTest {
preference = RestrictedSwitchPreference(context).apply { key = KEY_FSI_PERMISSION }
whenever(screen.findPreference<Preference>(KEY_FSI_PERMISSION)).thenReturn(preference)
screen = PreferenceManager(context).createPreferenceScreen(context)
screen.addPreference(preference)
controller = FullScreenIntentPermissionPreferenceController(
context,

View File

@@ -113,27 +113,6 @@ public class HeaderPreferenceControllerTest {
assertTrue(mController.isAvailable());
}
@Test
public void testGetLabel() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.label = "bananas";
mController.onResume(appRow, null, null, null, null, null, null);
assertEquals(appRow.label, mController.getLabel());
NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
mController.onResume(appRow, null, group, null, null, null, null);
assertEquals(appRow.label, mController.getLabel());
NotificationChannel channel = new NotificationChannel("cid", "cname", IMPORTANCE_NONE);
mController.onResume(appRow, channel, group, null, null, null, null);
assertEquals(channel.getName(), mController.getLabel());
NotificationChannel defaultChannel = new NotificationChannel(
NotificationChannel.DEFAULT_CHANNEL_ID, "", IMPORTANCE_NONE);
mController.onResume(appRow, defaultChannel, null, null, null, null, null);
assertEquals(appRow.label, mController.getLabel());
}
@Test
public void testGetSummary() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
@@ -146,16 +125,14 @@ public class HeaderPreferenceControllerTest {
NotificationChannel channel = new NotificationChannel("cid", "cname", IMPORTANCE_NONE);
mController.onResume(appRow, channel, group, null, null, null, null);
assertTrue(mController.getSummary().toString().contains(group.getName()));
assertTrue(mController.getSummary().toString().contains(appRow.label));
mController.onResume(appRow, channel, null, null, null, null, null);
assertFalse(mController.getSummary().toString().contains(group.getName()));
assertTrue(mController.getSummary().toString().contains(appRow.label));
NotificationChannel defaultChannel = new NotificationChannel(
NotificationChannel.DEFAULT_CHANNEL_ID, "", IMPORTANCE_NONE);
mController.onResume(appRow, defaultChannel, null, null, null, null, null);
assertEquals(appRow.label, mController.getSummary());
assertEquals("", mController.getSummary());
}
@Test

View File

@@ -34,6 +34,7 @@ import androidx.preference.PreferenceScreen;
import com.android.settings.notification.NotificationBackend;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settingslib.widget.SettingsThemeHelper;
import com.google.common.collect.ImmutableList;
@@ -88,6 +89,18 @@ public class InvalidConversationInfoPreferenceControllerTest {
mController.updateState(mock(Preference.class));
}
@Test
public void testIsAvailable_notIfExpressiveTheme() {
if (SettingsThemeHelper.isExpressiveTheme(mContext)) {
when(mBackend.isInInvalidMsgState(anyString(), anyInt())).thenReturn(true);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.pkg = "hi";
appRow.uid = 0;
mController.onResume(appRow, null, null, null, null, null, null);
assertFalse(mController.isAvailable());
}
}
@Test
public void testIsAvailable_notIfAppBlocked() {
when(mBackend.isInInvalidMsgState(anyString(), anyInt())).thenReturn(true);
@@ -111,6 +124,9 @@ public class InvalidConversationInfoPreferenceControllerTest {
@Test
public void testIsAvailable() {
if (SettingsThemeHelper.isExpressiveTheme(mContext)) {
return;
}
when(mBackend.isInInvalidMsgState(anyString(), anyInt())).thenReturn(true);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.pkg = "hi";

View File

@@ -18,13 +18,12 @@ package com.android.settings.notification.app;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Flags;
import android.content.Context;
@@ -32,7 +31,7 @@ import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceManager;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.notification.NotificationBackend;
@@ -55,8 +54,6 @@ public class PromotedNotificationsPreferenceControllerTest {
private NotificationBackend.AppRow mAppRow;
@Mock
private NotificationBackend mBackend;
@Mock
private PreferenceCategory mPrefCategory;
private RestrictedSwitchPreference mSwitch;
private PromotedNotificationsPreferenceController mPrefController;
@@ -66,7 +63,7 @@ public class PromotedNotificationsPreferenceControllerTest {
MockitoAnnotations.initMocks(this);
mContext = ApplicationProvider.getApplicationContext();
mSwitch = new RestrictedSwitchPreference(mContext);
when(mPrefCategory.findPreference("promoted_switch")).thenReturn(mSwitch);
new PreferenceManager(mContext).createPreferenceScreen(mContext).addPreference(mSwitch);
mPrefController = new PromotedNotificationsPreferenceController(mContext, mBackend);
mAppRow = new NotificationBackend.AppRow();
@@ -93,12 +90,12 @@ public class PromotedNotificationsPreferenceControllerTest {
mAppRow.canBePromoted = true;
mPrefController.onResume(mAppRow, null, null, null, null, null, null);
mPrefController.updateState(mPrefCategory);
mPrefController.updateState(mSwitch);
assertThat(mSwitch.isChecked()).isTrue();
mAppRow.canBePromoted = false;
mPrefController.onResume(mAppRow, null, null, null, null, null, null);
mPrefController.updateState(mPrefCategory);
mPrefController.updateState(mSwitch);
assertThat(mSwitch.isChecked()).isFalse();
}

View File

@@ -50,6 +50,7 @@ import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.applications.AppInfoBase;
import com.android.settings.notification.NotificationBackend;
import com.android.settingslib.widget.ButtonPreference;
import com.android.settingslib.widget.LayoutPreference;
import com.google.common.collect.ImmutableList;
@@ -232,14 +233,16 @@ public class RecentConversationsPreferenceControllerTest {
new NotificationChannelGroup("hi", "group"), 7,
false);
RecentConversationPreference pref = mController.createConversationPref(ccw);
Preference pref = mController.createConversationPref(ccw);
final View view = View.inflate(mContext, pref.getLayoutResource(), null);
PreferenceViewHolder holder = spy(PreferenceViewHolder.createInstanceForTests(view));
View delete = View.inflate(mContext, pref.getSecondTargetResId(), null);
when(holder.findViewById(pref.getClearId())).thenReturn(delete);
View delete = View.inflate(mContext, ((RecentConversationPreference) pref)
.getSecondTargetResId(), null);
when(holder.findViewById(((RecentConversationPreference) pref).getClearId()))
.thenReturn(delete);
pref.onBindViewHolder(holder);
pref.getClearView().performClick();
((RecentConversationPreference) pref).getClearView().performClick();
verify(mPs).removeRecentConversation(
si.getPackage(), UserHandle.getUserId(ccw.getUid()), si.getId());
@@ -260,24 +263,24 @@ public class RecentConversationsPreferenceControllerTest {
new NotificationChannelGroup("hi", "group"), 7,
true);
RecentConversationPreference pref = mController.createConversationPref(ccw);
Preference pref = mController.createConversationPref(ccw);
final View view = View.inflate(mContext, pref.getLayoutResource(), null);
PreferenceViewHolder holder = spy(PreferenceViewHolder.createInstanceForTests(view));
View delete = View.inflate(mContext, pref.getSecondTargetResId(), null);
when(holder.findViewById(pref.getClearId())).thenReturn(delete);
View delete = View.inflate(mContext, ((RecentConversationPreference) pref).
getSecondTargetResId(), null);
when(holder.findViewById(((RecentConversationPreference) pref).getClearId()))
.thenReturn(delete);
mPreferenceGroup.addPreference(pref);
RecentConversationPreference pref2 = mController.createConversationPref(ccw2);
final View view2 = View.inflate(mContext, pref2.getLayoutResource(), null);
PreferenceViewHolder holder2 = spy(PreferenceViewHolder.createInstanceForTests(view2));
View delete2 = View.inflate(mContext, pref2.getSecondTargetResId(), null);
when(holder2.findViewById(pref.getClearId())).thenReturn(delete2);
Preference pref2 = mController.createConversationPref(ccw2);
mPreferenceGroup.addPreference(pref2);
LayoutPreference clearAll = mController.getClearAll(mPreferenceGroup);
ButtonPreference clearAll = mController.getClearAll(mPreferenceGroup);
final View rootView = View.inflate(mContext, clearAll.getLayoutResource(), null);
clearAll.onBindViewHolder(PreferenceViewHolder.createInstanceForTests(rootView));
mPreferenceGroup.addPreference(clearAll);
clearAll.findViewById(R.id.conversation_settings_clear_recents).performClick();
clearAll.getButton().performClick();
verify(mPs).removeAllRecentConversations();
assertThat((Preference) mPreferenceGroup.findPreference("hi:person")).isNull();
@@ -294,9 +297,9 @@ public class RecentConversationsPreferenceControllerTest {
new NotificationChannelGroup("hi", "group"), 7,
true);
RecentConversationPreference pref = mController.createConversationPref(ccw);
Preference pref = mController.createConversationPref(ccw);
assertThat(pref.hasClearListener()).isFalse();
assertThat(pref instanceof RecentConversationPreference).isFalse();
}
@Test