App & channel notification settings updates

- change 'block all' to an on/off switch bar
- update channel list summary text when notifications are
toggled on/off on app settings page
- Add 'off state' text
- change style of foot items
- change 'importance' from a dropdown to its own page

Bug: 37538972
Bug: 37479730
Fixes: 37541624
Fixes: 37549732
Test: manual

Change-Id: I0e5cc66ba539ce2b76b4ad6541bf6bfb5b58c373
This commit is contained in:
Julia Reynolds
2017-04-21 08:27:06 -04:00
parent 8da8951b4b
commit 38c16a9417
12 changed files with 489 additions and 140 deletions

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2017 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.
-->
<!-- For use in a LayoutPreference -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="0px"
android:layout_width="match_parent"
android:layout_weight="1" >
<com.android.settings.widget.SwitchBar
android:id="@+id/switch_bar"
android:layout_height="?android:attr/actionBarSize"
android:layout_width="match_parent"
android:paddingStart="0dp"
android:background="@drawable/switchbar_background"
android:theme="?attr/switchBarTheme"
/>
</LinearLayout>

View File

@@ -6558,7 +6558,10 @@
<!-- Notification Settings: Title for the option managing notifications per application. [CHAR LIMIT=30] -->
<string name="app_notifications_title">Notifications</string>
<!-- [CHAR LIMIT=100] Notification importance slider title -->
<!-- [CHAR LIMIT=100] Notification channel title -->
<string name="notification_channel_title">Notification category</string>
<!-- [CHAR LIMIT=100] Notification importance screen title -->
<string name="notification_importance_title">Importance</string>
<!-- [CHAR LIMIT=100] Notification Importance: unspecified importance level description -->
@@ -6579,17 +6582,17 @@
<!-- [CHAR LIMIT=100] Notification Importance: high importance level description -->
<string name="notification_importance_high">Make sound and pop on screen</string>
<!-- [CHAR LIMIT=100] Notification Importance summary: min importance level description -->
<string name="notification_importance_min_summary">Low: No sound or visual interruption</string>
<!-- [CHAR LIMIT=100] Notification Importance title: min importance level title -->
<string name="notification_importance_min_title">Low</string>
<!-- [CHAR LIMIT=100] Notification Importance summary: low importance level description -->
<string name="notification_importance_low_summary">Medium: No sound</string>
<!-- [CHAR LIMIT=100] Notification Importance title: low importance level title -->
<string name="notification_importance_low_title">Medium</string>
<!-- [CHAR LIMIT=100] Notification Importance summary: normal importance level description -->
<string name="notification_importance_default_summary">High: Make sound</string>
<!-- [CHAR LIMIT=100] Notification Importance title: normal importance level title -->
<string name="notification_importance_default_title">High</string>
<!-- [CHAR LIMIT=100] Notification Importance summary: high importance level description -->
<string name="notification_importance_high_summary">Urgent: Make sound and pop on screen</string>
<!-- [CHAR LIMIT=100] Notification Importance title: high importance level title -->
<string name="notification_importance_high_title">Urgent</string>
<!-- [CHAR LIMIT=40] Notification importance title -->
<string name="allow_sound">Allow Sound</string>
@@ -6694,6 +6697,12 @@
<!-- [CHAR LIMIT=NONE] Text when loading app list in notification settings -->
<string name="loading_notification_apps">Loading apps...</string>
<!-- [CHAR LIMIT=NONE] Text appearing when app notifications are off -->
<string name="app_notifications_off_desc">Android is blocking this app\'s notifications from appearing on this device</string>
<!-- [CHAR LIMIT=NONE] Text appearing when channel notifications are off -->
<string name="channel_notifications_off_desc">Android is blocking this category of notifications from appearing on this device</string>
<!-- [CHAR LIMIT=NONE] App notification settings: channels title -->
<string name="notification_channels">Categories</string>

View File

@@ -18,13 +18,6 @@
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
android:title="@string/app_notifications_title"
android:key="app_notification_settings">
<!-- Block -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="block"
android:title="@string/app_notification_block_title"
android:summary="@string/app_notification_block_summary"
settings:useAdditionalSummary="true"
settings:restrictedSwitchSummary="@string/enabled_by_admin" />
<!-- Show badge -->
<com.android.settingslib.RestrictedSwitchPreference

