Merge "Fix screen attention contextual card" into qt-r1-dev
diff --git a/res/layout/notif_importance_preference.xml b/res/layout/notif_importance_preference.xml
index 29c337a..44c135b 100644
--- a/res/layout/notif_importance_preference.xml
+++ b/res/layout/notif_importance_preference.xml
@@ -99,7 +99,7 @@
         <TextView
             android:id="@+id/silence_summary"
             android:paddingTop="@dimen/notification_importance_button_padding"
-            android:text="@string/notification_channel_summary_default"
+            android:text="@string/notification_channel_summary_low"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:clickable="false"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 11af027..2636e6e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -790,13 +790,13 @@
     <!-- Security Settings --><skip />
 
     <!-- Security settings screen, setting option name to change screen timeout -->
-    <string name="lock_after_timeout">Automatically lock</string>
+    <string name="lock_after_timeout">Lock after screen timeout</string>
     <!-- Security settings screen, setting option summary to change screen timeout -->
-    <string name="lock_after_timeout_summary"><xliff:g id="timeout_string">%1$s</xliff:g> after sleep</string>
+    <string name="lock_after_timeout_summary"><xliff:g id="timeout_string">%1$s</xliff:g> after timeout</string>
     <!-- Security settings screen, setting option summary to change screen timeout, with additional explanation-->
-    <string name="lock_immediately_summary_with_exception">Immediately after sleep, except when kept unlocked by <xliff:g id="trust_agent_name">%1$s</xliff:g></string>
+    <string name="lock_immediately_summary_with_exception">Immediately after timeout, except when kept unlocked by <xliff:g id="trust_agent_name">%1$s</xliff:g></string>
     <!-- Security settings screen, setting option summary to change screen timeout, with additional explanation-->
-    <string name="lock_after_timeout_summary_with_exception"><xliff:g id="timeout_string">%1$s</xliff:g> after sleep, except when kept unlocked by <xliff:g id="trust_agent_name">%2$s</xliff:g></string>
+    <string name="lock_after_timeout_summary_with_exception"><xliff:g id="timeout_string">%1$s</xliff:g> after timeout, except when kept unlocked by <xliff:g id="trust_agent_name">%2$s</xliff:g></string>
     <!-- Text shown next to checkbox for showing owner info on LockScreen [CHAR LIMIT=50]-->
     <string name="show_owner_info_on_lockscreen_label">Show owner info on lock screen</string>
     <!-- Text shown for title of owner info setting [CHAR LIMIT=20]-->
@@ -2829,14 +2829,15 @@
     <!-- Display settings screen, setting option name to enable adaptive sleep [CHAR LIMIT=30] -->
     <string name="adaptive_sleep_title">Screen attention</string>
     <!-- Setting option summary when adaptive sleep is on [CHAR LIMIT=NONE] -->
-    <string name="adaptive_sleep_summary_on">On / Screen won’t turn off if you’re looking at it</string>
+    <string name="adaptive_sleep_summary_on">On / Screen won\u2019t turn off if you\u2019re looking at it</string>
     <!-- Setting option summary when adaptive sleep is off [CHAR LIMIT=NONE] -->
     <string name="adaptive_sleep_summary_off">Off</string>
     <!-- Description about the feature adaptive sleep [CHAR LIMIT=NONE]-->
-    <string name="adaptive_sleep_description">Keep screen on when viewing it</string>
+    <string name="adaptive_sleep_description">Prevents your screen from turning off if you\u2019re looking at it</string>
     <!-- Description feature's privacy sensitive details to make sure users understand what feature users, what it saves/sends etc [CHAR LIMIT=NONE]-->
     <string name="adaptive_sleep_privacy">Screen attention uses the front camera to see if someone is looking at the screen. It works on device, and images are never stored or sent to Google.</string>
-
+    <!-- Description about the contextual adaptive sleep card [CHAR LIMIT=NONE]-->
+    <string name="adaptive_sleep_contextual_slice_summary">Keep screen on when viewing it</string>
 
     <!-- Night display screen, setting option name to enable night display (renamed "Night Light" with title caps). [CHAR LIMIT=30] -->
     <string name="night_display_title">Night Light</string>
@@ -7034,6 +7035,8 @@
     <string name="help_uri_wifi_scanning_required" translatable="false"></string>
     <!-- url for the bluetooth toggle required dialog help page -->
     <string name="help_uri_bluetooth_screen" translatable="false"></string>
+    <!-- url for the SIM combination warning required dialog help page -->
+    <string name="help_uri_sim_combination_warning" translatable="false"></string>
 
     <!-- User account title [CHAR LIMIT=30] -->
     <string name="user_account_title">Account for content</string>
