Merge "Workaround for activity manager crashing when trying to start an app It flakes when one of the tests starts calculator while there zero activities in the system." into ub-launcher3-rvc-dev
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index 7334d80..e103f66 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -30,8 +30,10 @@
 import android.app.prediction.AppTarget;
 import android.app.prediction.AppTargetEvent;
 import android.content.ComponentName;
+import android.content.pm.ShortcutInfo;
 import android.os.Process;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.HapticFeedbackConstants;
 import android.view.View;
 import android.view.ViewGroup;
@@ -65,6 +67,7 @@
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.popup.SystemShortcut;
 import com.android.launcher3.shortcuts.ShortcutKey;
+import com.android.launcher3.shortcuts.ShortcutRequest;
 import com.android.launcher3.touch.ItemLongClickListener;
 import com.android.launcher3.uioverrides.PredictedAppIcon;
 import com.android.launcher3.uioverrides.QuickstepLauncher;
@@ -379,16 +382,24 @@
             mRestoreHelper.restoreBackup();
         }
         StringBuilder predictionLog = new StringBuilder("predictedApps: [\n");
-        ArrayList<ComponentKey> componentKeys = new ArrayList<>();
+        ArrayList<ComponentKey> componentKeysToBeCached = new ArrayList<>();
+        SparseArray<ShortcutRequest> requests = new SparseArray<>();
         for (AppTarget appTarget : appTargets) {
             ComponentKey key;
-            if (appTarget.getShortcutInfo() != null) {
-                key = ShortcutKey.fromInfo(appTarget.getShortcutInfo());
+            ShortcutRequest request = requests.get(appTarget.getUser().getIdentifier());
+            if (request == null) {
+                request = new ShortcutRequest(mLauncher, appTarget.getUser());
+                requests.put(appTarget.getUser().getIdentifier(), request);
+            }
+            List<ShortcutInfo> shortcutInfos = request.forPackage(appTarget.getPackageName(),
+                    appTarget.getClassName()).query(ShortcutRequest.ALL);
+            if (!shortcutInfos.isEmpty()) {
+                key = ShortcutKey.fromInfo(shortcutInfos.get(0));
             } else {
                 key = new ComponentKey(new ComponentName(appTarget.getPackageName(),
                         appTarget.getClassName()), appTarget.getUser());
+                componentKeysToBeCached.add(key);
             }
-            componentKeys.add(key);
             predictionLog.append(key.toString());
             predictionLog.append(",rank:");
             predictionLog.append(appTarget.getRank());
@@ -401,7 +412,7 @@
         }
         updateDependencies();
         fillGapsWithPrediction();
-        cachePredictionComponentKeysIfNecessary(componentKeys);
+        cachePredictionComponentKeysIfNecessary(componentKeysToBeCached);
     }
 
     private void cachePredictionComponentKeysIfNecessary(ArrayList<ComponentKey> componentKeys) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
index 597c17b..51d53fd 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
@@ -36,6 +36,7 @@
 import com.android.launcher3.CellLayout;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.R;
 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
 import com.android.launcher3.graphics.IconPalette;
@@ -90,8 +91,9 @@
     public void onDraw(Canvas canvas) {
         int count = canvas.save();
         if (!mIsPinned) {
-            boolean isBadged = getTag() instanceof WorkspaceItemInfo
-                    && !Process.myUserHandle().equals(((ItemInfo) getTag()).user);
+            ItemInfo info = (ItemInfo) getTag();
+            boolean isBadged = info != null && (!Process.myUserHandle().equals(info.user)
+                    || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT);
             drawEffect(canvas, isBadged);
             canvas.translate(getWidth() * RING_EFFECT_RATIO, getHeight() * RING_EFFECT_RATIO);
             canvas.scale(1 - 2 * RING_EFFECT_RATIO, 1 - 2 * RING_EFFECT_RATIO);
diff --git a/res/layout/work_mode_switch.xml b/res/layout/work_mode_switch.xml
index b5237db..31953c7 100644
--- a/res/layout/work_mode_switch.xml
+++ b/res/layout/work_mode_switch.xml
@@ -17,7 +17,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    style="@style/PrimaryMediumText"
+    style="@style/PrimaryHeadline"
     android:id="@+id/work_mode_toggle"
     android:drawableStart="@drawable/ic_corp"
     android:drawablePadding="16dp"
@@ -25,6 +25,7 @@
     android:textColor="?attr/workProfileOverlayTextColor"
     android:layout_alignParentBottom="true"
     android:ellipsize="end"
+    android:elevation="10dp"
     android:gravity="start"
     android:lines="1"
     android:showText="false"
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 82f5dc6..25f21f3 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -246,7 +246,6 @@
     <style name="DropTargetButton" parent="DropTargetButtonBase" />
 
     <style name="TextHeadline" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle" />
-    <style name="PrimaryMediumText" parent="@android:style/TextAppearance.DeviceDefault.Medium"/>
     <style name="PrimaryHeadline" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle"/>
 
     <style name="TextTitle" parent="@android:style/TextAppearance.DeviceDefault" />
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index ce37506..e24033f 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -21,6 +21,8 @@
 import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
 import static com.android.launcher3.folder.PreviewItemManager.INITIAL_ITEM_ANIMATION_DURATION;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_AUTO_LABELED;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_AUTO_LABELING_SKIPPED_EMPTY_PRIMARY;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_AUTO_LABELING_SKIPPED_EMPTY_SUGGESTIONS;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -82,6 +84,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.function.Predicate;
+import java.util.stream.Stream;
 
 /**
  * An icon that can appear on in the workspace representing an {@link Folder}.
@@ -445,7 +448,19 @@
                 || mInfo.hasOption(FolderInfo.FLAG_MANUAL_FOLDER_NAME)) {
             return;
         }
-        if (nameInfos == null || nameInfos[0] == null || isEmpty(nameInfos[0].getLabel())) {
+        if (nameInfos == null || Stream.of(nameInfos)
+                .allMatch(nameInfo -> nameInfo == null || isEmpty(nameInfo.getLabel()))) {
+            StatsLogManager.newInstance(getContext()).logger()
+                    .withInstanceId(instanceId)
+                    .withItemInfo(mInfo)
+                    .log(LAUNCHER_FOLDER_AUTO_LABELING_SKIPPED_EMPTY_SUGGESTIONS);
+            return;
+        }
+        if (nameInfos[0] == null || isEmpty(nameInfos[0].getLabel())) {
+            StatsLogManager.newInstance(getContext()).logger()
+                    .withInstanceId(instanceId)
+                    .withItemInfo(mInfo)
+                    .log(LAUNCHER_FOLDER_AUTO_LABELING_SKIPPED_EMPTY_PRIMARY);
             return;
         }
         CharSequence newTitle = nameInfos[0].getLabel();
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index be8edc7..3edfa8d 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -71,6 +71,12 @@
         @UiEvent(doc = "Folder's label is automatically assigned.")
         LAUNCHER_FOLDER_AUTO_LABELED(591),
 
+        @UiEvent(doc = "Could not auto-label a folder because primary suggestion is null or empty.")
+        LAUNCHER_FOLDER_AUTO_LABELING_SKIPPED_EMPTY_PRIMARY(592),
+
+        @UiEvent(doc = "Could not auto-label a folder because no suggestions exist.")
+        LAUNCHER_FOLDER_AUTO_LABELING_SKIPPED_EMPTY_SUGGESTIONS(593),
+
         @UiEvent(doc = "User manually updated the folder label.")
         LAUNCHER_FOLDER_LABEL_UPDATED(460),