Loading AndroidManifest.xml +11 −5 Original line number Original line Diff line number Diff line Loading @@ -1836,17 +1836,23 @@ android:label="@string/app_notifications_title" android:label="@string/app_notifications_title" android:exported="true" android:exported="true" android:taskAffinity=""> android:taskAffinity=""> <intent-filter> <action android:name="android.intent.action.MAIN" /> <action android:name="android.settings.ACTION_APP_NOTIFICATION_SETTINGS" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <meta-data android:name="com.android.settings.FRAGMENT_CLASS" <meta-data android:name="com.android.settings.FRAGMENT_CLASS" android:value="com.android.settings.notification.AppNotificationSettings" /> android:value="com.android.settings.notification.AppNotificationSettings" /> <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID" <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID" android:resource="@id/notification_settings" /> android:resource="@id/notification_settings" /> </activity> </activity> <activity android:name=".notification.AppNotificationDialog" android:theme="@style/Theme.AlertDialog" android:launchMode="singleTop" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <action android:name="android.settings.APP_NOTIFICATION_SETTINGS" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <!-- Show regulatory info (from settings item or dialing "*#07#") --> <!-- Show regulatory info (from settings item or dialing "*#07#") --> <activity android:name="RegulatoryInfoDisplayActivity" <activity android:name="RegulatoryInfoDisplayActivity" android:label="@string/regulatory_information" android:label="@string/regulatory_information" Loading src/com/android/settings/notification/AppNotificationDialog.java 0 → 100644 +180 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2014 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 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.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import android.widget.CompoundButton.OnCheckedChangeListener; import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertController; import com.android.settings.R; import com.android.settings.notification.AppNotificationSettings.Backend; import com.android.settings.notification.AppNotificationSettings.AppRow; public class AppNotificationDialog extends AlertActivity { private static final String TAG = "AppNotificationDialog"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); /** * Show a checkbox in the per-app notification control dialog to allow the user to * selectively redact this app's notifications on the lockscreen. */ private static final boolean ENABLE_APP_NOTIFICATION_PRIVACY_OPTION = false; private final Context mContext = this; private final Backend mBackend = new Backend(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (DEBUG) Log.d(TAG, "onCreate getIntent()=" + getIntent()); if (!buildDialog()) { Toast.makeText(mContext, R.string.app_not_found_dlg_text, Toast.LENGTH_SHORT).show(); finish(); } } private boolean buildDialog() { final Intent intent = getIntent(); if (intent != null) { final int uid = intent.getIntExtra(Settings.EXTRA_APP_UID, -1); final String pkg = intent.getStringExtra(Settings.EXTRA_APP_PACKAGE); if (uid != -1 && !TextUtils.isEmpty(pkg)) { if (DEBUG) Log.d(TAG, "Load details for pkg=" + pkg + " uid=" + uid); final PackageManager pm = getPackageManager(); final PackageInfo info = findPackageInfo(pm, pkg, uid); if (info != null) { final AppRow row = AppNotificationSettings.loadAppRow(pm, info, mBackend); final AlertController.AlertParams p = mAlertParams; p.mView = getLayoutInflater().inflate(R.layout.notification_app_dialog, null, false); p.mPositiveButtonText = getString(R.string.app_notifications_dialog_done); bindDialog(p.mView, row); setupAlert(); return true; } else { Log.w(TAG, "Failed to find package info"); } } else { Log.w(TAG, "Missing extras: " + Settings.EXTRA_APP_PACKAGE + " was " + pkg + ", " + Settings.EXTRA_APP_UID + " was " + uid); } } else { Log.w(TAG, "No intent"); } return false; } 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, 0); } catch (NameNotFoundException e) { Log.w(TAG, "Failed to load package " + pkg, e); } } } } return null; } private void bindDialog(final View v, final AppRow row) { final ImageView icon = (ImageView) v.findViewById(android.R.id.icon); icon.setImageDrawable(row.icon); final TextView title = (TextView) v.findViewById(android.R.id.title); title.setText(row.label); final CheckBox showNotifications = (CheckBox) v.findViewById(android.R.id.button1); final CheckBox highPriority = (CheckBox) v.findViewById(android.R.id.button2); final CheckBox sensitive = (CheckBox) v.findViewById(android.R.id.button3); if (!ENABLE_APP_NOTIFICATION_PRIVACY_OPTION) { sensitive.setVisibility(View.GONE); } showNotifications.setChecked(!row.banned); final OnCheckedChangeListener showListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { boolean success = mBackend.setNotificationsBanned(row.pkg, row.uid, !isChecked); if (success) { row.banned = !isChecked; highPriority.setEnabled(!row.banned); sensitive.setEnabled(!row.banned); } else { showNotifications.setOnCheckedChangeListener(null); showNotifications.setChecked(!isChecked); showNotifications.setOnCheckedChangeListener(this); } } }; showNotifications.setOnCheckedChangeListener(showListener); highPriority.setChecked(row.priority); final OnCheckedChangeListener priListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { boolean success = mBackend.setHighPriority(row.pkg, row.uid, isChecked); if (success) { row.priority = isChecked; } else { highPriority.setOnCheckedChangeListener(null); highPriority.setChecked(!isChecked); highPriority.setOnCheckedChangeListener(this); } } }; highPriority.setOnCheckedChangeListener(priListener); sensitive.setChecked(row.sensitive); final OnCheckedChangeListener senListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { boolean success = mBackend.setSensitive(row.pkg, row.uid, isChecked); if (success) { row.sensitive = isChecked; } else { sensitive.setOnCheckedChangeListener(null); sensitive.setChecked(!isChecked); sensitive.setOnCheckedChangeListener(this); } } }; sensitive.setOnCheckedChangeListener(senListener); highPriority.setEnabled(!row.banned); sensitive.setEnabled(!row.banned); } } src/com/android/settings/notification/AppNotificationSettings.java +27 −117 Original line number Original line Diff line number Diff line Loading @@ -17,9 +17,7 @@ package com.android.settings.notification; package com.android.settings.notification; import android.animation.LayoutTransition; import android.animation.LayoutTransition; import android.app.AlertDialog; import android.app.INotificationManager; import android.app.INotificationManager; import android.app.ListFragment; import android.app.Notification; import android.app.Notification; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; Loading @@ -37,6 +35,7 @@ import android.os.Handler; import android.os.Parcelable; import android.os.Parcelable; import android.os.ServiceManager; import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemClock; import android.provider.Settings; import android.util.ArrayMap; import android.util.ArrayMap; import android.util.Log; import android.util.Log; import android.util.TypedValue; import android.util.TypedValue; Loading @@ -45,11 +44,7 @@ import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ArrayAdapter; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.ImageView; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.SectionIndexer; import android.widget.SectionIndexer; import android.widget.TextView; import android.widget.TextView; Loading @@ -65,18 +60,7 @@ import java.util.List; /** Just a sectioned list of installed applications, nothing else to index **/ /** Just a sectioned list of installed applications, nothing else to index **/ public class AppNotificationSettings extends PinnedHeaderListFragment { public class AppNotificationSettings extends PinnedHeaderListFragment { private static final String TAG = "AppNotificationSettings"; private static final String TAG = "AppNotificationSettings"; private static final boolean DEBUG = true; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); /** * Show a checkbox in the per-app notification control dialog to allow the user * to promote this app's notifications to higher priority. */ private static final boolean ENABLE_APP_NOTIFICATION_PRIORITY_OPTION = true; /** * Show a checkbox in the per-app notification control dialog to allow the user to * selectively redact this app's notifications on the lockscreen. */ private static final boolean ENABLE_APP_NOTIFICATION_PRIVACY_OPTION = false; private static final String SECTION_BEFORE_A = "*"; private static final String SECTION_BEFORE_A = "*"; private static final String SECTION_AFTER_Z = "**"; private static final String SECTION_AFTER_Z = "**"; Loading Loading @@ -189,89 +173,6 @@ public class AppNotificationSettings extends PinnedHeaderListFragment { return null; return null; } } private void showDialog(final View v, final AppRow row) { final RelativeLayout layout = (RelativeLayout) mInflater.inflate(R.layout.notification_app_dialog, null); final ImageView icon = (ImageView) layout.findViewById(android.R.id.icon); icon.setImageDrawable(row.icon); final TextView title = (TextView) layout.findViewById(android.R.id.title); title.setText(row.label); final CheckBox showBox = (CheckBox) layout.findViewById(android.R.id.button1); final CheckBox priBox = (CheckBox) layout.findViewById(android.R.id.button2); final CheckBox senBox = (CheckBox) layout.findViewById(android.R.id.button3); if (!ENABLE_APP_NOTIFICATION_PRIORITY_OPTION) { priBox.setVisibility(View.GONE); } if (!ENABLE_APP_NOTIFICATION_PRIVACY_OPTION) { senBox.setVisibility(View.GONE); } showBox.setChecked(!row.banned); final OnCheckedChangeListener showListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { boolean success = mBackend.setNotificationsBanned(row.pkg, row.uid, !isChecked); if (success) { row.banned = !isChecked; mAdapter.bindView(v, row, true /*animate*/); priBox.setEnabled(!row.banned); senBox.setEnabled(!row.banned); } else { showBox.setOnCheckedChangeListener(null); showBox.setChecked(!isChecked); showBox.setOnCheckedChangeListener(this); } } }; showBox.setOnCheckedChangeListener(showListener); priBox.setChecked(row.priority); final OnCheckedChangeListener priListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { boolean success = mBackend.setHighPriority(row.pkg, row.uid, isChecked); if (success) { row.priority = isChecked; mAdapter.bindView(v, row, true /*animate*/); } else { priBox.setOnCheckedChangeListener(null); priBox.setChecked(!isChecked); priBox.setOnCheckedChangeListener(this); } } }; priBox.setOnCheckedChangeListener(priListener); senBox.setChecked(row.sensitive); final OnCheckedChangeListener senListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { boolean success = mBackend.setSensitive(row.pkg, row.uid, isChecked); if (success) { row.sensitive = isChecked; mAdapter.bindView(v, row, true /*animate*/); } else { senBox.setOnCheckedChangeListener(null); senBox.setChecked(!isChecked); senBox.setOnCheckedChangeListener(this); } } }; senBox.setOnCheckedChangeListener(senListener); priBox.setEnabled(!row.banned); senBox.setEnabled(!row.banned); final AlertDialog d = new AlertDialog.Builder(mContext) .setView(layout) .setPositiveButton(R.string.app_notifications_dialog_done, null) .create(); d.show(); } private static class ViewHolder { private static class ViewHolder { ViewGroup row; ViewGroup row; ViewGroup appButton; ViewGroup appButton; Loading Loading @@ -366,7 +267,10 @@ public class AppNotificationSettings extends PinnedHeaderListFragment { vh.appButton.setOnClickListener(new OnClickListener() { vh.appButton.setOnClickListener(new OnClickListener() { @Override @Override public void onClick(View v) { public void onClick(View v) { showDialog(view, row); mContext.startActivity(new Intent(mContext, AppNotificationDialog.class) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) .putExtra(Settings.EXTRA_APP_PACKAGE, row.pkg) .putExtra(Settings.EXTRA_APP_UID, row.uid)); } } }); }); enableLayoutTransitions(vh.appButton, animate); enableLayoutTransitions(vh.appButton, animate); Loading Loading @@ -428,7 +332,7 @@ public class AppNotificationSettings extends PinnedHeaderListFragment { public String section; public String section; } } private static class AppRow extends Row { public static class AppRow extends Row { public String pkg; public String pkg; public int uid; public int uid; public Drawable icon; public Drawable icon; Loading @@ -448,6 +352,23 @@ public class AppNotificationSettings extends PinnedHeaderListFragment { } } }; }; public static AppRow loadAppRow(PackageManager pm, PackageInfo pkg, Backend backend) { final AppRow row = new AppRow(); row.pkg = pkg.packageName; row.uid = pkg.applicationInfo.uid; try { row.label = pkg.applicationInfo.loadLabel(pm); } catch (Throwable t) { Log.e(TAG, "Error loading application label for " + row.pkg, t); row.label = row.pkg; } row.icon = pkg.applicationInfo.loadIcon(pm); row.banned = backend.getNotificationsBanned(row.pkg, row.uid); row.priority = backend.getHighPriority(row.pkg, row.uid); row.sensitive = backend.getSensitive(row.pkg, row.uid); return row; } private final Runnable mCollectAppsRunnable = new Runnable() { private final Runnable mCollectAppsRunnable = new Runnable() { @Override @Override public void run() { public void run() { Loading @@ -464,23 +385,12 @@ public class AppNotificationSettings extends PinnedHeaderListFragment { if (DEBUG) Log.d(TAG, "Skipping " + pkg.packageName); if (DEBUG) Log.d(TAG, "Skipping " + pkg.packageName); continue; continue; } } final AppRow row = new AppRow(); final AppRow row = loadAppRow(pm, pkg, mBackend); row.pkg = pkg.packageName; row.uid = pkg.applicationInfo.uid; try { row.label = pkg.applicationInfo.loadLabel(pm); } catch (Throwable t) { Log.e(TAG, "Error loading application label for " + row.pkg, t); row.label = row.pkg; } row.icon = pkg.applicationInfo.loadIcon(pm); row.banned = mBackend.getNotificationsBanned(row.pkg, row.uid); row.priority = mBackend.getHighPriority(row.pkg, row.uid); row.sensitive = mBackend.getSensitive(row.pkg, row.uid); mRows.put(row.pkg, row); mRows.put(row.pkg, row); } } // collect config activities // collect config activities Log.d(TAG, "APP_NOTIFICATION_PREFS_CATEGORY_INTENT is " + APP_NOTIFICATION_PREFS_CATEGORY_INTENT); if (DEBUG) Log.d(TAG, "APP_NOTIFICATION_PREFS_CATEGORY_INTENT is " + APP_NOTIFICATION_PREFS_CATEGORY_INTENT); final List<ResolveInfo> resolveInfos = pm.queryIntentActivities( final List<ResolveInfo> resolveInfos = pm.queryIntentActivities( APP_NOTIFICATION_PREFS_CATEGORY_INTENT, APP_NOTIFICATION_PREFS_CATEGORY_INTENT, PackageManager.MATCH_DEFAULT_ONLY); PackageManager.MATCH_DEFAULT_ONLY); Loading Loading
AndroidManifest.xml +11 −5 Original line number Original line Diff line number Diff line Loading @@ -1836,17 +1836,23 @@ android:label="@string/app_notifications_title" android:label="@string/app_notifications_title" android:exported="true" android:exported="true" android:taskAffinity=""> android:taskAffinity=""> <intent-filter> <action android:name="android.intent.action.MAIN" /> <action android:name="android.settings.ACTION_APP_NOTIFICATION_SETTINGS" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <meta-data android:name="com.android.settings.FRAGMENT_CLASS" <meta-data android:name="com.android.settings.FRAGMENT_CLASS" android:value="com.android.settings.notification.AppNotificationSettings" /> android:value="com.android.settings.notification.AppNotificationSettings" /> <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID" <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID" android:resource="@id/notification_settings" /> android:resource="@id/notification_settings" /> </activity> </activity> <activity android:name=".notification.AppNotificationDialog" android:theme="@style/Theme.AlertDialog" android:launchMode="singleTop" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <action android:name="android.settings.APP_NOTIFICATION_SETTINGS" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <!-- Show regulatory info (from settings item or dialing "*#07#") --> <!-- Show regulatory info (from settings item or dialing "*#07#") --> <activity android:name="RegulatoryInfoDisplayActivity" <activity android:name="RegulatoryInfoDisplayActivity" android:label="@string/regulatory_information" android:label="@string/regulatory_information" Loading
src/com/android/settings/notification/AppNotificationDialog.java 0 → 100644 +180 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2014 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 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.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import android.widget.CompoundButton.OnCheckedChangeListener; import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertController; import com.android.settings.R; import com.android.settings.notification.AppNotificationSettings.Backend; import com.android.settings.notification.AppNotificationSettings.AppRow; public class AppNotificationDialog extends AlertActivity { private static final String TAG = "AppNotificationDialog"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); /** * Show a checkbox in the per-app notification control dialog to allow the user to * selectively redact this app's notifications on the lockscreen. */ private static final boolean ENABLE_APP_NOTIFICATION_PRIVACY_OPTION = false; private final Context mContext = this; private final Backend mBackend = new Backend(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (DEBUG) Log.d(TAG, "onCreate getIntent()=" + getIntent()); if (!buildDialog()) { Toast.makeText(mContext, R.string.app_not_found_dlg_text, Toast.LENGTH_SHORT).show(); finish(); } } private boolean buildDialog() { final Intent intent = getIntent(); if (intent != null) { final int uid = intent.getIntExtra(Settings.EXTRA_APP_UID, -1); final String pkg = intent.getStringExtra(Settings.EXTRA_APP_PACKAGE); if (uid != -1 && !TextUtils.isEmpty(pkg)) { if (DEBUG) Log.d(TAG, "Load details for pkg=" + pkg + " uid=" + uid); final PackageManager pm = getPackageManager(); final PackageInfo info = findPackageInfo(pm, pkg, uid); if (info != null) { final AppRow row = AppNotificationSettings.loadAppRow(pm, info, mBackend); final AlertController.AlertParams p = mAlertParams; p.mView = getLayoutInflater().inflate(R.layout.notification_app_dialog, null, false); p.mPositiveButtonText = getString(R.string.app_notifications_dialog_done); bindDialog(p.mView, row); setupAlert(); return true; } else { Log.w(TAG, "Failed to find package info"); } } else { Log.w(TAG, "Missing extras: " + Settings.EXTRA_APP_PACKAGE + " was " + pkg + ", " + Settings.EXTRA_APP_UID + " was " + uid); } } else { Log.w(TAG, "No intent"); } return false; } 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, 0); } catch (NameNotFoundException e) { Log.w(TAG, "Failed to load package " + pkg, e); } } } } return null; } private void bindDialog(final View v, final AppRow row) { final ImageView icon = (ImageView) v.findViewById(android.R.id.icon); icon.setImageDrawable(row.icon); final TextView title = (TextView) v.findViewById(android.R.id.title); title.setText(row.label); final CheckBox showNotifications = (CheckBox) v.findViewById(android.R.id.button1); final CheckBox highPriority = (CheckBox) v.findViewById(android.R.id.button2); final CheckBox sensitive = (CheckBox) v.findViewById(android.R.id.button3); if (!ENABLE_APP_NOTIFICATION_PRIVACY_OPTION) { sensitive.setVisibility(View.GONE); } showNotifications.setChecked(!row.banned); final OnCheckedChangeListener showListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { boolean success = mBackend.setNotificationsBanned(row.pkg, row.uid, !isChecked); if (success) { row.banned = !isChecked; highPriority.setEnabled(!row.banned); sensitive.setEnabled(!row.banned); } else { showNotifications.setOnCheckedChangeListener(null); showNotifications.setChecked(!isChecked); showNotifications.setOnCheckedChangeListener(this); } } }; showNotifications.setOnCheckedChangeListener(showListener); highPriority.setChecked(row.priority); final OnCheckedChangeListener priListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { boolean success = mBackend.setHighPriority(row.pkg, row.uid, isChecked); if (success) { row.priority = isChecked; } else { highPriority.setOnCheckedChangeListener(null); highPriority.setChecked(!isChecked); highPriority.setOnCheckedChangeListener(this); } } }; highPriority.setOnCheckedChangeListener(priListener); sensitive.setChecked(row.sensitive); final OnCheckedChangeListener senListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { boolean success = mBackend.setSensitive(row.pkg, row.uid, isChecked); if (success) { row.sensitive = isChecked; } else { sensitive.setOnCheckedChangeListener(null); sensitive.setChecked(!isChecked); sensitive.setOnCheckedChangeListener(this); } } }; sensitive.setOnCheckedChangeListener(senListener); highPriority.setEnabled(!row.banned); sensitive.setEnabled(!row.banned); } }
src/com/android/settings/notification/AppNotificationSettings.java +27 −117 Original line number Original line Diff line number Diff line Loading @@ -17,9 +17,7 @@ package com.android.settings.notification; package com.android.settings.notification; import android.animation.LayoutTransition; import android.animation.LayoutTransition; import android.app.AlertDialog; import android.app.INotificationManager; import android.app.INotificationManager; import android.app.ListFragment; import android.app.Notification; import android.app.Notification; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; Loading @@ -37,6 +35,7 @@ import android.os.Handler; import android.os.Parcelable; import android.os.Parcelable; import android.os.ServiceManager; import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemClock; import android.provider.Settings; import android.util.ArrayMap; import android.util.ArrayMap; import android.util.Log; import android.util.Log; import android.util.TypedValue; import android.util.TypedValue; Loading @@ -45,11 +44,7 @@ import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ArrayAdapter; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.ImageView; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.SectionIndexer; import android.widget.SectionIndexer; import android.widget.TextView; import android.widget.TextView; Loading @@ -65,18 +60,7 @@ import java.util.List; /** Just a sectioned list of installed applications, nothing else to index **/ /** Just a sectioned list of installed applications, nothing else to index **/ public class AppNotificationSettings extends PinnedHeaderListFragment { public class AppNotificationSettings extends PinnedHeaderListFragment { private static final String TAG = "AppNotificationSettings"; private static final String TAG = "AppNotificationSettings"; private static final boolean DEBUG = true; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); /** * Show a checkbox in the per-app notification control dialog to allow the user * to promote this app's notifications to higher priority. */ private static final boolean ENABLE_APP_NOTIFICATION_PRIORITY_OPTION = true; /** * Show a checkbox in the per-app notification control dialog to allow the user to * selectively redact this app's notifications on the lockscreen. */ private static final boolean ENABLE_APP_NOTIFICATION_PRIVACY_OPTION = false; private static final String SECTION_BEFORE_A = "*"; private static final String SECTION_BEFORE_A = "*"; private static final String SECTION_AFTER_Z = "**"; private static final String SECTION_AFTER_Z = "**"; Loading Loading @@ -189,89 +173,6 @@ public class AppNotificationSettings extends PinnedHeaderListFragment { return null; return null; } } private void showDialog(final View v, final AppRow row) { final RelativeLayout layout = (RelativeLayout) mInflater.inflate(R.layout.notification_app_dialog, null); final ImageView icon = (ImageView) layout.findViewById(android.R.id.icon); icon.setImageDrawable(row.icon); final TextView title = (TextView) layout.findViewById(android.R.id.title); title.setText(row.label); final CheckBox showBox = (CheckBox) layout.findViewById(android.R.id.button1); final CheckBox priBox = (CheckBox) layout.findViewById(android.R.id.button2); final CheckBox senBox = (CheckBox) layout.findViewById(android.R.id.button3); if (!ENABLE_APP_NOTIFICATION_PRIORITY_OPTION) { priBox.setVisibility(View.GONE); } if (!ENABLE_APP_NOTIFICATION_PRIVACY_OPTION) { senBox.setVisibility(View.GONE); } showBox.setChecked(!row.banned); final OnCheckedChangeListener showListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { boolean success = mBackend.setNotificationsBanned(row.pkg, row.uid, !isChecked); if (success) { row.banned = !isChecked; mAdapter.bindView(v, row, true /*animate*/); priBox.setEnabled(!row.banned); senBox.setEnabled(!row.banned); } else { showBox.setOnCheckedChangeListener(null); showBox.setChecked(!isChecked); showBox.setOnCheckedChangeListener(this); } } }; showBox.setOnCheckedChangeListener(showListener); priBox.setChecked(row.priority); final OnCheckedChangeListener priListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { boolean success = mBackend.setHighPriority(row.pkg, row.uid, isChecked); if (success) { row.priority = isChecked; mAdapter.bindView(v, row, true /*animate*/); } else { priBox.setOnCheckedChangeListener(null); priBox.setChecked(!isChecked); priBox.setOnCheckedChangeListener(this); } } }; priBox.setOnCheckedChangeListener(priListener); senBox.setChecked(row.sensitive); final OnCheckedChangeListener senListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { boolean success = mBackend.setSensitive(row.pkg, row.uid, isChecked); if (success) { row.sensitive = isChecked; mAdapter.bindView(v, row, true /*animate*/); } else { senBox.setOnCheckedChangeListener(null); senBox.setChecked(!isChecked); senBox.setOnCheckedChangeListener(this); } } }; senBox.setOnCheckedChangeListener(senListener); priBox.setEnabled(!row.banned); senBox.setEnabled(!row.banned); final AlertDialog d = new AlertDialog.Builder(mContext) .setView(layout) .setPositiveButton(R.string.app_notifications_dialog_done, null) .create(); d.show(); } private static class ViewHolder { private static class ViewHolder { ViewGroup row; ViewGroup row; ViewGroup appButton; ViewGroup appButton; Loading Loading @@ -366,7 +267,10 @@ public class AppNotificationSettings extends PinnedHeaderListFragment { vh.appButton.setOnClickListener(new OnClickListener() { vh.appButton.setOnClickListener(new OnClickListener() { @Override @Override public void onClick(View v) { public void onClick(View v) { showDialog(view, row); mContext.startActivity(new Intent(mContext, AppNotificationDialog.class) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) .putExtra(Settings.EXTRA_APP_PACKAGE, row.pkg) .putExtra(Settings.EXTRA_APP_UID, row.uid)); } } }); }); enableLayoutTransitions(vh.appButton, animate); enableLayoutTransitions(vh.appButton, animate); Loading Loading @@ -428,7 +332,7 @@ public class AppNotificationSettings extends PinnedHeaderListFragment { public String section; public String section; } } private static class AppRow extends Row { public static class AppRow extends Row { public String pkg; public String pkg; public int uid; public int uid; public Drawable icon; public Drawable icon; Loading @@ -448,6 +352,23 @@ public class AppNotificationSettings extends PinnedHeaderListFragment { } } }; }; public static AppRow loadAppRow(PackageManager pm, PackageInfo pkg, Backend backend) { final AppRow row = new AppRow(); row.pkg = pkg.packageName; row.uid = pkg.applicationInfo.uid; try { row.label = pkg.applicationInfo.loadLabel(pm); } catch (Throwable t) { Log.e(TAG, "Error loading application label for " + row.pkg, t); row.label = row.pkg; } row.icon = pkg.applicationInfo.loadIcon(pm); row.banned = backend.getNotificationsBanned(row.pkg, row.uid); row.priority = backend.getHighPriority(row.pkg, row.uid); row.sensitive = backend.getSensitive(row.pkg, row.uid); return row; } private final Runnable mCollectAppsRunnable = new Runnable() { private final Runnable mCollectAppsRunnable = new Runnable() { @Override @Override public void run() { public void run() { Loading @@ -464,23 +385,12 @@ public class AppNotificationSettings extends PinnedHeaderListFragment { if (DEBUG) Log.d(TAG, "Skipping " + pkg.packageName); if (DEBUG) Log.d(TAG, "Skipping " + pkg.packageName); continue; continue; } } final AppRow row = new AppRow(); final AppRow row = loadAppRow(pm, pkg, mBackend); row.pkg = pkg.packageName; row.uid = pkg.applicationInfo.uid; try { row.label = pkg.applicationInfo.loadLabel(pm); } catch (Throwable t) { Log.e(TAG, "Error loading application label for " + row.pkg, t); row.label = row.pkg; } row.icon = pkg.applicationInfo.loadIcon(pm); row.banned = mBackend.getNotificationsBanned(row.pkg, row.uid); row.priority = mBackend.getHighPriority(row.pkg, row.uid); row.sensitive = mBackend.getSensitive(row.pkg, row.uid); mRows.put(row.pkg, row); mRows.put(row.pkg, row); } } // collect config activities // collect config activities Log.d(TAG, "APP_NOTIFICATION_PREFS_CATEGORY_INTENT is " + APP_NOTIFICATION_PREFS_CATEGORY_INTENT); if (DEBUG) Log.d(TAG, "APP_NOTIFICATION_PREFS_CATEGORY_INTENT is " + APP_NOTIFICATION_PREFS_CATEGORY_INTENT); final List<ResolveInfo> resolveInfos = pm.queryIntentActivities( final List<ResolveInfo> resolveInfos = pm.queryIntentActivities( APP_NOTIFICATION_PREFS_CATEGORY_INTENT, APP_NOTIFICATION_PREFS_CATEGORY_INTENT, PackageManager.MATCH_DEFAULT_ONLY); PackageManager.MATCH_DEFAULT_ONLY); Loading