diff --git a/res/values/strings.xml b/res/values/strings.xml index 8d5c400f881..730e0ed0709 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -6576,6 +6576,12 @@ Never show notifications + + %1$s: %2$s + + + No sound or visual interruption @@ -6588,6 +6594,9 @@ Make sound and pop on screen + + Low diff --git a/res/xml/legacy_channel_notification_settings.xml b/res/xml/legacy_channel_notification_settings.xml index 4e341a9173f..e2717050b29 100644 --- a/res/xml/legacy_channel_notification_settings.xml +++ b/res/xml/legacy_channel_notification_settings.xml @@ -17,6 +17,12 @@ + + + + + + + diff --git a/res/xml/app_notification_settings.xml b/res/xml/upgraded_app_notification_settings.xml similarity index 85% rename from res/xml/app_notification_settings.xml rename to res/xml/upgraded_app_notification_settings.xml index 483b4a0f2fe..f9a3304267e 100644 --- a/res/xml/app_notification_settings.xml +++ b/res/xml/upgraded_app_notification_settings.xml @@ -1,5 +1,5 @@ - + xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"> mChannelGroupList; private List mChannelGroups = new ArrayList(); - private RestrictedSwitchPreference mImportanceToggle; - private LayoutPreference mBlockBar; private FooterPreference mDeletedChannels; - private SwitchBar mSwitchBar; - - private boolean mShowLegacyChannelConfig = false; @Override public int getMetricsCategory() { @@ -92,38 +87,50 @@ public class AppNotificationSettings extends NotificationSettingsBase { if (getPreferenceScreen() != null) { getPreferenceScreen().removeAll(); mChannelGroups.clear(); + mDeletedChannels = null; mShowLegacyChannelConfig = false; } - addPreferencesFromResource(R.xml.app_notification_settings); + addPreferencesFromResource(R.xml.notification_settings); getPreferenceScreen().setOrderingAsAdded(true); - - mBadge = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BADGE); - mBlockedDesc = (FooterPreference) getPreferenceScreen().findPreference(KEY_BLOCKED_DESC); - setupBlock(); - setupBadge(); - // load settings intent + addHeaderPref(); + addAppLinkPref(); + + mShowLegacyChannelConfig = mBackend.onlyHasDefaultChannel(mAppRow.pkg, mAppRow.uid); + if (mShowLegacyChannelConfig) { + mChannel = mBackend.getChannel( + mAppRow.pkg, mAppRow.uid, NotificationChannel.DEFAULT_CHANNEL_ID); + populateDefaultChannelPrefs(); + } else { + addPreferencesFromResource(R.xml.upgraded_app_notification_settings); + setupBadge(); + // Load channel settings + new AsyncTask() { + @Override + protected Void doInBackground(Void... unused) { + mChannelGroupList = mBackend.getChannelGroups(mPkg, mUid).getList(); + Collections.sort(mChannelGroupList, mChannelGroupComparator); + return null; + } + + @Override + protected void onPostExecute(Void unused) { + if (getHost() == null) { + return; + } + populateChannelList(); + } + }.execute(); + } + + updateDependents(mAppRow.banned); + } + + private void addHeaderPref() { ArrayMap rows = new ArrayMap(); rows.put(mAppRow.pkg, mAppRow); collectConfigActivities(rows); - new AsyncTask() { - @Override - protected Void doInBackground(Void... unused) { - mChannelGroupList = mBackend.getChannelGroups(mPkg, mUid).getList(); - Collections.sort(mChannelGroupList, mChannelGroupComparator); - return null; - } - - @Override - protected void onPostExecute(Void unused) { - if (getHost() == null) { - return; - } - populateChannelList(); - } - }.execute(); - final Activity activity = getActivity(); final Preference pref = FeatureFactory.getFactory(activity) .getApplicationFeatureProvider(activity) @@ -135,15 +142,15 @@ public class AppNotificationSettings extends NotificationSettingsBase { .setButtonActions(AppHeaderController.ActionType.ACTION_APP_INFO, AppHeaderController.ActionType.ACTION_NOTIF_PREFERENCE) .done(activity, getPrefContext()); + pref.setKey(KEY_HEADER); getPreferenceScreen().addPreference(pref); - - updateDependents(mAppRow.banned); } private void populateChannelList() { if (mChannelGroupList.isEmpty()) { PreferenceCategory groupCategory = new PreferenceCategory(getPrefContext()); groupCategory.setTitle(R.string.notification_channels); + groupCategory.setKey(KEY_GENERAL_CATEGORY); getPreferenceScreen().addPreference(groupCategory); mChannelGroups.add(groupCategory); @@ -151,15 +158,6 @@ public class AppNotificationSettings extends NotificationSettingsBase { empty.setTitle(R.string.no_channels); empty.setEnabled(false); groupCategory.addPreference(empty); - - } else if (mChannelGroupList.size() == 1 && - mChannelGroupList.get(0).getChannels().get(0).getId() - .equals(NotificationChannel.DEFAULT_CHANNEL_ID)) { - // Legacy app using only default channel. Hoist default channel settings to main panel. - mShowLegacyChannelConfig = true; - mChannel = mChannelGroupList.get(0).getChannels().get(0); - populateDefaultChannelPrefs(); - } else { for (NotificationChannelGroup group : mChannelGroupList) { PreferenceCategory groupCategory = new PreferenceCategory(getPrefContext()); @@ -167,10 +165,11 @@ public class AppNotificationSettings extends NotificationSettingsBase { groupCategory.setTitle(mChannelGroupList.size() > 1 ? R.string.notification_channels_other : R.string.notification_channels); + groupCategory.setKey(KEY_GENERAL_CATEGORY); } else { groupCategory.setTitle(group.getName()); + groupCategory.setKey(group.getId()); } - groupCategory.setKey(group.getId()); groupCategory.setOrderingAsAdded(true); getPreferenceScreen().addPreference(groupCategory); mChannelGroups.add(groupCategory); @@ -184,13 +183,6 @@ public class AppNotificationSettings extends NotificationSettingsBase { } } - if (mAppRow.settingsIntent != null) { - Preference intentPref = new Preference(getPrefContext()); - intentPref.setIntent(mAppRow.settingsIntent); - intentPref.setTitle(mContext.getString(R.string.app_settings_link)); - getPreferenceScreen().addPreference(intentPref); - } - int deletedChannelCount = mBackend.getDeletedChannelCount(mAppRow.pkg, mAppRow.uid); if (deletedChannelCount > 0) { mDeletedChannels = new FooterPreference(getPrefContext()); @@ -198,9 +190,12 @@ public class AppNotificationSettings extends NotificationSettingsBase { mDeletedChannels.setTitle(getResources().getQuantityString( R.plurals.deleted_channels, deletedChannelCount, deletedChannelCount)); mDeletedChannels.setEnabled(false); + mDeletedChannels.setKey(KEY_DELETED); + mDeletedChannels.setOrder(ORDER_LAST); getPreferenceScreen().addPreference(mDeletedChannels); } } + updateDependents(mAppRow.banned); } @@ -212,7 +207,7 @@ public class AppNotificationSettings extends NotificationSettingsBase { channelPref.setKey(channel.getId()); channelPref.setTitle(channel.getName()); channelPref.setChecked(channel.getImportance() != IMPORTANCE_NONE); - channelPref.setSummary(getImportanceSummary(channel.getImportance())); + channelPref.setSummary(getImportanceSummary(channel)); Bundle channelArgs = new Bundle(); channelArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid); channelArgs.putBoolean(AppHeader.EXTRA_HIDE_INFO_BUTTON, true); @@ -234,7 +229,7 @@ public class AppNotificationSettings extends NotificationSettingsBase { channel.setImportance(importance); channel.lockFields( NotificationChannel.USER_LOCKED_IMPORTANCE); - channelPref.setSummary(getImportanceSummary(channel.getImportance())); + channelPref.setSummary(getImportanceSummary(channel)); mBackend.updateChannel(mPkg, mUid, channel); return true; @@ -243,36 +238,25 @@ public class AppNotificationSettings extends NotificationSettingsBase { groupCategory.addPreference(channelPref); } - private void populateDefaultChannelPrefs() { - addPreferencesFromResource(R.xml.legacy_channel_notification_settings); - mPriority = (RestrictedSwitchPreference) findPreference(KEY_BYPASS_DND); - mVisibilityOverride = - (RestrictedDropDownPreference) findPreference(KEY_VISIBILITY_OVERRIDE); - mImportanceToggle = (RestrictedSwitchPreference) findPreference(KEY_IMPORTANCE); - - if (mPkgInfo != null && mChannel != null) { - setupPriorityPref(mChannel.canBypassDnd()); - setupVisOverridePref(mChannel.getLockscreenVisibility()); - setupImportanceToggle(); + void setupBadge() { + mBadge = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BADGE); + mBadge.setDisabledByAdmin(mSuspendedAppsAdmin); + if (mChannel == null) { + mBadge.setChecked(mAppRow.showBadge); + } else { + mBadge.setChecked(mChannel.canShowBadge()); } - mSwitchBar.setChecked(!mAppRow.banned - && mChannel.getImportance() != NotificationManager.IMPORTANCE_NONE); - } - - // 'allow sound' - private void setupImportanceToggle() { - mImportanceToggle.setDisabledByAdmin(mSuspendedAppsAdmin); - mImportanceToggle.setChecked(mChannel.getImportance() >= IMPORTANCE_DEFAULT - || mChannel.getImportance() == IMPORTANCE_UNSPECIFIED); - mImportanceToggle.setOnPreferenceChangeListener( - new Preference.OnPreferenceChangeListener() { + mBadge.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - final int importance = - ((Boolean) newValue ? IMPORTANCE_UNSPECIFIED : IMPORTANCE_LOW); - mChannel.setImportance(importance); - mChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE); - mBackend.updateChannel(mPkg, mUid, mChannel); + final boolean value = (Boolean) newValue; + if (mChannel == null) { + mBackend.setShowBadge(mPkg, mUid, value); + } else { + mChannel.setShowBadge(value); + mChannel.lockFields(NotificationChannel.USER_LOCKED_SHOW_BADGE); + mBackend.updateChannel(mPkg, mUid, mChannel); + } return true; } }); @@ -296,12 +280,13 @@ public class AppNotificationSettings extends NotificationSettingsBase { mBackend.updateChannel(mPkg, mUid, mChannel); } mBackend.setNotificationsEnabledForPackage(mPkgInfo.packageName, mUid, isChecked); + mAppRow.banned = true; updateDependents(!isChecked); } }); mBlockBar = new LayoutPreference(getPrefContext(), switchBarContainer); - mBlockBar.setOrder(-500); + mBlockBar.setOrder(ORDER_FIRST); mBlockBar.setKey(KEY_BLOCK); getPreferenceScreen().addPreference(mBlockBar); @@ -312,20 +297,7 @@ public class AppNotificationSettings extends NotificationSettingsBase { setupBlockDesc(R.string.app_notifications_off_desc); } - private void setupBadge() { - mBadge.setDisabledByAdmin(mSuspendedAppsAdmin); - mBadge.setChecked(mAppRow.showBadge); - mBadge.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - final boolean value = (Boolean) newValue; - mBackend.setShowBadge(mPkg, mUid, value); - return true; - } - }); - } - - private void updateDependents(boolean banned) { + protected void updateDependents(boolean banned) { for (PreferenceCategory category : mChannelGroups) { setVisible(category, !banned); } @@ -336,17 +308,42 @@ public class AppNotificationSettings extends NotificationSettingsBase { setVisible(mBadge, !banned); if (mShowLegacyChannelConfig) { setVisible(mImportanceToggle, !banned); - setVisible(mPriority, !banned); - setVisible(mVisibilityOverride, !banned); + setVisible(mPriority, checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT) + || (checkCanBeVisible(NotificationManager.IMPORTANCE_LOW) + && mDndVisualEffectsSuppressed)); + setVisible(mVisibilityOverride, !banned && + checkCanBeVisible(NotificationManager.IMPORTANCE_LOW) && isLockScreenSecure()); + } + if (mAppLink != null) { + setVisible(mAppLink, !banned); } if (mAppRow.systemApp && !mAppRow.banned) { setVisible(mBlockBar, false); } } + private String getImportanceSummary(NotificationChannel channel) { + switch (channel.getImportance()) { + case NotificationManager.IMPORTANCE_UNSPECIFIED: + return getContext().getString(R.string.notification_importance_unspecified); + case NotificationManager.IMPORTANCE_NONE: + return getContext().getString(R.string.notification_toggle_off); + case NotificationManager.IMPORTANCE_MIN: + return getContext().getString(R.string.notification_importance_min_title); + case NotificationManager.IMPORTANCE_LOW: + return getContext().getString(R.string.notification_importance_low_title); + case NotificationManager.IMPORTANCE_DEFAULT: + return getContext().getString(R.string.notification_importance_default_title); + case NotificationManager.IMPORTANCE_HIGH: + case NotificationManager.IMPORTANCE_MAX: + default: + return getContext().getString(R.string.notification_importance_high_title); + } + + } + private Comparator mChannelComparator = new Comparator() { - private final Collator sCollator = Collator.getInstance(); @Override public int compare(NotificationChannel left, NotificationChannel right) { @@ -359,7 +356,6 @@ public class AppNotificationSettings extends NotificationSettingsBase { private Comparator mChannelGroupComparator = new Comparator() { - private final Collator sCollator = Collator.getInstance(); @Override public int compare(NotificationChannelGroup left, NotificationChannelGroup right) { diff --git a/src/com/android/settings/notification/ChannelImportanceSettings.java b/src/com/android/settings/notification/ChannelImportanceSettings.java index b396b205127..26dd57f1481 100644 --- a/src/com/android/settings/notification/ChannelImportanceSettings.java +++ b/src/com/android/settings/notification/ChannelImportanceSettings.java @@ -66,6 +66,12 @@ public class ChannelImportanceSettings extends NotificationSettingsBase createPreferenceHierarchy(); } + @Override + void setupBadge() {} + + @Override + void updateDependents(boolean banned) {} + @Override public void onPause() { super.onPause(); diff --git a/src/com/android/settings/notification/ChannelNotificationSettings.java b/src/com/android/settings/notification/ChannelNotificationSettings.java index 0fb42d27355..27e60c737df 100644 --- a/src/com/android/settings/notification/ChannelNotificationSettings.java +++ b/src/com/android/settings/notification/ChannelNotificationSettings.java @@ -18,6 +18,7 @@ package com.android.settings.notification; import static android.app.NotificationManager.IMPORTANCE_LOW; import static android.app.NotificationManager.IMPORTANCE_NONE; +import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; import android.app.Activity; import android.app.NotificationChannel; @@ -53,16 +54,16 @@ import com.android.settingslib.RestrictedSwitchPreference; public class ChannelNotificationSettings extends NotificationSettingsBase { private static final String TAG = "ChannelSettings"; - protected static final String KEY_LIGHTS = "lights"; - protected static final String KEY_VIBRATE = "vibrate"; - protected static final String KEY_RINGTONE = "ringtone"; + private static final String KEY_LIGHTS = "lights"; + private static final String KEY_VIBRATE = "vibrate"; + private static final String KEY_RINGTONE = "ringtone"; + private static final String KEY_IMPORTANCE = "importance"; - protected Preference mImportance; - protected RestrictedSwitchPreference mLights; - protected RestrictedSwitchPreference mVibrate; - protected NotificationSoundPreference mRingtone; - - protected LayoutPreference mBlockBar; + private Preference mImportance; + private RestrictedSwitchPreference mLights; + private RestrictedSwitchPreference mVibrate; + private NotificationSoundPreference mRingtone; + private FooterPreference mFooter; @Override public int getMetricsCategory() { @@ -81,34 +82,37 @@ public class ChannelNotificationSettings extends NotificationSettingsBase { if (getPreferenceScreen() != null) { getPreferenceScreen().removeAll(); } - addPreferencesFromResource(R.xml.channel_notification_settings); + addPreferencesFromResource(R.xml.notification_settings); + setupBlock(); + addHeaderPref(); + addAppLinkPref(); + addFooterPref(); - // load settings intent - ArrayMap rows = new ArrayMap(); - rows.put(mAppRow.pkg, mAppRow); - collectConfigActivities(rows); - - mBlockedDesc = (FooterPreference) getPreferenceScreen().findPreference(KEY_BLOCKED_DESC); - mBadge = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BADGE); - mImportance = findPreference(KEY_IMPORTANCE); - mPriority = (RestrictedSwitchPreference) findPreference(KEY_BYPASS_DND); - mVisibilityOverride = - (RestrictedDropDownPreference) findPreference(KEY_VISIBILITY_OVERRIDE); - mLights = (RestrictedSwitchPreference) findPreference(KEY_LIGHTS); - mVibrate = (RestrictedSwitchPreference) findPreference(KEY_VIBRATE); - mRingtone = (NotificationSoundPreference) findPreference(KEY_RINGTONE); + if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId())) { + populateDefaultChannelPrefs(); + mShowLegacyChannelConfig = true; + } else { + populateUpgradedChannelPrefs(); + } + updateDependents(mChannel.getImportance() == IMPORTANCE_NONE); + } + private void populateUpgradedChannelPrefs() { + addPreferencesFromResource(R.xml.upgraded_channel_notification_settings); + setupBadge(); setupPriorityPref(mChannel.canBypassDnd()); setupVisOverridePref(mChannel.getLockscreenVisibility()); setupLights(); setupVibrate(); setupRingtone(); - setupBadge(); - setupBlock(); setupImportance(); - updateDependents(); + } + private void addHeaderPref() { + ArrayMap rows = new ArrayMap(); + rows.put(mAppRow.pkg, mAppRow); + collectConfigActivities(rows); final Activity activity = getActivity(); final Preference pref = FeatureFactory.getFactory(activity) .getApplicationFeatureProvider(activity) @@ -122,25 +126,38 @@ public class ChannelNotificationSettings extends NotificationSettingsBase { AppHeaderController.ActionType.ACTION_NOTIF_PREFERENCE) .done(activity, getPrefContext()); getPreferenceScreen().addPreference(pref); + } - if (mAppRow.settingsIntent != null) { - Preference intentPref = new Preference(getPrefContext()); - intentPref.setIntent(mAppRow.settingsIntent); - intentPref.setTitle(mContext.getString(R.string.app_settings_link)); - getPreferenceScreen().addPreference(intentPref); - } - + private void addFooterPref() { if (!TextUtils.isEmpty(mChannel.getDescription())) { FooterPreference descPref = new FooterPreference(getPrefContext()); + descPref.setOrder(ORDER_LAST); descPref.setSelectable(false); - descPref.setSummary(mChannel.getDescription()); - descPref.setEnabled(false); + descPref.setTitle(mChannel.getDescription()); getPreferenceScreen().addPreference(descPref); } + } + protected void setupBadge() { + mBadge = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BADGE); + mBadge.setDisabledByAdmin(mSuspendedAppsAdmin); + mBadge.setEnabled(mAppRow.showBadge); + mBadge.setChecked(mChannel.canShowBadge()); + + mBadge.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final boolean value = (Boolean) newValue; + mChannel.setShowBadge(value); + mChannel.lockFields(NotificationChannel.USER_LOCKED_SHOW_BADGE); + mBackend.updateChannel(mPkg, mUid, mChannel); + return true; + } + }); } private void setupLights() { + mLights = (RestrictedSwitchPreference) findPreference(KEY_LIGHTS); mLights.setDisabledByAdmin(mSuspendedAppsAdmin); mLights.setChecked(mChannel.shouldShowLights()); mLights.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @@ -156,6 +173,7 @@ public class ChannelNotificationSettings extends NotificationSettingsBase { } private void setupVibrate() { + mVibrate = (RestrictedSwitchPreference) findPreference(KEY_VIBRATE); mVibrate.setDisabledByAdmin(mSuspendedAppsAdmin); mVibrate.setChecked(mChannel.shouldVibrate()); mVibrate.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @@ -171,6 +189,7 @@ public class ChannelNotificationSettings extends NotificationSettingsBase { } private void setupRingtone() { + mRingtone = (NotificationSoundPreference) findPreference(KEY_RINGTONE); mRingtone.setRingtone(mChannel.getSound()); mRingtone.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override @@ -183,27 +202,33 @@ public class ChannelNotificationSettings extends NotificationSettingsBase { }); } - protected void setupBlock() { + private void setupBlock() { View switchBarContainer = LayoutInflater.from( getPrefContext()).inflate(R.layout.styled_switch_bar, null); - SwitchBar switchBar = switchBarContainer.findViewById(R.id.switch_bar); - switchBar.show(); - switchBar.setDisabledByAdmin(mSuspendedAppsAdmin); - switchBar.setChecked(mChannel.getImportance() != NotificationManager.IMPORTANCE_NONE); - switchBar.addOnSwitchChangeListener(new SwitchBar.OnSwitchChangeListener() { + mSwitchBar = switchBarContainer.findViewById(R.id.switch_bar); + mSwitchBar.show(); + mSwitchBar.setDisabledByAdmin(mSuspendedAppsAdmin); + mSwitchBar.setChecked(mChannel.getImportance() != NotificationManager.IMPORTANCE_NONE); + mSwitchBar.addOnSwitchChangeListener(new SwitchBar.OnSwitchChangeListener() { @Override public void onSwitchChanged(Switch switchView, boolean isChecked) { - int importance = isChecked ? IMPORTANCE_LOW : IMPORTANCE_NONE; - mImportance.setSummary(getImportanceSummary(importance)); + int importance = 0; + if (mShowLegacyChannelConfig) { + importance = isChecked ? IMPORTANCE_UNSPECIFIED : IMPORTANCE_NONE; + mImportanceToggle.setChecked(importance == IMPORTANCE_UNSPECIFIED); + } else { + importance = isChecked ? IMPORTANCE_LOW : IMPORTANCE_NONE; + mImportance.setSummary(getImportanceSummary(importance)); + } mChannel.setImportance(importance); mChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE); mBackend.updateChannel(mPkg, mUid, mChannel); - updateDependents(); + updateDependents(mChannel.getImportance() == IMPORTANCE_NONE); } }); mBlockBar = new LayoutPreference(getPrefContext(), switchBarContainer); - mBlockBar.setOrder(-500); + mBlockBar.setOrder(ORDER_FIRST); mBlockBar.setKey(KEY_BLOCK); getPreferenceScreen().addPreference(mBlockBar); @@ -214,23 +239,8 @@ public class ChannelNotificationSettings extends NotificationSettingsBase { setupBlockDesc(R.string.channel_notifications_off_desc); } - protected void setupBadge() { - mBadge.setDisabledByAdmin(mSuspendedAppsAdmin); - mBadge.setEnabled(mAppRow.showBadge); - mBadge.setChecked(mChannel.canShowBadge()); - mBadge.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - final boolean value = (Boolean) newValue; - mChannel.setShowBadge(value); - mChannel.lockFields(NotificationChannel.USER_LOCKED_SHOW_BADGE); - mBackend.updateChannel(mPkg, mUid, mChannel); - return true; - } - }); - } - - protected void setupImportance() { + private void setupImportance() { + mImportance = findPreference(KEY_IMPORTANCE); Bundle channelArgs = new Bundle(); channelArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid); channelArgs.putBoolean(AppHeader.EXTRA_HIDE_INFO_BUTTON, true); @@ -245,23 +255,43 @@ public class ChannelNotificationSettings extends NotificationSettingsBase { mImportance.setSummary(getImportanceSummary(mChannel.getImportance())); } - private boolean isLockScreenSecure() { - LockPatternUtils utils = new LockPatternUtils(getActivity()); - boolean lockscreenSecure = utils.isSecure(UserHandle.myUserId()); - UserInfo parentUser = mUm.getProfileParent(UserHandle.myUserId()); - if (parentUser != null){ - lockscreenSecure |= utils.isSecure(parentUser.id); + private String getImportanceSummary(int importance) { + String title; + String summary = null; + switch (importance) { + case IMPORTANCE_UNSPECIFIED: + title = getContext().getString(R.string.notification_importance_unspecified); + break; + case NotificationManager.IMPORTANCE_MIN: + title = getContext().getString(R.string.notification_importance_min_title); + summary = getContext().getString(R.string.notification_importance_min); + break; + case NotificationManager.IMPORTANCE_LOW: + title = getContext().getString(R.string.notification_importance_low_title); + summary = getContext().getString(R.string.notification_importance_low); + break; + case NotificationManager.IMPORTANCE_DEFAULT: + title = getContext().getString(R.string.notification_importance_default_title); + if (hasValidSound()) { + summary = getContext().getString(R.string.notification_importance_default); + } + break; + case NotificationManager.IMPORTANCE_HIGH: + case NotificationManager.IMPORTANCE_MAX: + title = getContext().getString(R.string.notification_importance_high_title); + if (hasValidSound()) { + summary = getContext().getString(R.string.notification_importance_high); + } + break; + default: + return ""; } - return lockscreenSecure; - } - - protected boolean checkCanBeVisible(int minImportanceVisible) { - int importance = mChannel.getImportance(); - if (importance == NotificationManager.IMPORTANCE_UNSPECIFIED) { - return true; + if (summary != null) { + return getContext().getString(R.string.notification_importance_divider, title, summary); + } else { + return title; } - return importance >= minImportanceVisible; } @Override @@ -279,9 +309,10 @@ public class ChannelNotificationSettings extends NotificationSettingsBase { if (mRingtone != null) { mRingtone.onActivityResult(requestCode, resultCode, data); } + mImportance.setSummary(getImportanceSummary(mChannel.getImportance())); } - private boolean canPulseLight() { + boolean canPulseLight() { if (!getResources() .getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed)) { return false; @@ -290,18 +321,32 @@ public class ChannelNotificationSettings extends NotificationSettingsBase { Settings.System.NOTIFICATION_LIGHT_PULSE, 0) == 1; } - private void updateDependents() { - setVisible(mBlockedDesc, mChannel.getImportance() == IMPORTANCE_NONE); + boolean hasValidSound() { + return mChannel.getSound() != null && !Uri.EMPTY.equals(mChannel.getSound()); + } + + void updateDependents(boolean banned) { + if (mShowLegacyChannelConfig) { + setVisible(mImportanceToggle, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN)); + } else { + setVisible(mImportance, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN)); + setVisible(mLights, checkCanBeVisible( + NotificationManager.IMPORTANCE_DEFAULT) && canPulseLight()); + setVisible(mVibrate, checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT)); + setVisible(mRingtone, checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT)); + } setVisible(mBadge, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN)); - setVisible(mImportance, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN)); - setVisible(mLights, checkCanBeVisible( - NotificationManager.IMPORTANCE_LOW) && canPulseLight()); - setVisible(mVibrate, checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT)); - setVisible(mRingtone, checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT)); setVisible(mPriority, checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT) || (checkCanBeVisible(NotificationManager.IMPORTANCE_LOW) - && mDndVisualEffectsSuppressed)); - setVisible(mVisibilityOverride, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN) + && mDndVisualEffectsSuppressed)); + setVisible(mVisibilityOverride, checkCanBeVisible(NotificationManager.IMPORTANCE_LOW) && isLockScreenSecure()); + setVisible(mBlockedDesc, mChannel.getImportance() == IMPORTANCE_NONE); + if (mAppLink != null) { + setVisible(mAppLink, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN)); + } + if (mFooter !=null) { + setVisible(mFooter, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN)); + } } } diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java index 6226eac5d9b..84d7e314e50 100644 --- a/src/com/android/settings/notification/NotificationBackend.java +++ b/src/com/android/settings/notification/NotificationBackend.java @@ -148,6 +148,15 @@ public class NotificationBackend { } } + public boolean onlyHasDefaultChannel(String pkg, int uid) { + try { + return sINM.onlyHasDefaultChannel(pkg, uid); + } catch (Exception e) { + Log.w(TAG, "Error calling NoMan", e); + return false; + } + } + static class Row { public String section; } diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java index c08f161d3b8..695c7967c64 100644 --- a/src/com/android/settings/notification/NotificationSettingsBase.java +++ b/src/com/android/settings/notification/NotificationSettingsBase.java @@ -16,10 +16,18 @@ package com.android.settings.notification; +import static android.app.NotificationManager.IMPORTANCE_DEFAULT; +import static android.app.NotificationManager.IMPORTANCE_LOW; +import static android.app.NotificationManager.IMPORTANCE_NONE; +import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; + +import com.android.internal.widget.LockPatternUtils; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.applications.AppInfoBase; +import com.android.settings.applications.LayoutPreference; import com.android.settings.widget.FooterPreference; +import com.android.settings.widget.SwitchBar; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedSwitchPreference; @@ -35,6 +43,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; +import android.content.pm.UserInfo; import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; @@ -60,16 +69,23 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen = new Intent(Intent.ACTION_MAIN) .addCategory(Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES); + protected static final int ORDER_FIRST = -500; + protected static final int ORDER_LAST = 1000; + + protected static final String KEY_APP_LINK = "app_link"; + protected static final String KEY_HEADER = "header"; protected static final String KEY_BLOCK = "block"; protected static final String KEY_BADGE = "badge"; protected static final String KEY_BYPASS_DND = "bypass_dnd"; protected static final String KEY_VISIBILITY_OVERRIDE = "visibility_override"; - protected static final String KEY_IMPORTANCE = "importance"; protected static final String KEY_BLOCKED_DESC = "block_desc"; + protected static final String KEY_ALLOW_SOUND = "allow_sound"; protected PackageManager mPm; protected UserManager mUm; - protected final NotificationBackend mBackend = new NotificationBackend(); + protected NotificationBackend mBackend = new NotificationBackend(); + protected LockPatternUtils mLockPatternUtils; + protected NotificationManager mNm; protected Context mContext; protected boolean mCreated; protected int mUid; @@ -79,13 +95,18 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen protected RestrictedSwitchPreference mBadge; protected RestrictedSwitchPreference mPriority; protected RestrictedDropDownPreference mVisibilityOverride; + protected RestrictedSwitchPreference mImportanceToggle; + protected LayoutPreference mBlockBar; + protected SwitchBar mSwitchBar; protected FooterPreference mBlockedDesc; + protected Preference mAppLink; protected EnforcedAdmin mSuspendedAppsAdmin; protected boolean mDndVisualEffectsSuppressed; protected NotificationChannel mChannel; protected NotificationBackend.AppRow mAppRow; + protected boolean mShowLegacyChannelConfig = false; @Override public void onActivityCreated(Bundle savedInstanceState) { @@ -113,6 +134,7 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen mPm = getPackageManager(); mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE); + mNm = NotificationManager.from(mContext); mPkg = args != null && args.containsKey(AppInfoBase.ARG_PACKAGE_NAME) ? args.getString(AppInfoBase.ARG_PACKAGE_NAME) @@ -154,8 +176,7 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen mSuspendedAppsAdmin = RestrictedLockUtils.checkIfApplicationIsSuspended( mContext, mPkg, mUserId); - NotificationManager.Policy policy = - NotificationManager.from(mContext).getNotificationPolicy(); + NotificationManager.Policy policy = mNm.getNotificationPolicy(); mDndVisualEffectsSuppressed = policy == null ? false : policy.suppressedVisualEffects != 0; mSuspendedAppsAdmin = RestrictedLockUtils.checkIfApplicationIsSuspended( @@ -241,26 +262,56 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen return null; } - protected String getImportanceSummary(int importance) { - switch (importance) { - case NotificationManager.IMPORTANCE_UNSPECIFIED: - return getContext().getString(R.string.notification_importance_unspecified); - case NotificationManager.IMPORTANCE_NONE: - return getContext().getString(R.string.notification_importance_blocked); - case NotificationManager.IMPORTANCE_MIN: - return getContext().getString(R.string.notification_importance_min); - case NotificationManager.IMPORTANCE_LOW: - return getContext().getString(R.string.notification_importance_low); - case NotificationManager.IMPORTANCE_DEFAULT: - return getContext().getString(R.string.notification_importance_default); - case NotificationManager.IMPORTANCE_HIGH: - case NotificationManager.IMPORTANCE_MAX: - default: - return getContext().getString(R.string.notification_importance_high); + protected void addAppLinkPref() { + if (mAppRow.settingsIntent != null) { + mAppLink = new Preference(getPrefContext()); + mAppLink.setKey(KEY_APP_LINK); + mAppLink.setOrder(500); + mAppLink.setIntent(mAppRow.settingsIntent); + mAppLink.setTitle(mContext.getString(R.string.app_settings_link)); + getPreferenceScreen().addPreference(mAppLink); } } + protected void populateDefaultChannelPrefs() { + if (mPkgInfo != null && mChannel != null) { + addPreferencesFromResource(R.xml.legacy_channel_notification_settings); + setupPriorityPref(mChannel.canBypassDnd()); + setupVisOverridePref(mChannel.getLockscreenVisibility()); + setupImportanceToggle(); + setupBadge(); + } + mSwitchBar.setChecked(!mAppRow.banned + && mChannel.getImportance() != NotificationManager.IMPORTANCE_NONE); + } + + abstract void setupBadge(); + + abstract void updateDependents(boolean banned); + + // 'allow sound' + private void setupImportanceToggle() { + mImportanceToggle = (RestrictedSwitchPreference) findPreference(KEY_ALLOW_SOUND); + mImportanceToggle.setDisabledByAdmin(mSuspendedAppsAdmin); + mImportanceToggle.setChecked(mChannel.getImportance() >= IMPORTANCE_DEFAULT + || mChannel.getImportance() == IMPORTANCE_UNSPECIFIED); + mImportanceToggle.setOnPreferenceChangeListener( + new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final int importance = + ((Boolean) newValue ? IMPORTANCE_UNSPECIFIED : IMPORTANCE_LOW); + mChannel.setImportance(importance); + mChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE); + mBackend.updateChannel(mPkg, mUid, mChannel); + updateDependents(mChannel.getImportance() == IMPORTANCE_NONE); + return true; + } + }); + } + protected void setupPriorityPref(boolean priority) { + mPriority = (RestrictedSwitchPreference) findPreference(KEY_BYPASS_DND); mPriority.setDisabledByAdmin(mSuspendedAppsAdmin); mPriority.setChecked(priority); mPriority.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @@ -276,6 +327,8 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen } protected void setupVisOverridePref(int sensitive) { + mVisibilityOverride = + (RestrictedDropDownPreference) findPreference(KEY_VISIBILITY_OVERRIDE); ArrayList entries = new ArrayList<>(); ArrayList values = new ArrayList<>(); @@ -328,6 +381,8 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen } protected void setupBlockDesc(int summaryResId) { + mBlockedDesc = (FooterPreference) getPreferenceScreen().findPreference( + KEY_BLOCKED_DESC); mBlockedDesc = new FooterPreference(getPrefContext()); mBlockedDesc.setSelectable(false); mBlockedDesc.setTitle(summaryResId); @@ -336,6 +391,13 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen getPreferenceScreen().addPreference(mBlockedDesc); } + protected boolean checkCanBeVisible(int minImportanceVisible) { + int importance = mChannel.getImportance(); + if (importance == NotificationManager.IMPORTANCE_UNSPECIFIED) { + return true; + } + return importance >= minImportanceVisible; + } private void setRestrictedIfNotificationFeaturesDisabled(CharSequence entry, CharSequence entryValue, int keyguardNotificationFeatures) { @@ -359,7 +421,6 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen return globalVis; } - private boolean getLockscreenNotificationsEnabled() { return Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0) != 0; @@ -369,4 +430,17 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen return Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0) != 0; } + + protected boolean isLockScreenSecure() { + if (mLockPatternUtils == null) { + mLockPatternUtils = new LockPatternUtils(getActivity()); + } + boolean lockscreenSecure = mLockPatternUtils.isSecure(UserHandle.myUserId()); + UserInfo parentUser = mUm.getProfileParent(UserHandle.myUserId()); + if (parentUser != null){ + lockscreenSecure |= mLockPatternUtils.isSecure(parentUser.id); + } + + return lockscreenSecure; + } }