Merge "Build rule cleanup" into ub-launcher3-master
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index d7b1e8b..d9ecdcd 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -25,9 +25,12 @@
 import android.os.HandlerThread;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import com.android.launcher3.MainThreadExecutor;
+import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.compat.LauncherAppsCompat.OnAppsChangedCallbackCompat;
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.recents.model.Task;
@@ -71,6 +74,7 @@
         mIconCache = new TaskIconCache(context, loaderThread.getLooper());
         mThumbnailCache = new TaskThumbnailCache(context, loaderThread.getLooper());
         ActivityManagerWrapper.getInstance().registerTaskStackListener(this);
+        setupPackageListener();
     }
 
     public TaskIconCache getIconCache() {
@@ -169,6 +173,7 @@
     public void onTaskRemoved(int taskId) {
         Task.TaskKey dummyKey = new Task.TaskKey(taskId, 0, null, null, 0, 0);
         mThumbnailCache.remove(dummyKey);
+        mIconCache.onTaskRemoved(dummyKey);
     }
 
     public void setSystemUiProxy(ISystemUiProxy systemUiProxy) {
@@ -203,6 +208,21 @@
         }
     }
 
+    private void setupPackageListener() {
+        LauncherAppsCompat.getInstance(mContext)
+                .addOnAppsChangedCallback(new OnAppsChangedCallbackCompat() {
+                    @Override
+                    public void onPackageRemoved(String packageName, UserHandle user) {
+                        mIconCache.invalidatePackage(packageName);
+                    }
+
+                    @Override
+                    public void onPackageChanged(String packageName, UserHandle user) {
+                        mIconCache.invalidatePackage(packageName);
+                    }
+                });
+    }
+
     public void addThumbnailChangeListener(TaskThumbnailChangeListener listener) {
         mThumbnailChangeListeners.add(listener);
     }
diff --git a/quickstep/src/com/android/quickstep/TaskIconCache.java b/quickstep/src/com/android/quickstep/TaskIconCache.java
index 07af9b3..5e01958 100644
--- a/quickstep/src/com/android/quickstep/TaskIconCache.java
+++ b/quickstep/src/com/android/quickstep/TaskIconCache.java
@@ -31,17 +31,18 @@
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.icons.cache.HandlerRunnable;
-import com.android.launcher3.uioverrides.RecentsUiFactory;
 import com.android.launcher3.util.Preconditions;
 import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.model.Task.TaskKey;
 import com.android.systemui.shared.recents.model.TaskKeyLruCache;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 
+import java.util.Map;
 import java.util.function.Consumer;
 
 /**
  * Manages the caching of task icons and related data.
- * TODO: This class should later be merged into IconCache.
+ * TODO(b/138944598): This class should later be merged into IconCache.
  */
 public class TaskIconCache {
 
@@ -149,6 +150,21 @@
         return label;
     }
 