View File

@@ -18,16 +18,7 @@
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings" >
<!-- Importance -->
<!-- Block -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="block"
android:title="@string/app_notification_block_title"
android:summary="@string/app_notification_block_summary"
settings:useAdditionalSummary="true"
settings:restrictedSwitchSummary="@string/enabled_by_admin" />
<!-- Importance -->
<com.android.settings.notification.RestrictedDropDownPreference
<Preference
android:key="importance"
android:title="@string/notification_importance_title" />

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2017 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/notification_importance_title">
<com.android.settings.widget.RadioButtonPreference
android:key="importance_high"
android:title="@string/notification_importance_high_title"
android:summary="@string/notification_importance_high"
/>
<com.android.settings.widget.RadioButtonPreference
android:key="importance_default"
android:title="@string/notification_importance_default_title"
android:summary="@string/notification_importance_default" />
<com.android.settings.widget.RadioButtonPreference
android:key="importance_low"
android:title="@string/notification_importance_low_title"
android:summary="@string/notification_importance_low" />
<com.android.settings.widget.RadioButtonPreference
android:key="importance_min"
android:title="@string/notification_importance_min_title"
android:summary="@string/notification_importance_min" />
</PreferenceScreen>

View File

@@ -24,6 +24,7 @@ import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import android.app.Activity;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -33,17 +34,22 @@ import android.support.v7.preference.PreferenceCategory;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Switch;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.AppHeader;
import com.android.settings.DimmableIconPreference;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.applications.AppHeaderController;
import com.android.settings.applications.AppInfoBase;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.notification.NotificationBackend.AppRow;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.FooterPreference;
import com.android.settings.widget.MasterSwitchPreference;
import com.android.settings.widget.SwitchBar;
import com.android.settingslib.RestrictedSwitchPreference;
import java.text.Collator;
@@ -57,12 +63,14 @@ public class AppNotificationSettings extends NotificationSettingsBase {
private static final String TAG = "AppNotificationSettings";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final String KEY_BLOCK = "block";
private static final String KEY_IMPORTANCE = "allow_sound";
private List<NotificationChannelGroup> mChannelGroupList;
private List<PreferenceCategory> mChannelGroups = new ArrayList();
private RestrictedSwitchPreference mImportanceToggle;
private LayoutPreference mBlockBar;
private FooterPreference mDeletedChannels;
private SwitchBar mSwitchBar;
private boolean mShowLegacyChannelConfig = false;
@@ -88,8 +96,8 @@ public class AppNotificationSettings extends NotificationSettingsBase {
addPreferencesFromResource(R.xml.app_notification_settings);
getPreferenceScreen().setOrderingAsAdded(true);
mBlock = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BLOCK);
mBadge = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BADGE);
mBlockedDesc = (FooterPreference) getPreferenceScreen().findPreference(KEY_BLOCKED_DESC);
setupBlock();
setupBadge();
@@ -127,11 +135,7 @@ public class AppNotificationSettings extends NotificationSettingsBase {
.done(activity, getPrefContext());
getPreferenceScreen().addPreference(pref);
if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null) {
Log.w(TAG, "Missing package or uid or packageinfo");
finish();
return;
}
updateDependents(mAppRow.banned);
}
private void populateChannelList() {
@@ -187,12 +191,12 @@ public class AppNotificationSettings extends NotificationSettingsBase {
int deletedChannelCount = mBackend.getDeletedChannelCount(mAppRow.pkg, mAppRow.uid);
if (deletedChannelCount > 0) {
DimmableIconPreference deletedPref = new DimmableIconPreference(getPrefContext());
deletedPref.setSelectable(false);
deletedPref.setTitle(getResources().getQuantityString(
mDeletedChannels = new FooterPreference(getPrefContext());
mDeletedChannels.setSelectable(false);
mDeletedChannels.setTitle(getResources().getQuantityString(
R.plurals.deleted_channels, deletedChannelCount, deletedChannelCount));
deletedPref.setIcon(R.drawable.ic_info);
getPreferenceScreen().addPreference(deletedPref);
mDeletedChannels.setEnabled(false);
getPreferenceScreen().addPreference(mDeletedChannels);
}
}
updateDependents(mAppRow.banned);
@@ -214,7 +218,8 @@ public class AppNotificationSettings extends NotificationSettingsBase {
channelArgs.putString(Settings.EXTRA_CHANNEL_ID, channel.getId());
Intent channelIntent = Utils.onBuildStartFragmentIntent(getActivity(),
ChannelNotificationSettings.class.getName(),
channelArgs, null, 0, null, false, getMetricsCategory());
channelArgs, null, R.string.notification_channel_title, null, false,
getMetricsCategory());
channelPref.setIntent(channelIntent);
channelPref.setOnPreferenceChangeListener(
@@ -227,6 +232,7 @@ public class AppNotificationSettings extends NotificationSettingsBase {
channel.setImportance(importance);
channel.lockFields(
NotificationChannel.USER_LOCKED_IMPORTANCE);
channelPref.setSummary(getImportanceSummary(channel.getImportance()));
mBackend.updateChannel(mPkg, mUid, channel);
return true;
@@ -237,8 +243,7 @@ public class AppNotificationSettings extends NotificationSettingsBase {
private void populateDefaultChannelPrefs() {
addPreferencesFromResource(R.xml.legacy_channel_notification_settings);
mPriority =
(RestrictedSwitchPreference) findPreference(KEY_BYPASS_DND);
mPriority = (RestrictedSwitchPreference) findPreference(KEY_BYPASS_DND);
mVisibilityOverride =
(RestrictedDropDownPreference) findPreference(KEY_VISIBILITY_OVERRIDE);
mImportanceToggle = (RestrictedSwitchPreference) findPreference(KEY_IMPORTANCE);
@@ -248,8 +253,11 @@ public class AppNotificationSettings extends NotificationSettingsBase {
setupVisOverridePref(mChannel.getLockscreenVisibility());
setupImportanceToggle();
}
mSwitchBar.setChecked(!mAppRow.banned
&& mChannel.getImportance() != NotificationManager.IMPORTANCE_NONE);
}
// 'allow sound'
private void setupImportanceToggle() {
mImportanceToggle.setDisabledByAdmin(mSuspendedAppsAdmin);
mImportanceToggle.setChecked(mChannel.getImportance() >= IMPORTANCE_DEFAULT
@@ -268,6 +276,40 @@ public class AppNotificationSettings extends NotificationSettingsBase {
});
}
protected void setupBlock() {
View switchBarContainer = LayoutInflater.from(
getPrefContext()).inflate(R.layout.styled_switch_bar, null);
mSwitchBar = switchBarContainer.findViewById(R.id.switch_bar);
mSwitchBar.show();
mSwitchBar.setDisabledByAdmin(mSuspendedAppsAdmin);
mSwitchBar.setChecked(!mAppRow.banned);
mSwitchBar.addOnSwitchChangeListener(new SwitchBar.OnSwitchChangeListener() {
@Override
public void onSwitchChanged(Switch switchView, boolean isChecked) {
if (mShowLegacyChannelConfig && mChannel != null) {
final int importance = isChecked ? IMPORTANCE_UNSPECIFIED : IMPORTANCE_NONE;
mImportanceToggle.setChecked(importance == IMPORTANCE_UNSPECIFIED);
mChannel.setImportance(importance);
mChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
mBackend.updateChannel(mPkg, mUid, mChannel);
}
mBackend.setNotificationsEnabledForPackage(mPkgInfo.packageName, mUid, isChecked);
updateDependents(!isChecked);
}
});
mBlockBar = new LayoutPreference(getPrefContext(), switchBarContainer);
mBlockBar.setOrder(-500);
mBlockBar.setKey(KEY_BLOCK);
getPreferenceScreen().addPreference(mBlockBar);
if (mAppRow.systemApp && !mAppRow.banned) {
setVisible(mBlockBar, false);
}
setupBlockDesc(R.string.app_notifications_off_desc);
}
private void setupBadge() {
mBadge.setDisabledByAdmin(mSuspendedAppsAdmin);
mBadge.setChecked(mAppRow.showBadge);
@@ -281,31 +323,14 @@ public class AppNotificationSettings extends NotificationSettingsBase {
});
}
private void setupBlock() {
if (mAppRow.systemApp && !mAppRow.banned) {
setVisible(mBlock, false);
} else {
mBlock.setDisabledByAdmin(mSuspendedAppsAdmin);
mBlock.setChecked(mAppRow.banned);
mBlock.setOnPreferenceChangeListener(
new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference,
Object newValue) {
final boolean blocked = (Boolean) newValue;
mBackend.setNotificationsEnabledForPackage(mPkgInfo.packageName, mUid,
!blocked);
updateDependents(blocked);
return true;
}
});
}
}
private void updateDependents(boolean banned) {
for (PreferenceCategory category : mChannelGroups) {
setVisible(category, !banned);
}
if (mDeletedChannels != null) {
setVisible(mDeletedChannels, !banned);
}
setVisible(mBlockedDesc, banned);
setVisible(mBadge, !banned);
if (mShowLegacyChannelConfig) {
setVisible(mImportanceToggle, !banned);
@@ -313,7 +338,7 @@ public class AppNotificationSettings extends NotificationSettingsBase {
setVisible(mVisibilityOverride, !banned);
}
if (mAppRow.systemApp && !mAppRow.banned) {
setVisible(mBlock, false);
setVisible(mBlockBar, false);
}
}

View File

@@ -0,0 +1,151 @@
/*
* Copyright (C) 2017 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 static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_MAX;
import static android.app.NotificationManager.IMPORTANCE_MIN;
import android.content.Context;
import android.provider.SearchIndexableResource;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
import android.util.Log;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.widget.RadioButtonPreference;
import java.util.ArrayList;
import java.util.List;
public class ChannelImportanceSettings extends NotificationSettingsBase
implements RadioButtonPreference.OnClickListener, Indexable {
private static final String TAG = "NotiImportance";
private static final String KEY_IMPORTANCE_HIGH = "importance_high";
private static final String KEY_IMPORTANCE_DEFAULT = "importance_default";
private static final String KEY_IMPORTANCE_LOW = "importance_low";
private static final String KEY_IMPORTANCE_MIN = "importance_min";
List<RadioButtonPreference> mImportances = new ArrayList<>();
@Override
public int getMetricsCategory() {
return MetricsEvent.NOTIFICATION_CHANNEL_IMPORTANCE;
}
@Override
public void onResume() {
super.onResume();
if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null || mChannel == null) {
Log.w(TAG, "Missing package or uid or packageinfo or channel");
finish();
return;
}
createPreferenceHierarchy();
}
@Override
public void onPause() {
super.onPause();
}
private PreferenceScreen createPreferenceHierarchy() {
PreferenceScreen root = getPreferenceScreen();
if (root != null) {
root.removeAll();
}
addPreferencesFromResource(R.xml.notification_importance);
root = getPreferenceScreen();
for (int i = 0; i < root.getPreferenceCount(); i++) {
Preference pref = root.getPreference(i);
if (pref instanceof RadioButtonPreference) {
RadioButtonPreference radioPref = (RadioButtonPreference) pref;
radioPref.setOnClickListener(this);
mImportances.add(radioPref);
}
}
switch (mChannel.getImportance()) {
case IMPORTANCE_MIN:
updateRadioButtons(KEY_IMPORTANCE_MIN);
break;
case IMPORTANCE_LOW:
updateRadioButtons(KEY_IMPORTANCE_LOW);
break;
case IMPORTANCE_DEFAULT:
updateRadioButtons(KEY_IMPORTANCE_DEFAULT);
break;
case IMPORTANCE_HIGH:
case IMPORTANCE_MAX:
updateRadioButtons(KEY_IMPORTANCE_HIGH);
break;
}
return root;
}
private void updateRadioButtons(String selectionKey) {
for (RadioButtonPreference pref : mImportances) {
if (selectionKey.equals(pref.getKey())) {
pref.setChecked(true);
} else {
pref.setChecked(false);
}
}
}
@Override
public void onRadioButtonClicked(RadioButtonPreference clicked) {
switch (clicked.getKey()) {
case KEY_IMPORTANCE_HIGH:
mChannel.setImportance(IMPORTANCE_HIGH);
break;
case KEY_IMPORTANCE_DEFAULT:
mChannel.setImportance(IMPORTANCE_DEFAULT);
break;
case KEY_IMPORTANCE_LOW:
mChannel.setImportance(IMPORTANCE_LOW);
break;
case KEY_IMPORTANCE_MIN:
mChannel.setImportance(IMPORTANCE_MIN);
break;
}
updateRadioButtons(clicked.getKey());
mChannel.lockFields(USER_LOCKED_IMPORTANCE);
mBackend.updateChannel(mAppRow.pkg, mAppRow.uid, mChannel);
}
// This page exists per notification channel; should not be included
// in search
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) {
return null;
}
};
}

View File

@@ -16,9 +16,7 @@
package com.android.settings.notification;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import android.app.Activity;
@@ -27,25 +25,31 @@ import android.app.NotificationManager;
import android.content.Intent;
import android.content.pm.UserInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.Settings;
import android.support.v7.preference.Preference;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Switch;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.DimmableIconPreference;
import com.android.settings.AppHeader;
import com.android.settings.R;
import com.android.settings.RingtonePreference;
import com.android.settings.Utils;
import com.android.settings.applications.AppHeaderController;
import com.android.settings.applications.AppInfoBase;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.FooterPreference;
import com.android.settings.widget.SwitchBar;
import com.android.settingslib.RestrictedSwitchPreference;
import java.util.ArrayList;
import java.util.List;
public class ChannelNotificationSettings extends NotificationSettingsBase {
private static final String TAG = "ChannelSettings";
@@ -53,10 +57,13 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
protected static final String KEY_VIBRATE = "vibrate";
protected static final String KEY_RINGTONE = "ringtone";
protected Preference mImportance;
protected RestrictedSwitchPreference mLights;
protected RestrictedSwitchPreference mVibrate;
protected NotificationSoundPreference mRingtone;
protected LayoutPreference mBlockBar;
@Override
public int getMetricsCategory() {
return MetricsEvent.NOTIFICATION_TOPIC_NOTIFICATION;
@@ -75,33 +82,33 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
getPreferenceScreen().removeAll();
}
addPreferencesFromResource(R.xml.channel_notification_settings);
getPreferenceScreen().setOrderingAsAdded(true);
// load settings intent
ArrayMap<String, NotificationBackend.AppRow> rows = new ArrayMap<String, NotificationBackend.AppRow>();
rows.put(mAppRow.pkg, mAppRow);
collectConfigActivities(rows);
mBlock = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BLOCK);
mBlockedDesc = (FooterPreference) getPreferenceScreen().findPreference(KEY_BLOCKED_DESC);
mBadge = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BADGE);
mImportance = (RestrictedDropDownPreference) findPreference(KEY_IMPORTANCE);
mPriority =
(RestrictedSwitchPreference) findPreference(KEY_BYPASS_DND);
mImportance = findPreference(KEY_IMPORTANCE);
mPriority = (RestrictedSwitchPreference) findPreference(KEY_BYPASS_DND);
mVisibilityOverride =
(RestrictedDropDownPreference) findPreference(KEY_VISIBILITY_OVERRIDE);
mLights = (RestrictedSwitchPreference) findPreference(KEY_LIGHTS);
mVibrate = (RestrictedSwitchPreference) findPreference(KEY_VIBRATE);
mRingtone = (NotificationSoundPreference) findPreference(KEY_RINGTONE);
if (mPkgInfo != null && mChannel != null) {
setupPriorityPref(mChannel.canBypassDnd());
setupVisOverridePref(mChannel.getLockscreenVisibility());
setupLights();
setupVibrate();
setupRingtone();
setupBlockAndImportance();
setupBadge();
setupBlock();
setupImportance();
updateDependents();
}
final Activity activity = getActivity();
final Preference pref = FeatureFactory.getFactory(activity)
.getApplicationFeatureProvider(activity)
@@ -124,12 +131,13 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
}
if (!TextUtils.isEmpty(mChannel.getDescription())) {
DimmableIconPreference descPref = new DimmableIconPreference(getPrefContext());
FooterPreference descPref = new FooterPreference(getPrefContext());
descPref.setSelectable(false);
descPref.setSummary(mChannel.getDescription());
descPref.setIcon(R.drawable.ic_info);
descPref.setEnabled(false);
getPreferenceScreen().addPreference(descPref);
}
}
private void setupLights() {
@@ -175,27 +183,38 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
});
}
protected void setupBlockAndImportance() {
if (mAppRow.systemApp && mChannel.getImportance() != NotificationManager.IMPORTANCE_NONE) {
setVisible(mBlock, false);
} else {
mBlock.setEnabled(mAppRow.systemApp);
mBlock.setDisabledByAdmin(mSuspendedAppsAdmin);
mBlock.setChecked(mChannel.getImportance() == NotificationManager.IMPORTANCE_NONE);
mBlock.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
protected void setupBlock() {
View switchBarContainer = LayoutInflater.from(
getPrefContext()).inflate(R.layout.styled_switch_bar, null);
SwitchBar switchBar = switchBarContainer.findViewById(R.id.switch_bar);
switchBar.show();
switchBar.setDisabledByAdmin(mSuspendedAppsAdmin);
switchBar.setChecked(mChannel.getImportance() != NotificationManager.IMPORTANCE_NONE);
switchBar.addOnSwitchChangeListener(new SwitchBar.OnSwitchChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean value = (Boolean) newValue;
int importance = value ? IMPORTANCE_NONE : IMPORTANCE_LOW;
mImportance.setValue(String.valueOf(importance));
public void onSwitchChanged(Switch switchView, boolean isChecked) {
int importance = isChecked ? IMPORTANCE_LOW : IMPORTANCE_NONE;
mImportance.setSummary(getImportanceSummary(importance));
mChannel.setImportance(importance);
mChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
mBackend.updateChannel(mPkg, mUid, mChannel);
updateDependents();
return true;
}
});
mBlockBar = new LayoutPreference(getPrefContext(), switchBarContainer);
mBlockBar.setOrder(-500);
mBlockBar.setKey(KEY_BLOCK);
getPreferenceScreen().addPreference(mBlockBar);
if (mAppRow.systemApp && mChannel.getImportance() != NotificationManager.IMPORTANCE_NONE) {
setVisible(mBlockBar, false);
}
setupBlockDesc(R.string.channel_notifications_off_desc);
}
protected void setupBadge() {
mBadge.setDisabledByAdmin(mSuspendedAppsAdmin);
mBadge.setEnabled(mAppRow.showBadge);
mBadge.setChecked(mChannel.canShowBadge());
@@ -209,41 +228,21 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
return true;
}
});
mImportance.setDisabledByAdmin(mSuspendedAppsAdmin);
final int numImportances = IMPORTANCE_HIGH - IMPORTANCE_MIN + 1;
List<String> summaries = new ArrayList<>();
List<String> values = new ArrayList<>();
for (int i = 0; i < numImportances; i++) {
int importance = i + 1;
summaries.add(getImportanceSummary(importance));
values.add(String.valueOf(importance));
}
if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId())) {
// Add option to reset to letting the app decide
summaries.add(getImportanceSummary(NotificationManager.IMPORTANCE_UNSPECIFIED));
values.add(String.valueOf(NotificationManager.IMPORTANCE_UNSPECIFIED));
}
mImportance.setEntryValues(values.toArray(new String[0]));
mImportance.setEntries(summaries.toArray(new String[0]));
mImportance.setValue(String.valueOf(mChannel.getImportance()));
protected void setupImportance() {
Bundle channelArgs = new Bundle();
channelArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid);
channelArgs.putBoolean(AppHeader.EXTRA_HIDE_INFO_BUTTON, true);
channelArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, mPkg);
channelArgs.putString(Settings.EXTRA_CHANNEL_ID, mChannel.getId());
Intent channelIntent = Utils.onBuildStartFragmentIntent(getActivity(),
ChannelImportanceSettings.class.getName(),
channelArgs, null, R.string.notification_importance_title, null,
false, getMetricsCategory());
mImportance.setIntent(channelIntent);
mImportance.setEnabled(mSuspendedAppsAdmin == null);
mImportance.setSummary(getImportanceSummary(mChannel.getImportance()));
if (mAppRow.lockedImportance) {
mImportance.setEnabled(false);
} else {
mImportance.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
int importance = Integer.parseInt((String) newValue);
mChannel.setImportance(importance);
mChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
mBackend.updateChannel(mPkg, mUid, mChannel);
updateDependents();
return true;
}
});
}
}
private boolean isLockScreenSecure() {
@@ -292,6 +291,7 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
}
private void updateDependents() {
setVisible(mBlockedDesc, mChannel.getImportance() == IMPORTANCE_NONE);
setVisible(mBadge, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN));
setVisible(mImportance, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN));
setVisible(mLights, checkCanBeVisible(

View File

@@ -19,6 +19,7 @@ package com.android.settings.notification;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.applications.AppInfoBase;
import com.android.settings.widget.FooterPreference;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
@@ -39,6 +40,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.service.notification.NotificationListenerService;
import android.support.v7.preference.DropDownPreference;
import android.support.v7.preference.Preference;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -63,6 +65,7 @@ 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_BLOCKED_DESC = "block_desc";
protected PackageManager mPm;
protected UserManager mUm;
@@ -73,11 +76,10 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen
protected int mUserId;
protected String mPkg;
protected PackageInfo mPkgInfo;
protected RestrictedSwitchPreference mBlock;
protected RestrictedSwitchPreference mBadge;
protected RestrictedDropDownPreference mImportance;
protected RestrictedSwitchPreference mPriority;
protected RestrictedDropDownPreference mVisibilityOverride;
protected FooterPreference mBlockedDesc;
protected EnforcedAdmin mSuspendedAppsAdmin;
protected boolean mDndVisualEffectsSuppressed;
@@ -325,6 +327,15 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen
mVisibilityOverride.setDisabledByAdmin(mSuspendedAppsAdmin);
}
protected void setupBlockDesc(int summaryResId) {
mBlockedDesc = new FooterPreference(getPrefContext());
mBlockedDesc.setSelectable(false);
mBlockedDesc.setTitle(summaryResId);
mBlockedDesc.setEnabled(false);
mBlockedDesc.setOrder(50);
getPreferenceScreen().addPreference(mBlockedDesc);
}
private void setRestrictedIfNotificationFeaturesDisabled(CharSequence entry,
CharSequence entryValue, int keyguardNotificationFeatures) {

View File

@@ -1,3 +1,19 @@
/*
* Copyright (C) 2017 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.ContentResolver;

View File

@@ -0,0 +1,81 @@
/*
* Copyright (C) 2017 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.support.v7.preference.PreferenceViewHolder;
import android.util.AttributeSet;
import android.view.View;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.widget.ToggleSwitch;
import com.android.settingslib.RestrictedLockUtils;
public class NotificationSwitchBarPreference extends LayoutPreference {
private ToggleSwitch mSwitch;
private boolean mChecked;
private boolean mEnableSwitch = true;
public NotificationSwitchBarPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
mSwitch = (ToggleSwitch) holder.findViewById(android.R.id.switch_widget);
if (mSwitch != null) {
mSwitch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!mSwitch.isEnabled()) {
return;
}
mChecked = !mChecked;
setChecked(mChecked);
if (!callChangeListener(mChecked)) {
setChecked(!mChecked);
}
}
});
mSwitch.setChecked(mChecked);
mSwitch.setEnabled(mEnableSwitch);
}
}
public boolean isChecked() {
return mSwitch != null && mSwitch.isEnabled() && mChecked;
}
public void setChecked(boolean checked) {
mChecked = checked;
if (mSwitch != null) {
mSwitch.setChecked(checked);
}
}
public void setSwitchEnabled(boolean enabled) {
mEnableSwitch = enabled;
if (mSwitch != null) {
mSwitch.setEnabled(enabled);
}
}
public void setDisabledByAdmin(RestrictedLockUtils.EnforcedAdmin admin) {
setSwitchEnabled(admin == null);
}
}

View File

@@ -65,6 +65,7 @@ import com.android.settings.location.LocationSettings;
import com.android.settings.location.ScanningSettings;
import com.android.settings.network.NetworkDashboardFragment;
import com.android.settings.nfc.PaymentSettings;
import com.android.settings.notification.ChannelImportanceSettings;
import com.android.settings.notification.ConfigureNotificationSettings;
import com.android.settings.notification.SoundSettings;
import com.android.settings.notification.ZenModePrioritySettings;
@@ -179,6 +180,8 @@ public final class SearchIndexableResources {
R.drawable.ic_settings_accessibility);
addIndex(AccessibilityShortcutPreferenceFragment.class, NO_DATA_RES_ID,
R.drawable.ic_settings_accessibility);
addIndex(ChannelImportanceSettings.class, NO_DATA_RES_ID,
R.drawable.ic_settings_notifications);
}
private SearchIndexableResources() {