Merge "Implement auto revoke user whitelist intent handler" into rvc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ca969ab..d31fb30 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3181,6 +3181,7 @@
             android:theme="@style/Theme.Panel"
             android:launchMode="singleInstance"
             android:excludeFromRecents="true"
+            android:configChanges="orientation|keyboardHidden|screenSize"
             android:exported="true">
                  <intent-filter>
                      <action android:name="android.settings.panel.action.INTERNET_CONNECTIVITY" />
diff --git a/res/drawable/accessibility_captions.png b/res/drawable/accessibility_captions.png
index 5467386..718f4ef 100644
--- a/res/drawable/accessibility_captions.png
+++ b/res/drawable/accessibility_captions.png
Binary files differ
diff --git a/res/layout/accessibility_captions_preview.xml b/res/layout/accessibility_captions_preview.xml
index f3c0316..1818e64 100644
--- a/res/layout/accessibility_captions_preview.xml
+++ b/res/layout/accessibility_captions_preview.xml
@@ -1,19 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ 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.
-  -->
+  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.
+-->
 
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/res/values/config.xml b/res/values/config.xml
index 5bddc5e..2222156 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -220,10 +220,21 @@
     <!-- Settings intelligence interaction log intent action -->
     <string name="config_settingsintelligence_log_action" translatable="false"></string>
 
+    <!-- AOSP Emergency app package name -->
+    <string name="config_aosp_emergency_package_name" translatable="false">
+        com.android.emergency
+    </string>
+
+    <!-- AOSP Emergency app intent action -->
+    <string name="config_aosp_emergency_intent_action" translatable="false">
+        android.settings.EDIT_EMERGENCY_INFO
+    </string>
+
     <!-- Emergency app package name -->
     <string name="config_emergency_package_name" translatable="false">
         com.android.emergency
     </string>
+
     <!-- Emergency app intent action -->
     <string name="config_emergency_intent_action" translatable="false">
         android.settings.EDIT_EMERGENCY_INFO
diff --git a/src/com/android/settings/accounts/EmergencyInfoPreferenceController.java b/src/com/android/settings/accounts/EmergencyInfoPreferenceController.java
index 5bed05a0..790ce7f 100644
--- a/src/com/android/settings/accounts/EmergencyInfoPreferenceController.java
+++ b/src/com/android/settings/accounts/EmergencyInfoPreferenceController.java
@@ -24,6 +24,7 @@
 import android.os.UserManager;
 import android.text.TextUtils;
 
+import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
 
 import com.android.settings.R;
