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:
@@ -23,6 +23,7 @@ import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settingslib.widget.TopIntroPreference;
|
||||
|
||||
public class AllConversationsPreferenceController extends ConversationListPreferenceController {
|
||||
|
||||
@@ -39,9 +40,9 @@ public class AllConversationsPreferenceController extends ConversationListPrefer
|
||||
|
||||
@Override
|
||||
Preference getSummaryPreference() {
|
||||
Preference pref = new Preference(mContext);
|
||||
Preference pref = new TopIntroPreference(mContext);
|
||||
pref.setOrder(1);
|
||||
pref.setSummary(R.string.other_conversations_summary);
|
||||
pref.setTitle(R.string.other_conversations_summary);
|
||||
pref.setSelectable(false);
|
||||
return pref;
|
||||
}
|
||||
|
||||
@@ -71,6 +71,9 @@ public class AllowSoundPreferenceController extends NotificationPreferenceContro
|
||||
pref.setEnabled(!pref.isDisabledByAdmin());
|
||||
pref.setChecked(mChannel.getImportance() >= IMPORTANCE_DEFAULT
|
||||
|| mChannel.getImportance() == IMPORTANCE_UNSPECIFIED);
|
||||
if (preference.getParent() != null) {
|
||||
preference.getParent().setVisible(true);
|
||||
}
|
||||
} else { Log.i(TAG, "tried to updatestate on a null channel?!"); }
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,9 @@ public class AppLinkPreferenceController extends NotificationPreferenceControlle
|
||||
}
|
||||
|
||||
public void updateState(Preference preference) {
|
||||
if (preference.getParent() != null) {
|
||||
preference.getParent().setVisible(true);
|
||||
}
|
||||
if (mAppRow != null) {
|
||||
preference.setIntent(mAppRow.settingsIntent);
|
||||
}
|
||||
|
||||
@@ -82,6 +82,9 @@ public class BadgePreferenceController extends NotificationPreferenceController
|
||||
|
||||
public void updateState(Preference preference) {
|
||||
if (mAppRow != null) {
|
||||
if (preference.getParent() != null) {
|
||||
preference.getParent().setVisible(true);
|
||||
}
|
||||
RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
|
||||
pref.setDisabledByAdmin(mAdmin);
|
||||
if (mChannel != null) {
|
||||
|
||||
@@ -82,6 +82,9 @@ public class BubbleSummaryPreferenceController extends NotificationPreferenceCon
|
||||
intent.putExtra(Settings.EXTRA_APP_UID, mAppRow.uid);
|
||||
preference.setIntent(intent);
|
||||
}
|
||||
if (preference.getParent() != null) {
|
||||
preference.getParent().setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -58,6 +58,7 @@ public class ChannelListPreferenceController extends NotificationPreferenceContr
|
||||
|
||||
private List<NotificationChannelGroup> mChannelGroupList;
|
||||
private PreferenceCategory mPreference;
|
||||
int mChannelCount;
|
||||
|
||||
public ChannelListPreferenceController(Context context, NotificationBackend backend) {
|
||||
super(context, backend);
|
||||
@@ -107,6 +108,7 @@ public class ChannelListPreferenceController extends NotificationPreferenceContr
|
||||
} else {
|
||||
mChannelGroupList = mBackend.getGroups(mAppRow.pkg, mAppRow.uid).getList();
|
||||
}
|
||||
mChannelCount = mBackend.getChannelCount(mAppRow.pkg, mAppRow.uid);
|
||||
Collections.sort(mChannelGroupList, CHANNEL_GROUP_COMPARATOR);
|
||||
return null;
|
||||
}
|
||||
@@ -116,6 +118,7 @@ public class ChannelListPreferenceController extends NotificationPreferenceContr
|
||||
if (mContext == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateFullList(mPreference, mChannelGroupList);
|
||||
}
|
||||
}.execute();
|
||||
@@ -129,25 +132,30 @@ public class ChannelListPreferenceController extends NotificationPreferenceContr
|
||||
void updateFullList(@NonNull PreferenceCategory groupPrefsList,
|
||||
@NonNull List<NotificationChannelGroup> channelGroups) {
|
||||
if (channelGroups.isEmpty()) {
|
||||
if (groupPrefsList.getPreferenceCount() == 1
|
||||
&& KEY_ZERO_CATEGORIES.equals(groupPrefsList.getPreference(0).getKey())) {
|
||||
// Ensure the titles are correct for the current language, but otherwise leave alone
|
||||
PreferenceGroup groupCategory = (PreferenceGroup) groupPrefsList.getPreference(0);
|
||||
groupCategory.setTitle(R.string.notification_channels);
|
||||
groupCategory.getPreference(0).setTitle(R.string.no_channels);
|
||||
} else {
|
||||
// Clear any contents and create the 'zero-categories' group.
|
||||
if (mChannelCount > 0) {
|
||||
groupPrefsList.removeAll();
|
||||
} else {
|
||||
if (groupPrefsList.getPreferenceCount() == 1
|
||||
&& KEY_ZERO_CATEGORIES.equals(groupPrefsList.getPreference(0).getKey())) {
|
||||
// Ensure the titles are correct for the current language, but otherwise leave alone
|
||||
PreferenceGroup groupCategory = (PreferenceGroup) groupPrefsList.getPreference(
|
||||
0);
|
||||
groupCategory.setTitle(R.string.notification_channels);
|
||||
groupCategory.getPreference(0).setTitle(R.string.no_channels);
|
||||
} else {
|
||||
// Clear any contents and create the 'zero-categories' group.
|
||||
groupPrefsList.removeAll();
|
||||
|
||||
PreferenceCategory groupCategory = new PreferenceCategory(mContext);
|
||||
groupCategory.setTitle(R.string.notification_channels);
|
||||
groupCategory.setKey(KEY_ZERO_CATEGORIES);
|
||||
groupPrefsList.addPreference(groupCategory);
|
||||
PreferenceCategory groupCategory = new PreferenceCategory(mContext);
|
||||
groupCategory.setTitle(R.string.notification_channels);
|
||||
groupCategory.setKey(KEY_ZERO_CATEGORIES);
|
||||
groupPrefsList.addPreference(groupCategory);
|
||||
|
||||
Preference empty = new Preference(mContext);
|
||||
empty.setTitle(R.string.no_channels);
|
||||
empty.setEnabled(false);
|
||||
groupCategory.addPreference(empty);
|
||||
Preference empty = new Preference(mContext);
|
||||
empty.setTitle(R.string.no_channels);
|
||||
empty.setEnabled(false);
|
||||
groupCategory.addPreference(empty);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
updateGroupList(groupPrefsList, channelGroups);
|
||||
@@ -211,6 +219,11 @@ public class ChannelListPreferenceController extends NotificationPreferenceContr
|
||||
groupPrefsList.addPreference(group);
|
||||
}
|
||||
}
|
||||
Preference otherGroup = groupPrefsList.findPreference(KEY_GENERAL_CATEGORY);
|
||||
if (otherGroup != null) {
|
||||
otherGroup.setTitle(numFinalGroups == 1
|
||||
? R.string.notification_channels : R.string.notification_channels_other);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -248,8 +261,7 @@ public class ChannelListPreferenceController extends NotificationPreferenceContr
|
||||
List<Preference> finalOrderedPrefs = new ArrayList<>();
|
||||
Preference appDefinedGroupToggle;
|
||||
if (group.getId() == null) {
|
||||
// For the 'null' group, set the "Other" title.
|
||||
groupPrefGroup.setTitle(R.string.notification_channels_other);
|
||||
groupPrefGroup.setTitle(R.string.notification_channels);
|
||||
appDefinedGroupToggle = null;
|
||||
} else {
|
||||
// For an app-defined group, set their name and create a row to toggle 'isBlocked'.
|
||||
|
||||
@@ -63,6 +63,9 @@ public class DeletedChannelsPreferenceController extends NotificationPreferenceC
|
||||
}
|
||||
|
||||
public void updateState(Preference preference) {
|
||||
if (preference.getParent() != null) {
|
||||
preference.getParent().setVisible(true);
|
||||
}
|
||||
if (mAppRow != null) {
|
||||
int deletedChannelCount = mBackend.getDeletedChannelCount(mAppRow.pkg, mAppRow.uid);
|
||||
preference.setTitle(StringUtil.getIcuPluralsString(mContext, deletedChannelCount,
|
||||
|
||||
@@ -54,6 +54,9 @@ public class DndPreferenceController extends NotificationPreferenceController
|
||||
|
||||
public void updateState(Preference preference) {
|
||||
if (mChannel != null) {
|
||||
if (preference.getParent() != null) {
|
||||
preference.getParent().setVisible(true);
|
||||
}
|
||||
RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
|
||||
pref.setDisabledByAdmin(mAdmin);
|
||||
pref.setEnabled(!pref.isDisabledByAdmin());
|
||||
|
||||
@@ -21,9 +21,9 @@ import android.app.AppOpsManager
|
||||
import android.app.AppOpsManager.OP_USE_FULL_SCREEN_INTENT
|
||||
import android.content.AttributionSource
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager.NameNotFoundException
|
||||
import android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET
|
||||
import android.content.pm.PackageManager.GET_PERMISSIONS
|
||||
import android.content.pm.PackageManager.NameNotFoundException
|
||||
import android.os.UserHandle
|
||||
import android.permission.PermissionManager
|
||||
import android.util.Log
|
||||
@@ -65,6 +65,7 @@ class FullScreenIntentPermissionPreferenceController(
|
||||
preference.setDisabledByAdmin(mAdmin)
|
||||
preference.isEnabled = !preference.isDisabledByAdmin
|
||||
preference.isChecked = isPermissionGranted()
|
||||
preference.parent?.isVisible = true
|
||||
}
|
||||
|
||||
override fun onPreferenceChange(preference: Preference, value: Any): Boolean {
|
||||
|
||||
@@ -81,9 +81,8 @@ public class HeaderPreferenceController extends NotificationPreferenceController
|
||||
mHeaderController = EntityHeaderController.newInstance(
|
||||
activity, mFragment, pref.findViewById(R.id.entity_header));
|
||||
pref = mHeaderController.setIcon(mAppRow.icon)
|
||||
.setLabel(getLabel())
|
||||
.setSummary(getSummary())
|
||||
.setSecondSummary(getSecondSummary())
|
||||
.setLabel(getSummary())
|
||||
.setSummary(getSecondSummary())
|
||||
.setPackageName(mAppRow.pkg)
|
||||
.setUid(mAppRow.uid)
|
||||
.setButtonActions(EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE,
|
||||
@@ -95,14 +94,6 @@ public class HeaderPreferenceController extends NotificationPreferenceController
|
||||
}
|
||||
}
|
||||
|
||||
public CharSequence getLabel() {
|
||||
if (mChannel != null && !isDefaultChannel()) {
|
||||
return mChannel.getName();
|
||||
} else {
|
||||
return mAppRow.label;
|
||||
}
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_START)
|
||||
public void onStart() {
|
||||
mStarted = true;
|
||||
@@ -113,15 +104,7 @@ public class HeaderPreferenceController extends NotificationPreferenceController
|
||||
if (mChannel != null) {
|
||||
if (mChannelGroup != null
|
||||
&& !TextUtils.isEmpty(mChannelGroup.getName())) {
|
||||
final SpannableStringBuilder summary = new SpannableStringBuilder();
|
||||
BidiFormatter bidi = BidiFormatter.getInstance();
|
||||
summary.append(bidi.unicodeWrap(mAppRow.label));
|
||||
summary.append(bidi.unicodeWrap(mContext.getText(
|
||||
R.string.notification_header_divider_symbol_with_spaces)));
|
||||
summary.append(bidi.unicodeWrap(mChannelGroup.getName().toString()));
|
||||
return summary.toString();
|
||||
} else {
|
||||
return mAppRow.label.toString();
|
||||
return mChannelGroup.getName().toString();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
|
||||
@@ -23,6 +23,7 @@ import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settingslib.widget.SettingsThemeHelper;
|
||||
|
||||
public class InvalidConversationInfoPreferenceController extends NotificationPreferenceController {
|
||||
|
||||
@@ -49,6 +50,9 @@ public class InvalidConversationInfoPreferenceController extends NotificationPre
|
||||
if (mPreferenceFilter != null && !isIncludedInFilter()) {
|
||||
return false;
|
||||
}
|
||||
if (SettingsThemeHelper.isExpressiveTheme(mContext)) {
|
||||
return false;
|
||||
}
|
||||
return mBackend.isInInvalidMsgState(mAppRow.pkg, mAppRow.uid);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import androidx.preference.Preference;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
import com.android.settingslib.widget.SettingsThemeHelper;
|
||||
|
||||
public class InvalidConversationPreferenceController extends NotificationPreferenceController
|
||||
implements Preference.OnPreferenceChangeListener {
|
||||
@@ -67,7 +68,15 @@ public class InvalidConversationPreferenceController extends NotificationPrefere
|
||||
pref.setDisabledByAdmin(mAdmin);
|
||||
pref.setEnabled(!pref.isDisabledByAdmin());
|
||||
pref.setChecked(!mBackend.hasUserDemotedInvalidMsgApp(mAppRow.pkg, mAppRow.uid));
|
||||
preference.setSummary(mContext.getString(R.string.conversation_section_switch_summary));
|
||||
if (SettingsThemeHelper.isExpressiveTheme(mContext)) {
|
||||
if (preference.getParent() != null) {
|
||||
preference.getParent().setVisible(true);
|
||||
}
|
||||
preference.setSummary(mContext.getString(
|
||||
R.string.conversation_section_switch_complete_summary));
|
||||
} else {
|
||||
preference.setSummary(mContext.getString(R.string.conversation_section_switch_summary));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -23,6 +23,7 @@ import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settingslib.widget.TopIntroPreference;
|
||||
|
||||
public class PriorityConversationsPreferenceController extends
|
||||
ConversationListPreferenceController {
|
||||
@@ -40,9 +41,9 @@ public class PriorityConversationsPreferenceController extends
|
||||
|
||||
@Override
|
||||
Preference getSummaryPreference() {
|
||||
Preference pref = new Preference(mContext);
|
||||
Preference pref = new TopIntroPreference(mContext);
|
||||
pref.setOrder(1);
|
||||
pref.setSummary(R.string.important_conversations_summary_bubbles);
|
||||
pref.setTitle(R.string.important_conversations_summary_bubbles);
|
||||
pref.setSelectable(false);
|
||||
return pref;
|
||||
}
|
||||
|
||||
@@ -20,14 +20,12 @@ import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
|
||||
public class PromotedNotificationsPreferenceController extends
|
||||
NotificationPreferenceController implements Preference.OnPreferenceChangeListener {
|
||||
private static final String KEY_PROMOTED_CATEGORY = "promoted_category";
|
||||
protected static final String KEY_PROMOTED_SWITCH = "promoted_switch";
|
||||
|
||||
public PromotedNotificationsPreferenceController(@NonNull Context context,
|
||||
@@ -38,7 +36,7 @@ public class PromotedNotificationsPreferenceController extends
|
||||
@Override
|
||||
@NonNull
|
||||
public String getPreferenceKey() {
|
||||
return KEY_PROMOTED_CATEGORY;
|
||||
return KEY_PROMOTED_SWITCH;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -56,12 +54,13 @@ public class PromotedNotificationsPreferenceController extends
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the state of the promoted notifications switch. Because this controller governs
|
||||
* the full PreferenceCategory, we must find the switch preference within the category first.
|
||||
* Updates the state of the promoted notifications switch.
|
||||
*/
|
||||
public void updateState(@NonNull Preference preference) {
|
||||
PreferenceCategory category = (PreferenceCategory) preference;
|
||||
RestrictedSwitchPreference pref = category.findPreference(KEY_PROMOTED_SWITCH);
|
||||
RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
|
||||
if (pref.getParent() != null) {
|
||||
pref.getParent().setVisible(true);
|
||||
}
|
||||
|
||||
if (pref != null && mAppRow != null) {
|
||||
pref.setDisabledByAdmin(mAdmin);
|
||||
|
||||
@@ -40,6 +40,7 @@ import com.android.settings.applications.AppInfoBase;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.widget.ButtonPreference;
|
||||
import com.android.settingslib.widget.LayoutPreference;
|
||||
|
||||
import java.text.Collator;
|
||||
@@ -75,14 +76,12 @@ public class RecentConversationsPreferenceController extends AbstractPreferenceC
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO(b/233325816): Use ButtonPreference instead.
|
||||
LayoutPreference getClearAll(PreferenceGroup parent) {
|
||||
LayoutPreference pref = new LayoutPreference(
|
||||
mContext, R.layout.conversations_clear_recents);
|
||||
ButtonPreference getClearAll(PreferenceGroup parent) {
|
||||
ButtonPreference pref = new ButtonPreference(mContext);
|
||||
pref.setTitle(R.string.conversation_settings_clear_recents);
|
||||
pref.setKey(getPreferenceKey() + CLEAR_ALL_KEY_SUFFIX);
|
||||
pref.setOrder(1);
|
||||
Button button = pref.findViewById(R.id.conversation_settings_clear_recents);
|
||||
button.setOnClickListener(v -> {
|
||||
pref.setOnClickListener(v -> {
|
||||
try {
|
||||
mPs.removeAllRecentConversations();
|
||||
// Removing recents is asynchronous, so we can't immediately reload the list from
|
||||
@@ -97,7 +96,8 @@ public class RecentConversationsPreferenceController extends AbstractPreferenceC
|
||||
}
|
||||
}
|
||||
}
|
||||
button.announceForAccessibility(mContext.getString(R.string.recent_convos_removed));
|
||||
pref.getButton().announceForAccessibility(
|
||||
mContext.getString(R.string.recent_convos_removed));
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Could not clear recents", e);
|
||||
}
|
||||
@@ -160,25 +160,27 @@ public class RecentConversationsPreferenceController extends AbstractPreferenceC
|
||||
.forEachOrdered(pref -> {
|
||||
pref.setOrder(order.getAndIncrement());
|
||||
mPreferenceGroup.addPreference(pref);
|
||||
if (pref.hasClearListener()) {
|
||||
if (pref instanceof RecentConversationPreference
|
||||
&& ((RecentConversationPreference) pref).hasClearListener()) {
|
||||
hasClearable.set(true);
|
||||
}
|
||||
});
|
||||
return hasClearable.get();
|
||||
}
|
||||
|
||||
protected RecentConversationPreference createConversationPref(
|
||||
protected Preference createConversationPref(
|
||||
final ConversationChannel conversation) {
|
||||
final String pkg = conversation.getShortcutInfo().getPackage();
|
||||
final int uid = conversation.getUid();
|
||||
final String conversationId = conversation.getShortcutInfo().getId();
|
||||
RecentConversationPreference pref = new RecentConversationPreference(mContext);
|
||||
Preference pref = conversation.hasActiveNotifications() ? new Preference(mContext)
|
||||
: new RecentConversationPreference(mContext);
|
||||
|
||||
if (!conversation.hasActiveNotifications()) {
|
||||
pref.setOnClearClickListener(() -> {
|
||||
((RecentConversationPreference) pref).setOnClearClickListener(() -> {
|
||||
try {
|
||||
mPs.removeRecentConversation(pkg, UserHandle.getUserId(uid), conversationId);
|
||||
pref.getClearView().announceForAccessibility(
|
||||
((RecentConversationPreference) pref).getClearView().announceForAccessibility(
|
||||
mContext.getString(R.string.recent_convo_removed));
|
||||
mPreferenceGroup.removePreference(pref);
|
||||
} catch (RemoteException e) {
|
||||
|
||||
@@ -56,6 +56,9 @@ public class ShowMorePreferenceController extends NotificationPreferenceControll
|
||||
if (mAppRow.banned || mAppRow.showAllChannels) {
|
||||
return false;
|
||||
}
|
||||
if (mBackend.getChannelCount(mAppRow.pkg, mAppRow.uid) == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +75,10 @@ public class VisibilityPreferenceController extends NotificationPreferenceContro
|
||||
|
||||
public void updateState(Preference preference) {
|
||||
if (mChannel != null && mAppRow != null) {
|
||||
if (preference.getParent() != null) {
|
||||
preference.getParent().setVisible(true);
|
||||
}
|
||||
|
||||
RestrictedListPreference pref = (RestrictedListPreference) preference;
|
||||
ArrayList<CharSequence> entries = new ArrayList<>();
|
||||
ArrayList<CharSequence> values = new ArrayList<>();
|
||||
|
||||
Reference in New Issue
Block a user