@@ -10204,7 +10207,7 @@
     <!-- Title text for swipe up to switch apps [CHAR LIMIT=60] -->
     <string name="swipe_up_to_switch_apps_title">2-button navigation</string>
     <!-- Summary text for swipe up to switch apps  [CHAR LIMIT=250] -->
-    <string name="swipe_up_to_switch_apps_summary">To switch apps, swipe up on the Home button. Swipe up again to see all apps. Works from any screen. You’ll no longer have an Overview button on the bottom right of your screen.</string>
+    <string name="swipe_up_to_switch_apps_summary">To switch apps, swipe up on the Home button. To see all apps, swipe up again. To go back, tap the back button.</string>
     <!-- Title for settings suggestion for swipe up to switch apps [CHAR LIMIT=60] -->
     <string name="swipe_up_to_switch_apps_suggestion_title">Try the new Home button</string>
     <!-- Summary for settings suggestion for swipe up to switch apps [CHAR LIMIT=60] -->
@@ -10213,12 +10216,12 @@
     <!-- Title text for edge to edge navigation [CHAR LIMIT=60] -->
     <string name="edge_to_edge_navigation_title">Gesture navigation</string>
     <!-- Summary text for edge to edge navigation [CHAR LIMIT=NONE] -->
-    <string name="edge_to_edge_navigation_summary">To go Home, swipe up from the bottom of the screen. To go Back, swipe from either the left or right edge of the screen. To switch apps, start swiping up from the bottom of the screen and hold before releasing.</string>
+    <string name="edge_to_edge_navigation_summary">To go Home, swipe up from the bottom of the screen. To switch apps, swipe up from the bottom, hold, then release. To go back, swipe from either the left or right edge.</string>
 
     <!-- Title text for 3-button navigation [CHAR LIMIT=60] -->
     <string name="legacy_navigation_title">3-button navigation</string>
     <!-- Summary text for 3-button navigation  [CHAR LIMIT=NONE] -->
-    <string name="legacy_navigation_summary">Classic Android navigation mode where going Home, switching apps, and going Back are accessible via buttons.</string>
+    <string name="legacy_navigation_summary">Go back, Home, and switch apps with buttons at the bottom of your screen.</string>
 
     <!-- Search keywords for System Navigation settings. [CHAR_LIMIT=NONE]-->
     <string name="keywords_system_navigation">system navigation, 2 button navigation, 3 button navigation, gesture navigation</string>
@@ -10988,6 +10991,20 @@
     <!-- Label for the off position of a switch on the mobile network details page which allows
          disabling/enabling a SIM. The SIM is disabled in this state. [CHAR LIMIT=40] -->
     <string name="mobile_network_use_sim_off">Off</string>
+    <!-- Text shown in an information footer on the SIM details page for a physical SIM notifying
+         the user that the way to disable this SIM is to physically remove it. This is in contrast
+         to eSIM's, which can disabled using an on/off toggle switch. [CHAR LIMIT=NONE] -->
+    <string name="mobile_network_disable_sim_explanation">
+        To disable this SIM, remove the SIM card
+    </string>
+
+    <!--Summary used when a physical SIM is disabled, indicating that tapping on the preference will
+        enable the SIM. This may be used as the summary of the 'Mobile network' item on the
+        Network & internet page (if there are no other SIMs), or on the mobile network list page.
+        [CHAR LIMIT=50] -->
+    <string name="mobile_network_tap_to_activate">
+        Tap to activate <xliff:g id="carrier" example="T-mobile">%1$s</xliff:g>
+    </string>
 
     <!-- Title for a confirmation dialog when the user is enabling an eSIM subscription and there
          is already another active eSIM subscription which will need to be disabled if they proceed.
@@ -11279,4 +11296,12 @@
 
     <!-- Title for enable MMS notification channel.  [CHAR LIMIT=40] -->
     <string name="enable_mms_notification_channel_title">MMS message</string>
+
+    <!-- Title for SIM combination warning. [CHAR LIMIT=80] -->
+    <string name="sim_combination_warning_notification_title">Issue with SIM combination</string>
+    <!-- Message for DSDS dual CDMA SIM combination warning. [CHAR LIMIT=100] -->
+    <string name="dual_cdma_sim_warning_notification_summary">Using <xliff:g id="operator_names" example="T-Mobile &amp; Verizon">%1$s</xliff:g> may limit functionality. Tap to learn more.</string>
+
+    <!-- Title for enable MMS notification channel.  [CHAR LIMIT=40] -->
+    <string name="dual_cdma_sim_warning_notification_channel_title">SIM combination</string>
 </resources>
