Merge "DO NOT MERGE Allow app switches for accessibility services" into qt-qpr1-dev
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index efa0432..8f2aea3 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -2562,6 +2562,12 @@
         }
     }
 
+    @Override
+    protected boolean shouldAddFooterView() {
+        // To accommodate for window insets
+        return true;
+    }
+
     public class ChooserListAdapter extends ResolveListAdapter {
         public static final int TARGET_BAD = -1;
         public static final int TARGET_CALLER = 0;
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index f82c28e..3a9d4d5 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -382,14 +382,30 @@
         finish();
     }
 
+    /**
+     * Numerous layouts are supported, each with optional ViewGroups.
+     * Make sure the inset gets added to the correct View, using
+     * a footer for Lists so it can properly scroll under the navbar.
+     */
+    protected boolean shouldAddFooterView() {
+        if (useLayoutWithDefault()) return true;
+
+        View buttonBar = findViewById(R.id.button_bar);
+        if (buttonBar == null || buttonBar.getVisibility() == View.GONE) return true;
+
+        return false;
+    }
+
     protected WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
         mSystemWindowInsets = insets.getSystemWindowInsets();
 
         mResolverDrawerLayout.setPadding(mSystemWindowInsets.left, mSystemWindowInsets.top,
                 mSystemWindowInsets.right, 0);
 
+        resetButtonBar();
+
         // Need extra padding so the list can fully scroll up
-        if (useLayoutWithDefault()) {
+        if (shouldAddFooterView()) {
             if (mFooterSpacer == null) {
                 mFooterSpacer = new Space(getApplicationContext());
             } else {
@@ -407,8 +423,6 @@
             }
         }
 
-        resetButtonBar();
-
         return insets.consumeSystemWindowInsets();
     }
 
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 6289262..2b37a0c 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -1733,6 +1733,7 @@
         <item name="colorBackground">@color/background_device_default_light</item>
         <item name="colorBackgroundFloating">@color/background_device_default_light</item>
         <item name="layout_gravity">center</item>
+        <item name="windowAnimationStyle">@style/Animation.DeviceDefault.Dialog</item>
     </style>
 
     <style name="Theme.DeviceDefault.Notification" parent="@style/Theme.Material.Notification">
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
index 39c9632..6474b39 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
@@ -81,12 +81,6 @@
         });
     }
 
-    private void animate() {
-        mAnimator.cancel();
-        mAnimator.setFloatValues(mReveal, mAwake ? MAX_REVEAL : MIN_REVEAL);
-        mAnimator.start();
-    }
-
     public float getReveal() {
         return mReveal;
     }
@@ -95,8 +89,8 @@
         if (DEBUG) {
             Log.d(TAG, "updateAwake: awake=" + awake + ", duration=" + duration);
         }
+        mAnimator.cancel();
         mAwake = awake;
-        mAnimator.setDuration(duration);
         if (duration == 0) {
             // We are transiting from home to aod or aod to home directly,
             // we don't need to do transition in these cases.
@@ -105,7 +99,9 @@
             mRevealListener.onRevealStateChanged();
             mRevealListener.onRevealEnd();
         } else {
-            animate();
+            mAnimator.setDuration(duration);
+            mAnimator.setFloatValues(mReveal, mAwake ? MAX_REVEAL : MIN_REVEAL);
+            mAnimator.start();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index da2692e..9b30a77 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -475,9 +475,9 @@
                     SystemUiDeviceConfigFlags
                             .SCREENSHOT_NOTIFICATION_SMART_ACTIONS_TIMEOUT_MS,
                     1000);
-            List<Notification.Action> smartActions = buildSmartActions(
-                    GlobalScreenshot.getSmartActions(mScreenshotId, smartActionsFuture,
-                            timeoutMs, mSmartActionsProvider), context);
+            List<Notification.Action> smartActions = GlobalScreenshot.getSmartActions(mScreenshotId,
+                    smartActionsFuture, timeoutMs, mSmartActionsProvider);
+            smartActions = buildSmartActions(smartActions, context);
             for (Notification.Action action : smartActions) {
                 notificationBuilder.addAction(action);
             }
@@ -1082,8 +1082,8 @@
             List<Notification.Action> actions = smartActionsFuture.get(timeoutMs,
                     TimeUnit.MILLISECONDS);
             long waitTimeMs = SystemClock.uptimeMillis() - startTimeMs;
