Add running apps icons to taskbar for desktop environment.
This CL adds app icons for launched/running apps to the Launcher
taskbar hotseat. When the activity is closed, the app icon is
removed. The apps that are added to the taskbar on boot are never
removed.
Recall: http://recall/clips/ad6d3cfc-7358-4b37-846e-de843ad3000d
Bug: 183906774
Test: Launch an app and verify the app icon is added on the taskbar.
Close the app and verify the icon is removed from the taskbar.
Test: Switch navigation modes on the emulator and ensure that running
app icons are added to the taskbar after it is reinitialized.
Test: atest NexusLauncherTests:com.android.quickstep.RecentTasksListTest RecentTasksControllerTest
Change-Id: Ieaaf001530b5778871fb7a8d18cdcaa1ccbf0e31
Merged-In: Ieaaf001530b5778871fb7a8d18cdcaa1ccbf0e31
diff --git a/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarRecentAppsController.java b/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarRecentAppsController.java
new file mode 100644
index 0000000..acfbea3
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarRecentAppsController.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2022 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.launcher3.taskbar;
+
+import android.app.ActivityManager;
+import android.content.ComponentName;
+import android.util.SparseArray;
+
+import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.quickstep.RecentsModel;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Provides recent apps functionality specifically in a desktop environment.
+ */
+public class DesktopTaskbarRecentAppsController extends TaskbarRecentAppsController {
+
+ private final TaskbarActivityContext mContext;
+ private ArrayList<ItemInfo> mRunningApps = new ArrayList<>();
+ private AppInfo[] mApps;
+
+ public DesktopTaskbarRecentAppsController(TaskbarActivityContext context) {
+ mContext = context;
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mApps = null;
+ }
+
+ @Override
+ protected void setApps(AppInfo[] apps) {
+ mApps = apps;
+ }
+
+ @Override
+ protected boolean isEnabled() {
+ return true;
+ }
+
+ /**
+ * Set mRunningApps to hold currently running applications using the list of currently running
+ * tasks. Filtering is also done to ignore applications that are already on the taskbar in the
+ * original hotseat.
+ */
+ @Override
+ protected void updateRunningApps(SparseArray<ItemInfo> hotseatItems) {
+ ArrayList<AppInfo> runningApps = getRunningAppsFromTasks();
+ ArrayList<ItemInfo> filteredRunningApps = new ArrayList<>();
+ for (AppInfo runningApp : runningApps) {
+ boolean shouldAddOnTaskbar = true;
+ for (int i = 0; i < hotseatItems.size(); i++) {
+ if (hotseatItems.keyAt(i) >= mControllers.taskbarActivityContext.getDeviceProfile()
+ .numShownHotseatIcons) {
+ break;
+ }
+ if (hotseatItems.valueAt(i).getTargetPackage()
+ .equals(runningApp.getTargetPackage())) {
+ shouldAddOnTaskbar = false;
+ break;
+ }
+ }
+ if (shouldAddOnTaskbar) {
+ filteredRunningApps.add(new WorkspaceItemInfo(runningApp));
+ }
+ }
+ mRunningApps = filteredRunningApps;
+ mControllers.taskbarViewController.commitRunningAppsToUI();
+ }
+
+ /**
+ * Returns a copy of hotseatItems with the addition of currently running applications.
+ */
+ @Override
+ protected ItemInfo[] updateHotseatItemInfos(ItemInfo[] hotseatItemInfos) {
+ // hotseatItemInfos.length would be 0 if deviceProfile.numShownHotseatIcons is 0, so we
+ // don't want to show anything in the hotseat
+ if (hotseatItemInfos.length == 0) return hotseatItemInfos;
+
+ int runningAppsIndex = 0;
+ ItemInfo[] newHotseatItemsInfo = Arrays.copyOf(
+ hotseatItemInfos, hotseatItemInfos.length + mRunningApps.size());
+ for (int i = hotseatItemInfos.length; i < newHotseatItemsInfo.length; i++) {
+ newHotseatItemsInfo[i] = mRunningApps.get(runningAppsIndex);
+ runningAppsIndex++;
+ }
+ return newHotseatItemsInfo;
+ }
+
+
+ /**
+ * Returns a list of running applications from the list of currently running tasks.
+ */
+ private ArrayList<AppInfo> getRunningAppsFromTasks() {
+ ArrayList<ActivityManager.RunningTaskInfo> tasks =
+ RecentsModel.INSTANCE.get(mContext).getRunningTasks();
+ ArrayList<AppInfo> runningApps = new ArrayList<>();
+ // early return if apps is empty, since we would have no AppInfo to compare
+ if (mApps == null) {
+ return runningApps;
+ }
+
+ Set<String> seenPackages = new HashSet<>();
+ for (ActivityManager.RunningTaskInfo taskInfo : tasks) {
+ if (taskInfo.realActivity == null) continue;
+
+ // If a different task for the same package has already been handled, skip this one
+ String taskPackage = taskInfo.realActivity.getPackageName();
+ if (seenPackages.contains(taskPackage)) continue;
+
+ // Otherwise, get the corresponding AppInfo and add it to the list
+ seenPackages.add(taskPackage);
+ AppInfo app = getAppInfo(taskInfo.realActivity);
+ if (app == null) continue;
+ runningApps.add(app);
+ }
+ return runningApps;
+ }
+
+ /**
+ * Retrieves the corresponding AppInfo for the activity.
+ */
+ private AppInfo getAppInfo(ComponentName activity) {
+ String packageName = activity.getPackageName();
+ for (AppInfo app : mApps) {
+ if (!packageName.equals(app.getTargetPackage())) {
+ continue;
+ }
+ return app;
+ }
+ return null;
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarUIController.java
index e2359c0..3c76e8e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarUIController.java
@@ -32,11 +32,14 @@
@Override
protected void init(TaskbarControllers taskbarControllers) {
+ super.init(taskbarControllers);
mLauncher.getHotseat().setIconsAlpha(0f);
+ mControllers.taskbarViewController.updateRunningApps();
}
@Override
protected void onDestroy() {
+ super.onDestroy();
mLauncher.getHotseat().setIconsAlpha(1f);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 36806bc..2f6c2c0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -173,13 +173,15 @@
mAccessibilityDelegate = new TaskbarShortcutMenuAccessibilityDelegate(this);
+ final boolean isDesktopMode = getPackageManager().hasSystemFeature(FEATURE_PC);
+
// Construct controllers.
mControllers = new TaskbarControllers(this,
new TaskbarDragController(this),
buttonController,
- getPackageManager().hasSystemFeature(FEATURE_PC)
- ? new DesktopNavbarButtonsViewController(this, navButtonsView) :
- new NavbarButtonsViewController(this, navButtonsView),
+ isDesktopMode
+ ? new DesktopNavbarButtonsViewController(this, navButtonsView)
+ : new NavbarButtonsViewController(this, navButtonsView),
new RotationButtonController(this,
c.getColor(R.color.taskbar_nav_icon_light_color),
c.getColor(R.color.taskbar_nav_icon_dark_color),
@@ -202,7 +204,10 @@
new TaskbarForceVisibleImmersiveController(this),
new TaskbarAllAppsController(this, dp),
new TaskbarInsetsController(this),
- new VoiceInteractionWindowController(this));
+ new VoiceInteractionWindowController(this),
+ isDesktopMode
+ ? new DesktopTaskbarRecentAppsController(this)
+ : TaskbarRecentAppsController.DEFAULT);
}
public void init(@NonNull TaskbarSharedState sharedState) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
index d7b50b0..2b80b75 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
@@ -53,6 +53,7 @@
public final TaskbarAllAppsController taskbarAllAppsController;
public final TaskbarInsetsController taskbarInsetsController;
public final VoiceInteractionWindowController voiceInteractionWindowController;
+ public final TaskbarRecentAppsController taskbarRecentAppsController;
@Nullable private LoggableTaskbarController[] mControllersToLog = null;
@@ -82,7 +83,8 @@
TaskbarForceVisibleImmersiveController taskbarForceVisibleImmersiveController,
TaskbarAllAppsController taskbarAllAppsController,
TaskbarInsetsController taskbarInsetsController,
- VoiceInteractionWindowController voiceInteractionWindowController) {
+ VoiceInteractionWindowController voiceInteractionWindowController,
+ TaskbarRecentAppsController taskbarRecentAppsController) {
this.taskbarActivityContext = taskbarActivityContext;
this.taskbarDragController = taskbarDragController;
this.navButtonController = navButtonController;
@@ -102,6 +104,7 @@
this.taskbarAllAppsController = taskbarAllAppsController;
this.taskbarInsetsController = taskbarInsetsController;
this.voiceInteractionWindowController = voiceInteractionWindowController;
+ this.taskbarRecentAppsController = taskbarRecentAppsController;
}
/**
@@ -130,6 +133,7 @@
navButtonController.init(this);
taskbarInsetsController.init(this);
voiceInteractionWindowController.init(this);
+ taskbarRecentAppsController.init(this);
mControllersToLog = new LoggableTaskbarController[] {
taskbarDragController, navButtonController, navbarButtonsViewController,
@@ -178,6 +182,7 @@
navButtonController.onDestroy();
taskbarInsetsController.onDestroy();
voiceInteractionWindowController.onDestroy();
+ taskbarRecentAppsController.onDestroy();
mControllersToLog = null;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java
index 75881a3..5e670d294 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java
@@ -29,6 +29,7 @@
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.LauncherBindableItemsContainer;
+import com.android.quickstep.RecentsModel;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -42,7 +43,7 @@
* Launcher model Callbacks for rendering taskbar.
*/
public class TaskbarModelCallbacks implements
- BgDataModel.Callbacks, LauncherBindableItemsContainer {
+ BgDataModel.Callbacks, LauncherBindableItemsContainer, RecentsModel.RunningTasksListener {
private final SparseArray<ItemInfo> mHotseatItems = new SparseArray<>();
private List<ItemInfo> mPredictedItems = Collections.emptyList();
@@ -61,6 +62,16 @@
public void init(TaskbarControllers controllers) {
mControllers = controllers;
+ if (mControllers.taskbarRecentAppsController.isEnabled()) {
+ RecentsModel.INSTANCE.get(mContext).registerRunningTasksListener(this);
+ }
+ }
+
+ /**
+ * Unregisters listeners in this class.
+ */
+ public void unregisterListeners() {
+ RecentsModel.INSTANCE.get(mContext).unregisterRunningTasksListener();
}
@Override
@@ -185,6 +196,8 @@
isHotseatEmpty = false;
}
}
+ hotseatItemInfos = mControllers.taskbarRecentAppsController
+ .updateHotseatItemInfos(hotseatItemInfos);
mContainer.updateHotseatItems(hotseatItemInfos);
final boolean finalIsHotseatEmpty = isHotseatEmpty;
@@ -196,6 +209,21 @@
}
@Override
+ public void onRunningTasksChanged() {
+ updateRunningApps();
+ }
+
+ /** Called when there's a change in running apps to update the UI. */
+ public void commitRunningAppsToUI() {
+ commitItemsToUI();
+ }
+
+ /** Call TaskbarRecentAppsController to update running apps with mHotseatItems. */
+ public void updateRunningApps() {
+ mControllers.taskbarRecentAppsController.updateRunningApps(mHotseatItems);
+ }
+
+ @Override
public void bindDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMapCopy) {
mControllers.taskbarPopupController.setDeepShortcutMap(deepShortcutMapCopy);
}
@@ -203,6 +231,7 @@
@Override
public void bindAllApplications(AppInfo[] apps, int flags) {
mControllers.taskbarAllAppsController.setApps(apps, flags);
+ mControllers.taskbarRecentAppsController.setApps(apps);
}
protected void dumpLogs(String prefix, PrintWriter pw) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.java
new file mode 100644
index 0000000..8445cff
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 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.launcher3.taskbar;
+
+import android.util.SparseArray;
+
+import androidx.annotation.CallSuper;
+
+import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.model.data.ItemInfo;
+
+/**
+ * Base class for providing recent apps functionality
+ */
+public class TaskbarRecentAppsController {
+
+ public static final TaskbarRecentAppsController DEFAULT = new TaskbarRecentAppsController();
+
+ // Initialized in init.
+ protected TaskbarControllers mControllers;
+
+ @CallSuper
+ protected void init(TaskbarControllers taskbarControllers) {
+ mControllers = taskbarControllers;
+ }
+
+ @CallSuper
+ protected void onDestroy() {
+ mControllers = null;
+ }
+
+ /** Stores the current {@link AppInfo} instances, no-op except in desktop environment. */
+ protected void setApps(AppInfo[] apps) { }
+
+ /**
+ * Indicates whether recent apps functionality is enabled, should return false except in
+ * desktop environment.
+ */
+ protected boolean isEnabled() {
+ return false;
+ }
+
+ /** Called to update hotseatItems, no-op except in desktop environment. */
+ protected ItemInfo[] updateHotseatItemInfos(ItemInfo[] hotseatItems) {
+ return hotseatItems;
+ }
+
+ /** Called to update the list of currently running apps, no-op except in desktop environment. */
+ protected void updateRunningApps(SparseArray<ItemInfo> hotseatItems) { }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 6d45fd2..077172d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -126,6 +126,7 @@
public void onDestroy() {
LauncherAppState.getInstance(mActivity).getModel().removeCallbacks(mModelCallbacks);
+ mModelCallbacks.unregisterListeners();
}
public boolean areIconsVisible() {
@@ -389,6 +390,16 @@
mModelCallbacks.dumpLogs(prefix + "\t", pw);
}
+ /** Called when there's a change in running apps to update the UI. */
+ public void commitRunningAppsToUI() {
+ mModelCallbacks.commitRunningAppsToUI();
+ }
+
+ /** Call TaskbarModelCallbacks to update running apps. */
+ public void updateRunningApps() {
+ mModelCallbacks.updateRunningApps();
+ }
+
/**
* Callbacks for {@link TaskbarView} to interact with its controller.
*/
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index cd93dbe..813e687 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -62,6 +62,10 @@
private TaskLoadResult mResultsBg = INVALID_RESULT;
private TaskLoadResult mResultsUi = INVALID_RESULT;
+ private RecentsModel.RunningTasksListener mRunningTasksListener;
+ // Tasks are stored in order of least recently launched to most recently launched.
+ private ArrayList<ActivityManager.RunningTaskInfo> mRunningTasks;
+
public RecentTasksList(LooperExecutor mainThreadExecutor,
KeyguardManagerCompat keyguardManager, SystemUiProxy sysUiProxy) {
mMainThreadExecutor = mainThreadExecutor;
@@ -73,7 +77,26 @@
public void onRecentTasksChanged() throws RemoteException {
mMainThreadExecutor.execute(RecentTasksList.this::onRecentTasksChanged);
}
+
+ @Override
+ public void onRunningTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
+ mMainThreadExecutor.execute(() -> {
+ RecentTasksList.this.onRunningTaskAppeared(taskInfo);
+ });
+ }
+
+ @Override
+ public void onRunningTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+ mMainThreadExecutor.execute(() -> {
+ RecentTasksList.this.onRunningTaskVanished(taskInfo);
+ });
+ }
});
+ // We may receive onRunningTaskAppeared events later for tasks which have already been
+ // included in the list returned by mSysUiProxy.getRunningTasks(), or may receive
+ // onRunningTaskVanished for tasks not included in the returned list. These cases will be
+ // addressed when the tasks are added to/removed from mRunningTasks.
+ initRunningTasks(mSysUiProxy.getRunningTasks(Integer.MAX_VALUE));
}
@VisibleForTesting
@@ -154,6 +177,59 @@
mChangeId++;
}
+ /**
+ * Registers a listener for running tasks
+ */
+ public void registerRunningTasksListener(RecentsModel.RunningTasksListener listener) {
+ mRunningTasksListener = listener;
+ }
+
+ /**
+ * Removes the previously registered running tasks listener
+ */
+ public void unregisterRunningTasksListener() {
+ mRunningTasksListener = null;
+ }
+
+ private void initRunningTasks(ArrayList<ActivityManager.RunningTaskInfo> runningTasks) {
+ // Tasks are retrieved in order of most recently launched/used to least recently launched.
+ mRunningTasks = new ArrayList<>(runningTasks);
+ Collections.reverse(mRunningTasks);
+ }
+
+ /**
+ * Gets the set of running tasks.
+ */
+ public ArrayList<ActivityManager.RunningTaskInfo> getRunningTasks() {
+ return mRunningTasks;
+ }
+
+ private void onRunningTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
+ // Make sure this task is not already in the list
+ for (ActivityManager.RunningTaskInfo existingTask : mRunningTasks) {
+ if (taskInfo.taskId == existingTask.taskId) {
+ return;
+ }
+ }
+ mRunningTasks.add(taskInfo);
+ if (mRunningTasksListener != null) {
+ mRunningTasksListener.onRunningTasksChanged();
+ }
+ }
+
+ private void onRunningTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+ // Find the task from the list of running tasks, if it exists
+ for (ActivityManager.RunningTaskInfo existingTask : mRunningTasks) {
+ if (existingTask.taskId != taskInfo.taskId) continue;
+
+ mRunningTasks.remove(existingTask);
+ if (mRunningTasksListener != null) {
+ mRunningTasksListener.onRunningTasksChanged();
+ }
+ return;
+ }
+ }
+
/**
* Loads and creates a list of all the recent tasks.
*/
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 442578e..3074dbb 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -236,4 +236,35 @@
writer.println(prefix + "RecentsModel:");
mTaskList.dump(" ", writer);
}
+
+ /**
+ * Registers a listener for running tasks
+ */
+ public void registerRunningTasksListener(RunningTasksListener listener) {
+ mTaskList.registerRunningTasksListener(listener);
+ }
+
+ /**
+ * Removes the previously registered running tasks listener
+ */
+ public void unregisterRunningTasksListener() {
+ mTaskList.unregisterRunningTasksListener();
+ }
+
+ /**
+ * Gets the set of running tasks.
+ */
+ public ArrayList<ActivityManager.RunningTaskInfo> getRunningTasks() {
+ return mTaskList.getRunningTasks();
+ }
+
+ /**
+ * Listener for receiving running tasks changes
+ */
+ public interface RunningTasksListener {
+ /**
+ * Called when there's a change to running tasks
+ */
+ void onRunningTasksChanged();
+ }
}
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index cb80b4d..0ec7e62 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -20,12 +20,14 @@
import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import android.app.ActivityManager;
import android.app.PendingIntent;
import android.app.PictureInPictureParams;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Insets;
import android.graphics.Rect;
@@ -108,12 +110,14 @@
private boolean mLastNavButtonAnimate;
private boolean mHasNavButtonAlphaBeenSet = false;
private Runnable mPendingSetNavButtonAlpha = null;
+ private Context mContext;
// TODO(141886704): Find a way to remove this
private int mLastSystemUiStateFlags;
public SystemUiProxy(Context context) {
DisplayController.INSTANCE.get(context).addChangeListener(this);
+ mContext = context;
}
@Override
@@ -868,4 +872,20 @@
}
return new ArrayList<>();
}
+
+ /**
+ * Gets the set of running tasks.
+ */
+ public ArrayList<ActivityManager.RunningTaskInfo> getRunningTasks(int numTasks) {
+ if (mRecentTasks != null
+ && mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_PC)) {
+ try {
+ return new ArrayList<ActivityManager.RunningTaskInfo>(
+ Arrays.asList(mRecentTasks.getRunningTasks(numTasks)));
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call getRunningTasks", e);
+ }
+ }
+ return new ArrayList<>();
+ }
}