diff --git a/src/com/android/settings/applications/appinfo/ExternalSourcesDetails.java b/src/com/android/settings/applications/appinfo/ExternalSourcesDetails.java
index b723274..fe1d81c 100644
--- a/src/com/android/settings/applications/appinfo/ExternalSourcesDetails.java
+++ b/src/com/android/settings/applications/appinfo/ExternalSourcesDetails.java
@@ -18,6 +18,7 @@
 import static android.app.Activity.RESULT_CANCELED;
 import static android.app.Activity.RESULT_OK;
 
+import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.app.settings.SettingsEnums;
 import android.content.Context;
@@ -29,6 +30,7 @@
 import androidx.preference.Preference;
 import androidx.preference.Preference.OnPreferenceChangeListener;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
 import com.android.settings.Settings;
 import com.android.settings.applications.AppInfoWithHeader;
@@ -44,6 +46,7 @@
 
     private AppStateInstallAppsBridge mAppBridge;
     private AppOpsManager mAppOpsManager;
+    private ActivityManager mActivityManager;
     private UserManager mUserManager;
     private RestrictedSwitchPreference mSwitchPref;
     private InstallAppsState mInstallAppsState;
@@ -55,6 +58,7 @@
         final Context context = getActivity();
         mAppBridge = new AppStateInstallAppsBridge(context, mState, null);
         mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+        mActivityManager = context.getSystemService(ActivityManager.class);
         mUserManager = UserManager.get(context);
 
         addPreferencesFromResource(R.xml.external_sources_details);
@@ -99,10 +103,21 @@
                 : R.string.app_permission_summary_not_allowed);
     }
 
-    private void setCanInstallApps(boolean newState) {
+    @VisibleForTesting
+    void setCanInstallApps(boolean newState) {
         mAppOpsManager.setMode(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES,
                 mPackageInfo.applicationInfo.uid, mPackageName,
                 newState ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_ERRORED);
+        if (!newState) {
+            killApp(mPackageInfo.applicationInfo.uid);
+        }
+    }
+
+    private void killApp(int uid) {
+        if (UserHandle.isCore(uid)) {
+            return;
+        }
+        mActivityManager.killUid(uid, "User denied OP_REQUEST_INSTALL_PACKAGES");
     }
 
     @Override
diff --git a/src/com/android/settings/display/ColorModePreferenceFragment.java b/src/com/android/settings/display/ColorModePreferenceFragment.java
index c28de73..8736532 100644
--- a/src/com/android/settings/display/ColorModePreferenceFragment.java
+++ b/src/com/android/settings/display/ColorModePreferenceFragment.java
@@ -213,5 +213,12 @@
                     sir.xmlResId = R.xml.color_mode_settings;
                     return Arrays.asList(sir);
                 }
+
+                @Override
+                protected boolean isPageSearchEnabled(Context context) {
+                    final int[] availableColorModes = context.getResources().getIntArray(
+                            com.android.internal.R.array.config_availableColorModes);
+                    return availableColorModes != null && availableColorModes.length > 0;
+                }
             };
 }
diff --git a/src/com/android/settings/homepage/contextualcards/slices/ContextualAdaptiveSleepSlice.java b/src/com/android/settings/homepage/contextualcards/slices/ContextualAdaptiveSleepSlice.java
index 3b58fd3..3da5763 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/ContextualAdaptiveSleepSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/ContextualAdaptiveSleepSlice.java
@@ -80,7 +80,8 @@
             final IconCompat icon = IconCompat.createWithResource(mContext,
                     R.drawable.ic_settings_adaptive_sleep);
             final CharSequence title = mContext.getText(R.string.adaptive_sleep_title);
