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:
Julia Reynolds
2020-04-02 12:44:47 -04:00
parent 281e02a772
commit e24faa2c86
14 changed files with 56 additions and 60 deletions

View File

@@ -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";

View File

@@ -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

View File

@@ -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;

View File

@@ -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");

View File

@@ -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>

View File

@@ -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,

View File

@@ -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) =

View File

@@ -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;

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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)

View File

@@ -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);

View File

@@ -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);

View File

@@ -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"