@@ -34,9 +35,8 @@
 
 public class EmergencyInfoPreferenceController extends BasePreferenceController {
 
-    public static String getIntentAction(Context context) {
-        return context.getResources().getString(R.string.config_emergency_intent_action);
-    }
+    @VisibleForTesting
+    Intent mIntent;
 
     public EmergencyInfoPreferenceController(Context context, String preferenceKey) {
         super(context, preferenceKey);
@@ -62,10 +62,9 @@
 
     @Override
     public boolean handlePreferenceTreeClick(Preference preference) {
-        if (TextUtils.equals(getPreferenceKey(), preference.getKey())) {
-            Intent intent = new Intent(getIntentAction(mContext));
-            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-            mContext.startActivity(intent);
+        if (TextUtils.equals(getPreferenceKey(), preference.getKey()) && mIntent != null) {
+            mIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+            mContext.startActivity(mIntent);
             return true;
         }
         return false;
@@ -76,15 +75,38 @@
         if (!mContext.getResources().getBoolean(R.bool.config_show_emergency_info_in_device_info)) {
             return UNSUPPORTED_ON_DEVICE;
         }
-        final Intent intent = new Intent(getIntentAction(mContext)).setPackage(
-                getPackageName(mContext));
-        final List<ResolveInfo> infos = mContext.getPackageManager().queryIntentActivities(intent,
-                0);
-        return infos != null && !infos.isEmpty()
-                ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+
+        // If the variant of emergency info can not work, we should fallback to AOSP version.
+        if (isEmergencyInfoSupported()) {
+            return AVAILABLE;
+        } else if (isAOSPVersionSupported()) {
+            return AVAILABLE;
+        }
+        return UNSUPPORTED_ON_DEVICE;
     }
 
-    private static String getPackageName(Context context) {
-        return context.getResources().getString(R.string.config_emergency_package_name);
+    private boolean isEmergencyInfoSupported() {
+        final String packageName = mContext.getResources().getString(
+                R.string.config_emergency_package_name);
+        final String intentName = mContext.getResources().getString(
+                R.string.config_emergency_intent_action);
+        mIntent = new Intent(intentName).setPackage(packageName);
+        final List<ResolveInfo> infos = mContext.getPackageManager().queryIntentActivities(mIntent,
+                0);
+
+        return infos != null && !infos.isEmpty();
+    }
+
+    private boolean isAOSPVersionSupported() {
+        final String aospPackageName = mContext.getResources().getString(
+                R.string.config_aosp_emergency_package_name);
+        final String aospIntentName = mContext.getResources().getString(
+                R.string.config_aosp_emergency_intent_action);
+
+        mIntent = new Intent(aospIntentName).setPackage(aospPackageName);
+        final List<ResolveInfo> infos = mContext.getPackageManager().queryIntentActivities(mIntent,
+                0);
+
+        return infos != null && !infos.isEmpty();
     }
 }
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceController.java b/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceController.java
index 76a539f..fb17eca 100644
--- a/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceController.java
@@ -47,6 +47,10 @@
     @VisibleForTesting
     static final Intent MODULE_UPDATE_INTENT =
             new Intent("android.settings.MODULE_UPDATE_SETTINGS");
+    @VisibleForTesting
+    static final Intent MODULE_UPDATE_V2_INTENT =
+            new Intent("android.settings.MODULE_UPDATE_VERSIONS");
+
     private final PackageManager mPackageManager;
 
     private String mModuleVersion;
@@ -81,7 +85,14 @@
     public void updateState(Preference preference) {
         super.updateState(preference);
 
-        // Confirm MODULE_UPDATE_INTENT is handleable, and set it to Preference.
+        final ResolveInfo resolvedV2 =
+                mPackageManager.resolveActivity(MODULE_UPDATE_V2_INTENT, 0 /* flags */);
+        if (resolvedV2 != null) {
+            preference.setIntent(MODULE_UPDATE_V2_INTENT);
+            preference.setSelectable(true);
+            return;
+        }
+
         final ResolveInfo resolved =
                 mPackageManager.resolveActivity(MODULE_UPDATE_INTENT, 0 /* flags */);
         if (resolved != null) {
diff --git a/src/com/android/settings/notification/app/AppChannelsBypassingDndPreferenceController.java b/src/com/android/settings/notification/app/AppChannelsBypassingDndPreferenceController.java
index 4403873..fa05299 100644
--- a/src/com/android/settings/notification/app/AppChannelsBypassingDndPreferenceController.java
+++ b/src/com/android/settings/notification/app/AppChannelsBypassingDndPreferenceController.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.UserHandle;
 import android.provider.Settings;
 
 import androidx.core.text.BidiFormatter;
@@ -183,12 +184,16 @@
             channelArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, mAppRow.pkg);
             channelArgs.putString(Settings.EXTRA_CHANNEL_ID, channel.getId());
             channelArgs.putBoolean(ARG_FROM_SETTINGS, true);
-            channelPreference.setIntent(new SubSettingLauncher(mContext)
-                    .setDestination(ChannelNotificationSettings.class.getName())
-                    .setArguments(channelArgs)
-                    .setTitleRes(com.android.settings.R.string.notification_channel_title)
-                    .setSourceMetricsCategory(SettingsEnums.DND_APPS_BYPASSING)
-                    .toIntent());
+            channelPreference.setOnPreferenceClickListener(preference -> {
+                new SubSettingLauncher(mContext)
+                        .setDestination(ChannelNotificationSettings.class.getName())
+                        .setArguments(channelArgs)
+                        .setUserHandle(UserHandle.of(mAppRow.userId))
+                        .setTitleRes(com.android.settings.R.string.notification_channel_title)
+                        .setSourceMetricsCategory(SettingsEnums.DND_APPS_BYPASSING)
+                        .launch();
+                return true;
+            });
             mPreferenceCategory.addPreference(channelPreference);
         }
         mAllNotificationsToggle.setChecked(areAllChannelsBypassing());
diff --git a/src/com/android/settings/notification/app/ConversationListPreferenceController.java b/src/com/android/settings/notification/app/ConversationListPreferenceController.java
index 4d42483..b750a66 100644
--- a/src/com/android/settings/notification/app/ConversationListPreferenceController.java
+++ b/src/com/android/settings/notification/app/ConversationListPreferenceController.java
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.content.pm.ShortcutInfo;
 import android.os.Bundle;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.notification.ConversationChannelWrapper;
 import android.text.TextUtils;
@@ -97,7 +98,10 @@
                 conversation.getPkg(), conversation.getUid(),
                 conversation.getNotificationChannel().isImportantConversation()));
         pref.setKey(conversation.getNotificationChannel().getId());
-        pref.setIntent(getIntent(conversation, pref.getTitle()));
+        pref.setOnPreferenceClickListener(preference -> {
+            getSubSettingLauncher(conversation, pref.getTitle()).launch();
+            return true;
+        });
 
         return pref;
     }