-            final CharSequence subtitle = mContext.getText(R.string.adaptive_sleep_description);
+            final CharSequence subtitle = mContext.getText(
+                    R.string.adaptive_sleep_contextual_slice_summary);
 
             final SliceAction pAction = SliceAction.createDeeplink(getPrimaryAction(),
                     icon,
diff --git a/src/com/android/settings/network/telephony/RoamingDialogFragment.java b/src/com/android/settings/network/telephony/RoamingDialogFragment.java
index c527d3c..1298445 100644
--- a/src/com/android/settings/network/telephony/RoamingDialogFragment.java
+++ b/src/com/android/settings/network/telephony/RoamingDialogFragment.java
@@ -61,12 +61,13 @@
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
         int title = R.string.roaming_alert_title;
+        int message = R.string.roaming_warning;
         PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
         if (carrierConfig != null && carrierConfig.getBoolean(
                 CarrierConfigManager.KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL)) {
-            title = R.string.roaming_check_price_warning;
+            message = R.string.roaming_check_price_warning;
         }
-        builder.setMessage(getResources().getString(R.string.roaming_warning))
+        builder.setMessage(getResources().getString(message))
                 .setTitle(title)
                 .setIconAttribute(android.R.attr.alertDialogIcon)
                 .setPositiveButton(android.R.string.yes, this)
diff --git a/src/com/android/settings/notification/GentleDrawablePreferenceController.java b/src/com/android/settings/notification/GentleDrawablePreferenceController.java
index cdadf5a..b4e18db 100644
--- a/src/com/android/settings/notification/GentleDrawablePreferenceController.java
+++ b/src/com/android/settings/notification/GentleDrawablePreferenceController.java
@@ -72,7 +72,7 @@
 
     private boolean showOnLockscreen() {
         return Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0) == ON;
+                Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, ON) == ON;
     }
 
     private boolean showOnStatusBar() {
diff --git a/src/com/android/settings/notification/GentleNotificationsPreferenceController.java b/src/com/android/settings/notification/GentleNotificationsPreferenceController.java
index 97e4e25..ea16e72 100644
--- a/src/com/android/settings/notification/GentleNotificationsPreferenceController.java
+++ b/src/com/android/settings/notification/GentleNotificationsPreferenceController.java
@@ -69,7 +69,7 @@
 
     private boolean showOnLockscreen() {
         return Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0) == ON;
+                Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, ON) == ON;
     }
 
     private boolean showOnStatusBar() {
diff --git a/src/com/android/settings/notification/ImportancePreference.java b/src/com/android/settings/notification/ImportancePreference.java
index 3e81d0c..b059f91 100644
--- a/src/com/android/settings/notification/ImportancePreference.java
+++ b/src/com/android/settings/notification/ImportancePreference.java
@@ -27,6 +27,7 @@
 import android.content.res.ColorStateList;
 import android.graphics.drawable.Drawable;
 import android.transition.AutoTransition;
+import android.transition.Transition;
 import android.transition.TransitionManager;
 import android.util.AttributeSet;
 import android.view.View;
@@ -112,6 +113,7 @@
             mAlertButton.setEnabled(false);
         }
 
+        setImportanceSummary((ViewGroup) holder.itemView, mImportance, false);
         switch (mImportance) {
             case IMPORTANCE_MIN:
             case IMPORTANCE_LOW:
@@ -126,23 +128,29 @@
                 mAlertButton.setSelected(true);
                 break;
         }
-        setImportanceSummary((ViewGroup) holder.itemView, mImportance, false);
 
         mSilenceButton.setOnClickListener(v -> {
             callChangeListener(IMPORTANCE_LOW);
             mAlertButton.setBackground(unselectedBackground);
-            mAlertButton.setSelected(false);
             mSilenceButton.setBackground(selectedBackground);
-            mSilenceButton.setSelected(true);
             setImportanceSummary((ViewGroup) holder.itemView, IMPORTANCE_LOW, true);
+            // a11y service won't always read the newly appearing text in the right order if the
+            // selection happens too soon (readback happens on a different thread as layout). post
+            // the selection to make that conflict less likely
+            holder.itemView.post(() -> {
+                mAlertButton.setSelected(false);
+                mSilenceButton.setSelected(true);
+            });
         });
         mAlertButton.setOnClickListener(v -> {
             callChangeListener(IMPORTANCE_DEFAULT);
             mSilenceButton.setBackground(unselectedBackground);
-            mSilenceButton.setSelected(false);
             mAlertButton.setBackground(selectedBackground);
-            mAlertButton.setSelected(true);
             setImportanceSummary((ViewGroup) holder.itemView, IMPORTANCE_DEFAULT, true);
+            holder.itemView.post(() -> {
+                mSilenceButton.setSelected(false);
+                mAlertButton.setSelected(true);
+            });
         });
     }
 
@@ -172,9 +180,7 @@
             ((ImageView) parent.findViewById(R.id.alert_icon)).setImageTintList(colorAccent);
             ((TextView) parent.findViewById(R.id.alert_label)).setTextColor(colorAccent);
 
-            TextView view = parent.findViewById(R.id.alert_summary);
-            view.setText(R.string.notification_channel_summary_default);
-            view.setVisibility(VISIBLE);
+            parent.findViewById(R.id.alert_summary).setVisibility(VISIBLE);
         } else {
             parent.findViewById(R.id.alert_summary).setVisibility(GONE);
             ((ImageView) parent.findViewById(R.id.alert_icon)).setImageTintList(colorNormal);
@@ -182,9 +188,7 @@
 
             ((ImageView) parent.findViewById(R.id.silence_icon)).setImageTintList(colorAccent);
             ((TextView) parent.findViewById(R.id.silence_label)).setTextColor(colorAccent);
-            TextView view = parent.findViewById(R.id.silence_summary);
-            view.setVisibility(VISIBLE);
-            view.setText(R.string.notification_channel_summary_low);
+            parent.findViewById(R.id.silence_summary).setVisibility(VISIBLE);
         }
     }
 }
