Store conversation requirement in a setting
So we can show it in developer options. Also fix a bug where the setting wasn't being respected in systemui. Test: atest Bug: 152907434 Change-Id: I1eaed93a0c8a1ec4486c7072972e2f924402bb94
This commit is contained in:
@@ -4677,7 +4677,6 @@ package android.util {
|
||||
field public static final String FFLAG_OVERRIDE_PREFIX = "sys.fflag.override.";
|
||||
field public static final String FFLAG_PREFIX = "sys.fflag.";
|
||||
field public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
|
||||
field public static final String NOTIF_CONVO_BYPASS_SHORTCUT_REQ = "settings_notif_convo_bypass_shortcut_req";
|
||||
field public static final String PERSIST_PREFIX = "persist.sys.fflag.override.";
|
||||
field public static final String SCREENRECORD_LONG_PRESS = "settings_screenrecord_long_press";
|
||||
field public static final String SEAMLESS_TRANSFER = "settings_seamless_transfer";
|
||||
|
||||
@@ -13756,6 +13756,16 @@ public final class Settings {
|
||||
public static final String SHOW_NOTIFICATION_CHANNEL_WARNINGS =
|
||||
"show_notification_channel_warnings";
|
||||
|
||||
/**
|
||||
* When enabled, requires all notifications in the conversation section to be backed
|
||||
* by a long-lived sharing shortcut
|
||||
*
|
||||
* The value 1 - require a shortcut, 0 - do not require a shortcut
|
||||
* @hide
|
||||
*/
|
||||
public static final String REQUIRE_SHORTCUTS_FOR_CONVERSATIONS =
|
||||
"require_shortcuts_for_conversations";
|
||||
|
||||
/**
|
||||
* Whether cell is enabled/disabled
|
||||
* @hide
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
package android.service.notification;
|
||||
|
||||
import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
|
||||
import static android.util.FeatureFlagUtils.NOTIF_CONVO_BYPASS_SHORTCUT_REQ;
|
||||
import static android.util.FeatureFlagUtils.isEnabled;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.Notification;
|
||||
@@ -33,6 +31,7 @@ import android.os.Build;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.internal.logging.InstanceId;
|
||||
@@ -477,9 +476,10 @@ public class StatusBarNotification implements Parcelable {
|
||||
*/
|
||||
public String getShortcutId(Context context) {
|
||||
String conversationId = getNotification().getShortcutId();
|
||||
if (isEnabled(context, NOTIF_CONVO_BYPASS_SHORTCUT_REQ)
|
||||
&& getNotification().getNotificationStyle() == Notification.MessagingStyle.class
|
||||
&& TextUtils.isEmpty(conversationId)) {
|
||||
if (TextUtils.isEmpty(conversationId)
|
||||
&& (Settings.Global.getInt(context.getContentResolver(),
|
||||
Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0) == 0)
|
||||
&& getNotification().getNotificationStyle() == Notification.MessagingStyle.class) {
|
||||
conversationId = getId() + getTag() + PLACEHOLDER_CONVERSATION_ID;
|
||||
}
|
||||
return conversationId;
|
||||
|
||||
@@ -42,8 +42,6 @@ public class FeatureFlagUtils {
|
||||
public static final String DYNAMIC_SYSTEM = "settings_dynamic_system";
|
||||
public static final String SETTINGS_WIFITRACKER2 = "settings_wifitracker2";
|
||||
public static final String SETTINGS_FUSE_FLAG = "settings_fuse";
|
||||
public static final String NOTIF_CONVO_BYPASS_SHORTCUT_REQ =
|
||||
"settings_notif_convo_bypass_shortcut_req";
|
||||
/** @hide */
|
||||
public static final String SETTINGS_DO_NOT_RESTORE_PRESERVED =
|
||||
"settings_do_not_restore_preserved";
|
||||
@@ -66,7 +64,6 @@ public class FeatureFlagUtils {
|
||||
DEFAULT_FLAGS.put(SETTINGS_WIFITRACKER2, "true");
|
||||
DEFAULT_FLAGS.put("settings_controller_loading_enhancement", "false");
|
||||
DEFAULT_FLAGS.put("settings_conditionals", "false");
|
||||
DEFAULT_FLAGS.put(NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "true");
|
||||
// This flags guards a feature introduced in R and will be removed in the next release
|
||||
// (b/148367230).
|
||||
DEFAULT_FLAGS.put(SETTINGS_DO_NOT_RESTORE_PRESERVED, "true");
|
||||
|
||||
@@ -928,11 +928,15 @@
|
||||
<!-- UI debug setting: show all ANRs summary [CHAR LIMIT=100] -->
|
||||
<string name="show_all_anrs_summary">Display App Not Responding dialog for background apps</string>
|
||||
|
||||
<!-- UI debug setting: show all ANRs? [CHAR LIMIT=25] -->
|
||||
<!-- UI debug setting: show missing channel toasts? [CHAR LIMIT=25] -->
|
||||
<string name="show_notification_channel_warnings">Show notification channel warnings</string>
|
||||
<!-- UI debug setting: show all ANRs summary [CHAR LIMIT=50] -->
|
||||
<!-- UI debug setting: show missing channel toasts summary [CHAR LIMIT=50] -->
|
||||
<string name="show_notification_channel_warnings_summary">Displays on-screen warning when an app posts a notification without a valid channel</string>
|
||||
|
||||
<!-- UI debug setting: enforce shortcut requirements for conversation space [CHAR LIMIT=25] -->
|
||||
<string name="enforce_shortcuts_for_conversations">Enforce shortcuts for conversation notifications</string>
|
||||
<!-- UI debug setting: enforce shortcut requirements for conversation space summary [CHAR LIMIT=50] -->
|
||||
<string name="enforce_shortcuts_for_conversations_summary">Require notifications to be backed by a long-lived sharing shortcut in order to appear in the conversation section</string>
|
||||
|
||||
<!-- UI debug setting: force allow apps on external storage [CHAR LIMIT=50] -->
|
||||
<string name="force_allow_on_external">Force allow apps on external</string>
|
||||
|
||||
@@ -418,6 +418,7 @@ public class SettingsBackupTest {
|
||||
Settings.Global.RECOMMENDED_NETWORK_EVALUATOR_CACHE_EXPIRY_MS,
|
||||
Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT,
|
||||
Settings.Global.REQUIRE_PASSWORD_TO_DECRYPT,
|
||||
Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS,
|
||||
Settings.Global.SAFE_BOOT_DISALLOWED,
|
||||
Settings.Global.SELINUX_STATUS,
|
||||
Settings.Global.SELINUX_UPDATE_CONTENT_URL,
|
||||
|
||||
@@ -83,9 +83,9 @@ class PeopleNotificationIdentifierImpl @Inject constructor(
|
||||
|
||||
private val Ranking.personTypeInfo
|
||||
get() = when {
|
||||
!isConversation -> TYPE_NON_PERSON
|
||||
channel?.isImportantConversation == true -> TYPE_IMPORTANT_PERSON
|
||||
isConversation -> TYPE_PERSON
|
||||
else -> TYPE_NON_PERSON
|
||||
else -> TYPE_PERSON
|
||||
}
|
||||
|
||||
private fun extractPersonTypeInfo(sbn: StatusBarNotification) =
|
||||
|
||||
@@ -20,7 +20,6 @@ import static android.app.Notification.EXTRA_IS_GROUP_CONVERSATION;
|
||||
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
|
||||
import static android.app.NotificationManager.IMPORTANCE_LOW;
|
||||
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
|
||||
import static android.provider.Settings.Secure.BUBBLE_IMPORTANT_CONVERSATIONS;
|
||||
|
||||
import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN;
|
||||
|
||||
@@ -44,7 +43,6 @@ import android.os.Handler;
|
||||
import android.os.Parcelable;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.text.TextUtils;
|
||||
import android.transition.ChangeBounds;
|
||||
@@ -56,15 +54,12 @@ import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settingslib.notification.ConversationIconFactory;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.notification.VisualStabilityManager;
|
||||
|
||||
@@ -107,7 +107,6 @@ import android.annotation.CallbackExecutor;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.UserIdInt;
|
||||
import android.annotation.WorkerThread;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManagerInternal;
|
||||
@@ -214,7 +213,6 @@ import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.AtomicFile;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.util.IntArray;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
@@ -5604,18 +5602,16 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
mUsageStats.registerEnqueuedByApp(pkg);
|
||||
|
||||
final StatusBarNotification n = new StatusBarNotification(
|
||||
pkg, opPkg, id, tag, notificationUid, callingPid, notification,
|
||||
user, null, System.currentTimeMillis());
|
||||
|
||||
// setup local book-keeping
|
||||
String channelId = notification.getChannelId();
|
||||
if (mIsTelevision && (new Notification.TvExtender(notification)).getChannelId() != null) {
|
||||
channelId = (new Notification.TvExtender(notification)).getChannelId();
|
||||
}
|
||||
String shortcutId = notification.getShortcutId();
|
||||
if (FeatureFlagUtils.isEnabled(getContext(),
|
||||
FeatureFlagUtils.NOTIF_CONVO_BYPASS_SHORTCUT_REQ)
|
||||
&& shortcutId == null
|
||||
&& notification.getNotificationStyle() == Notification.MessagingStyle.class) {
|
||||
shortcutId = id + tag + NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
|
||||
}
|
||||
String shortcutId = n.getShortcutId(getContext());
|
||||
final NotificationChannel channel = mPreferencesHelper.getConversationNotificationChannel(
|
||||
pkg, notificationUid, channelId, shortcutId,
|
||||
true /* parent ok */, false /* includeDeleted */);
|
||||
@@ -5643,9 +5639,6 @@ public class NotificationManagerService extends SystemService {
|
||||
return;
|
||||
}
|
||||
|
||||
final StatusBarNotification n = new StatusBarNotification(
|
||||
pkg, opPkg, id, tag, notificationUid, callingPid, notification,
|
||||
user, null, System.currentTimeMillis());
|
||||
final NotificationRecord r = new NotificationRecord(getContext(), n, channel);
|
||||
r.setIsAppImportanceLocked(mPreferencesHelper.getIsAppImportanceLocked(pkg, callingUid));
|
||||
r.setPostSilently(postSilently);
|
||||
|
||||
@@ -1383,9 +1383,8 @@ public final class NotificationRecord {
|
||||
|| !Notification.MessagingStyle.class.equals(notification.getNotificationStyle())) {
|
||||
return false;
|
||||
}
|
||||
if (mShortcutInfo == null
|
||||
&& !FeatureFlagUtils.isEnabled(
|
||||
mContext, FeatureFlagUtils.NOTIF_CONVO_BYPASS_SHORTCUT_REQ)) {
|
||||
if (mShortcutInfo == null && Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0) == 1) {
|
||||
return false;
|
||||
}
|
||||
if (mIsNotConversationOverride) {
|
||||
|
||||
@@ -46,7 +46,6 @@ import android.service.notification.RankingHelperProto;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.util.Pair;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseBooleanArray;
|
||||
@@ -180,8 +179,8 @@ public class PreferencesHelper implements RankingConfig {
|
||||
updateBadgingEnabled();
|
||||
updateBubblesEnabled();
|
||||
syncChannelsBypassingDnd(mContext.getUserId());
|
||||
mAllowInvalidShortcuts = FeatureFlagUtils.isEnabled(mContext,
|
||||
FeatureFlagUtils.NOTIF_CONVO_BYPASS_SHORTCUT_REQ);
|
||||
mAllowInvalidShortcuts = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0) == 0;
|
||||
}
|
||||
|
||||
public void readXml(XmlPullParser parser, boolean forRestore, int userId)
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.android.server.notification;
|
||||
|
||||
import static android.app.NotificationManager.IMPORTANCE_HIGH;
|
||||
import static android.app.NotificationManager.IMPORTANCE_LOW;
|
||||
import static android.util.FeatureFlagUtils.NOTIF_CONVO_BYPASS_SHORTCUT_REQ;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertNull;
|
||||
@@ -77,8 +76,8 @@ public class NotificationChannelExtractorTest extends UiServiceTestCase {
|
||||
|
||||
@Test
|
||||
public void testInvalidShortcutFlagEnabled_looksUpCorrectChannel() {
|
||||
Settings.Global.putString(
|
||||
mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "true");
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0);
|
||||
|
||||
NotificationChannelExtractor extractor = new NotificationChannelExtractor();
|
||||
extractor.setConfig(mConfig);
|
||||
@@ -97,7 +96,8 @@ public class NotificationChannelExtractorTest extends UiServiceTestCase {
|
||||
NotificationChannel updatedChannel =
|
||||
new NotificationChannel("a", "", IMPORTANCE_HIGH);
|
||||
when(mConfig.getConversationNotificationChannel(
|
||||
any(), anyInt(), eq("a"), eq(r.getSbn().getShortcutId(mContext)), eq(true), eq(false)))
|
||||
any(), anyInt(), eq("a"), eq(r.getSbn().getShortcutId(mContext)),
|
||||
eq(true), eq(false)))
|
||||
.thenReturn(updatedChannel);
|
||||
|
||||
assertNull(extractor.process(r));
|
||||
@@ -106,8 +106,8 @@ public class NotificationChannelExtractorTest extends UiServiceTestCase {
|
||||
|
||||
@Test
|
||||
public void testInvalidShortcutFlagDisabled_looksUpCorrectChannel() {
|
||||
Settings.Global.putString(
|
||||
mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "false");
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1);
|
||||
|
||||
NotificationChannelExtractor extractor = new NotificationChannelExtractor();
|
||||
extractor.setConfig(mConfig);
|
||||
|
||||
@@ -63,7 +63,6 @@ import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.service.notification.Adjustment;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
@@ -124,8 +123,8 @@ public class NotificationRecordTest extends UiServiceTestCase {
|
||||
when(mMockContext.getResources()).thenReturn(getContext().getResources());
|
||||
when(mMockContext.getPackageManager()).thenReturn(mPm);
|
||||
when(mMockContext.getContentResolver()).thenReturn(mContentResolver);
|
||||
Settings.Global.putString(mContentResolver,
|
||||
FeatureFlagUtils.NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "false");
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1);
|
||||
ApplicationInfo appInfo = new ApplicationInfo();
|
||||
appInfo.targetSdkVersion = Build.VERSION_CODES.O;
|
||||
when(mMockContext.getApplicationInfo()).thenReturn(appInfo);
|
||||
@@ -1138,8 +1137,8 @@ public class NotificationRecordTest extends UiServiceTestCase {
|
||||
|
||||
@Test
|
||||
public void testIsConversation_bypassShortcutFlagEnabled() {
|
||||
Settings.Global.putString(mContentResolver,
|
||||
FeatureFlagUtils.NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "true");
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0);
|
||||
StatusBarNotification sbn = getMessagingStyleNotification();
|
||||
NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
|
||||
record.setShortcutInfo(null);
|
||||
|
||||
@@ -22,7 +22,6 @@ import static android.app.NotificationManager.IMPORTANCE_LOW;
|
||||
import static android.app.NotificationManager.IMPORTANCE_MAX;
|
||||
import static android.app.NotificationManager.IMPORTANCE_NONE;
|
||||
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
|
||||
import static android.util.FeatureFlagUtils.NOTIF_CONVO_BYPASS_SHORTCUT_REQ;
|
||||
|
||||
import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_COUNT_LIMIT;
|
||||
|
||||
@@ -2922,9 +2921,10 @@ public class PreferencesHelperTest extends UiServiceTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPlaceholderConversationId_flagOn() throws Exception {
|
||||
Settings.Global.putString(
|
||||
mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "true");
|
||||
public void testPlaceholderConversationId_shortcutNotRequired() throws Exception {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0);
|
||||
|
||||
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
|
||||
|
||||
final String xml = "<ranking version=\"1\">\n"
|
||||
@@ -2942,9 +2942,9 @@ public class PreferencesHelperTest extends UiServiceTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPlaceholderConversationId_flagOff() throws Exception {
|
||||
Settings.Global.putString(
|
||||
mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "false");
|
||||
public void testPlaceholderConversationId_shortcutRequired() throws Exception {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1);
|
||||
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
|
||||
|
||||
final String xml = "<ranking version=\"1\">\n"
|
||||
@@ -2962,9 +2962,9 @@ public class PreferencesHelperTest extends UiServiceTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalConversationId_flagOff() throws Exception {
|
||||
Settings.Global.putString(
|
||||
mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "false");
|
||||
public void testNormalConversationId_shortcutRequired() throws Exception {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1);
|
||||
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
|
||||
|
||||
final String xml = "<ranking version=\"1\">\n"
|
||||
@@ -2982,9 +2982,9 @@ public class PreferencesHelperTest extends UiServiceTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoConversationId_flagOff() throws Exception {
|
||||
Settings.Global.putString(
|
||||
mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "false");
|
||||
public void testNoConversationId_shortcutRequired() throws Exception {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1);
|
||||
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
|
||||
|
||||
final String xml = "<ranking version=\"1\">\n"
|
||||
|
||||
Reference in New Issue
Block a user