Separate conversations from channels
Test: atest Bug: 137397357 Change-Id: I15c360e8ef89f9fcb8db92678dd02a2c6fe083c5
This commit is contained in:
@@ -17,6 +17,8 @@ package com.android.settings.notification;
|
||||
|
||||
import static android.app.NotificationManager.IMPORTANCE_NONE;
|
||||
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
|
||||
import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC;
|
||||
import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED;
|
||||
|
||||
import android.app.INotificationManager;
|
||||
import android.app.NotificationChannel;
|
||||
@@ -29,13 +31,17 @@ import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.content.pm.ShortcutManager;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.service.notification.ConversationChannelWrapper;
|
||||
import android.service.notification.NotifyingApp;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.IconDrawableFactory;
|
||||
@@ -48,6 +54,7 @@ import com.android.settingslib.Utils;
|
||||
import com.android.settingslib.utils.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -154,7 +161,7 @@ public class NotificationBackend {
|
||||
try {
|
||||
if (onlyHasDefaultChannel(pkg, uid)) {
|
||||
NotificationChannel defaultChannel =
|
||||
getChannel(pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID);
|
||||
getChannel(pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID, null);
|
||||
defaultChannel.setImportance(enabled ? IMPORTANCE_UNSPECIFIED : IMPORTANCE_NONE);
|
||||
updateChannel(pkg, uid, defaultChannel);
|
||||
}
|
||||
@@ -204,13 +211,17 @@ public class NotificationBackend {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public NotificationChannel getChannel(String pkg, int uid, String channelId) {
|
||||
return getChannel(pkg, uid, channelId, null);
|
||||
}
|
||||
|
||||
public NotificationChannel getChannel(String pkg, int uid, String channelId,
|
||||
String conversationId) {
|
||||
if (channelId == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return sINM.getNotificationChannelForPackage(pkg, uid, channelId, true);
|
||||
return sINM.getNotificationChannelForPackage(pkg, uid, channelId, conversationId, true);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Error calling NoMan", e);
|
||||
return null;
|
||||
@@ -238,6 +249,15 @@ public class NotificationBackend {
|
||||
}
|
||||
}
|
||||
|
||||
public ParceledListSlice<ConversationChannelWrapper> getConversations(String pkg, int uid) {
|
||||
try {
|
||||
return sINM.getConversationsForPackage(pkg, uid);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Error calling NoMan", e);
|
||||
return ParceledListSlice.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all notification channels associated with the package and uid that will bypass DND
|
||||
*/
|
||||
@@ -474,6 +494,32 @@ public class NotificationBackend {
|
||||
}
|
||||
}
|
||||
|
||||
public ShortcutInfo getConversationInfo(Context context, String pkg, int uid, String id) {
|
||||
LauncherApps la = context.getSystemService(LauncherApps.class);
|
||||
|
||||
LauncherApps.ShortcutQuery query = new LauncherApps.ShortcutQuery()
|
||||
.setPackage(pkg)
|
||||
.setQueryFlags(FLAG_MATCH_DYNAMIC | FLAG_MATCH_PINNED)
|
||||
.setShortcutIds(Arrays.asList(id));
|
||||
List<ShortcutInfo> shortcuts = la.getShortcuts(
|
||||
query, UserHandle.of(UserHandle.getUserId(uid)));
|
||||
if (shortcuts != null && !shortcuts.isEmpty()) {
|
||||
return shortcuts.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Drawable getConversationDrawable(Context context, ShortcutInfo info) {
|
||||
LauncherApps la = context.getSystemService(LauncherApps.class);
|
||||
return la.getShortcutBadgedIconDrawable(info,
|
||||
context.getResources().getDisplayMetrics().densityDpi);
|
||||
}
|
||||
|
||||
public void requestPinShortcut(Context context, ShortcutInfo shortcutInfo) {
|
||||
ShortcutManager sm = context.getSystemService(ShortcutManager.class);
|
||||
sm.requestPinShortcut(shortcutInfo, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* NotificationsSentState contains how often an app sends notifications and how recently it sent
|
||||
* one.
|
||||
|
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.app;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Slog;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
|
||||
public class AddToHomeScreenPreferenceController extends NotificationPreferenceController
|
||||
implements PreferenceControllerMixin {
|
||||
|
||||
private static final String TAG = "HomeScreenPref";
|
||||
private static final String KEY = "add_to_home";
|
||||
|
||||
public AddToHomeScreenPreferenceController(Context context, NotificationBackend backend) {
|
||||
super(context, backend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
if (!super.isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
return mConversationInfo != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handlePreferenceTreeClick(Preference preference) {
|
||||
if (KEY.equals(preference.getKey())) {
|
||||
try {
|
||||
mBackend.requestPinShortcut(mContext, mConversationInfo);
|
||||
return true;
|
||||
} catch (SecurityException e) {
|
||||
Slog.e(TAG, "Cannot add to home screen", e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -84,7 +84,7 @@ public class AppBubbleNotificationSettings extends NotificationSettings implemen
|
||||
}
|
||||
|
||||
for (NotificationPreferenceController controller : mControllers) {
|
||||
controller.onResume(mAppRow, mChannel, mChannelGroup, mSuspendedAppsAdmin);
|
||||
controller.onResume(mAppRow, mChannel, mChannelGroup, null, null, mSuspendedAppsAdmin);
|
||||
controller.displayPreference(getPreferenceScreen());
|
||||
}
|
||||
updatePreferenceStates();
|
||||
|
@@ -80,7 +80,7 @@ public class AppNotificationSettings extends NotificationSettings {
|
||||
}
|
||||
|
||||
for (NotificationPreferenceController controller : mControllers) {
|
||||
controller.onResume(mAppRow, mChannel, mChannelGroup, mSuspendedAppsAdmin);
|
||||
controller.onResume(mAppRow, mChannel, mChannelGroup, null, null, mSuspendedAppsAdmin);
|
||||
controller.displayPreference(getPreferenceScreen());
|
||||
}
|
||||
updatePreferenceStates();
|
||||
@@ -123,6 +123,7 @@ public class AppNotificationSettings extends NotificationSettings {
|
||||
mControllers.add(new DeletedChannelsPreferenceController(context, mBackend));
|
||||
mControllers.add(new BubbleSummaryPreferenceController(context, mBackend));
|
||||
mControllers.add(new ChannelListPreferenceController(context, mBackend));
|
||||
mControllers.add(new ConversationListPreferenceController(context, mBackend));
|
||||
return new ArrayList<>(mControllers);
|
||||
}
|
||||
}
|
||||
|
@@ -22,15 +22,15 @@ import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
public class BubblePreferenceController extends NotificationPreferenceController
|
||||
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
|
||||
|
||||
|
@@ -31,6 +31,7 @@ import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
@@ -132,9 +133,7 @@ public class ChannelListPreferenceController extends NotificationPreferenceContr
|
||||
groupCategory.setOrderingAsAdded(true);
|
||||
mPreference.addPreference(groupCategory);
|
||||
if (group.getId() == null) {
|
||||
if (mChannelGroupList.size() > 1) {
|
||||
groupCategory.setTitle(R.string.notification_channels_other);
|
||||
}
|
||||
groupCategory.setTitle(R.string.notification_channels_other);
|
||||
groupCategory.setKey(KEY_GENERAL_CATEGORY);
|
||||
} else {
|
||||
groupCategory.setTitle(group.getName());
|
||||
@@ -147,7 +146,10 @@ public class ChannelListPreferenceController extends NotificationPreferenceContr
|
||||
int N = channels.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
final NotificationChannel channel = channels.get(i);
|
||||
populateSingleChannelPrefs(groupCategory, channel, group.isBlocked());
|
||||
// conversations get their own section
|
||||
if (TextUtils.isEmpty(channel.getConversationId()) || channel.isDemoted()) {
|
||||
populateSingleChannelPrefs(groupCategory, channel, group.isBlocked());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -30,6 +30,7 @@ import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -65,8 +66,20 @@ public class ChannelNotificationSettings extends NotificationSettings {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mChannel != null && !TextUtils.isEmpty(mChannel.getConversationId())
|
||||
&& !mChannel.isDemoted()) {
|
||||
startActivity(new SubSettingLauncher(mContext)
|
||||
.setDestination(ConversationNotificationSettings.class.getName())
|
||||
.setArguments(getArguments())
|
||||
.setExtras(getIntent() != null ? getIntent().getExtras(): null)
|
||||
.setSourceMetricsCategory(SettingsEnums.NOTIFICATION_TOPIC_NOTIFICATION)
|
||||
.toIntent());
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
for (NotificationPreferenceController controller : mControllers) {
|
||||
controller.onResume(mAppRow, mChannel, mChannelGroup, mSuspendedAppsAdmin);
|
||||
controller.onResume(mAppRow, mChannel, mChannelGroup, null, null, mSuspendedAppsAdmin);
|
||||
controller.displayPreference(getPreferenceScreen());
|
||||
}
|
||||
updatePreferenceStates();
|
||||
@@ -118,6 +131,7 @@ public class ChannelNotificationSettings extends NotificationSettings {
|
||||
mControllers.add(new NotificationsOffPreferenceController(context));
|
||||
mControllers.add(new BubblePreferenceController(context, getChildFragmentManager(),
|
||||
mBackend, false /* isAppPage */));
|
||||
mControllers.add(new ConversationPromotePreferenceController(context, this, mBackend));
|
||||
return new ArrayList<>(mControllers);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.app;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
|
||||
public class ConversationDemotePreferenceController extends NotificationPreferenceController
|
||||
implements PreferenceControllerMixin {
|
||||
|
||||
private static final String KEY = "demote";
|
||||
|
||||
SettingsPreferenceFragment mHostFragment;
|
||||
|
||||
public ConversationDemotePreferenceController(Context context,
|
||||
SettingsPreferenceFragment hostFragment,
|
||||
NotificationBackend backend) {
|
||||
super(context, backend);
|
||||
mHostFragment = hostFragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
if (!super.isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
if (mAppRow == null || mChannel == null) {
|
||||
return false;
|
||||
}
|
||||
return !TextUtils.isEmpty(mChannel.getConversationId()) && !mChannel.isDemoted();
|
||||
}
|
||||
|
||||
public void updateState(Preference preference) {
|
||||
preference.setEnabled(mAdmin == null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handlePreferenceTreeClick(Preference preference) {
|
||||
if (KEY.equals(preference.getKey())) {
|
||||
mChannel.setDemoted(true);
|
||||
saveChannel();
|
||||
|
||||
mHostFragment.getActivity().finish();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.app;
|
||||
|
||||
import static com.android.settings.widget.EntityHeaderController.PREF_KEY_APP_HEADER;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.text.BidiFormatter;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
import androidx.lifecycle.OnLifecycleEvent;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.widget.LayoutPreference;
|
||||
|
||||
public class ConversationHeaderPreferenceController extends NotificationPreferenceController
|
||||
implements PreferenceControllerMixin, LifecycleObserver {
|
||||
|
||||
private final DashboardFragment mFragment;
|
||||
private EntityHeaderController mHeaderController;
|
||||
private boolean mStarted = false;
|
||||
|
||||
public ConversationHeaderPreferenceController(Context context, DashboardFragment fragment) {
|
||||
super(context, null);
|
||||
mFragment = fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return PREF_KEY_APP_HEADER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mAppRow != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
if (mAppRow != null && mFragment != null) {
|
||||
|
||||
Activity activity = null;
|
||||
if (mStarted) {
|
||||
// don't call done on an activity if it hasn't started yet
|
||||
activity = mFragment.getActivity();
|
||||
}
|
||||
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
LayoutPreference pref = (LayoutPreference) preference;
|
||||
mHeaderController = EntityHeaderController.newInstance(
|
||||
activity, mFragment, pref.findViewById(R.id.entity_header));
|
||||
pref = mHeaderController.setIcon(mConversationDrawable)
|
||||
.setLabel(getLabel())
|
||||
.setSummary(getSummary())
|
||||
.setPackageName(mAppRow.pkg)
|
||||
.setUid(mAppRow.uid)
|
||||
.setButtonActions(EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE,
|
||||
EntityHeaderController.ActionType.ACTION_NONE)
|
||||
.setHasAppInfoLink(true)
|
||||
.setRecyclerView(mFragment.getListView(), mFragment.getSettingsLifecycle())
|
||||
.done(activity, mContext);
|
||||
pref.findViewById(R.id.entity_header).setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
if (mChannel != null && !isDefaultChannel()) {
|
||||
if (mChannelGroup != null
|
||||
&& !TextUtils.isEmpty(mChannelGroup.getName())) {
|
||||
final SpannableStringBuilder summary = new SpannableStringBuilder();
|
||||
BidiFormatter bidi = BidiFormatter.getInstance();
|
||||
summary.append(bidi.unicodeWrap(mAppRow.label.toString()));
|
||||
summary.append(bidi.unicodeWrap(mContext.getText(
|
||||
R.string.notification_header_divider_symbol_with_spaces)));
|
||||
summary.append(bidi.unicodeWrap(mChannelGroup.getName().toString()));
|
||||
return summary.toString();
|
||||
} else {
|
||||
return mAppRow.label.toString();
|
||||
}
|
||||
} else if (mChannelGroup != null) {
|
||||
return mAppRow.label.toString();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_START)
|
||||
public void onStart() {
|
||||
mStarted = true;
|
||||
if (mHeaderController != null) {
|
||||
mHeaderController.styleActionBar(mFragment.getActivity());
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
CharSequence getLabel() {
|
||||
return mConversationInfo != null
|
||||
? mConversationInfo.getShortLabel()
|
||||
: mChannel.getName();
|
||||
}
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.app;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
|
||||
public class ConversationImportantPreferenceController extends NotificationPreferenceController
|
||||
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
|
||||
|
||||
private static final String TAG = "ConvoImpPC";
|
||||
private static final String KEY = "important";
|
||||
|
||||
public ConversationImportantPreferenceController(Context context,
|
||||
NotificationBackend backend) {
|
||||
super(context, backend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
if (!super.isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
if (mAppRow == null || mChannel == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void updateState(Preference preference) {
|
||||
if (mAppRow != null) {
|
||||
RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
|
||||
pref.setDisabledByAdmin(mAdmin);
|
||||
pref.setChecked(mChannel.isImportantConversation());
|
||||
pref.setEnabled(!pref.isDisabledByAdmin());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (mChannel == null) {
|
||||
return false;
|
||||
}
|
||||
final boolean value = (Boolean) newValue;
|
||||
mChannel.setImportantConversation(value);
|
||||
saveChannel();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.app;
|
||||
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.service.notification.ConversationChannelWrapper;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.applications.AppInfoBase;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationListPreferenceController extends NotificationPreferenceController {
|
||||
|
||||
private static final String KEY = "conversations";
|
||||
public static final String ARG_FROM_SETTINGS = "fromSettings";
|
||||
|
||||
private List<ConversationChannelWrapper> mConversations;
|
||||
private PreferenceCategory mPreference;
|
||||
|
||||
public ConversationListPreferenceController(Context context, NotificationBackend backend) {
|
||||
super(context, backend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
if (mAppRow == null) {
|
||||
return false;
|
||||
}
|
||||
if (mAppRow.banned) {
|
||||
return false;
|
||||
}
|
||||
if (mChannel != null) {
|
||||
if (mBackend.onlyHasDefaultChannel(mAppRow.pkg, mAppRow.uid)
|
||||
|| NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
mPreference = (PreferenceCategory) preference;
|
||||
// Load channel settings
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... unused) {
|
||||
mConversations = mBackend.getConversations(mAppRow.pkg, mAppRow.uid).getList();
|
||||
Collections.sort(mConversations, mConversationComparator);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void unused) {
|
||||
if (mContext == null) {
|
||||
return;
|
||||
}
|
||||
populateList();
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
private void populateList() {
|
||||
// TODO: if preference has children, compare with newly loaded list
|
||||
mPreference.removeAll();
|
||||
mPreference.setTitle(R.string.conversations_category_title);
|
||||
|
||||
if (mConversations.isEmpty()) {
|
||||
mPreference.setVisible(false);
|
||||
} else {
|
||||
mPreference.setVisible(true);
|
||||
populateConversations();
|
||||
}
|
||||
}
|
||||
|
||||
private void populateConversations() {
|
||||
for (ConversationChannelWrapper conversation : mConversations) {
|
||||
if (conversation.getNotificationChannel().isDemoted()) {
|
||||
continue;
|
||||
}
|
||||
mPreference.addPreference(createConversationPref(conversation));
|
||||
}
|
||||
}
|
||||
|
||||
protected Preference createConversationPref(final ConversationChannelWrapper conversation) {
|
||||
Preference pref = new Preference(mContext);
|
||||
ShortcutInfo si = conversation.getShortcutInfo();
|
||||
|
||||
pref.setTitle(si != null
|
||||
? si.getShortLabel()
|
||||
: conversation.getNotificationChannel().getName());
|
||||
pref.setSummary(conversation.getNotificationChannel().getGroup() != null
|
||||
? mContext.getString(R.string.notification_conversation_summary,
|
||||
conversation.getParentChannelLabel(), conversation.getGroupLabel())
|
||||
: conversation.getParentChannelLabel());
|
||||
if (si != null) {
|
||||
pref.setIcon(mBackend.getConversationDrawable(mContext, si));
|
||||
}
|
||||
pref.setKey(conversation.getNotificationChannel().getId());
|
||||
|
||||
Bundle channelArgs = new Bundle();
|
||||
channelArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mAppRow.uid);
|
||||
channelArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, mAppRow.pkg);
|
||||
channelArgs.putString(Settings.EXTRA_CHANNEL_ID,
|
||||
conversation.getNotificationChannel().getParentChannelId());
|
||||
channelArgs.putString(Settings.EXTRA_CONVERSATION_ID,
|
||||
conversation.getNotificationChannel().getConversationId());
|
||||
channelArgs.putBoolean(ARG_FROM_SETTINGS, true);
|
||||
pref.setIntent(new SubSettingLauncher(mContext)
|
||||
.setDestination(ChannelNotificationSettings.class.getName())
|
||||
.setArguments(channelArgs)
|
||||
.setExtras(channelArgs)
|
||||
.setTitleText(pref.getTitle())
|
||||
.setSourceMetricsCategory(SettingsEnums.NOTIFICATION_APP_NOTIFICATION)
|
||||
.toIntent());
|
||||
return pref;
|
||||
}
|
||||
|
||||
protected Comparator<ConversationChannelWrapper> mConversationComparator =
|
||||
(left, right) -> {
|
||||
if (left.getNotificationChannel().isImportantConversation()
|
||||
!= right.getNotificationChannel().isImportantConversation()) {
|
||||
// important first
|
||||
return Boolean.compare(right.getNotificationChannel().isImportantConversation(),
|
||||
left.getNotificationChannel().isImportantConversation());
|
||||
}
|
||||
return left.getNotificationChannel().getId().compareTo(
|
||||
right.getNotificationChannel().getId());
|
||||
};
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.app;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationNotificationSettings extends NotificationSettings {
|
||||
private static final String TAG = "ConvoSettings";
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.NOTIFICATION_CONVERSATION_SETTINGS;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
for (NotificationPreferenceController controller : mControllers) {
|
||||
controller.onResume(mAppRow, mChannel, mChannelGroup, mConversationDrawable,
|
||||
mConversationInfo, mSuspendedAppsAdmin);
|
||||
controller.displayPreference(getPreferenceScreen());
|
||||
}
|
||||
updatePreferenceStates();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
for (NotificationPreferenceController controller : mControllers) {
|
||||
if (controller instanceof PreferenceManager.OnActivityResultListener) {
|
||||
((PreferenceManager.OnActivityResultListener) controller)
|
||||
.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLogTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.conversation_notification_settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||
mControllers = new ArrayList<>();
|
||||
mControllers.add(new ConversationHeaderPreferenceController(context, this));
|
||||
mControllers.add(new ConversationImportantPreferenceController(context, mBackend));
|
||||
mControllers.add(new DefaultImportancePreferenceController(
|
||||
context, mImportanceListener, mBackend));
|
||||
mControllers.add(new AddToHomeScreenPreferenceController(context, mBackend));
|
||||
mControllers.add(new HighImportancePreferenceController(
|
||||
context, mImportanceListener, mBackend));
|
||||
mControllers.add(new SoundPreferenceController(context, this,
|
||||
mImportanceListener, mBackend));
|
||||
mControllers.add(new VibrationPreferenceController(context, mBackend));
|
||||
mControllers.add(new AppLinkPreferenceController(context));
|
||||
mControllers.add(new DescriptionPreferenceController(context));
|
||||
mControllers.add(new VisibilityPreferenceController(context, new LockPatternUtils(context),
|
||||
mBackend));
|
||||
mControllers.add(new LightsPreferenceController(context, mBackend));
|
||||
mControllers.add(new BadgePreferenceController(context, mBackend));
|
||||
mControllers.add(new NotificationsOffPreferenceController(context));
|
||||
mControllers.add(new BubblePreferenceController(context, getChildFragmentManager(),
|
||||
mBackend, false /* isAppPage */));
|
||||
mControllers.add(new ConversationDemotePreferenceController(context, this, mBackend));
|
||||
return new ArrayList<>(mControllers);
|
||||
}
|
||||
}
|
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.app;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
|
||||
public class ConversationPromotePreferenceController extends NotificationPreferenceController
|
||||
implements PreferenceControllerMixin {
|
||||
|
||||
private static final String KEY = "convo_promote";
|
||||
|
||||
SettingsPreferenceFragment mHostFragment;
|
||||
|
||||
public ConversationPromotePreferenceController(Context context,
|
||||
SettingsPreferenceFragment hostFragment,
|
||||
NotificationBackend backend) {
|
||||
super(context, backend);
|
||||
mHostFragment = hostFragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
if (!super.isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
if (mAppRow == null || mChannel == null) {
|
||||
return false;
|
||||
}
|
||||
return !TextUtils.isEmpty(mChannel.getConversationId()) && mChannel.isDemoted();
|
||||
}
|
||||
|
||||
public void updateState(Preference preference) {
|
||||
preference.setEnabled(mAdmin == null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handlePreferenceTreeClick(Preference preference) {
|
||||
if (mChannel == null) {
|
||||
return false;
|
||||
}
|
||||
mChannel.setDemoted(false);
|
||||
saveChannel();
|
||||
|
||||
if (mHostFragment != null) {
|
||||
mHostFragment.getActivity().finish();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.app;
|
||||
|
||||
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
|
||||
import static android.app.NotificationManager.IMPORTANCE_LOW;
|
||||
|
||||
import android.app.NotificationChannel;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
|
||||
public class DefaultImportancePreferenceController extends NotificationPreferenceController
|
||||
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
|
||||
|
||||
private static final String KEY = "alerting";
|
||||
private NotificationSettings.ImportanceListener mImportanceListener;
|
||||
|
||||
public DefaultImportancePreferenceController(Context context,
|
||||
NotificationSettings.ImportanceListener importanceListener,
|
||||
NotificationBackend backend) {
|
||||
super(context, backend);
|
||||
mImportanceListener = importanceListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
if (!super.isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
if (mChannel == null) {
|
||||
return false;
|
||||
}
|
||||
if (isDefaultChannel()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
if (mAppRow != null && mChannel != null) {
|
||||
preference.setEnabled(mAdmin == null && !mChannel.isImportanceLockedByOEM());
|
||||
|
||||
RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference;
|
||||
pref.setChecked(mChannel.getImportance() >= IMPORTANCE_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (mChannel != null) {
|
||||
final boolean checked = (boolean) newValue;
|
||||
|
||||
mChannel.setImportance(checked ? IMPORTANCE_DEFAULT : IMPORTANCE_LOW);
|
||||
mChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
|
||||
saveChannel();
|
||||
mImportanceListener.onImportanceChanged();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -24,6 +24,8 @@ import android.app.NotificationChannelGroup;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.UserManager;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -53,6 +55,10 @@ public abstract class NotificationPreferenceController extends AbstractPreferenc
|
||||
protected final UserManager mUm;
|
||||
protected final PackageManager mPm;
|
||||
protected Preference mPreference;
|
||||
@Nullable
|
||||
protected Drawable mConversationDrawable;
|
||||
@Nullable
|
||||
protected ShortcutInfo mConversationInfo;
|
||||
|
||||
public NotificationPreferenceController(Context context, NotificationBackend backend) {
|
||||
super(context);
|
||||
@@ -87,11 +93,15 @@ public abstract class NotificationPreferenceController extends AbstractPreferenc
|
||||
|
||||
protected void onResume(NotificationBackend.AppRow appRow,
|
||||
@Nullable NotificationChannel channel, @Nullable NotificationChannelGroup group,
|
||||
Drawable conversationDrawable,
|
||||
ShortcutInfo conversationInfo,
|
||||
RestrictedLockUtils.EnforcedAdmin admin) {
|
||||
mAppRow = appRow;
|
||||
mChannel = channel;
|
||||
mChannelGroup = group;
|
||||
mAdmin = admin;
|
||||
mConversationDrawable = conversationDrawable;
|
||||
mConversationInfo = conversationInfo;
|
||||
}
|
||||
|
||||
protected boolean checkCanBeVisible(int minImportanceVisible) {
|
||||
|
@@ -32,6 +32,8 @@ import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
@@ -46,8 +48,6 @@ import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.applications.AppInfoBase;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settings.notification.app.HeaderPreferenceController;
|
||||
import com.android.settings.notification.app.NotificationPreferenceController;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -71,6 +71,8 @@ abstract public class NotificationSettings extends DashboardFragment {
|
||||
protected NotificationChannelGroup mChannelGroup;
|
||||
protected NotificationChannel mChannel;
|
||||
protected NotificationBackend.AppRow mAppRow;
|
||||
protected Drawable mConversationDrawable;
|
||||
protected ShortcutInfo mConversationInfo;
|
||||
|
||||
protected boolean mShowLegacyChannelConfig = false;
|
||||
protected boolean mListeningToPackageRemove;
|
||||
@@ -118,10 +120,17 @@ abstract public class NotificationSettings extends DashboardFragment {
|
||||
loadChannelGroup();
|
||||
collectConfigActivities();
|
||||
|
||||
getSettingsLifecycle().addObserver(use(HeaderPreferenceController.class));
|
||||
if (use(HeaderPreferenceController.class) != null) {
|
||||
getSettingsLifecycle().addObserver(use(HeaderPreferenceController.class));
|
||||
}
|
||||
if (use(ConversationHeaderPreferenceController.class) != null) {
|
||||
getSettingsLifecycle().addObserver(
|
||||
use(ConversationHeaderPreferenceController.class));
|
||||
}
|
||||
|
||||
for (NotificationPreferenceController controller : mControllers) {
|
||||
controller.onResume(mAppRow, mChannel, mChannelGroup, mSuspendedAppsAdmin);
|
||||
controller.onResume(mAppRow, mChannel, mChannelGroup, null, null,
|
||||
mSuspendedAppsAdmin);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -169,6 +178,7 @@ abstract public class NotificationSettings extends DashboardFragment {
|
||||
return;
|
||||
}
|
||||
loadChannel();
|
||||
loadConversation();
|
||||
loadChannelGroup();
|
||||
collectConfigActivities();
|
||||
}
|
||||
@@ -180,7 +190,21 @@ abstract public class NotificationSettings extends DashboardFragment {
|
||||
Bundle args = intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
|
||||
channelId = args != null ? args.getString(Settings.EXTRA_CHANNEL_ID) : null;
|
||||
}
|
||||
mChannel = mBackend.getChannel(mPkg, mUid, channelId);
|
||||
String conversationId = intent != null
|
||||
? intent.getStringExtra(Settings.EXTRA_CONVERSATION_ID) : null;
|
||||
mChannel = mBackend.getChannel(mPkg, mUid, channelId, conversationId);
|
||||
}
|
||||
|
||||
private void loadConversation() {
|
||||
if (mChannel == null || TextUtils.isEmpty(mChannel.getConversationId())
|
||||
|| mChannel.isDemoted()) {
|
||||
return;
|
||||
}
|
||||
mConversationInfo = mBackend.getConversationInfo(
|
||||
mContext, mPkg, mUid, mChannel.getConversationId());
|
||||
if (mConversationInfo != null) {
|
||||
mConversationDrawable = mBackend.getConversationDrawable(mContext, mConversationInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadAppRow() {
|
||||
@@ -194,7 +218,7 @@ abstract public class NotificationSettings extends DashboardFragment {
|
||||
|
||||
if (mShowLegacyChannelConfig) {
|
||||
mChannel = mBackend.getChannel(
|
||||
mAppRow.pkg, mAppRow.uid, NotificationChannel.DEFAULT_CHANNEL_ID);
|
||||
mAppRow.pkg, mAppRow.uid, NotificationChannel.DEFAULT_CHANNEL_ID, null);
|
||||
}
|
||||
if (mChannel != null && !TextUtils.isEmpty(mChannel.getGroup())) {
|
||||
NotificationChannelGroup group = mBackend.getGroup(mPkg, mUid, mChannel.getGroup());
|
||||
|
Reference in New Issue
Block a user