@@ -116,7 +120,8 @@
                 : conversation.getNotificationChannel().getName();
     }
 
-    Intent getIntent(ConversationChannelWrapper conversation, CharSequence title) {
+    SubSettingLauncher getSubSettingLauncher(ConversationChannelWrapper conversation,
+            CharSequence title) {
         Bundle channelArgs = new Bundle();
         channelArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, conversation.getUid());
         channelArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, conversation.getPkg());
@@ -129,9 +134,9 @@
                 .setDestination(ChannelNotificationSettings.class.getName())
                 .setArguments(channelArgs)
                 .setExtras(channelArgs)
+                .setUserHandle(UserHandle.getUserHandleForUid(conversation.getUid()))
                 .setTitleText(title)
-                .setSourceMetricsCategory(SettingsEnums.NOTIFICATION_CONVERSATION_LIST_SETTINGS)
-                .toIntent();
+                .setSourceMetricsCategory(SettingsEnums.NOTIFICATION_CONVERSATION_LIST_SETTINGS);
     }
 
     protected Comparator<ConversationChannelWrapper> mConversationComparator =
diff --git a/src/com/android/settings/notification/zen/ZenModeAllBypassingAppsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeAllBypassingAppsPreferenceController.java
index 52c872c..fc034e5 100644
--- a/src/com/android/settings/notification/zen/ZenModeAllBypassingAppsPreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModeAllBypassingAppsPreferenceController.java
@@ -20,6 +20,7 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.os.Bundle;
+import android.os.UserHandle;
 
 import androidx.annotation.VisibleForTesting;
 import androidx.core.text.BidiFormatter;
@@ -137,6 +138,7 @@
                         new SubSettingLauncher(mContext)
                                 .setDestination(AppChannelsBypassingDndSettings.class.getName())
                                 .setArguments(args)
+                                .setUserHandle(UserHandle.getUserHandleForUid(app.info.uid))
                                 .setResultListener(mHostFragment, 0)
                                 .setSourceMetricsCategory(
                                         SettingsEnums.NOTIFICATION_ZEN_MODE_OVERRIDING_APP)
diff --git a/src/com/android/settings/panel/SettingsPanelActivity.java b/src/com/android/settings/panel/SettingsPanelActivity.java
index ce437bb..da46564 100644
--- a/src/com/android/settings/panel/SettingsPanelActivity.java
+++ b/src/com/android/settings/panel/SettingsPanelActivity.java
@@ -19,12 +19,14 @@
 import static com.android.settingslib.media.MediaOutputSliceConstants.EXTRA_PACKAGE_NAME;
 
 import android.content.Intent;
+import android.content.res.Configuration;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.Gravity;
 import android.view.Window;
 import android.view.WindowManager;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentActivity;
@@ -43,6 +45,8 @@
 
     @VisibleForTesting
     final Bundle mBundle = new Bundle();
+    @VisibleForTesting
+    boolean mForceCreation = false;
 
     /**
      * Key specifying which Panel the app is requesting.
@@ -59,8 +63,6 @@
      */
     public static final String KEY_MEDIA_PACKAGE_NAME = "PANEL_MEDIA_PACKAGE_NAME";
 
-    private boolean mForceCreation = false;
-
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -87,6 +89,12 @@
         mForceCreation = true;
     }
 
+    @Override
+    public void onConfigurationChanged(@NonNull Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        mForceCreation = true;
+    }
+
     private void createOrUpdatePanel(boolean shouldForceCreation) {
         final Intent callingIntent = getIntent();
         if (callingIntent == null) {
diff --git a/tests/robotests/src/com/android/settings/accounts/EmergencyInfoPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/EmergencyInfoPreferenceControllerTest.java
index 3217226..67ec836 100644
--- a/tests/robotests/src/com/android/settings/accounts/EmergencyInfoPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/EmergencyInfoPreferenceControllerTest.java
@@ -156,10 +156,11 @@
         final Preference preference = new Preference(activity);
         preference.setKey("emergency_info");
         mController = new EmergencyInfoPreferenceController(activity, preference.getKey());
+        mController.mIntent = new Intent("com.example.action.new").setPackage("com.example.test");
 
         mController.handlePreferenceTreeClick(preference);
 
         assertThat(application.getNextStartedActivity().getAction())
-                .isEqualTo("android.settings.EDIT_EMERGENCY_INFO");
+                .isEqualTo("com.example.action.new");
     }
 }
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceControllerTest.java
index 59f24dd..3f49b15 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceControllerTest.java
@@ -19,6 +19,7 @@
 import static com.android.settings.core.BasePreferenceController.AVAILABLE;
 import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
 import static com.android.settings.deviceinfo.firmwareversion.MainlineModuleVersionPreferenceController.MODULE_UPDATE_INTENT;