-            Slog.d(TAG, String.format("Wait time for smart actions: %d ms",
-                    waitTimeMs));
+            Slog.d(TAG, String.format("Got %d smart actions. Wait time: %d ms",
+                    actions.size(), waitTimeMs));
             notifyScreenshotOp(screenshotId, smartActionsProvider,
                     ScreenshotNotificationSmartActionsProvider.ScreenshotOp.WAIT_FOR_SMART_ACTIONS,
                     ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus.SUCCESS,
@@ -1091,7 +1091,8 @@
             return actions;
         } catch (Throwable e) {
             long waitTimeMs = SystemClock.uptimeMillis() - startTimeMs;
-            Slog.d(TAG, "Failed to obtain screenshot notification smart actions.", e);
+            Slog.e(TAG, String.format("Error getting smart actions. Wait time: %d ms", waitTimeMs),
+                    e);
             ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus status =
                     (e instanceof TimeoutException)
                             ? ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus.TIMEOUT
@@ -1209,14 +1210,16 @@
     public static class SmartActionsReceiver extends BroadcastReceiver {
         @Override
         public void onReceive(Context context, Intent intent) {
-            PendingIntent actionIntent = intent.getParcelableExtra(EXTRA_ACTION_INTENT);
+            PendingIntent pendingIntent = intent.getParcelableExtra(EXTRA_ACTION_INTENT);
+            Intent actionIntent = pendingIntent.getIntent();
+            String actionType = intent.getStringExtra(EXTRA_ACTION_TYPE);
+            Slog.d(TAG, "Executing smart action [" + actionType + "]:" + actionIntent);
             ActivityOptions opts = ActivityOptions.makeBasic();
-            context.startActivityAsUser(actionIntent.getIntent(), opts.toBundle(),
+            context.startActivityAsUser(actionIntent, opts.toBundle(),
                     UserHandle.CURRENT);
 
-            Slog.d(TAG, "Screenshot notification smart action is invoked.");
             notifyScreenshotAction(context, intent.getStringExtra(EXTRA_ID),
-                    intent.getStringExtra(EXTRA_ACTION_TYPE),
+                    actionType,
                     true);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index aa7fce7..7f11759 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -2638,7 +2638,7 @@
                 if (mRemoteInputManager.getController() != null) {
                     mRemoteInputManager.getController().closeRemoteInputs();
                 }
-                if (mBubbleController.isStackExpanded()) {
+                if (mBubbleController != null && mBubbleController.isStackExpanded()) {
                     mBubbleController.collapseStack();
                 }
                 if (mLockscreenUserManager.isCurrentProfile(getSendingUserId())) {
@@ -2654,7 +2654,7 @@
                 if (mStatusBarWindowController != null) {
                     mStatusBarWindowController.setNotTouchable(false);
                 }
-                if (mBubbleController.isStackExpanded()) {
+                if (mBubbleController != null && mBubbleController.isStackExpanded()) {
                     mBubbleController.collapseStack();
                 }
                 finishBarAnimations();
@@ -3386,7 +3386,9 @@
             if (mNotificationPanel.canPanelBeCollapsed()) {
                 animateCollapsePanels();
             } else {
-                mBubbleController.performBackPressIfNeeded();
+                if (mBubbleController != null) {
+                    mBubbleController.performBackPressIfNeeded();
+                }
             }
             return true;
         }
diff --git a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
index 183e059..ebfc2a0 100644
--- a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
+++ b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
@@ -66,9 +66,7 @@
         setCancelable(false);
         Resources res = getContext().getResources();
         // Custom view due to alignment and font size requirements
-        // TODO (b/145021634): disabled because it's delaying user switch by 3 seconds
-        // getContext()
-        // .setTheme(R.style.Theme_DeviceDefault_Light_Dialog_Alert_UserSwitchingDialog);
+        getContext().setTheme(R.style.Theme_DeviceDefault_Light_Dialog_Alert_UserSwitchingDialog);
         View view = LayoutInflater.from(getContext()).inflate(
                 R.layout.car_user_switching_dialog,
                 null);
diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS
index 877bef7..bd17e84 100644
--- a/services/core/java/com/android/server/am/OWNERS
+++ b/services/core/java/com/android/server/am/OWNERS
@@ -31,3 +31,5 @@
 narayan@google.com
 
 per-file SettingsToPropertiesMapper.java = omakoto@google.com, svetoslavganov@google.com, yamasani@google.com
+
+per-file CarUserSwitchingDialog.java = keunyoung@google.com, felipeal@google.com, gurunagarajan@google.com
diff --git a/services/core/java/com/android/server/am/UserSwitchingDialog.java b/services/core/java/com/android/server/am/UserSwitchingDialog.java
index 98f5557..0ec4454 100644
--- a/services/core/java/com/android/server/am/UserSwitchingDialog.java
+++ b/services/core/java/com/android/server/am/UserSwitchingDialog.java
@@ -24,6 +24,7 @@
 import android.os.Message;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.util.Slog;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewTreeObserver;
@@ -46,6 +47,9 @@
     // Time to wait for the onWindowShown() callback before continuing the user switch
     private static final int WINDOW_SHOWN_TIMEOUT_MS = 3000;
 
+    // User switching doesn't happen that frequently, so it doesn't hurt to have it always on
+    protected static final boolean DEBUG = true;
+
     private final ActivityManagerService mService;
     private final int mUserId;
     private static final int MSG_START_USER = 1;
@@ -118,7 +122,7 @@
 
     @Override
     public void show() {
-        // Slog.v(TAG, "show called");
+        if (DEBUG) Slog.d(TAG, "show called");
         super.show();
         final View decorView = getWindow().getDecorView();
         if (decorView != null) {
@@ -132,13 +136,14 @@
 
     @Override
     public void onWindowShown() {
-        // Slog.v(TAG, "onWindowShown called");
+        if (DEBUG) Slog.d(TAG, "onWindowShown called");
         startUser();
     }
 
     void startUser() {
         synchronized (this) {
             if (!mStartedUser) {
+                Slog.i(TAG, "starting user " + mUserId);
                 mService.mUserController.startUserInForeground(mUserId);
                 dismiss();
                 mStartedUser = true;
@@ -147,6 +152,8 @@
                     decorView.getViewTreeObserver().removeOnWindowShownListener(this);
                 }
                 mHandler.removeMessages(MSG_START_USER);
+            } else {
+                Slog.i(TAG, "user " + mUserId + " already started");
             }
         }
     }
@@ -156,6 +163,8 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case MSG_START_USER:
+                    Slog.w(TAG, "user switch window not shown in "
+                            + WINDOW_SHOWN_TIMEOUT_MS + " ms");
                     startUser();
                     break;
             }
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index 163be51..628dc93 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -89,8 +89,8 @@
     private int mCarrierId;
 
     /**
-     * The source of the name, NAME_SOURCE_DEFAULT_SOURCE, NAME_SOURCE_SIM_SOURCE or
-     * NAME_SOURCE_USER_INPUT.
+     * The source of the name, NAME_SOURCE_DEFAULT_SOURCE, NAME_SOURCE_SIM_SPN,
+     * NAME_SOURCE_SIM_PNN, or NAME_SOURCE_USER_INPUT.
      */
     private int mNameSource;
 
@@ -334,7 +334,7 @@
     }
 
     /**
-     * @return the source of the name, eg NAME_SOURCE_DEFAULT_SOURCE, NAME_SOURCE_SIM_SOURCE or
+     * @return the source of the name, eg NAME_SOURCE_DEFAULT_SOURCE, NAME_SOURCE_SIM_SPN or
      * NAME_SOURCE_USER_INPUT.
      * @hide
      */
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index c3a7985..e2ac1f2 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -393,19 +393,19 @@
     public static final String NAME_SOURCE = "name_source";
 
     /**
-     * The name_source is the default
+     * The name_source is the default, which is from the carrier id.
      * @hide
      */
     public static final int NAME_SOURCE_DEFAULT_SOURCE = 0;
 
     /**
-     * The name_source is from the SIM
+     * The name_source is from SIM EF_SPN.
      * @hide
      */
-    public static final int NAME_SOURCE_SIM_SOURCE = 1;
+    public static final int NAME_SOURCE_SIM_SPN = 1;
 
     /**
-     * The name_source is from the user
+     * The name_source is from user input
      * @hide
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
@@ -418,6 +418,24 @@
     public static final int NAME_SOURCE_CARRIER = 3;
 
     /**
+     * The name_source is from SIM EF_PNN.
+     * @hide
+     */
+    public static final int NAME_SOURCE_SIM_PNN = 4;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"NAME_SOURCE_"},
+            value = {
+                    NAME_SOURCE_DEFAULT_SOURCE,
+                    NAME_SOURCE_SIM_SPN,
+                    NAME_SOURCE_USER_INPUT,
+                    NAME_SOURCE_CARRIER,
+                    NAME_SOURCE_SIM_PNN
+            })
+    public @interface SimDisplayNameSource {}
+
+    /**
      * TelephonyProvider column name for the color of a SIM.
      * <P>Type: INTEGER (int)</P>
      */
@@ -1669,13 +1687,12 @@
      * Set display name by simInfo index with name source
      * @param displayName the display name of SIM card
      * @param subId the unique SubscriptionInfo index in database
-     * @param nameSource 0: NAME_SOURCE_DEFAULT_SOURCE, 1: NAME_SOURCE_SIM_SOURCE,
-     *                   2: NAME_SOURCE_USER_INPUT
+     * @param nameSource SIM display name source
      * @return the number of records updated or < 0 if invalid subId
      * @hide
      */
     @UnsupportedAppUsage
-    public int setDisplayName(String displayName, int subId, int nameSource) {
+    public int setDisplayName(String displayName, int subId, @SimDisplayNameSource int nameSource) {
         if (VDBG) {
             logd("[setDisplayName]+  displayName:" + displayName + " subId:" + subId
                     + " nameSource:" + nameSource);