diff --git a/src/com/android/settings/notification/ImportancePreferenceController.java b/src/com/android/settings/notification/ImportancePreferenceController.java
index dc59275..4ef4593 100644
--- a/src/com/android/settings/notification/ImportancePreferenceController.java
+++ b/src/com/android/settings/notification/ImportancePreferenceController.java
@@ -66,7 +66,7 @@
             pref.setImportance(mChannel.getImportance());
             pref.setDisplayInStatusBar(mBackend.showSilentInStatusBar(mContext.getPackageName()));
             pref.setDisplayOnLockscreen(Settings.Secure.getInt(mContext.getContentResolver(),
-                    Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0) == 1);
+                    Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1) == 1);
         }
     }
 
diff --git a/src/com/android/settings/notification/ShowOnLockScreenNotificationPreferenceController.java b/src/com/android/settings/notification/ShowOnLockScreenNotificationPreferenceController.java
index 5d08ac7..df1f4a2 100644
--- a/src/com/android/settings/notification/ShowOnLockScreenNotificationPreferenceController.java
+++ b/src/com/android/settings/notification/ShowOnLockScreenNotificationPreferenceController.java
@@ -150,11 +150,11 @@
 
     private boolean getLockscreenNotificationsEnabled() {
         return Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0) != 0;
+                Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1) != 0;
     }
 
     private boolean getLockscreenSilentNotificationsEnabled() {
         return Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0) != 0;
+                Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1) != 0;
     }
 }
diff --git a/src/com/android/settings/notification/SilentLockscreenPreferenceController.java b/src/com/android/settings/notification/SilentLockscreenPreferenceController.java
index 219d312..317f7da 100644
--- a/src/com/android/settings/notification/SilentLockscreenPreferenceController.java
+++ b/src/com/android/settings/notification/SilentLockscreenPreferenceController.java
@@ -38,7 +38,7 @@
     @Override
     public boolean isChecked() {
         return Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0) == 1;
+                Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1) == 1;
     }
 
     @Override
diff --git a/src/com/android/settings/sim/SimSelectNotification.java b/src/com/android/settings/sim/SimSelectNotification.java
index d228b6e..a303e42 100644
--- a/src/com/android/settings/sim/SimSelectNotification.java
+++ b/src/com/android/settings/sim/SimSelectNotification.java
@@ -24,6 +24,10 @@
 import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL;
 import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA;
 import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE;
+import static android.telephony.TelephonyManager.EXTRA_SIM_COMBINATION_NAMES;
+import static android.telephony.TelephonyManager.EXTRA_SIM_COMBINATION_WARNING_TYPE;
+import static android.telephony.TelephonyManager.EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA;
+import static android.telephony.TelephonyManager.EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE;
 import static android.telephony.TelephonyManager.EXTRA_SUBSCRIPTION_ID;
 import static android.telephony.data.ApnSetting.TYPE_MMS;
 
@@ -43,6 +47,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
 import com.android.settings.network.telephony.MobileNetworkActivity;
+import com.android.settingslib.HelpUtils;
 
 public class SimSelectNotification extends BroadcastReceiver {
     private static final String TAG = "SimSelectNotification";
@@ -50,6 +55,8 @@
     public static final int SIM_SELECT_NOTIFICATION_ID = 1;
     @VisibleForTesting
     public static final int ENABLE_MMS_NOTIFICATION_ID = 2;
+    @VisibleForTesting
+    public static final int SIM_WARNING_NOTIFICATION_ID = 3;
 
     @VisibleForTesting
     public static final String SIM_SELECT_NOTIFICATION_CHANNEL =
@@ -59,6 +66,10 @@
     public static final String ENABLE_MMS_NOTIFICATION_CHANNEL =
             "enable_mms_notification_channel";
 
+    @VisibleForTesting
+    public static final String SIM_WARNING_NOTIFICATION_CHANNEL =
+            "sim_warning_notification_channel";
+
     @Override
     public void onReceive(Context context, Intent intent) {
         String action = intent.getAction();
@@ -125,13 +136,23 @@
     }
 
     private void onPrimarySubscriptionListChanged(Context context, Intent intent) {
+        startSimSelectDialogIfNeeded(context, intent);
+        sendSimCombinationWarningIfNeeded(context, intent);
+    }
+
+    private void startSimSelectDialogIfNeeded(Context context, Intent intent) {
+        int dialogType = intent.getIntExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE,
+                EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE);
+
+        if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE) {
+            return;
+        }
+
         // Cancel any previous notifications
         cancelSimSelectNotification(context);
         // Create a notification to tell the user that some defaults are missing
         createSimSelectNotification(context);
 
