Merge "Add settings page for notification channel groups"
This commit is contained in:
committed by
Android (Google) Code Review
commit
0e497230d9
@@ -2700,6 +2700,22 @@
|
|||||||
android:value="com.android.settings.notification.AppNotificationSettings" />
|
android:value="com.android.settings.notification.AppNotificationSettings" />
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<!-- Show channel group-level notification settings (group passed in as extras) -->
|
||||||
|
<activity android:name="Settings$ChannelGroupNotificationSettingsActivity"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter android:priority="1">
|
||||||
|
<action android:name="android.settings.CHANNEL_GROUP_NOTIFICATION_SETTINGS" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
</intent-filter>
|
||||||
|
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
|
||||||
|
android:value="com.android.settings.notification.ChannelGroupNotificationSettings" />
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
|
||||||
<!-- Show channel-level notification settings (channel passed in as extras) -->
|
<!-- Show channel-level notification settings (channel passed in as extras) -->
|
||||||
<activity android:name="Settings$ChannelNotificationSettingsActivity"
|
<activity android:name="Settings$ChannelNotificationSettingsActivity"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
|
@@ -6836,6 +6836,9 @@
|
|||||||
<!-- [CHAR LIMIT=100] Notification channel title -->
|
<!-- [CHAR LIMIT=100] Notification channel title -->
|
||||||
<string name="notification_channel_title">Notification category</string>
|
<string name="notification_channel_title">Notification category</string>
|
||||||
|
|
||||||
|
<!-- [CHAR LIMIT=200] Notification channel group title -->
|
||||||
|
<string name="notification_group_title">Notification category group</string>
|
||||||
|
|
||||||
<!-- [CHAR LIMIT=100] Notification importance screen title -->
|
<!-- [CHAR LIMIT=100] Notification importance screen title -->
|
||||||
<string name="notification_importance_title">Importance</string>
|
<string name="notification_importance_title">Importance</string>
|
||||||
|
|
||||||
@@ -7003,12 +7006,21 @@
|
|||||||
<!-- [CHAR LIMIT=NONE] Text appearing when channel notifications are off -->
|
<!-- [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>
|
<string name="channel_notifications_off_desc">Android is blocking this category of notifications from appearing on this device</string>
|
||||||
|
|
||||||
|
<!-- [CHAR LIMIT=NONE] Text appearing when channel group notifications are off -->
|
||||||
|
<string name="channel_group_notifications_off_desc">Android is blocking this group of notifications from appearing on this device</string>
|
||||||
|
|
||||||
<!-- [CHAR LIMIT=NONE] App notification settings: channels title -->
|
<!-- [CHAR LIMIT=NONE] App notification settings: channels title -->
|
||||||
<string name="notification_channels">Categories</string>
|
<string name="notification_channels">Categories</string>
|
||||||
|
|
||||||
<!-- [CHAR LIMIT=NONE] App notification settings: non-grouped-channels title -->
|
<!-- [CHAR LIMIT=NONE] App notification settings: non-grouped-channels title -->
|
||||||
<string name="notification_channels_other">Other</string>
|
<string name="notification_channels_other">Other</string>
|
||||||
|
|
||||||
|
<!-- [CHAR LIMIT=45] App notification settings, group summary-->
|
||||||
|
<plurals name="notification_group_summary">
|
||||||
|
<item quantity="one"><xliff:g id="count" example="1">%d</xliff:g> category</item>
|
||||||
|
<item quantity="other"><xliff:g id="count" example="10">%d</xliff:g> categories</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
<!-- [CHAR LIMIT=NONE] App notification settings: no channels -->
|
<!-- [CHAR LIMIT=NONE] App notification settings: no channels -->
|
||||||
<string name="no_channels">This app has not posted any notifications</string>
|
<string name="no_channels">This app has not posted any notifications</string>
|
||||||
|
|
||||||
|
@@ -38,6 +38,7 @@
|
|||||||
settings:useAdditionalSummary="true" />
|
settings:useAdditionalSummary="true" />
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
|
android:key="advanced"
|
||||||
android:title="@string/advanced_apps">
|
android:title="@string/advanced_apps">
|
||||||
|
|
||||||
<!-- Visibility Override -->
|
<!-- Visibility Override -->
|
||||||
|
@@ -124,6 +124,7 @@ public class Settings extends SettingsActivity {
|
|||||||
public static class NotificationAppListActivity extends SettingsActivity { /* empty */ }
|
public static class NotificationAppListActivity extends SettingsActivity { /* empty */ }
|
||||||
public static class AppNotificationSettingsActivity extends SettingsActivity { /* empty */ }
|
public static class AppNotificationSettingsActivity extends SettingsActivity { /* empty */ }
|
||||||
public static class ChannelNotificationSettingsActivity extends SettingsActivity { /* empty */ }
|
public static class ChannelNotificationSettingsActivity extends SettingsActivity { /* empty */ }
|
||||||
|
public static class ChannelGroupNotificationSettingsActivity extends SettingsActivity { /* empty */ }
|
||||||
public static class ManageDomainUrlsActivity extends SettingsActivity { /* empty */ }
|
public static class ManageDomainUrlsActivity extends SettingsActivity { /* empty */ }
|
||||||
public static class AutomaticStorageManagerSettingsActivity extends SettingsActivity { /* empty */ }
|
public static class AutomaticStorageManagerSettingsActivity extends SettingsActivity { /* empty */ }
|
||||||
public static class GamesStorageActivity extends SettingsActivity { /* empty */ }
|
public static class GamesStorageActivity extends SettingsActivity { /* empty */ }
|
||||||
|
@@ -100,6 +100,7 @@ import com.android.settings.nfc.AndroidBeam;
|
|||||||
import com.android.settings.nfc.PaymentSettings;
|
import com.android.settings.nfc.PaymentSettings;
|
||||||
import com.android.settings.notification.AppNotificationSettings;
|
import com.android.settings.notification.AppNotificationSettings;
|
||||||
import com.android.settings.notification.ChannelNotificationSettings;
|
import com.android.settings.notification.ChannelNotificationSettings;
|
||||||
|
import com.android.settings.notification.ChannelGroupNotificationSettings;
|
||||||
import com.android.settings.notification.ConfigureNotificationSettings;
|
import com.android.settings.notification.ConfigureNotificationSettings;
|
||||||
import com.android.settings.notification.NotificationAccessSettings;
|
import com.android.settings.notification.NotificationAccessSettings;
|
||||||
import com.android.settings.notification.NotificationStation;
|
import com.android.settings.notification.NotificationStation;
|
||||||
@@ -209,6 +210,7 @@ public class SettingsGateway {
|
|||||||
BatterySaverSettings.class.getName(),
|
BatterySaverSettings.class.getName(),
|
||||||
AppNotificationSettings.class.getName(),
|
AppNotificationSettings.class.getName(),
|
||||||
ChannelNotificationSettings.class.getName(),
|
ChannelNotificationSettings.class.getName(),
|
||||||
|
ChannelGroupNotificationSettings.class.getName(),
|
||||||
ApnSettings.class.getName(),
|
ApnSettings.class.getName(),
|
||||||
ApnEditor.class.getName(),
|
ApnEditor.class.getName(),
|
||||||
WifiCallingSettings.class.getName(),
|
WifiCallingSettings.class.getName(),
|
||||||
|
@@ -26,6 +26,7 @@ import android.os.Bundle;
|
|||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.support.v7.preference.PreferenceCategory;
|
import android.support.v7.preference.PreferenceCategory;
|
||||||
|
import android.support.v7.preference.PreferenceGroup;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -50,7 +51,6 @@ import java.util.Collections;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static android.app.NotificationManager.IMPORTANCE_LOW;
|
|
||||||
import static android.app.NotificationManager.IMPORTANCE_NONE;
|
import static android.app.NotificationManager.IMPORTANCE_NONE;
|
||||||
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
|
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ public class AppNotificationSettings extends NotificationSettingsBase {
|
|||||||
new AsyncTask<Void, Void, Void>() {
|
new AsyncTask<Void, Void, Void>() {
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... unused) {
|
protected Void doInBackground(Void... unused) {
|
||||||
mChannelGroupList = mBackend.getChannelGroups(mPkg, mUid).getList();
|
mChannelGroupList = mBackend.getGroups(mPkg, mUid).getList();
|
||||||
Collections.sort(mChannelGroupList, mChannelGroupComparator);
|
Collections.sort(mChannelGroupList, mChannelGroupComparator);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -115,7 +115,7 @@ public class AppNotificationSettings extends NotificationSettingsBase {
|
|||||||
if (getHost() == null) {
|
if (getHost() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
populateChannelList();
|
populateList();
|
||||||
addAppLinkPref();
|
addAppLinkPref();
|
||||||
}
|
}
|
||||||
}.execute();
|
}.execute();
|
||||||
@@ -144,7 +144,7 @@ public class AppNotificationSettings extends NotificationSettingsBase {
|
|||||||
getPreferenceScreen().addPreference(pref);
|
getPreferenceScreen().addPreference(pref);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateChannelList() {
|
private void populateList() {
|
||||||
if (!mChannelGroups.isEmpty()) {
|
if (!mChannelGroups.isEmpty()) {
|
||||||
// If there's anything in mChannelGroups, we've called populateChannelList twice.
|
// If there's anything in mChannelGroups, we've called populateChannelList twice.
|
||||||
// Clear out existing channels and log.
|
// Clear out existing channels and log.
|
||||||
@@ -166,30 +166,7 @@ public class AppNotificationSettings extends NotificationSettingsBase {
|
|||||||
empty.setEnabled(false);
|
empty.setEnabled(false);
|
||||||
groupCategory.addPreference(empty);
|
groupCategory.addPreference(empty);
|
||||||
} else {
|
} else {
|
||||||
for (NotificationChannelGroup group : mChannelGroupList) {
|
populateGroupList();
|
||||||
PreferenceCategory groupCategory = new PreferenceCategory(getPrefContext());
|
|
||||||
if (group.getId() == null) {
|
|
||||||
groupCategory.setTitle(mChannelGroupList.size() > 1
|
|
||||||
? R.string.notification_channels_other
|
|
||||||
: R.string.notification_channels);
|
|
||||||
groupCategory.setKey(KEY_GENERAL_CATEGORY);
|
|
||||||
} else {
|
|
||||||
groupCategory.setTitle(group.getName());
|
|
||||||
groupCategory.setKey(group.getId());
|
|
||||||
}
|
|
||||||
groupCategory.setOrderingAsAdded(true);
|
|
||||||
getPreferenceScreen().addPreference(groupCategory);
|
|
||||||
mChannelGroups.add(groupCategory);
|
|
||||||
|
|
||||||
final List<NotificationChannel> channels = group.getChannels();
|
|
||||||
Collections.sort(channels, mChannelComparator);
|
|
||||||
int N = channels.size();
|
|
||||||
for (int i = 0; i < N; i++) {
|
|
||||||
final NotificationChannel channel = channels.get(i);
|
|
||||||
populateSingleChannelPrefs(groupCategory, channel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int deletedChannelCount = mBackend.getDeletedChannelCount(mAppRow.pkg, mAppRow.uid);
|
int deletedChannelCount = mBackend.getDeletedChannelCount(mAppRow.pkg, mAppRow.uid);
|
||||||
if (deletedChannelCount > 0) {
|
if (deletedChannelCount > 0) {
|
||||||
mDeletedChannels = new FooterPreference(getPrefContext());
|
mDeletedChannels = new FooterPreference(getPrefContext());
|
||||||
@@ -202,48 +179,63 @@ public class AppNotificationSettings extends NotificationSettingsBase {
|
|||||||
getPreferenceScreen().addPreference(mDeletedChannels);
|
getPreferenceScreen().addPreference(mDeletedChannels);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDependents(mAppRow.banned);
|
updateDependents(mAppRow.banned);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateSingleChannelPrefs(PreferenceCategory groupCategory,
|
private void populateGroupList() {
|
||||||
final NotificationChannel channel) {
|
PreferenceCategory groupCategory = new PreferenceCategory(getPrefContext());
|
||||||
MasterSwitchPreference channelPref = new MasterSwitchPreference(
|
groupCategory.setTitle(R.string.notification_channels);
|
||||||
getPrefContext());
|
groupCategory.setKey(KEY_GENERAL_CATEGORY);
|
||||||
channelPref.setSwitchEnabled(mSuspendedAppsAdmin == null
|
groupCategory.setOrderingAsAdded(true);
|
||||||
&& isChannelBlockable(mAppRow.systemApp, channel)
|
getPreferenceScreen().addPreference(groupCategory);
|
||||||
&& isChannelConfigurable(channel));
|
mChannelGroups.add(groupCategory);
|
||||||
channelPref.setKey(channel.getId());
|
for (NotificationChannelGroup group : mChannelGroupList) {
|
||||||
channelPref.setTitle(channel.getName());
|
final List<NotificationChannel> channels = group.getChannels();
|
||||||
channelPref.setChecked(channel.getImportance() != IMPORTANCE_NONE);
|
int N = channels.size();
|
||||||
channelPref.setSummary(getImportanceSummary(channel));
|
// app defined groups with one channel and channels with no group display the channel
|
||||||
Bundle channelArgs = new Bundle();
|
// name and no summary and link directly to the channel page unless the group is blocked
|
||||||
channelArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid);
|
if ((group.getId() == null || N < 2) && !group.isBlocked()) {
|
||||||
channelArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, mPkg);
|
Collections.sort(channels, mChannelComparator);
|
||||||
channelArgs.putString(Settings.EXTRA_CHANNEL_ID, channel.getId());
|
for (int i = 0; i < N; i++) {
|
||||||
Intent channelIntent = Utils.onBuildStartFragmentIntent(getActivity(),
|
final NotificationChannel channel = channels.get(i);
|
||||||
ChannelNotificationSettings.class.getName(),
|
populateSingleChannelPrefs(groupCategory, channel, "");
|
||||||
channelArgs, null, R.string.notification_channel_title, null, false,
|
}
|
||||||
getMetricsCategory());
|
} else {
|
||||||
channelPref.setIntent(channelIntent);
|
populateGroupPreference(groupCategory, group, N);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
channelPref.setOnPreferenceChangeListener(
|
void populateGroupPreference(PreferenceGroup parent,
|
||||||
new Preference.OnPreferenceChangeListener() {
|
final NotificationChannelGroup group, int channelCount) {
|
||||||
@Override
|
MasterSwitchPreference groupPref = new MasterSwitchPreference(
|
||||||
public boolean onPreferenceChange(Preference preference,
|
getPrefContext());
|
||||||
Object o) {
|
groupPref.setSwitchEnabled(mSuspendedAppsAdmin == null
|
||||||
|
&& isChannelGroupBlockable(group));
|
||||||
|
groupPref.setKey(group.getId());
|
||||||
|
groupPref.setTitle(group.getName());
|
||||||
|
groupPref.setChecked(!group.isBlocked());
|
||||||
|
groupPref.setSummary(getResources().getQuantityString(
|
||||||
|
R.plurals.notification_group_summary, channelCount, channelCount));
|
||||||
|
Bundle groupArgs = new Bundle();
|
||||||
|
groupArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid);
|
||||||
|
groupArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, mPkg);
|
||||||
|
groupArgs.putString(Settings.EXTRA_CHANNEL_GROUP_ID, group.getId());
|
||||||
|
Intent groupIntent = Utils.onBuildStartFragmentIntent(getActivity(),
|
||||||
|
ChannelGroupNotificationSettings.class.getName(),
|
||||||
|
groupArgs, null, R.string.notification_group_title, null, false,
|
||||||
|
getMetricsCategory());
|
||||||
|
groupPref.setIntent(groupIntent);
|
||||||
|
|
||||||
|
groupPref.setOnPreferenceChangeListener(
|
||||||
|
(preference, o) -> {
|
||||||
boolean value = (Boolean) o;
|
boolean value = (Boolean) o;
|
||||||
int importance = value ? IMPORTANCE_LOW : IMPORTANCE_NONE;
|
group.setBlocked(!value);
|
||||||
channel.setImportance(importance);
|
mBackend.updateChannelGroup(mPkg, mUid, group);
|
||||||
channel.lockFields(
|
|
||||||
NotificationChannel.USER_LOCKED_IMPORTANCE);
|
|
||||||
channelPref.setSummary(getImportanceSummary(channel));
|
|
||||||
mBackend.updateChannel(mPkg, mUid, channel);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
groupCategory.addPreference(channelPref);
|
parent.addPreference(groupPref);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupBadge() {
|
void setupBadge() {
|
||||||
@@ -330,38 +322,6 @@ public class AppNotificationSettings extends NotificationSettingsBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getImportanceSummary(NotificationChannel channel) {
|
|
||||||
switch (channel.getImportance()) {
|
|
||||||
case NotificationManager.IMPORTANCE_UNSPECIFIED:
|
|
||||||
return getContext().getString(R.string.notification_importance_unspecified);
|
|
||||||
case NotificationManager.IMPORTANCE_NONE:
|
|
||||||
return getContext().getString(R.string.notification_toggle_off);
|
|
||||||
case NotificationManager.IMPORTANCE_MIN:
|
|
||||||
return getContext().getString(R.string.notification_importance_min);
|
|
||||||
case NotificationManager.IMPORTANCE_LOW:
|
|
||||||
return getContext().getString(R.string.notification_importance_low);
|
|
||||||
case NotificationManager.IMPORTANCE_DEFAULT:
|
|
||||||
return getContext().getString(R.string.notification_importance_default);
|
|
||||||
case NotificationManager.IMPORTANCE_HIGH:
|
|
||||||
case NotificationManager.IMPORTANCE_MAX:
|
|
||||||
default:
|
|
||||||
return getContext().getString(R.string.notification_importance_high);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Comparator<NotificationChannel> mChannelComparator =
|
|
||||||
new Comparator<NotificationChannel>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compare(NotificationChannel left, NotificationChannel right) {
|
|
||||||
if (left.isDeleted() != right.isDeleted()) {
|
|
||||||
return Boolean.compare(left.isDeleted(), right.isDeleted());
|
|
||||||
}
|
|
||||||
return left.getId().compareTo(right.getId());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private Comparator<NotificationChannelGroup> mChannelGroupComparator =
|
private Comparator<NotificationChannelGroup> mChannelGroupComparator =
|
||||||
new Comparator<NotificationChannelGroup>() {
|
new Comparator<NotificationChannelGroup>() {
|
||||||
|
|
||||||
|
@@ -0,0 +1,188 @@
|
|||||||
|
/*
|
||||||
|
* 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.app.Activity;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
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 com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.applications.LayoutPreference;
|
||||||
|
import com.android.settings.widget.EntityHeaderController;
|
||||||
|
import com.android.settingslib.widget.FooterPreference;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ChannelGroupNotificationSettings extends NotificationSettingsBase {
|
||||||
|
private static final String TAG = "ChannelGroupSettings";
|
||||||
|
|
||||||
|
private static String KEY_DELETED = "deleted";
|
||||||
|
|
||||||
|
private EntityHeaderController mHeaderPref;
|
||||||
|
private List<Preference> mChannels = new ArrayList();
|
||||||
|
private FooterPreference mDeletedChannels;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMetricsCategory() {
|
||||||
|
return MetricsEvent.NOTIFICATION_CHANNEL_GROUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null || mChannelGroup == null) {
|
||||||
|
Log.w(TAG, "Missing package or uid or packageinfo or group");
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getPreferenceScreen() != null) {
|
||||||
|
getPreferenceScreen().removeAll();
|
||||||
|
}
|
||||||
|
addPreferencesFromResource(R.xml.notification_settings);
|
||||||
|
setupBlock();
|
||||||
|
addHeaderPref();
|
||||||
|
addAppLinkPref();
|
||||||
|
addFooterPref();
|
||||||
|
populateChannelList();
|
||||||
|
|
||||||
|
updateDependents(mChannelGroup.isBlocked());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void setupBadge() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateChannelList() {
|
||||||
|
if (!mChannels.isEmpty()) {
|
||||||
|
// If there's anything in mChannels, we've called populateChannelList twice.
|
||||||
|
// Clear out existing channels and log.
|
||||||
|
Log.w(TAG, "Notification channel group posted twice to settings - old size " +
|
||||||
|
mChannels.size() + ", new size " + mChannels.size());
|
||||||
|
for (Preference p : mChannels) {
|
||||||
|
getPreferenceScreen().removePreference(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mChannelGroup.getChannels().isEmpty()) {
|
||||||
|
Preference empty = new Preference(getPrefContext());
|
||||||
|
empty.setTitle(R.string.no_channels);
|
||||||
|
empty.setEnabled(false);
|
||||||
|
getPreferenceScreen().addPreference(empty);
|
||||||
|
mChannels.add(empty);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
final List<NotificationChannel> channels = mChannelGroup.getChannels();
|
||||||
|
Collections.sort(channels, mChannelComparator);
|
||||||
|
for (NotificationChannel channel : channels) {
|
||||||
|
mChannels.add(populateSingleChannelPrefs(
|
||||||
|
getPreferenceScreen(), channel, getImportanceSummary(channel)));
|
||||||
|
}
|
||||||
|
|
||||||
|
int deletedChannelCount = mBackend.getDeletedChannelCount(mAppRow.pkg, mAppRow.uid);
|
||||||
|
if (deletedChannelCount > 0) {
|
||||||
|
mDeletedChannels = new FooterPreference(getPrefContext());
|
||||||
|
mDeletedChannels.setSelectable(false);
|
||||||
|
mDeletedChannels.setTitle(getResources().getQuantityString(
|
||||||
|
R.plurals.deleted_channels, deletedChannelCount, deletedChannelCount));
|
||||||
|
mDeletedChannels.setEnabled(false);
|
||||||
|
mDeletedChannels.setKey(KEY_DELETED);
|
||||||
|
mDeletedChannels.setOrder(ORDER_LAST);
|
||||||
|
getPreferenceScreen().addPreference(mDeletedChannels);
|
||||||
|
mChannels.add(mDeletedChannels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateDependents(mAppRow.banned);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addHeaderPref() {
|
||||||
|
ArrayMap<String, NotificationBackend.AppRow> rows = new ArrayMap<>();
|
||||||
|
rows.put(mAppRow.pkg, mAppRow);
|
||||||
|
collectConfigActivities(rows);
|
||||||
|
final Activity activity = getActivity();
|
||||||
|
mHeaderPref = EntityHeaderController
|
||||||
|
.newInstance(activity, this /* fragment */, null /* header */)
|
||||||
|
.setRecyclerView(getListView(), getLifecycle());
|
||||||
|
final Preference pref = mHeaderPref
|
||||||
|
.setIcon(mAppRow.icon)
|
||||||
|
.setLabel(mChannelGroup.getName())
|
||||||
|
.setSummary(mAppRow.label)
|
||||||
|
.setPackageName(mAppRow.pkg)
|
||||||
|
.setUid(mAppRow.uid)
|
||||||
|
.setButtonActions(EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE,
|
||||||
|
EntityHeaderController.ActionType.ACTION_NONE)
|
||||||
|
.setHasAppInfoLink(true)
|
||||||
|
.done(activity, getPrefContext());
|
||||||
|
getPreferenceScreen().addPreference(pref);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addFooterPref() {
|
||||||
|
if (!TextUtils.isEmpty(mChannelGroup.getDescription())) {
|
||||||
|
FooterPreference descPref = new FooterPreference(getPrefContext());
|
||||||
|
descPref.setOrder(ORDER_LAST);
|
||||||
|
descPref.setSelectable(false);
|
||||||
|
descPref.setTitle(mChannelGroup.getDescription());
|
||||||
|
getPreferenceScreen().addPreference(descPref);
|
||||||
|
mChannels.add(descPref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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(!mChannelGroup.isBlocked());
|
||||||
|
mSwitchBar.addOnSwitchChangeListener((switchView, isChecked) -> {
|
||||||
|
mChannelGroup.setBlocked(!isChecked);
|
||||||
|
mBackend.updateChannelGroup(mPkg, mUid, mChannelGroup);
|
||||||
|
updateDependents(!isChecked);
|
||||||
|
});
|
||||||
|
|
||||||
|
mBlockBar = new LayoutPreference(getPrefContext(), switchBarContainer);
|
||||||
|
mBlockBar.setOrder(ORDER_FIRST);
|
||||||
|
mBlockBar.setKey(KEY_BLOCK);
|
||||||
|
getPreferenceScreen().addPreference(mBlockBar);
|
||||||
|
|
||||||
|
if (!isChannelGroupBlockable(mChannelGroup)) {
|
||||||
|
setVisible(mBlockBar, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
setupBlockDesc(R.string.channel_group_notifications_off_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateDependents(boolean banned) {
|
||||||
|
for (Preference channel : mChannels) {
|
||||||
|
setVisible(channel, !banned);
|
||||||
|
}
|
||||||
|
if (mAppLink != null) {
|
||||||
|
setVisible(mAppLink, !banned);
|
||||||
|
}
|
||||||
|
setVisible(mBlockBar, isChannelGroupBlockable(mChannelGroup));
|
||||||
|
setVisible(mBlockedDesc, mAppRow.banned || mChannelGroup.isBlocked());
|
||||||
|
}
|
||||||
|
}
|
@@ -26,6 +26,7 @@ import android.os.Bundle;
|
|||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
|
import android.support.v7.preference.PreferenceGroup;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.BidiFormatter;
|
import android.text.BidiFormatter;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
@@ -57,6 +58,7 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
|
|||||||
private static final String KEY_VIBRATE = "vibrate";
|
private static final String KEY_VIBRATE = "vibrate";
|
||||||
private static final String KEY_RINGTONE = "ringtone";
|
private static final String KEY_RINGTONE = "ringtone";
|
||||||
private static final String KEY_IMPORTANCE = "importance";
|
private static final String KEY_IMPORTANCE = "importance";
|
||||||
|
private static final String KEY_ADVANCED = "advanced";
|
||||||
|
|
||||||
private Preference mImportance;
|
private Preference mImportance;
|
||||||
private RestrictedSwitchPreference mLights;
|
private RestrictedSwitchPreference mLights;
|
||||||
@@ -65,6 +67,7 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
|
|||||||
private FooterPreference mFooter;
|
private FooterPreference mFooter;
|
||||||
private NotificationChannelGroup mChannelGroup;
|
private NotificationChannelGroup mChannelGroup;
|
||||||
private EntityHeaderController mHeaderPref;
|
private EntityHeaderController mHeaderPref;
|
||||||
|
private PreferenceGroup mAdvanced;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMetricsCategory() {
|
public int getMetricsCategory() {
|
||||||
@@ -96,24 +99,10 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
|
|||||||
populateUpgradedChannelPrefs();
|
populateUpgradedChannelPrefs();
|
||||||
|
|
||||||
if (mChannel.getGroup() != null) {
|
if (mChannel.getGroup() != null) {
|
||||||
// Go look up group name
|
mChannelGroup = mBackend.getGroup(mPkg, mUid, mChannel.getGroup());
|
||||||
new AsyncTask<Void, Void, Void>() {
|
if (mChannelGroup != null) {
|
||||||
@Override
|
|
||||||
protected Void doInBackground(Void... unused) {
|
|
||||||
if (mChannel.getGroup() != null) {
|
|
||||||
mChannelGroup = mBackend.getGroup(mChannel.getGroup(), mPkg, mUid);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Void unused) {
|
|
||||||
if (getHost() == null || mChannelGroup == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setChannelGroupLabel(mChannelGroup.getName());
|
setChannelGroupLabel(mChannelGroup.getName());
|
||||||
}
|
}
|
||||||
}.execute();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,6 +118,7 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
|
|||||||
setupVibrate();
|
setupVibrate();
|
||||||
setupRingtone();
|
setupRingtone();
|
||||||
setupImportance();
|
setupImportance();
|
||||||
|
mAdvanced = (PreferenceGroup) findPreference(KEY_ADVANCED);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addHeaderPref() {
|
private void addHeaderPref() {
|
||||||
@@ -272,7 +262,7 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
|
|||||||
mBlockBar.setKey(KEY_BLOCK);
|
mBlockBar.setKey(KEY_BLOCK);
|
||||||
getPreferenceScreen().addPreference(mBlockBar);
|
getPreferenceScreen().addPreference(mBlockBar);
|
||||||
|
|
||||||
if (!isChannelBlockable(mAppRow.systemApp, mChannel)) {
|
if (!isChannelBlockable(mChannel)) {
|
||||||
setVisible(mBlockBar, false);
|
setVisible(mBlockBar, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,6 +363,7 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
|
|||||||
if (mShowLegacyChannelConfig) {
|
if (mShowLegacyChannelConfig) {
|
||||||
setVisible(mImportanceToggle, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN));
|
setVisible(mImportanceToggle, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN));
|
||||||
} else {
|
} else {
|
||||||
|
setVisible(mAdvanced, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN));
|
||||||
setVisible(mImportance, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN));
|
setVisible(mImportance, checkCanBeVisible(NotificationManager.IMPORTANCE_MIN));
|
||||||
setVisible(mLights, checkCanBeVisible(
|
setVisible(mLights, checkCanBeVisible(
|
||||||
NotificationManager.IMPORTANCE_DEFAULT) && canPulseLight());
|
NotificationManager.IMPORTANCE_DEFAULT) && canPulseLight());
|
||||||
|
@@ -136,8 +136,7 @@ public class NotificationBackend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NotificationChannelGroup getGroup(String pkg, int uid, String groupId) {
|
||||||
public NotificationChannelGroup getGroup(String groupId, String pkg, int uid) {
|
|
||||||
if (groupId == null) {
|
if (groupId == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -149,7 +148,19 @@ public class NotificationBackend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ParceledListSlice<NotificationChannelGroup> getChannelGroups(String pkg, int uid) {
|
public NotificationChannelGroup getGroupWithChannels(String pkg, int uid, String groupId) {
|
||||||
|
if (groupId == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return sINM.getPopulatedNotificationChannelGroupForPackage(pkg, uid, groupId, true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.w(TAG, "Error calling NoMan", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParceledListSlice<NotificationChannelGroup> getGroups(String pkg, int uid) {
|
||||||
try {
|
try {
|
||||||
return sINM.getNotificationChannelGroupsForPackage(pkg, uid, false);
|
return sINM.getNotificationChannelGroupsForPackage(pkg, uid, false);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -166,6 +177,15 @@ public class NotificationBackend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateChannelGroup(String pkg, int uid, NotificationChannelGroup group) {
|
||||||
|
try {
|
||||||
|
sINM.updateNotificationChannelGroupForPackage(pkg, uid, group);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.w(TAG, "Error calling NoMan", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getDeletedChannelCount(String pkg, int uid) {
|
public int getDeletedChannelCount(String pkg, int uid) {
|
||||||
try {
|
try {
|
||||||
return sINM.getDeletedChannelCount(pkg, uid);
|
return sINM.getDeletedChannelCount(pkg, uid);
|
||||||
|
@@ -24,8 +24,10 @@ import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
|
|||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.SettingsPreferenceFragment;
|
import com.android.settings.SettingsPreferenceFragment;
|
||||||
|
import com.android.settings.Utils;
|
||||||
import com.android.settings.applications.AppInfoBase;
|
import com.android.settings.applications.AppInfoBase;
|
||||||
import com.android.settings.applications.LayoutPreference;
|
import com.android.settings.applications.LayoutPreference;
|
||||||
|
import com.android.settings.widget.MasterSwitchPreference;
|
||||||
import com.android.settings.widget.SwitchBar;
|
import com.android.settings.widget.SwitchBar;
|
||||||
import com.android.settingslib.RestrictedLockUtils;
|
import com.android.settingslib.RestrictedLockUtils;
|
||||||
import com.android.settingslib.RestrictedSwitchPreference;
|
import com.android.settingslib.RestrictedSwitchPreference;
|
||||||
@@ -33,6 +35,7 @@ import com.android.settingslib.widget.FooterPreference;
|
|||||||
|
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationChannel;
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationChannelGroup;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
@@ -51,8 +54,8 @@ import android.os.UserHandle;
|
|||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.service.notification.NotificationListenerService;
|
import android.service.notification.NotificationListenerService;
|
||||||
import android.support.v7.preference.DropDownPreference;
|
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
|
import android.support.v7.preference.PreferenceGroup;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -61,6 +64,7 @@ import android.widget.Toast;
|
|||||||
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
abstract public class NotificationSettingsBase extends SettingsPreferenceFragment {
|
abstract public class NotificationSettingsBase extends SettingsPreferenceFragment {
|
||||||
@@ -106,6 +110,7 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen
|
|||||||
protected EnforcedAdmin mSuspendedAppsAdmin;
|
protected EnforcedAdmin mSuspendedAppsAdmin;
|
||||||
protected boolean mDndVisualEffectsSuppressed;
|
protected boolean mDndVisualEffectsSuppressed;
|
||||||
|
|
||||||
|
protected NotificationChannelGroup mChannelGroup;
|
||||||
protected NotificationChannel mChannel;
|
protected NotificationChannel mChannel;
|
||||||
protected NotificationBackend.AppRow mAppRow;
|
protected NotificationBackend.AppRow mAppRow;
|
||||||
protected boolean mShowLegacyChannelConfig = false;
|
protected boolean mShowLegacyChannelConfig = false;
|
||||||
@@ -185,6 +190,11 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen
|
|||||||
mChannel = (args != null && args.containsKey(Settings.EXTRA_CHANNEL_ID)) ?
|
mChannel = (args != null && args.containsKey(Settings.EXTRA_CHANNEL_ID)) ?
|
||||||
mBackend.getChannel(mPkg, mUid, args.getString(Settings.EXTRA_CHANNEL_ID)) : null;
|
mBackend.getChannel(mPkg, mUid, args.getString(Settings.EXTRA_CHANNEL_ID)) : null;
|
||||||
|
|
||||||
|
mChannelGroup = (args != null && args.containsKey(Settings.EXTRA_CHANNEL_GROUP_ID)) ?
|
||||||
|
mBackend.getGroupWithChannels(mPkg, mUid,
|
||||||
|
args.getString(Settings.EXTRA_CHANNEL_GROUP_ID))
|
||||||
|
: null;
|
||||||
|
|
||||||
mSuspendedAppsAdmin = RestrictedLockUtils.checkIfApplicationIsSuspended(
|
mSuspendedAppsAdmin = RestrictedLockUtils.checkIfApplicationIsSuspended(
|
||||||
mContext, mPkg, mUserId);
|
mContext, mPkg, mUserId);
|
||||||
NotificationManager.Policy policy = mNm.getNotificationPolicy();
|
NotificationManager.Policy policy = mNm.getNotificationPolicy();
|
||||||
@@ -249,6 +259,10 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen
|
|||||||
if (mChannel != null) {
|
if (mChannel != null) {
|
||||||
row.settingsIntent.putExtra(Notification.EXTRA_CHANNEL_ID, mChannel.getId());
|
row.settingsIntent.putExtra(Notification.EXTRA_CHANNEL_ID, mChannel.getId());
|
||||||
}
|
}
|
||||||
|
if (mChannelGroup != null) {
|
||||||
|
row.settingsIntent.putExtra(
|
||||||
|
Notification.EXTRA_CHANNEL_GROUP_ID, mChannelGroup.getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,7 +290,7 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen
|
|||||||
protected void addAppLinkPref() {
|
protected void addAppLinkPref() {
|
||||||
if (mAppRow.settingsIntent != null && mAppLink == null) {
|
if (mAppRow.settingsIntent != null && mAppLink == null) {
|
||||||
addPreferencesFromResource(R.xml.inapp_notification_settings);
|
addPreferencesFromResource(R.xml.inapp_notification_settings);
|
||||||
mAppLink = (Preference) findPreference(KEY_APP_LINK);
|
mAppLink = findPreference(KEY_APP_LINK);
|
||||||
mAppLink.setIntent(mAppRow.settingsIntent);
|
mAppLink.setIntent(mAppRow.settingsIntent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -392,16 +406,56 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void setupBlockDesc(int summaryResId) {
|
protected void setupBlockDesc(int summaryResId) {
|
||||||
mBlockedDesc = (FooterPreference) getPreferenceScreen().findPreference(
|
|
||||||
KEY_BLOCKED_DESC);
|
|
||||||
mBlockedDesc = new FooterPreference(getPrefContext());
|
mBlockedDesc = new FooterPreference(getPrefContext());
|
||||||
mBlockedDesc.setSelectable(false);
|
mBlockedDesc.setSelectable(false);
|
||||||
mBlockedDesc.setTitle(summaryResId);
|
mBlockedDesc.setTitle(summaryResId);
|
||||||
mBlockedDesc.setEnabled(false);
|
mBlockedDesc.setEnabled(false);
|
||||||
mBlockedDesc.setOrder(50);
|
mBlockedDesc.setOrder(50);
|
||||||
|
mBlockedDesc.setKey(KEY_BLOCKED_DESC);
|
||||||
getPreferenceScreen().addPreference(mBlockedDesc);
|
getPreferenceScreen().addPreference(mBlockedDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Preference populateSingleChannelPrefs(PreferenceGroup parent,
|
||||||
|
final NotificationChannel channel, String summary) {
|
||||||
|
MasterSwitchPreference channelPref = new MasterSwitchPreference(
|
||||||
|
getPrefContext());
|
||||||
|
channelPref.setSwitchEnabled(mSuspendedAppsAdmin == null
|
||||||
|
&& isChannelBlockable(channel)
|
||||||
|
&& isChannelConfigurable(channel));
|
||||||
|
channelPref.setKey(channel.getId());
|
||||||
|
channelPref.setTitle(channel.getName());
|
||||||
|
channelPref.setChecked(channel.getImportance() != IMPORTANCE_NONE);
|
||||||
|
channelPref.setSummary(summary);
|
||||||
|
Bundle channelArgs = new Bundle();
|
||||||
|
channelArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid);
|
||||||
|
channelArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, mPkg);
|
||||||
|
channelArgs.putString(Settings.EXTRA_CHANNEL_ID, channel.getId());
|
||||||
|
Intent channelIntent = Utils.onBuildStartFragmentIntent(getActivity(),
|
||||||
|
ChannelNotificationSettings.class.getName(),
|
||||||
|
channelArgs, null, R.string.notification_channel_title, null, false,
|
||||||
|
getMetricsCategory());
|
||||||
|
channelPref.setIntent(channelIntent);
|
||||||
|
|
||||||
|
channelPref.setOnPreferenceChangeListener(
|
||||||
|
new Preference.OnPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference,
|
||||||
|
Object o) {
|
||||||
|
boolean value = (Boolean) o;
|
||||||
|
int importance = value ? IMPORTANCE_LOW : IMPORTANCE_NONE;
|
||||||
|
channel.setImportance(importance);
|
||||||
|
channel.lockFields(
|
||||||
|
NotificationChannel.USER_LOCKED_IMPORTANCE);
|
||||||
|
channelPref.setSummary(summary);
|
||||||
|
mBackend.updateChannel(mPkg, mUid, channel);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
parent.addPreference(channelPref);
|
||||||
|
return channelPref;
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean checkCanBeVisible(int minImportanceVisible) {
|
protected boolean checkCanBeVisible(int minImportanceVisible) {
|
||||||
int importance = mChannel.getImportance();
|
int importance = mChannel.getImportance();
|
||||||
if (importance == NotificationManager.IMPORTANCE_UNSPECIFIED) {
|
if (importance == NotificationManager.IMPORTANCE_UNSPECIFIED) {
|
||||||
@@ -410,6 +464,26 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen
|
|||||||
return importance >= minImportanceVisible;
|
return importance >= minImportanceVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String getImportanceSummary(NotificationChannel channel) {
|
||||||
|
switch (channel.getImportance()) {
|
||||||
|
case NotificationManager.IMPORTANCE_UNSPECIFIED:
|
||||||
|
return getContext().getString(R.string.notification_importance_unspecified);
|
||||||
|
case NotificationManager.IMPORTANCE_NONE:
|
||||||
|
return getContext().getString(R.string.notification_toggle_off);
|
||||||
|
case NotificationManager.IMPORTANCE_MIN:
|
||||||
|
return getContext().getString(R.string.notification_importance_min);
|
||||||
|
case NotificationManager.IMPORTANCE_LOW:
|
||||||
|
return getContext().getString(R.string.notification_importance_low);
|
||||||
|
case NotificationManager.IMPORTANCE_DEFAULT:
|
||||||
|
return getContext().getString(R.string.notification_importance_default);
|
||||||
|
case NotificationManager.IMPORTANCE_HIGH:
|
||||||
|
case NotificationManager.IMPORTANCE_MAX:
|
||||||
|
default:
|
||||||
|
return getContext().getString(R.string.notification_importance_high);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void setRestrictedIfNotificationFeaturesDisabled(CharSequence entry,
|
private void setRestrictedIfNotificationFeaturesDisabled(CharSequence entry,
|
||||||
CharSequence entryValue, int keyguardNotificationFeatures) {
|
CharSequence entryValue, int keyguardNotificationFeatures) {
|
||||||
RestrictedLockUtils.EnforcedAdmin admin =
|
RestrictedLockUtils.EnforcedAdmin admin =
|
||||||
@@ -459,7 +533,7 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen
|
|||||||
return !channel.getId().equals(mAppRow.lockedChannelId);
|
return !channel.getId().equals(mAppRow.lockedChannelId);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isChannelBlockable(boolean systemApp, NotificationChannel channel) {
|
protected boolean isChannelBlockable(NotificationChannel channel) {
|
||||||
if (!mAppRow.systemApp) {
|
if (!mAppRow.systemApp) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -468,6 +542,14 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen
|
|||||||
|| channel.getImportance() == NotificationManager.IMPORTANCE_NONE;
|
|| channel.getImportance() == NotificationManager.IMPORTANCE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean isChannelGroupBlockable(NotificationChannelGroup group) {
|
||||||
|
if (!mAppRow.systemApp) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return group.isBlocked();
|
||||||
|
}
|
||||||
|
|
||||||
protected void startListeningToPackageRemove() {
|
protected void startListeningToPackageRemove() {
|
||||||
if (mListeningToPackageRemove) {
|
if (mListeningToPackageRemove) {
|
||||||
return;
|
return;
|
||||||
@@ -501,4 +583,12 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
protected Comparator<NotificationChannel> mChannelComparator =
|
||||||
|
(left, right) -> {
|
||||||
|
if (left.isDeleted() != right.isDeleted()) {
|
||||||
|
return Boolean.compare(left.isDeleted(), right.isDeleted());
|
||||||
|
}
|
||||||
|
return left.getId().compareTo(right.getId());
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,7 @@ com.android.settings.inputmethod.UserDictionaryList
|
|||||||
com.android.settings.deviceinfo.Status
|
com.android.settings.deviceinfo.Status
|
||||||
com.android.settings.datausage.DataSaverSummary
|
com.android.settings.datausage.DataSaverSummary
|
||||||
com.android.settings.notification.ChannelNotificationSettings
|
com.android.settings.notification.ChannelNotificationSettings
|
||||||
|
com.android.settings.notification.ChannelGroupNotificationSettings
|
||||||
com.android.settings.datausage.AppDataUsage
|
com.android.settings.datausage.AppDataUsage
|
||||||
com.android.settings.accessibility.FontSizePreferenceFragmentForSetupWizard
|
com.android.settings.accessibility.FontSizePreferenceFragmentForSetupWizard
|
||||||
com.android.settings.applications.ManageDomainUrls
|
com.android.settings.applications.ManageDomainUrls
|
||||||
|
@@ -16,7 +16,29 @@
|
|||||||
|
|
||||||
package com.android.settings.notification;
|
package com.android.settings.notification;
|
||||||
|
|
||||||
|
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
|
||||||
|
import static android.support.test.espresso.Espresso.onView;
|
||||||
|
import static android.support.test.espresso.action.ViewActions.click;
|
||||||
|
import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
|
||||||
|
import static android.support.test.espresso.assertion.ViewAssertions.matches;
|
||||||
|
import android.support.test.espresso.intent.Intents;
|
||||||
|
|
||||||
|
import static android.support.test.espresso.intent.Intents.intended;
|
||||||
|
import static android.support.test.espresso.intent.matcher.IntentMatchers.hasExtra;
|
||||||
|
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
|
||||||
|
import static android.support.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
|
||||||
|
import static android.support.test.espresso.matcher.ViewMatchers.withId;
|
||||||
|
import static android.support.test.espresso.matcher.ViewMatchers.withText;
|
||||||
|
|
||||||
|
import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.allOf;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import android.app.Instrumentation;
|
import android.app.Instrumentation;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationChannelGroup;
|
||||||
|
import android.app.NotificationManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
@@ -29,12 +51,6 @@ import org.junit.Before;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import static android.support.test.espresso.Espresso.onView;
|
|
||||||
import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
|
|
||||||
import static android.support.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
|
|
||||||
import static android.support.test.espresso.matcher.ViewMatchers.withId;
|
|
||||||
import static org.hamcrest.Matchers.allOf;
|
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public class AppNotificationSettingsTest {
|
public class AppNotificationSettingsTest {
|
||||||
@@ -42,10 +58,29 @@ public class AppNotificationSettingsTest {
|
|||||||
private Context mTargetContext;
|
private Context mTargetContext;
|
||||||
private Instrumentation mInstrumentation;
|
private Instrumentation mInstrumentation;
|
||||||
|
|
||||||
|
NotificationManager mNm;
|
||||||
|
private NotificationChannelGroup mGroup1;
|
||||||
|
private NotificationChannel mGroup1Channel1;
|
||||||
|
private NotificationChannel mGroup1Channel2;
|
||||||
|
private NotificationChannelGroup mGroup2;
|
||||||
|
private NotificationChannel mGroup2Channel1;
|
||||||
|
private NotificationChannel mUngroupedChannel;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
mInstrumentation = InstrumentationRegistry.getInstrumentation();
|
mInstrumentation = InstrumentationRegistry.getInstrumentation();
|
||||||
mTargetContext = mInstrumentation.getTargetContext();
|
mTargetContext = mInstrumentation.getTargetContext();
|
||||||
|
mNm = (NotificationManager) mTargetContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
|
mGroup1 = new NotificationChannelGroup(this.getClass().getName() + "1", "group1");
|
||||||
|
mGroup2 = new NotificationChannelGroup(this.getClass().getName() + "2", "group2");
|
||||||
|
mNm.createNotificationChannelGroup(mGroup1);
|
||||||
|
mNm.createNotificationChannelGroup(mGroup2);
|
||||||
|
|
||||||
|
mGroup1Channel1 = createChannel(mGroup1, this.getClass().getName()+ "c1-1");
|
||||||
|
mGroup1Channel2 = createChannel(mGroup1, this.getClass().getName()+ "c1-2");
|
||||||
|
mGroup2Channel1 = createChannel(mGroup2, this.getClass().getName()+ "c2-1");
|
||||||
|
mUngroupedChannel = createChannel(null, this.getClass().getName()+ "c");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -60,4 +95,72 @@ public class AppNotificationSettingsTest {
|
|||||||
.check(doesNotExist());
|
.check(doesNotExist());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void launchNotificationSetting_showGroupsWithMultipleChannels() {
|
||||||
|
final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
|
||||||
|
.putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName());
|
||||||
|
mInstrumentation.startActivitySync(intent);
|
||||||
|
onView(allOf(withText(mGroup1.getName().toString()))).check(
|
||||||
|
matches(isDisplayed()));
|
||||||
|
try {
|
||||||
|
onView(allOf(withText(mGroup1Channel1.getName().toString())))
|
||||||
|
.check(matches(isDisplayed()));
|
||||||
|
fail("Channel erroneously appearing");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
// links to group page
|
||||||
|
Intents.init();
|
||||||
|
onView(allOf(withText(mGroup1.getName().toString()))).perform(click());
|
||||||
|
intended(allOf(hasExtra(EXTRA_SHOW_FRAGMENT,
|
||||||
|
ChannelGroupNotificationSettings.class.getName())));
|
||||||
|
Intents.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void launchNotificationSetting_showUngroupedChannels() {
|
||||||
|
final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
|
||||||
|
.putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName());
|
||||||
|
mInstrumentation.startActivitySync(intent);
|
||||||
|
onView(allOf(withText(mUngroupedChannel.getName().toString())))
|
||||||
|
.check(matches(isDisplayed()));
|
||||||
|
// links directly to channel page
|
||||||
|
Intents.init();
|
||||||
|
onView(allOf(withText(mUngroupedChannel.getName().toString()))).perform(click());
|
||||||
|
intended(allOf(hasExtra(EXTRA_SHOW_FRAGMENT, ChannelNotificationSettings.class.getName())));
|
||||||
|
Intents.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void launchNotificationSetting_showGroupsWithOneChannel() {
|
||||||
|
final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
|
||||||
|
.putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName());
|
||||||
|
mInstrumentation.startActivitySync(intent);
|
||||||
|
|
||||||
|
onView(allOf(withText(mGroup2Channel1.getName().toString())))
|
||||||
|
.check(matches(isDisplayed()));
|
||||||
|
try {
|
||||||
|
onView(allOf(withText(mGroup2.getName().toString()))).check(
|
||||||
|
matches(isDisplayed()));
|
||||||
|
fail("Group erroneously appearing");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
|
||||||
|
// links directly to channel page
|
||||||
|
Intents.init();
|
||||||
|
onView(allOf(withText(mGroup2Channel1.getName().toString()))).perform(click());
|
||||||
|
intended(allOf(hasExtra(EXTRA_SHOW_FRAGMENT, ChannelNotificationSettings.class.getName())));
|
||||||
|
Intents.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
private NotificationChannel createChannel(NotificationChannelGroup group,
|
||||||
|
String id) {
|
||||||
|
NotificationChannel channel = new NotificationChannel(id, id, IMPORTANCE_DEFAULT);
|
||||||
|
if (group != null) {
|
||||||
|
channel.setGroup(group.getId());
|
||||||
|
}
|
||||||
|
mNm.createNotificationChannel(channel);
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* 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.NotificationManager.IMPORTANCE_HIGH;
|
||||||
|
import static android.app.NotificationManager.IMPORTANCE_MIN;
|
||||||
|
import static android.support.test.espresso.Espresso.onView;
|
||||||
|
import static android.support.test.espresso.assertion.ViewAssertions.matches;
|
||||||
|
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
|
||||||
|
import static android.support.test.espresso.matcher.ViewMatchers.withId;
|
||||||
|
import static android.support.test.espresso.matcher.ViewMatchers.withText;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.allOf;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import android.app.INotificationManager;
|
||||||
|
import android.app.Instrumentation;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationChannelGroup;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Process;
|
||||||
|
import android.os.ServiceManager;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.support.test.InstrumentationRegistry;
|
||||||
|
import android.support.test.filters.SmallTest;
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
@SmallTest
|
||||||
|
public class ChannelGroupNotificationSettingsTest {
|
||||||
|
|
||||||
|
private Context mTargetContext;
|
||||||
|
private Instrumentation mInstrumentation;
|
||||||
|
private NotificationManager mNm;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
mInstrumentation = InstrumentationRegistry.getInstrumentation();
|
||||||
|
mTargetContext = mInstrumentation.getTargetContext();
|
||||||
|
mNm = (NotificationManager) mTargetContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void launchNotificationSetting_displaysChannels() {
|
||||||
|
NotificationChannelGroup group =
|
||||||
|
new NotificationChannelGroup(this.getClass().getName(), this.getClass().getName());
|
||||||
|
group.setDescription("description");
|
||||||
|
NotificationChannel channel = new NotificationChannel(this.getClass().getName(),
|
||||||
|
"channel" + this.getClass().getName(), IMPORTANCE_MIN);
|
||||||
|
channel.setGroup(this.getClass().getName());
|
||||||
|
NotificationChannel channel2 = new NotificationChannel("2"+this.getClass().getName(),
|
||||||
|
"2channel" + this.getClass().getName(), IMPORTANCE_MIN);
|
||||||
|
channel2.setGroup(this.getClass().getName());
|
||||||
|
|
||||||
|
mNm.createNotificationChannelGroup(group);
|
||||||
|
mNm.createNotificationChannel(channel);
|
||||||
|
mNm.createNotificationChannel(channel2);
|
||||||
|
|
||||||
|
final Intent intent = new Intent(Settings.ACTION_CHANNEL_GROUP_NOTIFICATION_SETTINGS)
|
||||||
|
.putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName())
|
||||||
|
.putExtra(Settings.EXTRA_CHANNEL_GROUP_ID, group.getId());
|
||||||
|
|
||||||
|
mInstrumentation.startActivitySync(intent);
|
||||||
|
|
||||||
|
onView(allOf(withText(group.getName().toString()))).check(matches(isDisplayed()));
|
||||||
|
onView(allOf(withText(channel.getName().toString()))).check(
|
||||||
|
matches(isDisplayed()));
|
||||||
|
onView(allOf(withText(group.getDescription().toString()))).check(
|
||||||
|
matches(isDisplayed()));
|
||||||
|
onView(allOf(withText(channel2.getName().toString()))).check(
|
||||||
|
matches(isDisplayed()));
|
||||||
|
try {
|
||||||
|
onView(allOf(withText("Android is blocking this group of notifications from"
|
||||||
|
+ " appearing on this device"))).check(matches(isDisplayed()));
|
||||||
|
fail("Blocking footer erroneously appearing");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void launchNotificationSettings_blockedGroup() throws Exception {
|
||||||
|
NotificationChannelGroup blocked =
|
||||||
|
new NotificationChannelGroup("blocked", "blocked");
|
||||||
|
NotificationChannel channel =
|
||||||
|
new NotificationChannel("channel", "channel", IMPORTANCE_HIGH);
|
||||||
|
channel.setGroup(blocked.getId());
|
||||||
|
mNm.createNotificationChannelGroup(blocked);
|
||||||
|
mNm.createNotificationChannel(channel);
|
||||||
|
|
||||||
|
INotificationManager sINM = INotificationManager.Stub.asInterface(
|
||||||
|
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
|
||||||
|
blocked.setBlocked(true);
|
||||||
|
sINM.updateNotificationChannelGroupForPackage(
|
||||||
|
mTargetContext.getPackageName(), Process.myUid(), blocked);
|
||||||
|
|
||||||
|
final Intent intent = new Intent(Settings.ACTION_CHANNEL_GROUP_NOTIFICATION_SETTINGS)
|
||||||
|
.putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName())
|
||||||
|
.putExtra(Settings.EXTRA_CHANNEL_GROUP_ID, blocked.getId());
|
||||||
|
mInstrumentation.startActivitySync(intent);
|
||||||
|
|
||||||
|
onView(allOf(withText("Off"), isDisplayed())).check(matches(isDisplayed()));
|
||||||
|
onView(allOf(withText("Android is blocking this group of notifications from"
|
||||||
|
+ " appearing on this device"))).check(matches(isDisplayed()));
|
||||||
|
|
||||||
|
try {
|
||||||
|
onView(allOf(withText(channel.getName().toString()))).check(matches(isDisplayed()));
|
||||||
|
fail("settings appearing for blocked group");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* 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.NotificationManager.IMPORTANCE_MIN;
|
||||||
|
import static android.app.NotificationManager.IMPORTANCE_NONE;
|
||||||
|
import static android.support.test.espresso.Espresso.onView;
|
||||||
|
import static android.support.test.espresso.assertion.ViewAssertions.matches;
|
||||||
|
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
|
||||||
|
import static android.support.test.espresso.matcher.ViewMatchers.withId;
|
||||||
|
import static android.support.test.espresso.matcher.ViewMatchers.withText;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.allOf;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import android.app.INotificationManager;
|
||||||
|
import android.app.Instrumentation;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Process;
|
||||||
|
import android.os.ServiceManager;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.support.test.InstrumentationRegistry;
|
||||||
|
import android.support.test.filters.SmallTest;
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
@SmallTest
|
||||||
|
public class ChannelNotificationSettingsTest {
|
||||||
|
|
||||||
|
private Context mTargetContext;
|
||||||
|
private Instrumentation mInstrumentation;
|
||||||
|
private NotificationChannel mNotificationChannel;
|
||||||
|
private NotificationManager mNm;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
mInstrumentation = InstrumentationRegistry.getInstrumentation();
|
||||||
|
mTargetContext = mInstrumentation.getTargetContext();
|
||||||
|
|
||||||
|
mNm = (NotificationManager) mTargetContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
mNotificationChannel = new NotificationChannel(this.getClass().getName(),
|
||||||
|
this.getClass().getName(), IMPORTANCE_MIN);
|
||||||
|
mNm.createNotificationChannel(mNotificationChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void launchNotificationSetting_shouldNotCrash() {
|
||||||
|
final Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
|
||||||
|
.putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName())
|
||||||
|
.putExtra(Settings.EXTRA_CHANNEL_ID, mNotificationChannel.getId());
|
||||||
|
mInstrumentation.startActivitySync(intent);
|
||||||
|
|
||||||
|
onView(allOf(withText(mNotificationChannel.getName().toString()))).check(
|
||||||
|
matches(isDisplayed()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void launchNotificationSettings_blockedChannel() throws Exception {
|
||||||
|
NotificationChannel blocked =
|
||||||
|
new NotificationChannel("blocked", "blocked", IMPORTANCE_NONE);
|
||||||
|
mNm.createNotificationChannel(blocked);
|
||||||
|
|
||||||
|
INotificationManager sINM = INotificationManager.Stub.asInterface(
|
||||||
|
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
|
||||||
|
blocked.setImportance(IMPORTANCE_NONE);
|
||||||
|
sINM.updateNotificationChannelForPackage(
|
||||||
|
mTargetContext.getPackageName(), Process.myUid(), blocked);
|
||||||
|
|
||||||
|
final Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
|
||||||
|
.putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName())
|
||||||
|
.putExtra(Settings.EXTRA_CHANNEL_ID, blocked.getId());
|
||||||
|
mInstrumentation.startActivitySync(intent);
|
||||||
|
|
||||||
|
onView(allOf(withText("Off"), isDisplayed())).check(matches(isDisplayed()));
|
||||||
|
onView(allOf(withText("Android is blocking this category of notifications from"
|
||||||
|
+ " appearing on this device"))).check(matches(isDisplayed()));
|
||||||
|
|
||||||
|
try {
|
||||||
|
onView(allOf(withText("On the lock screen"))).check(matches(isDisplayed()));
|
||||||
|
fail("settings appearing for blocked channel");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user