Add AllAppsRow plugin interface

Bug: 115877296
Change-Id: I750941f220d08ca9ee14067253253f6d81417101
diff --git a/Android.mk b/Android.mk
index b8e6c85..15daf1f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -53,7 +53,6 @@
 LOCAL_SDK_VERSION := current
 LOCAL_MIN_SDK_VERSION := 28
 LOCAL_MODULE := LauncherPluginLib
-LOCAL_PRIVILEGED_MODULE := true
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
@@ -69,7 +68,7 @@
     androidx.recyclerview_recyclerview \
     androidx.dynamicanimation_dynamicanimation
 
-LOCAL_STATIC_JAVA_LIBRARIES := libPluginCore
+LOCAL_STATIC_JAVA_LIBRARIES := LauncherPluginLib
 
 LOCAL_SRC_FILES := \
     $(call all-proto-files-under, protos) \
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
index ca12951..88c362d 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
@@ -43,7 +43,12 @@
     }
 
     public void addPluginListener(PluginListener<? extends Plugin> listener, Class<?> pluginClass) {
-        mPluginManager.addPluginListener(listener, pluginClass);
+        addPluginListener(listener, pluginClass, false);
+    }
+
+    public void addPluginListener(PluginListener<? extends Plugin> listener, Class<?> pluginClass,
+            boolean allowMultiple) {
+        mPluginManager.addPluginListener(listener, pluginClass, allowMultiple);
     }
 
     public void removePluginListener(PluginListener<? extends Plugin> listener) {
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 5348349..90e195b 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -25,16 +25,22 @@
 import android.view.ViewGroup;
 import android.view.animation.Interpolator;
 import android.widget.LinearLayout;
-
-import com.android.launcher3.R;
-import com.android.launcher3.anim.PropertySetter;
-
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.recyclerview.widget.RecyclerView;
+import com.android.launcher3.R;
+import com.android.launcher3.anim.PropertySetter;
+import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
+import com.android.systemui.plugins.AllAppsRow;
+import com.android.systemui.plugins.PluginListener;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 public class FloatingHeaderView extends LinearLayout implements
-        ValueAnimator.AnimatorUpdateListener {
+        ValueAnimator.AnimatorUpdateListener, PluginListener<AllAppsRow> {
 
     private final Rect mClip = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
     private final ValueAnimator mAnimator = ValueAnimator.ofInt(0, 0);
@@ -64,6 +70,9 @@
     private AllAppsRecyclerView mMainRV;
     private AllAppsRecyclerView mWorkRV;
     private AllAppsRecyclerView mCurrentRV;
+    protected final Map<AllAppsRow, View> mPluginRows;
+    // Contains just the values of the above map so we can iterate without extracting a new list.
+    protected final List<View> mPluginRowViews;
     private ViewGroup mParent;
     private boolean mHeaderCollapsed;
     private int mSnappedScrolledY;
@@ -82,6 +91,8 @@
 
     public FloatingHeaderView(@NonNull Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
+        mPluginRows = new HashMap<>();
+        mPluginRowViews = new ArrayList<>();
     }
 
     @Override
@@ -90,6 +101,38 @@
         mTabLayout = findViewById(R.id.tabs);
     }
 
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        PluginManagerWrapper.INSTANCE.get(getContext()).addPluginListener(this,
+                AllAppsRow.class, true /* allowMultiple */);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        PluginManagerWrapper.INSTANCE.get(getContext()).removePluginListener(this);
+    }
+
+    @Override
+    public void onPluginConnected(AllAppsRow allAppsRowPlugin, Context context) {
+        mPluginRows.put(allAppsRowPlugin, null);
+        setupPluginRows();
+        allAppsRowPlugin.setOnHeightUpdatedListener(this::onPluginRowHeightUpdated);
+    }
+
+    protected void onPluginRowHeightUpdated() {
+    }
+
+    @Override
+    public void onPluginDisconnected(AllAppsRow plugin) {
+        View pluginRowView = mPluginRows.get(plugin);
+        removeView(pluginRowView);
+        mPluginRows.remove(plugin);
+        mPluginRowViews.remove(pluginRowView);
+        onPluginRowHeightUpdated();
+    }
+
     public void setup(AllAppsContainerView.AdapterHolder[] mAH, boolean tabsHidden) {
         mTabsHidden = tabsHidden;
         mTabLayout.setVisibility(tabsHidden ? View.GONE : View.VISIBLE);
@@ -97,9 +140,24 @@
         mWorkRV = setupRV(mWorkRV, mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView);
         mParent = (ViewGroup) mMainRV.getParent();
         setMainActive(mMainRVActive || mWorkRV == null);
+        setupPluginRows();
         reset(false);
     }
 
+    private void setupPluginRows() {
+        for (Map.Entry<AllAppsRow, View> rowPluginEntry : mPluginRows.entrySet()) {
+            if (rowPluginEntry.getValue() == null) {
+                View pluginRow = rowPluginEntry.getKey().setup(this);
+                addView(pluginRow, indexOfChild(mTabLayout));
+                rowPluginEntry.setValue(pluginRow);
+                mPluginRowViews.add(pluginRow);
+            }
+        }
+        for (View plugin : mPluginRowViews) {
+            plugin.setVisibility(mHeaderCollapsed ? GONE : VISIBLE);
+        }
+    }
+
     private AllAppsRecyclerView setupRV(AllAppsRecyclerView old, AllAppsRecyclerView updated) {
         if (old != updated && updated != null ) {
             updated.addOnScrollListener(mOnScrollListener);
diff --git a/src_plugins/com/android/systemui/plugins/AllAppsRow.java b/src_plugins/com/android/systemui/plugins/AllAppsRow.java
new file mode 100644
index 0000000..c003fc1
--- /dev/null
+++ b/src_plugins/com/android/systemui/plugins/AllAppsRow.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+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 row of views to the top of the all apps drawer.
+ */
+@ProvidesInterface(action = AllAppsRow.ACTION, version = AllAppsRow.VERSION)
+public interface AllAppsRow extends Plugin {
+    String ACTION = "com.android.systemui.action.PLUGIN_ALL_APPS_ACTIONS";
+    int VERSION = 1;
+
+    /**
+     * Setup the row and return the parent view.
+     * @param parent The ViewGroup to which launcher will add this row.
+     */
+    View setup(ViewGroup parent);
+
+    /**
+     * @return The height to reserve in all apps for your views.
+     */
+    int getExpectedHeight();
+
+    /**
+     * Update launcher whenever {@link #getExpectedHeight()} changes.
+     */
+    void setOnHeightUpdatedListener(OnHeightUpdatedListener onHeightUpdatedListener);
+
+    interface OnHeightUpdatedListener {
+        void onHeightUpdated();
+    }
+}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java b/src_ui_overrides/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
index fcb2abe..31dbb34 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
@@ -31,6 +31,10 @@
     public void addPluginListener(PluginListener<? extends Plugin> listener, Class<?> pluginClass) {
     }
 
+    public void addPluginListener(PluginListener<? extends Plugin> listener, Class<?> pluginClass,
+            boolean allowMultiple) {
+    }
+
     public void removePluginListener(PluginListener<? extends Plugin> listener) {
     }
 }