-        int dialogType = intent.getIntExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE,
-                EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE);
         if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL) {
             int subId = intent.getIntExtra(EXTRA_SUBSCRIPTION_ID,
                     SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
@@ -139,11 +160,12 @@
             // If there is only one subscription, ask if user wants to use if for everything
             Intent newIntent = new Intent(context, SimDialogActivity.class);
             newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            newIntent.putExtra(SimDialogActivity.DIALOG_TYPE_KEY, SimDialogActivity.PREFERRED_PICK);
+            newIntent.putExtra(SimDialogActivity.DIALOG_TYPE_KEY,
+                    SimDialogActivity.PREFERRED_PICK);
             newIntent.putExtra(SimDialogActivity.PREFERRED_SIM, slotIndex);
             context.startActivity(newIntent);
         } else if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA) {
-            // If there are mulitple, ensure they pick default data
+            // If there are multiple, ensure they pick default data
             Intent newIntent = new Intent(context, SimDialogActivity.class);
             newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             newIntent.putExtra(SimDialogActivity.DIALOG_TYPE_KEY, SimDialogActivity.DATA_PICK);
@@ -151,6 +173,18 @@
         }
     }
 
+    private void sendSimCombinationWarningIfNeeded(Context context, Intent intent) {
+        final int warningType = intent.getIntExtra(EXTRA_SIM_COMBINATION_WARNING_TYPE,
+                EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE);
+
+        if (warningType == EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA) {
+            // Cancel any previous notifications
+            cancelSimCombinationWarningNotification(context);
+            // Create a notification to tell the user that some defaults are missing
+            createSimCombinationWarningNotification(context, intent);
+        }
+    }
+
     private void createSimSelectNotification(Context context){
         final Resources resources = context.getResources();
 
@@ -222,4 +256,52 @@
                 (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
         notificationManager.cancel(ENABLE_MMS_NOTIFICATION_ID);
     }
+
+    private void createSimCombinationWarningNotification(Context context, Intent intent){
+        final Resources resources = context.getResources();
+        final String simNames = intent.getStringExtra(EXTRA_SIM_COMBINATION_NAMES);
+
+        if (simNames == null) {
+            return;
+        }
+
+        CharSequence dualCdmaSimWarningSummary = resources.getString(
+                R.string.dual_cdma_sim_warning_notification_summary, simNames);
+
+        NotificationChannel notificationChannel = new NotificationChannel(
+                SIM_WARNING_NOTIFICATION_CHANNEL,
+                resources.getText(R.string.dual_cdma_sim_warning_notification_channel_title),
+                NotificationManager.IMPORTANCE_HIGH);
+
+        Notification.Builder builder =
+                new Notification.Builder(context, SIM_WARNING_NOTIFICATION_CHANNEL)
+                        .setSmallIcon(R.drawable.ic_sim_card_alert_white_48dp)
+                        .setColor(context.getColor(R.color.sim_noitification))
+                        .setContentTitle(resources.getText(
+                                R.string.sim_combination_warning_notification_title))
+                        .setContentText(dualCdmaSimWarningSummary)
+                        .setStyle(new Notification.BigTextStyle().bigText(
+                                dualCdmaSimWarningSummary))
+                        .setAutoCancel(true);
+
+        // Create the pending intent that will lead to the helper page.
+        Intent resultIntent = HelpUtils.getHelpIntent(
+                context,
+                context.getString(R.string.help_uri_sim_combination_warning),
+                context.getClass().getName());
+        PendingIntent resultPendingIntent = PendingIntent.getActivity(context, 0, resultIntent,
+                PendingIntent.FLAG_CANCEL_CURRENT);
+        builder.setContentIntent(resultPendingIntent);
+
+        NotificationManager notificationManager =
+                context.getSystemService(NotificationManager.class);
+        notificationManager.createNotificationChannel(notificationChannel);
+        notificationManager.notify(SIM_WARNING_NOTIFICATION_ID, builder.build());
+    }
+
+    public static void cancelSimCombinationWarningNotification(Context context) {
+        NotificationManager notificationManager =
+                context.getSystemService(NotificationManager.class);
+        notificationManager.cancel(SIM_WARNING_NOTIFICATION_ID);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/ExternalSourcesDetailsTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/ExternalSourcesDetailsTest.java
index 10c2675..002a0bc 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/ExternalSourcesDetailsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/ExternalSourcesDetailsTest.java
@@ -19,11 +19,17 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
+import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.pm.ApplicationInfo;
@@ -55,6 +61,10 @@
     @Mock
     private UserManager mUserManager;
     @Mock
+    private ActivityManager mActivityManager;
+    @Mock
+    private AppOpsManager mAppOpsManager;
+    @Mock
     private RestrictedSwitchPreference mSwitchPref;
     @Mock
     private RestrictedPreferenceHelper mHelper;
@@ -69,10 +79,47 @@
 
         mFragment = new ExternalSourcesDetails();
         ReflectionHelpers.setField(mFragment, "mUserManager", mUserManager);
+        ReflectionHelpers.setField(mFragment, "mActivityManager", mActivityManager);
+        ReflectionHelpers.setField(mFragment, "mAppOpsManager", mAppOpsManager);
         ReflectionHelpers.setField(mFragment, "mSwitchPref", mSwitchPref);
     }
 
     @Test
+    public void setCanInstallApps_false_shouldKillNonCoreUid() {
+        int mockUid = 23456;
+        ReflectionHelpers.setField(mFragment, "mPackageInfo", mPackageInfo);
+
+        mPackageInfo.applicationInfo = new ApplicationInfo();
+        mPackageInfo.applicationInfo.uid = mockUid;
+        assertThat(UserHandle.isCore(mockUid)).isFalse();
+        mFragment.setCanInstallApps(false);
+        verify(mActivityManager).killUid(eq(mockUid), anyString());
+    }
+
+    @Test
+    public void setCanInstallApps_false_shouldNotKillCoreUid() {
+        int mockUid = 1234;
+        ReflectionHelpers.setField(mFragment, "mPackageInfo", mPackageInfo);
+
+        mPackageInfo.applicationInfo = new ApplicationInfo();
+        mPackageInfo.applicationInfo.uid = mockUid;
+        assertThat(UserHandle.isCore(mockUid)).isTrue();
+        mFragment.setCanInstallApps(false);
+        verify(mActivityManager, never()).killUid(eq(mockUid), anyString());
+    }
+
+    @Test
+    public void setCanInstallApps_true_shouldNotKillUid() {
+        int mockUid = 23456;
+        ReflectionHelpers.setField(mFragment, "mPackageInfo", mPackageInfo);
+
+        mPackageInfo.applicationInfo = new ApplicationInfo();
+        mPackageInfo.applicationInfo.uid = mockUid;
+        mFragment.setCanInstallApps(true);
+        verify(mActivityManager, never()).killUid(eq(mockUid), anyString());
+    }
+
+    @Test
     public void refreshUi_noPackageInfo_shouldReturnFalseAndNoCrash() {
         mFragment.refreshUi();
 
diff --git a/tests/robotests/src/com/android/settings/notification/ShowOnLockscreenNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ShowOnLockscreenNotificationPreferenceControllerTest.java
index 6907051..a341def 100644
--- a/tests/robotests/src/com/android/settings/notification/ShowOnLockscreenNotificationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ShowOnLockscreenNotificationPreferenceControllerTest.java
@@ -133,6 +133,18 @@
     }
 
     @Test
+    public void updateState_allNotifsOnLockscreen_isDefault() {
+        // settings don't exist
+
+        mController.updateState(mPreference);
+
+        assertThat(mPreference.getValue()).isEqualTo(
+                String.valueOf(R.string.lock_screen_notifs_show_all));
+        assertThat(mPreference.getSummary())
+                .isEqualTo(mContext.getString(R.string.lock_screen_notifs_show_all));
+    }
+
+    @Test
     public void updateState_dpmSaysNo() {
         Settings.Secure.putInt(mContext.getContentResolver(),
                 LOCK_SCREEN_SHOW_NOTIFICATIONS,
diff --git a/tests/robotests/src/com/android/settings/sim/SimSelectNotificationTest.java b/tests/robotests/src/com/android/settings/sim/SimSelectNotificationTest.java
index 69c0919..5a2dd48 100644
--- a/tests/robotests/src/com/android/settings/sim/SimSelectNotificationTest.java
+++ b/tests/robotests/src/com/android/settings/sim/SimSelectNotificationTest.java
@@ -21,10 +21,15 @@
 import static android.provider.Settings.ENABLE_MMS_DATA_REQUEST_REASON_OUTGOING_MMS;
 import static android.provider.Settings.EXTRA_ENABLE_MMS_DATA_REQUEST_REASON;
 import static android.provider.Settings.EXTRA_SUB_ID;
+import static android.telephony.TelephonyManager.EXTRA_SIM_COMBINATION_NAMES;
+import static android.telephony.TelephonyManager.EXTRA_SIM_COMBINATION_WARNING_TYPE;
+import static android.telephony.TelephonyManager.EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA;
 import static android.telephony.data.ApnSetting.TYPE_MMS;
 
 import static com.android.settings.sim.SimSelectNotification.ENABLE_MMS_NOTIFICATION_CHANNEL;
 import static com.android.settings.sim.SimSelectNotification.ENABLE_MMS_NOTIFICATION_ID;
+import static com.android.settings.sim.SimSelectNotification.SIM_WARNING_NOTIFICATION_CHANNEL;
+import static com.android.settings.sim.SimSelectNotification.SIM_WARNING_NOTIFICATION_ID;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -76,10 +81,16 @@
     @Mock
     private Resources mResources;
 
-    private String mFakeOperatorName = "fake_operator_name";
-    private CharSequence mFakeNotificationChannelTitle = "fake_notification_channel_title";
-    private CharSequence mFakeNotificationTitle = "fake_notification_title";
-    private String mFakeNotificationSummary = "fake_notification_Summary";
+    private final String mFakeOperatorName = "fake_operator_name";
+    private final CharSequence mFakeNotificationChannelTitle = "fake_notification_channel_title";
+    private final CharSequence mFakeNotificationTitle = "fake_notification_title";
+    private final String mFakeNotificationSummary = "fake_notification_Summary";
+
+    // Dual CDMA combination notification.
+    private final String mFakeDualCdmaWarningChannelTitle = "fake_dual_cdma_warning_channel_title";
+    private final String mFakeDualCdmaWarningTitle = "fake_dual_cdma_warning_title";
+    private final String mFakeDualCdmaWarningSummary = "fake_dual_cdma_warning_summary";
+    private final String mSimCombinationName = " carrier1 & carrier 2";
 
     private int mSubId = 1;
 
@@ -90,6 +101,8 @@
         MockitoAnnotations.initMocks(this);
         when(mContext.getSystemService(Context.NOTIFICATION_SERVICE))
                 .thenReturn(mNotificationManager);
+        when(mContext.getSystemService(NotificationManager.class))
+                .thenReturn(mNotificationManager);
         when(mContext.getSystemService(Context.TELEPHONY_SERVICE))
                 .thenReturn(mTelephonyManager);
         when(mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE))
@@ -111,6 +124,13 @@
                 .thenReturn(mFakeNotificationChannelTitle);
         when(mResources.getString(R.string.enable_mms_notification_summary,
                 mFakeOperatorName)).thenReturn(mFakeNotificationSummary);
+
+        when(mResources.getText(R.string.dual_cdma_sim_warning_notification_channel_title))
+                .thenReturn(mFakeDualCdmaWarningChannelTitle);
+        when(mResources.getText(R.string.sim_combination_warning_notification_title))
+                .thenReturn(mFakeDualCdmaWarningTitle);
+        when(mResources.getString(R.string.dual_cdma_sim_warning_notification_summary,
+                mSimCombinationName)).thenReturn(mFakeDualCdmaWarningSummary);
     }
 
     @Test
@@ -162,5 +182,43 @@
         mSimSelectNotification.onReceive(mContext, intent);
         verify(mNotificationManager, never()).createNotificationChannel(any());
     }
