diff --git a/res/layout/preference_importance_slider.xml b/res/layout/preference_importance_slider.xml index 677a32b9e54..dc7c9dbcb6a 100644 --- a/res/layout/preference_importance_slider.xml +++ b/res/layout/preference_importance_slider.xml @@ -15,47 +15,64 @@ --> + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="?android:attr/listPreferredItemHeight" + android:gravity="center_vertical" + android:paddingStart="?android:attr/listPreferredItemPaddingStart" + android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" + android:paddingTop="8dp" + android:paddingBottom="8dp" + android:orientation="vertical" + android:clickable="false" + android:focusable="false" > - + + + + + + + android:layout_height="48dp" + android:focusable="true" + android:background="#00ffffff" + android:progressBackgroundTint="@color/importance_secondary_slider_color" + android:thumbTint="@color/importance_disabled_slider_color" + android:progressTint="@color/importance_disabled_slider_color" + style="@android:style/Widget.Material.SeekBar.Discrete" + android:tickMarkTint="@android:color/black" /> - + - - - - - + diff --git a/res/values/colors.xml b/res/values/colors.xml index 89b2d15c0b6..a9756adc909 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -125,6 +125,10 @@ #fff + @*android:color/material_deep_teal_500 + @*android:color/material_grey_300 + #858383 + #B0BEC5 diff --git a/res/values/strings.xml b/res/values/strings.xml index 2675e15ce31..16ab7082e7e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5979,22 +5979,25 @@ Not set - Blocked: Never show these notifications + Never show notifications from this app - Min: Silently show at the bottom of the notification list + No full screen interruption, peeking, sound, or vibration. Show at the bottom of the notification list. Hide from lock screen and status bar. - Low: Silently show these notifications + No full screen interruption, peeking, sound, or vibration. - Normal: Allow these notification to make sounds + No full screen interruption or peeking. - High: Peek onto the screen and allow sound + Always peek. No full screen interruption. - Urgent: Show at the top of the notifications list, peek onto the screen and allow sound + Always peek, and allow full screen interruption. Show at the top of the notification list. + + + App determines importance for each notification Reset @@ -6486,6 +6489,8 @@ Do Not Disturb overridden \u00A0/\u00A0 + + Level %d diff --git a/res/xml/app_notification_settings.xml b/res/xml/app_notification_settings.xml index 8bd0c88aee3..fd2f33e79b6 100644 --- a/res/xml/app_notification_settings.xml +++ b/res/xml/app_notification_settings.xml @@ -32,30 +32,22 @@ android:summary="@string/show_silently_summary" android:order="3" /> - - - + android:title="@string/notification_importance_title" + android:order="4"/> + android:order="5" /> + android:order="6" /> diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java index 035b50482f8..7813745085b 100755 --- a/src/com/android/settings/applications/InstalledAppDetails.java +++ b/src/com/android/settings/applications/InstalledAppDetails.java @@ -51,7 +51,9 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; import android.os.UserManager; +import android.provider.Settings; import android.service.notification.NotificationListenerService; +import android.service.notification.NotificationListenerService.Ranking; import android.support.v7.preference.Preference; import android.support.v7.preference.Preference.OnPreferenceClickListener; import android.support.v7.preference.PreferenceCategory; @@ -144,6 +146,8 @@ public class InstalledAppDetails extends AppInfoBase private static final String KEY_BATTERY = "battery"; private static final String KEY_MEMORY = "memory"; + private static final String NOTIFICATION_TUNER_SETTING = "show_importance_slider"; + private final HashSet mHomePackages = new HashSet(); private boolean mInitialized; @@ -1016,13 +1020,22 @@ public class InstalledAppDetails extends AppInfoBase } public static CharSequence getNotificationSummary(AppRow appRow, Context context) { + boolean showSlider = Settings.Secure.getInt( + context.getContentResolver(), NOTIFICATION_TUNER_SETTING, 0) == 1; List summaryAttributes = new ArrayList<>(); StringBuffer summary = new StringBuffer(); - if (appRow.banned) { - summaryAttributes.add(context.getString(R.string.notifications_disabled)); - } else if (appRow.appImportance > NotificationListenerService.Ranking.IMPORTANCE_NONE - && appRow.appImportance < NotificationListenerService.Ranking.IMPORTANCE_DEFAULT) { - summaryAttributes.add(context.getString(R.string.notifications_silenced)); + if (showSlider) { + if (appRow.appImportance != Ranking.IMPORTANCE_UNSPECIFIED) { + summaryAttributes.add(context.getString( + R.string.notification_summary_level, appRow.appImportance)); + } + } else { + if (appRow.banned) { + summaryAttributes.add(context.getString(R.string.notifications_disabled)); + } else if (appRow.appImportance > Ranking.IMPORTANCE_NONE + && appRow.appImportance < Ranking.IMPORTANCE_DEFAULT) { + summaryAttributes.add(context.getString(R.string.notifications_silenced)); + } } final boolean lockscreenSecure = new LockPatternUtils(context).isSecure( UserHandle.myUserId()); diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java index 144c841a0d6..5113dc64b18 100644 --- a/src/com/android/settings/notification/AppNotificationSettings.java +++ b/src/com/android/settings/notification/AppNotificationSettings.java @@ -72,8 +72,6 @@ public class AppNotificationSettings extends NotificationSettingsBase { addPreferencesFromResource(R.xml.app_notification_settings); mImportance = (ImportanceSeekBarPreference) findPreference(KEY_IMPORTANCE); - mImportanceReset = (LayoutPreference) findPreference(KEY_IMPORTANCE_RESET); - mImportanceTitle = (RestrictedPreference) findPreference(KEY_IMPORTANCE_TITLE); mPriority = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BYPASS_DND); mVisibilityOverride = diff --git a/src/com/android/settings/notification/ImportanceSeekBarPreference.java b/src/com/android/settings/notification/ImportanceSeekBarPreference.java index aff96882544..46f9b3f4951 100644 --- a/src/com/android/settings/notification/ImportanceSeekBarPreference.java +++ b/src/com/android/settings/notification/ImportanceSeekBarPreference.java @@ -20,10 +20,16 @@ import com.android.settings.R; import com.android.settings.SeekBarPreference; import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.service.notification.NotificationListenerService; import android.support.v7.preference.PreferenceViewHolder; import android.util.AttributeSet; +import android.view.View; import android.widget.ImageView; import android.widget.SeekBar; +import android.widget.TextView; /** * A slider preference that controls notification importance. @@ -34,12 +40,23 @@ public class ImportanceSeekBarPreference extends SeekBarPreference implements private Callback mCallback; private int mMinProgress; - private boolean mSystemApp; + private TextView mSummaryTextView; + private String mSummary; + private SeekBar mSeekBar; + private ColorStateList mActiveSliderTint; + private ColorStateList mInactiveSliderTint; + private boolean mAutoOn; + private Handler mHandler; public ImportanceSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); setLayoutResource(R.layout.preference_importance_slider); + mActiveSliderTint = ColorStateList.valueOf( + context.getColor(R.color.importance_slider_color)); + mInactiveSliderTint = ColorStateList.valueOf( + context.getColor(R.color.importance_disabled_slider_color)); + mHandler = new Handler(); } public ImportanceSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr) { @@ -63,20 +80,67 @@ public class ImportanceSeekBarPreference extends SeekBarPreference implements notifyChanged(); } - public void setSystemApp(boolean systemApp) { - mSystemApp = systemApp; + @Override + public void setProgress(int progress) { + mSummary = getProgressSummary(progress); + super.setProgress(progress); + } + + public void setAutoOn(boolean autoOn) { + mAutoOn = autoOn; notifyChanged(); } @Override public void onBindViewHolder(PreferenceViewHolder view) { super.onBindViewHolder(view); - if (mSystemApp) { - ((ImageView) view.findViewById(R.id.low_importance)).getDrawable().setTint( - getContext().getColor(R.color.importance_disabled_tint)); + mSummaryTextView = (TextView) view.findViewById(com.android.internal.R.id.summary); + mSeekBar = (SeekBar) view.findViewById( + com.android.internal.R.id.seekbar); + + final ImageView autoButton = (ImageView) view.findViewById(R.id.auto_importance); + applyAutoUi(autoButton); + autoButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + applyAuto(autoButton); + } + }); + } + + private void applyAuto(ImageView autoButton) { + mAutoOn = !mAutoOn; + if (!mAutoOn) { + setProgress(NotificationListenerService.Ranking.IMPORTANCE_DEFAULT); + mCallback.onImportanceChanged( + NotificationListenerService.Ranking.IMPORTANCE_DEFAULT, true); + } else { + mCallback.onImportanceChanged( + NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED, true); } - view.setDividerAllowedAbove(false); - view.setDividerAllowedBelow(false); + applyAutoUi(autoButton); + } + + private void applyAutoUi(ImageView autoButton) { + mSeekBar.setEnabled(!mAutoOn); + + final ColorStateList tint = mAutoOn ? mInactiveSliderTint : mActiveSliderTint; + Drawable icon = autoButton.getDrawable().mutate(); + icon.setTintList(tint); + autoButton.setImageDrawable(icon); + mSeekBar.setProgressTintList(tint); + mSeekBar.setThumbTintList(tint); + + if (mAutoOn) { + mSummary = getProgressSummary( + NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED); + } + mSummaryTextView.setText(mSummary); + } + + @Override + public CharSequence getSummary() { + return mSummary; } @Override @@ -86,12 +150,49 @@ public class ImportanceSeekBarPreference extends SeekBarPreference implements seekBar.setProgress(mMinProgress); progress = mMinProgress; } - if (fromTouch) { - mCallback.onImportanceChanged(progress); + if (mSummaryTextView != null) { + mSummary = getProgressSummary(progress); + mSummaryTextView.setText(mSummary); + } + mCallback.onImportanceChanged(progress, fromTouch); + } + + private String getProgressSummary(int progress) { + switch (progress) { + case NotificationListenerService.Ranking.IMPORTANCE_NONE: + return getContext().getString(R.string.notification_importance_blocked); + case NotificationListenerService.Ranking.IMPORTANCE_MIN: + return getContext().getString(R.string.notification_importance_min); + case NotificationListenerService.Ranking.IMPORTANCE_LOW: + return getContext().getString(R.string.notification_importance_low); + case NotificationListenerService.Ranking.IMPORTANCE_DEFAULT: + return getContext().getString(R.string.notification_importance_default); + case NotificationListenerService.Ranking.IMPORTANCE_HIGH: + return getContext().getString(R.string.notification_importance_high); + case NotificationListenerService.Ranking.IMPORTANCE_MAX: + return getContext().getString(R.string.notification_importance_max); + default: + return getContext().getString(R.string.notification_importance_unspecified); } } + @Override + protected void notifyChanged() { + mHandler.post(mNotifyChanged); + } + + private void postNotifyChanged() { + super.notifyChanged(); + } + + private final Runnable mNotifyChanged = new Runnable() { + @Override + public void run() { + postNotifyChanged(); + } + }; + public interface Callback { - void onImportanceChanged(int progress); + void onImportanceChanged(int progress, boolean fromTouch); } } diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java index 314c2f8d0c7..e0349656fec 100644 --- a/src/com/android/settings/notification/NotificationSettingsBase.java +++ b/src/com/android/settings/notification/NotificationSettingsBase.java @@ -20,9 +20,7 @@ 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.RestrictedPreference; import com.android.settingslib.RestrictedSwitchPreference; -import com.android.settings.applications.LayoutPreference; import android.app.Notification; import android.content.Context; @@ -38,8 +36,6 @@ import android.support.v7.preference.DropDownPreference; import android.support.v7.preference.Preference; import android.text.TextUtils; import android.util.Log; -import android.view.View; -import android.widget.Button; import android.widget.Toast; import java.util.ArrayList; @@ -54,8 +50,6 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen 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_IMPORTANCE_TITLE = "importance_title"; - protected static final String KEY_IMPORTANCE_RESET = "importance_reset_button"; protected static final String KEY_BLOCK = "block"; protected static final String KEY_SILENT = "silent"; @@ -68,8 +62,6 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen protected String mPkg; protected PackageInfo mPkgInfo; protected ImportanceSeekBarPreference mImportance; - protected RestrictedPreference mImportanceTitle; - protected LayoutPreference mImportanceReset; protected RestrictedSwitchPreference mPriority; protected DropDownPreference mVisibilityOverride; protected RestrictedSwitchPreference mBlock; @@ -147,9 +139,6 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen if (mPriority != null) { mPriority.setDisabledByAdmin(mSuspendedAppsAdmin); } - if (mImportanceTitle != null) { - mImportanceTitle.setDisabledByAdmin(mSuspendedAppsAdmin); - } if (mBlock != null) { mBlock.setDisabledByAdmin(mSuspendedAppsAdmin); } @@ -163,54 +152,22 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen setVisible(mBlock, false); setVisible(mSilent, false); mImportance.setDisabledByAdmin(mSuspendedAppsAdmin); - mImportanceTitle.setDisabledByAdmin(mSuspendedAppsAdmin); - if (importance == Ranking.IMPORTANCE_UNSPECIFIED) { - mImportance.setVisible(false); - mImportanceReset.setVisible(false); - mImportanceTitle.setOnPreferenceClickListener(showEditableImportance); - } else { - mImportanceTitle.setOnPreferenceClickListener(null); - } - - mImportanceTitle.setSummary(getProgressSummary(importance)); - mImportance.setSystemApp(isSystemApp); mImportance.setMinimumProgress( isSystemApp ? Ranking.IMPORTANCE_MIN : Ranking.IMPORTANCE_NONE); mImportance.setMax(Ranking.IMPORTANCE_MAX); mImportance.setProgress(importance); + mImportance.setAutoOn(importance == Ranking.IMPORTANCE_UNSPECIFIED); mImportance.setCallback(new ImportanceSeekBarPreference.Callback() { @Override - public void onImportanceChanged(int progress) { - mBackend.setImportance(mPkg, mUid, progress); - mImportanceTitle.setSummary(getProgressSummary(progress)); + public void onImportanceChanged(int progress, boolean fromUser) { + if (fromUser) { + mBackend.setImportance(mPkg, mUid, progress); + } updateDependents(progress); } }); - - Button button = (Button) mImportanceReset.findViewById(R.id.left_button); - button.setText(R.string.importance_reset); - button.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (mSuspendedAppsAdmin != null) { - RestrictedLockUtils.sendShowAdminSupportDetailsIntent( - getActivity(), mSuspendedAppsAdmin); - return; - } - - mBackend.setImportance(mPkg, mUid, Ranking.IMPORTANCE_UNSPECIFIED); - mImportanceReset.setVisible(false); - mImportance.setVisible(false); - mImportanceTitle.setOnPreferenceClickListener(showEditableImportance); - mImportanceTitle.setSummary(getProgressSummary(Ranking.IMPORTANCE_UNSPECIFIED)); - updateDependents(Ranking.IMPORTANCE_UNSPECIFIED); - } - }); - mImportanceReset.findViewById(R.id.right_button).setVisibility(View.INVISIBLE); } else { setVisible(mImportance, false); - setVisible(mImportanceReset, false); - setVisible(mImportanceTitle, false); boolean blocked = importance == Ranking.IMPORTANCE_NONE || banned; mBlock.setChecked(blocked); mBlock.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @@ -240,27 +197,6 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen } } - private String getProgressSummary(int progress) { - switch (progress) { - case Ranking.IMPORTANCE_NONE: - return mContext.getString(R.string.notification_importance_blocked); - case Ranking.IMPORTANCE_MIN: - return mContext.getString(R.string.notification_importance_min); - case Ranking.IMPORTANCE_LOW: - return mContext.getString(R.string.notification_importance_low); - case Ranking.IMPORTANCE_DEFAULT: - return mContext.getString(R.string.notification_importance_default); - case Ranking.IMPORTANCE_HIGH: - return mContext.getString(R.string.notification_importance_high); - case Ranking.IMPORTANCE_MAX: - return mContext.getString(R.string.notification_importance_max); - case Ranking.IMPORTANCE_UNSPECIFIED: - return mContext.getString(R.string.notification_importance_none); - default: - return ""; - } - } - protected void setupPriorityPref(boolean priority) { mPriority.setDisabledByAdmin(mSuspendedAppsAdmin); mPriority.setChecked(priority); @@ -363,18 +299,4 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen } return null; } - - private Preference.OnPreferenceClickListener showEditableImportance = - new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - mBackend.setImportance(mPkg, mUid, Ranking.IMPORTANCE_DEFAULT); - mImportance.setProgress(Ranking.IMPORTANCE_DEFAULT); - mImportanceTitle.setSummary(getProgressSummary(Ranking.IMPORTANCE_DEFAULT)); - mImportance.setVisible(true); - mImportanceReset.setVisible(true); - mImportanceTitle.setOnPreferenceClickListener(null); - return true; - } - }; }