+
+    void onTaskRemoved(TaskKey taskKey) {
+        mIconCache.remove(taskKey);
+    }
+
+    void invalidatePackage(String packageName) {
+        // TODO(b/138944598): Merge this class into IconCache so we can do this at the base level
+        Map<ComponentName, ActivityInfo> activityInfoCache = mActivityInfoCache.snapshot();
+        for (ComponentName cn : activityInfoCache.keySet()) {
+            if (cn.getPackageName().equals(packageName)) {
+                mActivityInfoCache.remove(cn);
+            }
+        }
+    }
+
     public static abstract class IconLoadRequest extends HandlerRunnable {
         IconLoadRequest(Handler handler) {
             super(handler, null);
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java
index 58fc73d..cdb5c4d 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java
@@ -27,25 +27,27 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 
+import androidx.annotation.Nullable;
+
 import com.android.launcher3.Utilities;
 import com.android.launcher3.util.PackageUserKey;
 
 import java.util.List;
 
-import androidx.annotation.Nullable;
-
 public abstract class LauncherAppsCompat {
 
     public interface OnAppsChangedCallbackCompat {
-        void onPackageRemoved(String packageName, UserHandle user);
-        void onPackageAdded(String packageName, UserHandle user);
-        void onPackageChanged(String packageName, UserHandle user);
-        void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing);
-        void onPackagesUnavailable(String[] packageNames, UserHandle user, boolean replacing);
-        void onPackagesSuspended(String[] packageNames, UserHandle user);
-        void onPackagesUnsuspended(String[] packageNames, UserHandle user);
-        void onShortcutsChanged(String packageName, List<ShortcutInfo> shortcuts,
-                UserHandle user);
+        default void onPackageRemoved(String packageName, UserHandle user) { }
+        default void onPackageAdded(String packageName, UserHandle user) { }
+        default void onPackageChanged(String packageName, UserHandle user) { }
+        default void onPackagesAvailable(String[] packageNames, UserHandle user,
+                boolean replacing) { }
+        default void onPackagesUnavailable(String[] packageNames, UserHandle user,
+                boolean replacing) { }
+        default void onPackagesSuspended(String[] packageNames, UserHandle user) { }
+        default void onPackagesUnsuspended(String[] packageNames, UserHandle user) { }
+        default void onShortcutsChanged(String packageName, List<ShortcutInfo> shortcuts,
+                UserHandle user) { }
     }
 
     protected LauncherAppsCompat() {
diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java
index 54efcb7..31e8267 100644
--- a/src/com/android/launcher3/config/BaseFlags.java
+++ b/src/com/android/launcher3/config/BaseFlags.java
@@ -112,6 +112,10 @@
             "FAKE_LANDSCAPE_UI", false,
             "Rotate launcher UI instead of using transposed layout");
 
+    public static final TogglableFlag APP_SEARCH_IMPROVEMENTS = new TogglableFlag(
+            "APP_SEARCH_IMPROVEMENTS", false,
+            "Adds localized title and keyword search and ranking");
+
     public static void initialize(Context context) {
         // Avoid the disk read for user builds
         if (Utilities.IS_DEBUG_DEVICE) {
diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java
index bab454f..4fd0f88 100644
--- a/src/com/android/launcher3/testing/TestInformationHandler.java
+++ b/src/com/android/launcher3/testing/TestInformationHandler.java
@@ -112,6 +112,13 @@
                 }
                 break;
             }
+
+            case TestProtocol.REQUEST_ALLOCATED_MEMORY: {
+                final Runtime runtime = Runtime.getRuntime();
+                response.putLong(TestProtocol.TEST_INFO_RESPONSE_FIELD,
+                        runtime.totalMemory() - runtime.freeMemory());
+                break;
+            }
         }
         return response;
     }
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index cb8f811..f9f5dc4 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -73,6 +73,7 @@
     public static final String REQUEST_APP_LIST_FREEZE_FLAGS = "app-list-freeze-flags";
     public static final String REQUEST_OVERVIEW_LEFT_GESTURE_MARGIN = "overview-left-margin";
     public static final String REQUEST_OVERVIEW_RIGHT_GESTURE_MARGIN = "overview-right-margin";
+    public static final String REQUEST_ALLOCATED_MEMORY = "allocated-memory";
 
     public static boolean sDebugTracing = false;
     public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing";
diff --git a/src_plugins/com/android/systemui/plugins/HotseatPlugin.java b/src_plugins/com/android/systemui/plugins/HotseatPlugin.java
new file mode 100644
index 0000000..1264e0d
--- /dev/null
+++ b/src_plugins/com/android/systemui/plugins/HotseatPlugin.java
@@ -0,0 +1,20 @@
+package com.android.systemui.plugins;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+/**
+ * Implement this plugin interface to add a sub-view in the Hotseat.
+ */
+@ProvidesInterface(action = HotseatPlugin.ACTION, version = HotseatPlugin.VERSION)
+public interface HotseatPlugin extends Plugin {
+    String ACTION = "com.android.systemui.action.PLUGIN_HOTSEAT";
+    int VERSION = 1;
+
+    /**
+     * Creates a plugin view which will be added to the Hotseat.
+     */
+    View createView(ViewGroup parent);
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 6348c41..c012628 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -956,4 +956,9 @@
     public void disableDebugTracing() {
         getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING);
     }
+
+    public long getAllocatedMemory() {
+        return getTestInfo(TestProtocol.REQUEST_ALLOCATED_MEMORY).
+                getLong(TestProtocol.TEST_INFO_RESPONSE_FIELD);
+    }
 }
\ No newline at end of file