+
+    @Test
+    public void onReceivePrimarySubListChange_NoExtra_notificationShouldNotSend() {
+        Intent intent = new Intent(TelephonyManager.ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED);
+
+        // EXTRA_SUB_ID and EXTRA_ENABLE_MMS_DATA_REQUEST_REASON are required.
+        mSimSelectNotification.onReceive(mContext, intent);
+        verify(mNotificationManager, never()).createNotificationChannel(any());
+    }
+
+    @Test
+    public void onReceivePrimarySubListChange_DualCdmaWarning_notificationShouldSend() {
+        Intent intent = new Intent(TelephonyManager.ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED);
+
+        intent.putExtra(EXTRA_SIM_COMBINATION_NAMES, mSimCombinationName);
+        intent.putExtra(EXTRA_SIM_COMBINATION_WARNING_TYPE,
+                EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA);
+
+        mSimSelectNotification.onReceive(mContext, intent);
+
+        // Capture the notification channel created and verify its fields.
+        ArgumentCaptor<NotificationChannel> nc = ArgumentCaptor.forClass(NotificationChannel.class);
+        verify(mNotificationManager).createNotificationChannel(nc.capture());
+
+        assertThat(nc.getValue().getId()).isEqualTo(SIM_WARNING_NOTIFICATION_CHANNEL);
+        assertThat(nc.getValue().getName()).isEqualTo(mFakeDualCdmaWarningChannelTitle);
+        assertThat(nc.getValue().getImportance()).isEqualTo(IMPORTANCE_HIGH);
+
+        // Capture the notification it notifies and verify its fields.
+        ArgumentCaptor<Notification> notification = ArgumentCaptor.forClass(Notification.class);
+        verify(mNotificationManager).notify(
+                eq(SIM_WARNING_NOTIFICATION_ID), notification.capture());
+        assertThat(notification.getValue().extras.getCharSequence(Notification.EXTRA_TITLE))
+                .isEqualTo(mFakeDualCdmaWarningTitle);
+        assertThat(notification.getValue().extras.getCharSequence(Notification.EXTRA_BIG_TEXT))
+                .isEqualTo(mFakeDualCdmaWarningSummary);
+        assertThat(notification.getValue().contentIntent).isNotNull();
+    }
 }