+import static com.android.settings.deviceinfo.firmwareversion.MainlineModuleVersionPreferenceController.MODULE_UPDATE_V2_INTENT;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -97,7 +98,33 @@
     }
 
     @Test
-    public void updateStates_canHandleIntent_setIntentToPreference() throws Exception {
+    public void updateState_canHandleV2Intent_setIntentToPreference() throws Exception {
+        setupModulePackage("test version 123");
+        when(mPackageManager.resolveActivity(MODULE_UPDATE_V2_INTENT, 0))
+                .thenReturn(new ResolveInfo());
+        final MainlineModuleVersionPreferenceController controller =
+                new MainlineModuleVersionPreferenceController(mContext, "key");
+
+        controller.updateState(mPreference);
+
+        assertThat(mPreference.getIntent()).isEqualTo(MODULE_UPDATE_V2_INTENT);
+    }
+
+    @Test
+    public void updateState_canHandleV2Intent_preferenceShouldBeSelectable() throws Exception {
+        setupModulePackage("test version 123");
+        when(mPackageManager.resolveActivity(MODULE_UPDATE_V2_INTENT, 0))
+                .thenReturn(new ResolveInfo());
+        final MainlineModuleVersionPreferenceController controller =
+                new MainlineModuleVersionPreferenceController(mContext, "key");
+
+        controller.updateState(mPreference);
+
+        assertThat(mPreference.isSelectable()).isTrue();
+    }
+
+    @Test
+    public void updateState_canHandleIntent_setIntentToPreference() throws Exception {
         setupModulePackage("test version 123");
         when(mPackageManager.resolveActivity(MODULE_UPDATE_INTENT, 0))
                 .thenReturn(new ResolveInfo());
@@ -111,7 +138,7 @@
     }
 
     @Test
-    public void updateStates_canHandleIntent_preferenceShouldBeSelectable() throws Exception {
+    public void updateState_canHandleIntent_preferenceShouldBeSelectable() throws Exception {
         setupModulePackage("test version 123");
         when(mPackageManager.resolveActivity(MODULE_UPDATE_INTENT, 0))
                 .thenReturn(new ResolveInfo());
@@ -125,10 +152,12 @@
     }
 
     @Test
-    public void updateStates_cannotHandleIntent_setNullToPreference() throws Exception {
+    public void updateState_cannotHandleIntent_setNullToPreference() throws Exception {
         setupModulePackage("test version 123");
         when(mPackageManager.resolveActivity(MODULE_UPDATE_INTENT, 0))
                 .thenReturn(null);
+        when(mPackageManager.resolveActivity(MODULE_UPDATE_V2_INTENT, 0))
+                .thenReturn(null);
 
         final MainlineModuleVersionPreferenceController controller =
                 new MainlineModuleVersionPreferenceController(mContext, "key");
diff --git a/tests/robotests/src/com/android/settings/notification/app/ConversationListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/ConversationListPreferenceControllerTest.java
index dc82adb..cbd9115 100644
--- a/tests/robotests/src/com/android/settings/notification/app/ConversationListPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/app/ConversationListPreferenceControllerTest.java
@@ -191,7 +191,7 @@
     }
 
     @Test
-    public void testGetIntent() {
+    public void testGetSubSettingLauncher() {
         ConversationChannelWrapper ccw = new ConversationChannelWrapper();
         NotificationChannel channel = new NotificationChannel("a", "child", 2);
         channel.setConversationId("parent", "convo id");
@@ -199,7 +199,7 @@
         ccw.setPkg("pkg");
         ccw.setUid(1);
         ccw.setParentChannelLabel("parent label");
-        Intent intent = mController.getIntent(ccw, "title");
+        Intent intent = mController.getSubSettingLauncher(ccw, "title").toIntent();
 
         Bundle extras = intent.getExtras();
         assertThat(extras.getString(AppInfoBase.ARG_PACKAGE_NAME)).isEqualTo(ccw.getPkg());
diff --git a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
index 44e5eefc..833d510 100644
--- a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
+++ b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
@@ -31,6 +31,7 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Intent;
+import android.content.res.Configuration;
 import android.os.Build;
 import android.view.Window;
 import android.view.WindowManager;
@@ -139,4 +140,12 @@
         assertThat(paramCaptor.getValue().privateFlags
                 & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0);
     }
+
+    @Test
+    public void onConfigurationChanged_shouldForceUpdate() {
+        mSettingsPanelActivity.mForceCreation = false;
+        mSettingsPanelActivity.onConfigurationChanged(new Configuration());
+
+        assertThat(mSettingsPanelActivity.mForceCreation).isTrue();
+    }
 }