diff --git a/res/values/strings.xml b/res/values/strings.xml index da83867c057..0572b351acb 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -6229,6 +6229,9 @@ Not set + + Let the app decide + Never show notifications @@ -7634,6 +7637,8 @@ importance explanation + + can show badge intent diff --git a/res/xml/app_notification_settings.xml b/res/xml/app_notification_settings.xml index 82660dc81d1..7d51fa8da0c 100644 --- a/res/xml/app_notification_settings.xml +++ b/res/xml/app_notification_settings.xml @@ -23,6 +23,15 @@ android:key="block" android:title="@string/app_notification_block_title" android:summary="@string/app_notification_block_summary" + android:order="1" + settings:useAdditionalSummary="true" + settings:restrictedSwitchSummary="@string/enabled_by_admin" /> + + + diff --git a/res/xml/channel_notification_settings.xml b/res/xml/channel_notification_settings.xml index e1d6d55f91d..4af9fe8e668 100644 --- a/res/xml/channel_notification_settings.xml +++ b/res/xml/channel_notification_settings.xml @@ -27,54 +27,55 @@ settings:useAdditionalSummary="true" settings:restrictedSwitchSummary="@string/enabled_by_admin" /> + + + + + + + + + - - + + + android:order="7" /> - - - - - - - - diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java index b740b92a230..d4cd6f8991d 100644 --- a/src/com/android/settings/notification/AppNotificationSettings.java +++ b/src/com/android/settings/notification/AppNotificationSettings.java @@ -19,6 +19,7 @@ package com.android.settings.notification; import android.app.Activity; import android.app.Notification; import android.app.NotificationChannel; +import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; @@ -35,11 +36,13 @@ import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.applications.AppHeaderController; import com.android.settings.applications.AppInfoBase; +import com.android.settings.core.PreferenceController; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.notification.NotificationBackend.AppRow; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.RestrictedPreference; import com.android.settingslib.RestrictedSwitchPreference; +import com.android.settingslib.drawer.CategoryKey; import java.text.Collator; import java.util.Collections; @@ -88,10 +91,12 @@ public class AppNotificationSettings extends NotificationSettingsBase { addPreferencesFromResource(R.xml.app_notification_settings); mBlock = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BLOCK); + mBadge = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BADGE); mChannels = (PreferenceCategory) findPreference(KEY_CHANNELS); if (mPkgInfo != null) { - setupBlock(mAppRow.systemApp, mAppRow.banned); + setupBlock(); + setupBadge(); // load settings intent ArrayMap rows = new ArrayMap(); rows.put(mAppRow.pkg, mAppRow); @@ -113,6 +118,7 @@ public class AppNotificationSettings extends NotificationSettingsBase { if (channel.isDeleted()) { channelPref.setTitle( getString(R.string.deleted_channel_name, channel.getName())); + channelPref.setEnabled(false); } else { Bundle channelArgs = new Bundle(); channelArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid); @@ -153,16 +159,27 @@ public class AppNotificationSettings extends NotificationSettingsBase { finish(); return; } - if (mBlock != null) { - mBlock.setDisabledByAdmin(mSuspendedAppsAdmin); - } } - private void setupBlock(boolean notBlockable, boolean banned) { - if (notBlockable) { + 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 setupBlock() { + if (mAppRow.systemApp) { setVisible(mBlock, false); } else { - mBlock.setChecked(banned); + mBlock.setDisabledByAdmin(mSuspendedAppsAdmin); + mBlock.setChecked(mAppRow.banned); mBlock.setOnPreferenceChangeListener( new Preference.OnPreferenceChangeListener() { @Override @@ -180,6 +197,7 @@ public class AppNotificationSettings extends NotificationSettingsBase { private void updateDependents(boolean banned) { setVisible(mChannels, !(mChannelList.isEmpty() || banned)); + setVisible(mBadge, !banned); } private List queryNotificationConfigActivities() { diff --git a/src/com/android/settings/notification/ChannelNotificationSettings.java b/src/com/android/settings/notification/ChannelNotificationSettings.java index e73feb56c5f..2749e030268 100644 --- a/src/com/android/settings/notification/ChannelNotificationSettings.java +++ b/src/com/android/settings/notification/ChannelNotificationSettings.java @@ -26,6 +26,7 @@ import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; +import android.content.Context; import android.content.Intent; import android.content.pm.UserInfo; import android.net.Uri; @@ -47,15 +48,17 @@ import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedSwitchPreference; import java.util.ArrayList; +import java.util.List; public class ChannelNotificationSettings extends NotificationSettingsBase { + private static final String TAG = "ChannelSettings"; + 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_LIGHTS = "lights"; protected static final String KEY_VIBRATE = "vibrate"; protected static final String KEY_RINGTONE = "ringtone"; - protected static final String KEY_BADGE = "badge"; protected RestrictedSwitchPreference mLights; protected RestrictedSwitchPreference mVibrate; @@ -114,8 +117,8 @@ public class ChannelNotificationSettings extends NotificationSettingsBase { .getApplicationFeatureProvider(activity) .newAppHeaderController(this /* fragment */, null /* appHeader */) .setIcon(mAppRow.icon) - .setLabel(mAppRow.label) - .setSummary(mChannel.getName()) + .setLabel(mChannel.getName()) + .setSummary(mAppRow.label) .setPackageName(mAppRow.pkg) .setUid(mAppRow.uid) .setButtonActions(AppHeaderController.ActionType.ACTION_APP_INFO, @@ -138,8 +141,6 @@ public class ChannelNotificationSettings extends NotificationSettingsBase { mImportance.setDisabledByAdmin(mSuspendedAppsAdmin); mPriority.setDisabledByAdmin(mSuspendedAppsAdmin); mVisibilityOverride.setDisabledByAdmin(mSuspendedAppsAdmin); - mBlock.setDisabledByAdmin(mSuspendedAppsAdmin); - mBadge.setDisabledByAdmin(mSuspendedAppsAdmin); } private void setupLights() { @@ -204,6 +205,7 @@ public class ChannelNotificationSettings extends NotificationSettingsBase { } }); mBadge.setDisabledByAdmin(mSuspendedAppsAdmin); + mBadge.setEnabled(mAppRow.showBadge); mBadge.setChecked(mChannel.canShowBadge()); mBadge.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override @@ -218,15 +220,20 @@ public class ChannelNotificationSettings extends NotificationSettingsBase { mImportance.setDisabledByAdmin(mSuspendedAppsAdmin); final int numImportances = IMPORTANCE_HIGH - IMPORTANCE_MIN + 1; - String[] summaries = new String[numImportances]; - String[] values = new String[numImportances]; + List summaries = new ArrayList<>(); + List values = new ArrayList<>();; for (int i = 0; i < numImportances; i++) { int importance = i + 1; - summaries[i] = getSummary(importance); - values[i] = String.valueOf(importance); + summaries.add(getSummary(importance)); + values.add(String.valueOf(importance)); } - mImportance.setEntryValues(values); - mImportance.setEntries(summaries); + if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId())) { + // Add option to reset to letting the app decide + summaries.add(getSummary(NotificationManager.IMPORTANCE_UNSPECIFIED)); + values.add(String.valueOf(NotificationManager.IMPORTANCE_UNSPECIFIED)); + } + mImportance.setEntryValues(values.toArray(new String[0])); + mImportance.setEntries(summaries.toArray(new String[0])); mImportance.setValue(String.valueOf(mChannel.getImportance())); mImportance.setSummary("%s"); @@ -245,6 +252,8 @@ public class ChannelNotificationSettings extends NotificationSettingsBase { private String getSummary(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: diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java index 692e1f6aa1c..124579f5ee2 100644 --- a/src/com/android/settings/notification/NotificationBackend.java +++ b/src/com/android/settings/notification/NotificationBackend.java @@ -26,6 +26,7 @@ import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.graphics.drawable.Drawable; import android.os.ServiceManager; +import android.os.UserHandle; import android.util.Log; import com.android.settingslib.Utils; @@ -48,6 +49,8 @@ public class NotificationBackend { } row.icon = app.loadIcon(pm); row.banned = getNotificationsBanned(row.pkg, row.uid); + row.showBadge = canShowBadge(row.pkg, row.uid); + row.userId = UserHandle.getUserId(row.uid); return row; } @@ -87,6 +90,25 @@ public class NotificationBackend { } } + public boolean canShowBadge(String pkg, int uid) { + try { + return sINM.canShowBadge(pkg, uid); + } catch (Exception e) { + Log.w(TAG, "Error calling NoMan", e); + return false; + } + } + + public boolean setShowBadge(String pkg, int uid, boolean showBadge) { + try { + sINM.setShowBadge(pkg, uid, showBadge); + return true; + } catch (Exception e) { + Log.w(TAG, "Error calling NoMan", e); + return false; + } + } + public NotificationChannel getChannel(String pkg, int uid, String channelId) { if (channelId == null) { return null; @@ -129,6 +151,8 @@ public class NotificationBackend { public boolean banned; public boolean first; // first app in section public boolean systemApp; + public boolean showBadge; + public int userId; } public static class ChannelRow extends AppRow { diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java index f3e4390d40f..15352697699 100644 --- a/src/com/android/settings/notification/NotificationSettingsBase.java +++ b/src/com/android/settings/notification/NotificationSettingsBase.java @@ -16,36 +16,28 @@ package com.android.settings.notification; -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.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedSwitchPreference; -import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; -import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.UserInfo; import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; -import android.service.notification.NotificationListenerService.Ranking; import android.support.v7.preference.Preference; import android.text.TextUtils; import android.util.Log; import android.widget.Toast; -import java.util.ArrayList; - -import static com.android.settings.notification.RestrictedDropDownPreference.RestrictedItem; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; abstract public class NotificationSettingsBase extends SettingsPreferenceFragment { @@ -55,6 +47,7 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen protected static final String ARG_CHANNEL = "channel"; protected static final String KEY_BLOCK = "block"; + protected static final String KEY_BADGE = "badge"; protected PackageManager mPm; protected UserManager mUm; @@ -145,6 +138,7 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen mSuspendedAppsAdmin = RestrictedLockUtils.checkIfApplicationIsSuspended( mContext, mPkg, mUserId); mBlock.setDisabledByAdmin(mSuspendedAppsAdmin); + mBadge.setDisabledByAdmin(mSuspendedAppsAdmin); } protected void setVisible(Preference p, boolean visible) { diff --git a/src/com/android/settings/notification/NotificationStation.java b/src/com/android/settings/notification/NotificationStation.java index 04897e464e5..50bcd9521ac 100644 --- a/src/com/android/settings/notification/NotificationStation.java +++ b/src/com/android/settings/notification/NotificationStation.java @@ -56,7 +56,7 @@ import java.util.*; public class NotificationStation extends SettingsPreferenceFragment { private static final String TAG = NotificationStation.class.getSimpleName(); - private static final boolean DEBUG = false; + private static final boolean DEBUG = true; private static final boolean DUMP_EXTRAS = true; private static final boolean DUMP_PARCEL = true; private Handler mHandler; @@ -362,6 +362,11 @@ public class NotificationStation extends SettingsPreferenceFragment { .append(delim) .append(rank.getImportanceExplanation()); } + sb.append("\n") + .append(bold(getString( + R.string.notification_log_details_badge))) + .append(delim) + .append(Boolean.toString(rank.canShowBadge())); } else { if (mRanking == null) { sb.append("\n")