-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- 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:orientation="vertical"
- android:clickable="false"
- android:focusable="false" >
-
- <FrameLayout
+ 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" >
+
+ <TextView
+ android:id="@android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textColor="?android:attr/textColorPrimary"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <ImageView
+ android:id="@+id/auto_importance"
+ android:src="@drawable/notification_auto_importance"
+ android:layout_gravity="center_vertical|start"
+ android:layout_width="48dp"
+ android:layout_height="48dp" />
+
+ <SeekBar
+ android:id="@*android:id/seekbar"
+ android:layout_marginStart="56dp"
+ android:layout_marginEnd="32dp"
+ android:layout_gravity="center_vertical"
android:layout_width="match_parent"
- android:layout_height="wrap_content" >
-
- <ImageView
- android:id="@+id/low_importance"
- android:src="@*android:drawable/ic_notification_block"
- android:layout_gravity="center_vertical|start"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:tint="@color/importance_icon_tint" />
-
- <SeekBar
- android:id="@*android:id/seekbar"
- android:layout_marginStart="56dp"
- android:layout_marginEnd="56dp"
- android:layout_gravity="center_vertical"
- android:layout_width="match_parent"
- android:layout_height="48dp"
- android:focusable="true"
- android:background="#00ffffff"
- style="@android:style/Widget.Material.SeekBar.Discrete"
- android:tickMarkTint="@android:color/black"/>
-
- <ImageView
- android:id="@+id/max_importance"
- android:src="@*android:drawable/ic_notification_alert"
- android:layout_gravity="center_vertical|end"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:tint="@color/importance_icon_tint" />
-
- </FrameLayout>
+ 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" />
+
+ </FrameLayout>
+
+ <TextView
+ android:id="@android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignStart="@android:id/title"
+ android:textAlignment="viewStart"
+ android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textColor="?android:attr/textColorSecondary"
+ android:maxLines="10"
+ android:minLines="3" />
</LinearLayout>
<color name="seek_bar_preference_preview_text">#fff</color>
+ <color name="importance_slider_color">@*android:color/material_deep_teal_500</color>
+ <color name="importance_disabled_slider_color">@*android:color/material_grey_300</color>
+ <color name="importance_secondary_slider_color">#858383</color>
+
<color name="usage_graph_dots">#B0BEC5</color>
</resources>
<string name="notification_importance_none">Not set</string>
<!-- [CHAR LIMIT=100] Notification Importance slider: blocked importance level description -->
- <string name="notification_importance_blocked">Blocked: Never show these notifications</string>
+ <string name="notification_importance_blocked">Never show notifications from this app</string>
<!-- [CHAR LIMIT=100] Notification Importance slider: min importance level description -->
- <string name="notification_importance_min">Min: Silently show at the bottom of the notification list</string>
+ <string name="notification_importance_min">No full screen interruption, peeking, sound, or vibration. Show at the bottom of the notification list. Hide from lock screen and status bar.</string>
<!-- [CHAR LIMIT=100] Notification Importance slider: low importance level description -->
- <string name="notification_importance_low">Low: Silently show these notifications</string>
+ <string name="notification_importance_low">No full screen interruption, peeking, sound, or vibration.</string>
<!-- [CHAR LIMIT=100] Notification Importance slider: normal importance level description -->
- <string name="notification_importance_default">Normal: Allow these notification to make sounds</string>
+ <string name="notification_importance_default">No full screen interruption or peeking.</string>
<!-- [CHAR LIMIT=100] Notification Importance slider: high importance level description -->
- <string name="notification_importance_high">High: Peek onto the screen and allow sound</string>
+ <string name="notification_importance_high">Always peek. No full screen interruption.</string>
<!-- [CHAR LIMIT=100] Notification Importance slider: max importance level description -->
- <string name="notification_importance_max">Urgent: Show at the top of the notifications list, peek onto the screen and allow sound</string>
+ <string name="notification_importance_max">Always peek, and allow full screen interruption. Show at the top of the notification list.</string>
+
+ <!-- [CHAR LIMIT=100] Notification Importance slider: max importance level description -->
+ <string name="notification_importance_unspecified">App determines importance for each notification</string>
<!-- [CHAR LIMIT=60] Notification importance reset button -->
<string name="importance_reset">Reset</string>
<string name="notifications_priority">Do Not Disturb overridden</string>
<!-- App notification summary divider [CHAR LIMIT=40] -->
<string name="notifications_summary_divider">\u00A0/\u00A0</string>
+ <!-- App notification summary for advanced controls -->
+ <string name="notification_summary_level">Level %d</string>
<!-- Permissions preference summary [CHAR LIMIT=40] -->
<plurals name="permissions_summary">
android:summary="@string/show_silently_summary"
android:order="3" />
<!-- Slider -->
- <com.android.settingslib.RestrictedPreference
- android:key="importance_title"
- android:title="@string/notification_importance_title"
- android:order="4"/>
<com.android.settings.notification.ImportanceSeekBarPreference
android:key="importance"
- android:order="5"/>
-
- <com.android.settings.applications.LayoutPreference
- android:key="importance_reset_button"
- android:layout="@layout/two_buttons_panel"
- android:order="6" />
+ android:title="@string/notification_importance_title"
+ android:order="4"/>
<!-- Visibility Override -->
<DropDownPreference
android:key="visibility_override"
android:title="@string/app_notification_visibility_override_title"
- android:order="7" />
+ android:order="5" />
<!-- Bypass DND -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="bypass_dnd"
android:title="@string/app_notification_override_dnd_title"
android:summary="@string/app_notification_override_dnd_summary"
- android:order="8" />
+ android:order="6" />
</PreferenceScreen>
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;
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<String> mHomePackages = new HashSet<String>();
private boolean mInitialized;
}
public static CharSequence getNotificationSummary(AppRow appRow, Context context) {
+ boolean showSlider = Settings.Secure.getInt(
+ context.getContentResolver(), NOTIFICATION_TUNER_SETTING, 0) == 1;
List<String> 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());
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 =
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.
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) {
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
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);
}
}
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;
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;
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";
protected String mPkg;
protected PackageInfo mPkgInfo;
protected ImportanceSeekBarPreference mImportance;
- protected RestrictedPreference mImportanceTitle;
- protected LayoutPreference mImportanceReset;
protected RestrictedSwitchPreference mPriority;
protected DropDownPreference mVisibilityOverride;
protected RestrictedSwitchPreference mBlock;
if (mPriority != null) {
mPriority.setDisabledByAdmin(mSuspendedAppsAdmin);
}
- if (mImportanceTitle != null) {
- mImportanceTitle.setDisabledByAdmin(mSuspendedAppsAdmin);
- }
if (mBlock != null) {
mBlock.setDisabledByAdmin(mSuspendedAppsAdmin);
}
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));
- 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;
+ public void onImportanceChanged(int progress, boolean fromUser) {
+ if (fromUser) {
+ mBackend.setImportance(mPkg, mUid, progress);
}
-
- 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);
+ updateDependents(progress);
}
});
- 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() {
}
}
- 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);
}
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;
- }
- };
}