diff --git a/res/layout/preference_importance_slider.xml b/res/layout/preference_importance_slider.xml index d7d04b4a8b5..00993842a0e 100644 --- a/res/layout/preference_importance_slider.xml +++ b/res/layout/preference_importance_slider.xml @@ -58,7 +58,8 @@ android:src="@*android:drawable/ic_notification_block" android:layout_gravity="center_vertical|start" android:layout_width="24dp" - android:layout_height="24dp" /> + android:layout_height="24dp" + android:tint="@color/importance_icon_tint" /> + android:layout_height="24dp" + android:tint="@color/importance_icon_tint" /> diff --git a/res/values/colors.xml b/res/values/colors.xml index 60c15d7624d..579cd9eb7f5 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -104,6 +104,9 @@ #ff009587 #ffced7db + #8a000000 + #4d000000 + #4285F4 #3367D6 diff --git a/res/xml/app_notification_settings.xml b/res/xml/app_notification_settings.xml index 5f00caf865c..3141af85ece 100644 --- a/res/xml/app_notification_settings.xml +++ b/res/xml/app_notification_settings.xml @@ -18,24 +18,10 @@ android:title="@string/app_notifications_title" android:key="app_notification_settings"> - - - - + - - diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java index 9add4eba90d..a5832490980 100644 --- a/src/com/android/settings/notification/AppNotificationSettings.java +++ b/src/com/android/settings/notification/AppNotificationSettings.java @@ -17,33 +17,23 @@ package com.android.settings.notification; import android.app.Notification; -import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.os.Bundle; -import android.os.UserHandle; -import android.provider.Settings; import android.service.notification.NotificationListenerService; import android.support.v14.preference.SwitchPreference; import android.support.v7.preference.Preference; import android.support.v7.preference.Preference.OnPreferenceChangeListener; import android.support.v7.preference.Preference.OnPreferenceClickListener; import android.support.v7.preference.PreferenceCategory; -import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; -import android.widget.Toast; import com.android.internal.logging.MetricsLogger; -import com.android.internal.widget.LockPatternUtils; import com.android.settings.AppHeader; import com.android.settings.R; -import com.android.settings.SettingsPreferenceFragment; import com.android.settings.Utils; import com.android.settings.applications.AppInfoBase; import com.android.settings.notification.NotificationBackend.AppRow; @@ -51,7 +41,7 @@ import com.android.settings.notification.NotificationBackend.AppRow; import java.util.List; /** These settings are per app, so should not be returned in global search results. */ -public class AppNotificationSettings extends SettingsPreferenceFragment { +public class AppNotificationSettings extends NotificationSettingsBase { private static final String TAG = "AppNotificationSettings"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -63,24 +53,13 @@ public class AppNotificationSettings extends SettingsPreferenceFragment { = new Intent(Intent.ACTION_MAIN) .addCategory(Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES); - private final NotificationBackend mBackend = new NotificationBackend(); - - private Context mContext; private SwitchPreference mBlock; private PreferenceCategory mCategories; private AppRow mAppRow; - private boolean mCreated; - private int mUid; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - if (DEBUG) Log.d(TAG, "onActivityCreated mCreated=" + mCreated); - if (mCreated) { - Log.w(TAG, "onActivityCreated: ignoring duplicate call"); - return; - } - mCreated = true; if (mAppRow == null) return; AppHeader.createAppHeader(this, mAppRow.icon, mAppRow.label, mAppRow.pkg, mAppRow.uid); } @@ -93,86 +72,48 @@ public class AppNotificationSettings extends SettingsPreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mContext = getActivity(); - Intent intent = getActivity().getIntent(); - Bundle args = getArguments(); - if (DEBUG) Log.d(TAG, "onCreate getIntent()=" + intent); - if (intent == null && args == null) { - Log.w(TAG, "No intent"); - toastAndFinish(); - return; - } - final String pkg = args != null && args.containsKey(AppInfoBase.ARG_PACKAGE_NAME) - ? args.getString(AppInfoBase.ARG_PACKAGE_NAME) - : intent.getStringExtra(Settings.EXTRA_APP_PACKAGE); - mUid = args != null && args.containsKey(AppInfoBase.ARG_PACKAGE_UID) - ? args.getInt(AppInfoBase.ARG_PACKAGE_UID) - : intent.getIntExtra(Settings.EXTRA_APP_UID, -1); - if (mUid == -1 || TextUtils.isEmpty(pkg)) { - Log.w(TAG, "Missing extras: " + Settings.EXTRA_APP_PACKAGE + " was " + pkg + ", " - + Settings.EXTRA_APP_UID + " was " + mUid); - toastAndFinish(); - return; - } - - if (DEBUG) Log.d(TAG, "Load details for pkg=" + pkg + " uid=" + mUid); - final PackageManager pm = getPackageManager(); - final PackageInfo info = findPackageInfo(pm, pkg, mUid); - if (info == null) { - Log.w(TAG, "Failed to find package info: " + Settings.EXTRA_APP_PACKAGE + " was " + pkg - + ", " + Settings.EXTRA_APP_UID + " was " + mUid); - toastAndFinish(); - return; - } addPreferencesFromResource(R.xml.app_notification_settings); - mBlock = (SwitchPreference) findPreference(KEY_BLOCK); - - mAppRow = mBackend.loadAppRow(pm, info); + getPreferenceScreen().setOrderingAsAdded(true); + mAppRow = mBackend.loadAppRow(mPm, mPkgInfo); // load settings intent ArrayMap rows = new ArrayMap(); rows.put(mAppRow.pkg, mAppRow); - collectConfigActivities(getPackageManager(), rows); + collectConfigActivities(rows); // Add topics - List topics = mBackend.getTopics(pkg, mUid); - mCategories = (PreferenceCategory) getPreferenceScreen().findPreference(KEY_CATEGORIES); - for (Notification.Topic topic : topics) { - Preference topicPreference = new Preference(mContext); - topicPreference.setKey(topic.getId()); - topicPreference.setTitle(topic.getLabel()); - // Create intent for this preference. - Bundle topicArgs = new Bundle(); - topicArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid); - topicArgs.putParcelable(TopicNotificationSettings.ARG_TOPIC, topic); - topicArgs.putBoolean(AppHeader.EXTRA_HIDE_INFO_BUTTON, true); - topicArgs.putParcelable(TopicNotificationSettings.ARG_PACKAGE_INFO, info); + List topics = mBackend.getTopics(mPkg, mUid); + if (topics.size() <= 1) { + setupImportancePref(mAppRow, null, mAppRow.appImportance); + setupPriorityPref(null, mAppRow.appBypassDnd); + setupSensitivePref(null, mAppRow.appSensitive); + } else { + setupBlockSwitch(); + mCategories = new PreferenceCategory(getPrefContext()); + mCategories.setKey(KEY_CATEGORIES); + mCategories.setTitle(R.string.notification_topic_categories); + mCategories.setOrderingAsAdded(true); + getPreferenceScreen().addPreference(mCategories); + for (Notification.Topic topic : topics) { + Preference topicPreference = new Preference(getPrefContext()); + topicPreference.setKey(topic.getId()); + topicPreference.setTitle(topic.getLabel()); + // Create intent for this preference. + Bundle topicArgs = new Bundle(); + topicArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid); + topicArgs.putParcelable(TopicNotificationSettings.ARG_TOPIC, topic); + topicArgs.putBoolean(AppHeader.EXTRA_HIDE_INFO_BUTTON, true); + topicArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, mPkg); + topicArgs.putParcelable(TopicNotificationSettings.ARG_PACKAGE_INFO, mPkgInfo); - Intent topicIntent = Utils.onBuildStartFragmentIntent(getActivity(), - TopicNotificationSettings.class.getName(), - topicArgs, null, R.string.topic_notifications_title, null, false); - topicPreference.setIntent(topicIntent); - mCategories.addPreference(topicPreference); - } - - mBlock.setChecked(mAppRow.banned); - updateDependents(mAppRow.systemApp, mAppRow.banned); - - mBlock.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - final boolean banned = (Boolean) newValue; - if (banned) { - MetricsLogger.action(getActivity(), MetricsLogger.ACTION_BAN_APP_NOTES, pkg); - } - final boolean success = mBackend.setNotificationsBanned(pkg, mUid, banned); - if (success) { - updateDependents(mAppRow.systemApp, banned); - } - return success; + Intent topicIntent = Utils.onBuildStartFragmentIntent(getActivity(), + TopicNotificationSettings.class.getName(), + topicArgs, null, R.string.topic_notifications_title, null, false); + topicPreference.setIntent(topicIntent); + mCategories.addPreference(topicPreference); } - }); + } if (mAppRow.settingsIntent != null) { findPreference(KEY_APP_SETTINGS).setOnPreferenceClickListener( @@ -189,70 +130,59 @@ public class AppNotificationSettings extends SettingsPreferenceFragment { } @Override - public void onResume() { - super.onResume(); - if (mUid != -1 && getPackageManager().getPackagesForUid(mUid) == null) { - // App isn't around anymore, must have been removed. - finish(); - } + protected void updateDependents(int progress) { + updateDependents(progress == NotificationListenerService.Ranking.IMPORTANCE_NONE); } - private void updateDependents(boolean isSystemPackage, boolean banned) { - setVisible(mBlock, !isSystemPackage); + private void updateDependents(boolean banned) { + if (mBlock != null) { + mBlock.setEnabled(!mAppRow.systemApp); + } if (mCategories != null) { setVisible(mCategories, !banned); } } - private void setVisible(Preference p, boolean visible) { - final boolean isVisible = getPreferenceScreen().findPreference(p.getKey()) != null; - if (isVisible == visible) return; - if (visible) { - getPreferenceScreen().addPreference(p); - } else { - getPreferenceScreen().removePreference(p); - } - } - - private void toastAndFinish() { - Toast.makeText(mContext, R.string.app_not_found_dlg_text, Toast.LENGTH_SHORT).show(); - getActivity().finish(); - } - - private static PackageInfo findPackageInfo(PackageManager pm, String pkg, int uid) { - final String[] packages = pm.getPackagesForUid(uid); - if (packages != null && pkg != null) { - final int N = packages.length; - for (int i = 0; i < N; i++) { - final String p = packages[i]; - if (pkg.equals(p)) { - try { - return pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES); - } catch (NameNotFoundException e) { - Log.w(TAG, "Failed to load package " + pkg, e); - } + private void setupBlockSwitch() { + mBlock = new SwitchPreference(getPrefContext()); + mBlock.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final boolean banned = (Boolean) newValue; + if (banned) { + MetricsLogger.action(getActivity(), MetricsLogger.ACTION_BAN_APP_NOTES, mPkg); } + final boolean success = mBackend.setNotificationsBanned(mPkg, mUid, banned); + if (success) { + updateDependents(banned); + } + return success; } - } - return null; + }); + mBlock.setKey(KEY_BLOCK); + mBlock.setTitle(R.string.app_notification_block_title); + mBlock.setSummary(R.string.app_notification_block_summary); + getPreferenceScreen().addPreference(mBlock); + mBlock.setChecked(mAppRow.banned); + updateDependents(mAppRow.banned); } - public static List queryNotificationConfigActivities(PackageManager pm) { + private List queryNotificationConfigActivities() { if (DEBUG) Log.d(TAG, "APP_NOTIFICATION_PREFS_CATEGORY_INTENT is " + APP_NOTIFICATION_PREFS_CATEGORY_INTENT); - final List resolveInfos = pm.queryIntentActivities( + final List resolveInfos = mPm.queryIntentActivities( APP_NOTIFICATION_PREFS_CATEGORY_INTENT, 0 //PackageManager.MATCH_DEFAULT_ONLY ); return resolveInfos; } - public static void collectConfigActivities(PackageManager pm, ArrayMap rows) { - final List resolveInfos = queryNotificationConfigActivities(pm); - applyConfigActivities(pm, rows, resolveInfos); + private void collectConfigActivities(ArrayMap rows) { + final List resolveInfos = queryNotificationConfigActivities(); + applyConfigActivities(rows, resolveInfos); } - public static void applyConfigActivities(PackageManager pm, ArrayMap rows, + private void applyConfigActivities(ArrayMap rows, List resolveInfos) { if (DEBUG) Log.d(TAG, "Found " + resolveInfos.size() + " preference activities" + (resolveInfos.size() == 0 ? " ;_;" : "")); diff --git a/src/com/android/settings/notification/ImportanceSeekBarPreference.java b/src/com/android/settings/notification/ImportanceSeekBarPreference.java index 190a9ab0127..920fcc30b77 100644 --- a/src/com/android/settings/notification/ImportanceSeekBarPreference.java +++ b/src/com/android/settings/notification/ImportanceSeekBarPreference.java @@ -23,6 +23,7 @@ import android.content.Context; import android.service.notification.NotificationListenerService; import android.support.v7.preference.PreferenceViewHolder; import android.util.AttributeSet; +import android.widget.ImageView; import android.widget.SeekBar; import android.widget.TextView; @@ -37,6 +38,7 @@ public class ImportanceSeekBarPreference extends SeekBarPreference implements private TextView mSummaryTextView; private String mSummary; private int mMinProgress; + private boolean mSystemApp; public ImportanceSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { @@ -64,10 +66,19 @@ public class ImportanceSeekBarPreference extends SeekBarPreference implements mMinProgress = minProgress; } + public void setSystemApp(boolean systemApp) { + mSystemApp = systemApp; + notifyChanged(); + } + @Override public void onBindViewHolder(PreferenceViewHolder view) { super.onBindViewHolder(view); mSummaryTextView = (TextView) view.findViewById(com.android.internal.R.id.summary); + if (mSystemApp) { + ((ImageView) view.findViewById(R.id.low_importance)).getDrawable().setTint( + getContext().getColor(R.color.importance_disabled_tint)); + } } @Override @@ -83,8 +94,9 @@ public class ImportanceSeekBarPreference extends SeekBarPreference implements seekBar.setProgress(mMinProgress); progress = mMinProgress; } + mSummary = getProgressSummary(progress); if (mSummaryTextView != null) { - mSummaryTextView.setText(getProgressSummary(progress)); + mSummaryTextView.setText(mSummary); } if (fromTouch) { mCallback.onImportanceChanged(progress); diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java index d37cccaa76b..292d24771bf 100644 --- a/src/com/android/settings/notification/NotificationBackend.java +++ b/src/com/android/settings/notification/NotificationBackend.java @@ -51,6 +51,9 @@ public class NotificationBackend { } row.icon = app.loadIcon(pm); row.banned = getNotificationsBanned(row.pkg, row.uid); + row.appImportance = getImportance(row.pkg, row.uid, null); + row.appBypassDnd = getBypassZenMode(row.pkg, row.uid, null); + row.appSensitive = getSensitive(row.pkg, row.uid, null); return row; } @@ -97,7 +100,7 @@ public class NotificationBackend { public boolean getBypassZenMode(String pkg, int uid, Notification.Topic topic) { try { - return sINM.getTopicPriority(pkg, uid, topic) == Notification.PRIORITY_MAX; + return sINM.getPriority(pkg, uid, topic) == Notification.PRIORITY_MAX; } catch (Exception e) { Log.w(TAG, "Error calling NoMan", e); return false; @@ -107,7 +110,7 @@ public class NotificationBackend { public boolean setBypassZenMode(String pkg, int uid, Notification.Topic topic, boolean bypassZen) { try { - sINM.setTopicPriority(pkg, uid, topic, + sINM.setPriority(pkg, uid, topic, bypassZen ? Notification.PRIORITY_MAX : Notification.PRIORITY_DEFAULT); return true; } catch (Exception e) { @@ -118,7 +121,7 @@ public class NotificationBackend { public boolean getSensitive(String pkg, int uid, Notification.Topic topic) { try { - return sINM.getTopicVisibilityOverride(pkg, uid, topic) + return sINM.getVisibilityOverride(pkg, uid, topic) == Notification.VISIBILITY_PRIVATE; } catch (Exception e) { Log.w(TAG, "Error calling NoMan", e); @@ -128,7 +131,7 @@ public class NotificationBackend { public boolean setSensitive(String pkg, int uid, Notification.Topic topic, boolean sensitive) { try { - sINM.setTopicVisibilityOverride(pkg, uid, topic, + sINM.setVisibilityOverride(pkg, uid, topic, sensitive ? Notification.VISIBILITY_PRIVATE : NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE); return true; @@ -140,7 +143,7 @@ public class NotificationBackend { public boolean setImportance(String pkg, int uid, Notification.Topic topic, int importance) { try { - sINM.setTopicImportance(pkg, uid, topic, importance); + sINM.setImportance(pkg, uid, topic, importance); return true; } catch (Exception e) { Log.w(TAG, "Error calling NoMan", e); @@ -150,7 +153,7 @@ public class NotificationBackend { public int getImportance(String pkg, int uid, Notification.Topic topic) { try { - return sINM.getTopicImportance(pkg, uid, topic); + return sINM.getImportance(pkg, uid, topic); } catch (Exception e) { Log.w(TAG, "Error calling NoMan", e); return NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED; @@ -180,6 +183,9 @@ public class NotificationBackend { public boolean banned; public boolean first; // first app in section public boolean systemApp; + public int appImportance; + public boolean appBypassDnd; + public boolean appSensitive; } public static class TopicRow extends AppRow { @@ -188,5 +194,4 @@ public class NotificationBackend { public boolean sensitive; public int importance; } - } diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java new file mode 100644 index 00000000000..a669d9548c3 --- /dev/null +++ b/src/com/android/settings/notification/NotificationSettingsBase.java @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.notification; + +import com.android.settings.R; +import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.applications.AppInfoBase; + +import android.app.Notification; +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.os.Bundle; +import android.provider.Settings; +import android.service.notification.NotificationListenerService.Ranking; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.Preference; +import android.text.TextUtils; +import android.util.Log; +import android.widget.Toast; + +abstract public class NotificationSettingsBase extends SettingsPreferenceFragment { + private static final String TAG = "NotifiSettingsBase"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + + protected static final String ARG_PACKAGE_INFO = "arg_info"; + + protected static final String KEY_BYPASS_DND = "bypass_dnd"; + protected static final String KEY_SENSITIVE = "sensitive"; + protected static final String KEY_IMPORTANCE = "importance"; + + protected PackageManager mPm; + protected final NotificationBackend mBackend = new NotificationBackend(); + protected Context mContext; + protected boolean mCreated; + protected int mUid; + protected String mPkg; + protected PackageInfo mPkgInfo; + protected ImportanceSeekBarPreference mImportance; + protected SwitchPreference mPriority; + protected SwitchPreference mSensitive; + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + if (DEBUG) Log.d(TAG, "onActivityCreated mCreated=" + mCreated); + if (mCreated) { + Log.w(TAG, "onActivityCreated: ignoring duplicate call"); + return; + } + mCreated = true; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mContext = getActivity(); + Intent intent = getActivity().getIntent(); + Bundle args = getArguments(); + if (DEBUG) Log.d(TAG, "onCreate getIntent()=" + intent); + if (intent == null && args == null) { + Log.w(TAG, "No intent"); + toastAndFinish(); + return; + } + + mPm = getPackageManager(); + + mPkg = args != null && args.containsKey(AppInfoBase.ARG_PACKAGE_NAME) + ? args.getString(AppInfoBase.ARG_PACKAGE_NAME) + : intent.getStringExtra(Settings.EXTRA_APP_PACKAGE); + mUid = args != null && args.containsKey(AppInfoBase.ARG_PACKAGE_UID) + ? args.getInt(AppInfoBase.ARG_PACKAGE_UID) + : intent.getIntExtra(Settings.EXTRA_APP_UID, -1); + if (mUid == -1 || TextUtils.isEmpty(mPkg)) { + Log.w(TAG, "Missing extras: " + Settings.EXTRA_APP_PACKAGE + " was " + mPkg + ", " + + Settings.EXTRA_APP_UID + " was " + mUid); + toastAndFinish(); + return; + } + + if (DEBUG) Log.d(TAG, "Load details for pkg=" + mPkg + " uid=" + mUid); + mPkgInfo = args != null && args.containsKey(ARG_PACKAGE_INFO) + ? (PackageInfo) args.getParcelable(ARG_PACKAGE_INFO) : null; + if (mPkgInfo == null) { + mPkgInfo = findPackageInfo(mPkg, mUid); + } + if (mPkgInfo == null) { + Log.w(TAG, "Failed to find package info: " + Settings.EXTRA_APP_PACKAGE + " was " + mPkg + + ", " + Settings.EXTRA_APP_UID + " was " + mUid); + toastAndFinish(); + return; + } + } + + @Override + public void onResume() { + super.onResume(); + if (mUid != -1 && getPackageManager().getPackagesForUid(mUid) == null) { + // App isn't around anymore, must have been removed. + finish(); + } + } + + protected void setupImportancePref(final NotificationBackend.AppRow appRow, + final Notification.Topic topic, int importance) { + if (mImportance == null) { + mImportance = new ImportanceSeekBarPreference(getPrefContext()); + mImportance.setTitle(R.string.notification_importance_title); + mImportance.setKey(KEY_IMPORTANCE); + getPreferenceScreen().addPreference(mImportance); + } + mImportance.setSystemApp(appRow.systemApp); + mImportance.setMinimumProgress( + appRow.systemApp ? Ranking.IMPORTANCE_LOW : Ranking.IMPORTANCE_NONE); + mImportance.setMax(Ranking.IMPORTANCE_MAX); + // TODO: stop defaulting to 'normal' in the UI when there are mocks for this scenario. + importance = importance == Ranking.IMPORTANCE_UNSPECIFIED + ? Ranking.IMPORTANCE_DEFAULT + : importance; + mImportance.setProgress(importance); + mImportance.setCallback(new ImportanceSeekBarPreference.Callback() { + @Override + public void onImportanceChanged(int progress) { + mBackend.setImportance(appRow.pkg, appRow.uid, topic, progress); + updateDependents(progress); + } + }); + } + + protected void setupPriorityPref(final Notification.Topic topic, boolean priority) { + if (mPriority == null) { + mPriority = new SwitchPreference(getPrefContext()); + mPriority.setTitle(R.string.app_notification_override_dnd_title); + mPriority.setSummary(R.string.app_notification_override_dnd_summary); + mPriority.setKey(KEY_BYPASS_DND); + getPreferenceScreen().addPreference(mPriority); + } + mPriority.setChecked(priority); + mPriority.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final boolean bypassZenMode = (Boolean) newValue; + return mBackend.setBypassZenMode(mPkgInfo.packageName, mUid, topic, bypassZenMode); + } + }); + } + + protected void setupSensitivePref(final Notification.Topic topic, boolean sensitive) { + if (mSensitive == null) { + mSensitive = new SwitchPreference(getPrefContext()); + mSensitive.setTitle(R.string.app_notification_sensitive_title); + mSensitive.setSummary(R.string.app_notification_sensitive_summary); + mSensitive.setKey(KEY_SENSITIVE); + getPreferenceScreen().addPreference(mSensitive); + } + mSensitive.setChecked(sensitive); + mSensitive.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final boolean sensitive = (Boolean) newValue; + return mBackend.setSensitive(mPkgInfo.packageName, mUid, topic, sensitive); + } + }); + } + + abstract void updateDependents(int progress); + + protected void setVisible(Preference p, boolean visible) { + final boolean isVisible = getPreferenceScreen().findPreference(p.getKey()) != null; + if (isVisible == visible) return; + if (visible) { + getPreferenceScreen().addPreference(p); + } else { + getPreferenceScreen().removePreference(p); + } + } + + protected void toastAndFinish() { + Toast.makeText(mContext, R.string.app_not_found_dlg_text, Toast.LENGTH_SHORT).show(); + getActivity().finish(); + } + + private PackageInfo findPackageInfo(String pkg, int uid) { + final String[] packages = mPm.getPackagesForUid(uid); + if (packages != null && pkg != null) { + final int N = packages.length; + for (int i = 0; i < N; i++) { + final String p = packages[i]; + if (pkg.equals(p)) { + try { + return mPm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES); + } catch (NameNotFoundException e) { + Log.w(TAG, "Failed to load package " + pkg, e); + } + } + } + } + return null; + } +} diff --git a/src/com/android/settings/notification/TopicNotificationSettings.java b/src/com/android/settings/notification/TopicNotificationSettings.java index f2cbf1a551e..52e7f657d5d 100644 --- a/src/com/android/settings/notification/TopicNotificationSettings.java +++ b/src/com/android/settings/notification/TopicNotificationSettings.java @@ -42,36 +42,17 @@ import android.util.Log; import android.widget.Toast; /** These settings are per topic, so should not be returned in global search results. */ -public class TopicNotificationSettings extends SettingsPreferenceFragment { +public class TopicNotificationSettings extends NotificationSettingsBase { private static final String TAG = "TopicNotiSettings"; - private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); protected static final String ARG_TOPIC = "arg_topic"; - protected static final String ARG_PACKAGE_INFO = "arg_info"; - private static final String KEY_BYPASS_DND = "bypass_dnd"; - private static final String KEY_SENSITIVE = "sensitive"; - private static final String KEY_IMPORTANCE = "importance"; - private final NotificationBackend mBackend = new NotificationBackend(); - - private Context mContext; - private ImportanceSeekBarPreference mImportance; - private SwitchPreference mPriority; - private SwitchPreference mSensitive; private TopicRow mTopicRow; - private boolean mCreated; - private int mUid; private boolean mDndVisualEffectsSuppressed; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - if (DEBUG) Log.d(TAG, "onActivityCreated mCreated=" + mCreated); - if (mCreated) { - Log.w(TAG, "onActivityCreated: ignoring duplicate call"); - return; - } - mCreated = true; if (mTopicRow == null) return; AppHeader.createAppHeader( this, mTopicRow.icon, mTopicRow.label, mTopicRow.pkg, mTopicRow.uid); @@ -85,102 +66,36 @@ public class TopicNotificationSettings extends SettingsPreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mContext = getActivity(); - Intent intent = getActivity().getIntent(); - Bundle args = getArguments(); - if (DEBUG) Log.d(TAG, "onCreate getIntent()=" + intent); - if (intent == null && args == null) { - Log.w(TAG, "No intent"); - toastAndFinish(); - return; - } NotificationManager.Policy policy = NotificationManager.from(mContext).getNotificationPolicy(); mDndVisualEffectsSuppressed = policy == null ? false : policy.suppressedVisualEffects != 0; + Bundle args = getArguments(); final Notification.Topic topic = args != null && args.containsKey(ARG_TOPIC) ? (Notification.Topic) args.getParcelable(ARG_TOPIC) : null; - if (topic == null) { toastAndFinish(); return; } - final PackageInfo info = args != null && args.containsKey(ARG_PACKAGE_INFO) - ? (PackageInfo) args.getParcelable(ARG_PACKAGE_INFO) : null; - if (info == null) { - Log.w(TAG, "Failed to find package info"); - toastAndFinish(); - return; - } - - mUid = args != null && args.containsKey(AppInfoBase.ARG_PACKAGE_UID) - ? args.getInt(AppInfoBase.ARG_PACKAGE_UID) - : intent.getIntExtra(Settings.EXTRA_APP_UID, -1); - if (mUid == -1) { - Log.w(TAG, "Missing extras: " + Settings.EXTRA_APP_UID + " was " + mUid); - toastAndFinish(); - return; - } - - final PackageManager pm = getPackageManager(); - addPreferencesFromResource(R.xml.topic_notification_settings); + mTopicRow = mBackend.loadTopicRow(mPm, mPkgInfo, topic); + mImportance = (ImportanceSeekBarPreference) findPreference(KEY_IMPORTANCE); + setupImportancePref(mTopicRow, mTopicRow.topic, mTopicRow.importance); + mPriority = (SwitchPreference) findPreference(KEY_BYPASS_DND); + setupPriorityPref(mTopicRow.topic, mTopicRow.priority); + mSensitive = (SwitchPreference) findPreference(KEY_SENSITIVE); + setupSensitivePref(mTopicRow.topic, mTopicRow.sensitive); - mTopicRow = mBackend.loadTopicRow(pm, info, topic); - - mImportance.setMinimumProgress( - mTopicRow.systemApp ? Ranking.IMPORTANCE_LOW : Ranking.IMPORTANCE_NONE); - mImportance.setMax(Ranking.IMPORTANCE_MAX); - // TODO: stop defaulting to 'normal' in the UI when there are mocks for this scenario. - int importance = - mTopicRow.importance == NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED - ? NotificationListenerService.Ranking.IMPORTANCE_DEFAULT - : mTopicRow.importance; - mImportance.setProgress(importance); - mImportance.setCallback(new ImportanceSeekBarPreference.Callback() { - @Override - public void onImportanceChanged(int progress) { - mBackend.setImportance(mTopicRow.pkg, mTopicRow.uid, mTopicRow.topic, progress); - updateDependents(progress); - } - }); - mPriority.setChecked(mTopicRow.priority); - mSensitive.setChecked(mTopicRow.sensitive); - - mPriority.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - final boolean bypassZenMode = (Boolean) newValue; - return mBackend.setBypassZenMode(info.packageName, mUid, topic, bypassZenMode); - } - }); - - mSensitive.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - final boolean sensitive = (Boolean) newValue; - return mBackend.setSensitive(info.packageName, mUid, topic, sensitive); - } - }); updateDependents(mTopicRow.importance); - } @Override - public void onResume() { - super.onResume(); - if (mUid != -1 && getPackageManager().getPackagesForUid(mUid) == null) { - // App isn't around anymore, must have been removed. - finish(); - } - } - - private void updateDependents(int importance) { + protected void updateDependents(int importance) { final boolean lockscreenSecure = new LockPatternUtils(getActivity()).isSecure( UserHandle.myUserId()); final boolean lockscreenNotificationsEnabled = getLockscreenNotificationsEnabled(); @@ -193,16 +108,6 @@ public class TopicNotificationSettings extends SettingsPreferenceFragment { && lockscreenSecure && lockscreenNotificationsEnabled && allowPrivate); } - private void setVisible(Preference p, boolean visible) { - final boolean isVisible = getPreferenceScreen().findPreference(p.getKey()) != null; - if (isVisible == visible) return; - if (visible) { - getPreferenceScreen().addPreference(p); - } else { - getPreferenceScreen().removePreference(p); - } - } - private boolean getLockscreenNotificationsEnabled() { return Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0) != 0; @@ -212,9 +117,4 @@ public class TopicNotificationSettings extends SettingsPreferenceFragment { return Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0) != 0; } - - private void toastAndFinish() { - Toast.makeText(mContext, R.string.app_not_found_dlg_text, Toast.LENGTH_SHORT).show(); - getActivity().finish(); - } }