Merge "resolve merge conflicts of 057059665ebb1277626e01317ae999ffc0453d39 to ub-launcher3-master" into ub-launcher3-master
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
index a12917f..79a5ace 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2019 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -41,12 +41,19 @@
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
 import com.android.launcher3.model.AppLaunchTracker;
+import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
+import com.android.systemui.plugins.AppLaunchEventsPlugin;
+import com.android.systemui.plugins.PluginListener;
+
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Subclass of app tracker which publishes the data to the prediction engine and gets back results.
  */
 @TargetApi(Build.VERSION_CODES.Q)
-public class PredictionAppTracker extends AppLaunchTracker {
+public class PredictionAppTracker extends AppLaunchTracker
+        implements PluginListener<AppLaunchEventsPlugin> {
 
     private static final String TAG = "PredictionAppTracker";
     private static final boolean DBG = false;
@@ -58,6 +65,7 @@
 
     protected final Context mContext;
     private final Handler mMessageHandler;
+    private final List<AppLaunchEventsPlugin> mAppLaunchEventsPluginsList;
 
     // Accessed only on worker thread
     private AppPredictor mHomeAppPredictor;
@@ -69,6 +77,10 @@
         InvariantDeviceProfile.INSTANCE.get(mContext).addOnChangeListener(this::onIdpChanged);
 
         mMessageHandler.sendEmptyMessage(MSG_INIT);
+
+        mAppLaunchEventsPluginsList = new ArrayList<>();
+        PluginManagerWrapper.INSTANCE.get(context)
+                .addPluginListener(this, AppLaunchEventsPlugin.class, true);
     }
 
     @UiThread
@@ -96,7 +108,7 @@
         AppPredictionManager apm = mContext.getSystemService(AppPredictionManager.class);
 
         if (apm == null) {
-          return null;
+            return null;
         }
 
         AppPredictor predictor = apm.createAppPredictionSession(
@@ -116,7 +128,7 @@
      */
     @WorkerThread
     @Nullable
-    public Bundle getAppPredictionContextExtras(Client client){
+    public Bundle getAppPredictionContextExtras(Client client) {
         return null;
     }
 
@@ -167,12 +179,15 @@
         if (DBG) {
             Log.d(TAG, String.format("Sent immediate message to update %s", client));
         }
+
+        // Relay onReturnedToHome to every plugin.
+        mAppLaunchEventsPluginsList.forEach(AppLaunchEventsPlugin::onReturnedToHome);
     }
 
     @Override
     @UiThread
     public void onStartShortcut(String packageName, String shortcutId, UserHandle user,
-            String container) {
+                                String container) {
         // TODO: Use the full shortcut info
         AppTarget target = new AppTarget.Builder(
                 new AppTargetId("shortcut:" + shortcutId), packageName, user)
@@ -180,6 +195,16 @@
                 .build();
 
         sendLaunch(target, container);
+
+        // Relay onStartShortcut info to every connected plugin.
+        mAppLaunchEventsPluginsList
+                .forEach(plugin -> plugin.onStartShortcut(
+                        packageName,
+                        shortcutId,
+                        user,
+                        container != null ? container : CONTAINER_DEFAULT)
+        );
+
     }
 
     @Override
@@ -191,6 +216,14 @@
                     .setClassName(cn.getClassName())
                     .build();
             sendLaunch(target, container);
+
+            // Relay onStartApp to every connected plugin.
+            mAppLaunchEventsPluginsList
+                    .forEach(plugin -> plugin.onStartApp(
+                            cn,
+                            user,
+                            container != null ? container : CONTAINER_DEFAULT)
+            );
         }
     }
 
@@ -203,6 +236,14 @@
                 .setClassName(cn.getClassName())
                 .build();
         sendDismiss(target, container);
+
+        // Relay onDismissApp to every connected plugin.
+        mAppLaunchEventsPluginsList
+                .forEach(plugin -> plugin.onDismissApp(
+                        cn,
+                        user,
+                        container != null ? container : CONTAINER_DEFAULT)
+        );
     }
 
     @UiThread
@@ -222,4 +263,14 @@
     private void sendDismiss(AppTarget target, String container) {
         sendEvent(target, container, AppTargetEvent.ACTION_DISMISS);
     }
+
+    @Override
+    public void onPluginConnected(AppLaunchEventsPlugin appLaunchEventsPlugin, Context context) {
+        mAppLaunchEventsPluginsList.add(appLaunchEventsPlugin);
+    }
+
+    @Override
+    public void onPluginDisconnected(AppLaunchEventsPlugin appLaunchEventsPlugin) {
+        mAppLaunchEventsPluginsList.remove(appLaunchEventsPlugin);
+    }
 }
diff --git a/src_plugins/com/android/systemui/plugins/AppLaunchEventsPlugin.java b/src_plugins/com/android/systemui/plugins/AppLaunchEventsPlugin.java
new file mode 100644
index 0000000..15a0ffa
--- /dev/null
+++ b/src_plugins/com/android/systemui/plugins/AppLaunchEventsPlugin.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2019 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.content.ComponentName;
+import android.os.UserHandle;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+/**
+ * Plugin interface which sends app launch events.
+ */
+@ProvidesInterface(action = AppLaunchEventsPlugin.ACTION, version = AppLaunchEventsPlugin.VERSION)
+public interface AppLaunchEventsPlugin extends Plugin {
+    String ACTION = "com.android.systemui.action.PLUGIN_APP_EVENTS";
+    int VERSION = 1;
+
+    /**
+     * Receives onStartShortcut event from
+     * {@link com.android.launcher3.appprediction.PredictionAppTracker}.
+     */
+    void onStartShortcut(String packageName, String shortcutId, UserHandle user, String container);
+
+    /**
+     * Receives onStartApp event from
+     * {@link com.android.launcher3.appprediction.PredictionAppTracker}.
+     */
+    void onStartApp(ComponentName componentName, UserHandle user, String container);
+
+    /**
+     * Receives onDismissApp event from
+     * {@link com.android.launcher3.appprediction.PredictionAppTracker}.
+     */
+    void onDismissApp(ComponentName componentName, UserHandle user, String container);
+
+    /**
+     * Receives onReturnedToHome event from
+     * {@link com.android.launcher3.appprediction.PredictionAppTracker}.
+     */
+    void onReturnedToHome();
+}