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: I2c839b6f35310d2d0fa98cc8d4a432eb1163861d
This commit is contained in:
@@ -435,6 +435,7 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
|
|||||||
}
|
}
|
||||||
notifyLocusVisibilityIfNeeded(info.getTaskInfo());
|
notifyLocusVisibilityIfNeeded(info.getTaskInfo());
|
||||||
notifyCompatUI(info.getTaskInfo(), listener);
|
notifyCompatUI(info.getTaskInfo(), listener);
|
||||||
|
mRecentTasks.ifPresent(recentTasks -> recentTasks.onTaskAdded(info.getTaskInfo()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.wm.shell.recents;
|
package com.android.wm.shell.recents;
|
||||||
|
|
||||||
|
import android.app.ActivityManager;
|
||||||
|
|
||||||
import com.android.wm.shell.recents.IRecentTasksListener;
|
import com.android.wm.shell.recents.IRecentTasksListener;
|
||||||
import com.android.wm.shell.util.GroupedRecentTaskInfo;
|
import com.android.wm.shell.util.GroupedRecentTaskInfo;
|
||||||
|
|
||||||
@@ -38,4 +40,9 @@ interface IRecentTasks {
|
|||||||
* Gets the set of recent tasks.
|
* Gets the set of recent tasks.
|
||||||
*/
|
*/
|
||||||
GroupedRecentTaskInfo[] getRecentTasks(int maxNum, int flags, int userId) = 3;
|
GroupedRecentTaskInfo[] getRecentTasks(int maxNum, int flags, int userId) = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the set of running tasks.
|
||||||
|
*/
|
||||||
|
ActivityManager.RunningTaskInfo[] getRunningTasks(int maxNum) = 4;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.wm.shell.recents;
|
package com.android.wm.shell.recents;
|
||||||
|
|
||||||
|
import android.app.ActivityManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listener interface that Launcher attaches to SystemUI to get split-screen callbacks.
|
* Listener interface that Launcher attaches to SystemUI to get split-screen callbacks.
|
||||||
*/
|
*/
|
||||||
@@ -25,4 +27,14 @@ oneway interface IRecentTasksListener {
|
|||||||
* Called when the set of recent tasks change.
|
* Called when the set of recent tasks change.
|
||||||
*/
|
*/
|
||||||
void onRecentTasksChanged();
|
void onRecentTasksChanged();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a running task appears.
|
||||||
|
*/
|
||||||
|
void onRunningTaskAppeared(in ActivityManager.RunningTaskInfo taskInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a running task vanishes.
|
||||||
|
*/
|
||||||
|
void onRunningTaskVanished(in ActivityManager.RunningTaskInfo taskInfo);
|
||||||
}
|
}
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.wm.shell.recents;
|
package com.android.wm.shell.recents;
|
||||||
|
|
||||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||||
|
import static android.content.pm.PackageManager.FEATURE_PC;
|
||||||
|
|
||||||
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
|
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
|
||||||
|
|
||||||
@@ -63,8 +64,9 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
|||||||
private final ShellExecutor mMainExecutor;
|
private final ShellExecutor mMainExecutor;
|
||||||
private final TaskStackListenerImpl mTaskStackListener;
|
private final TaskStackListenerImpl mTaskStackListener;
|
||||||
private final RecentTasks mImpl = new RecentTasksImpl();
|
private final RecentTasks mImpl = new RecentTasksImpl();
|
||||||
|
private IRecentTasksListener mListener;
|
||||||
|
private final boolean mIsDesktopMode;
|
||||||
|
|
||||||
private final ArrayList<Runnable> mCallbacks = new ArrayList<>();
|
|
||||||
// Mapping of split task ids, mappings are symmetrical (ie. if t1 is the taskid of a task in a
|
// Mapping of split task ids, mappings are symmetrical (ie. if t1 is the taskid of a task in a
|
||||||
// pair, then mSplitTasks[t1] = t2, and mSplitTasks[t2] = t1)
|
// pair, then mSplitTasks[t1] = t2, and mSplitTasks[t2] = t1)
|
||||||
private final SparseIntArray mSplitTasks = new SparseIntArray();
|
private final SparseIntArray mSplitTasks = new SparseIntArray();
|
||||||
@@ -95,6 +97,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
|||||||
RecentTasksController(Context context, TaskStackListenerImpl taskStackListener,
|
RecentTasksController(Context context, TaskStackListenerImpl taskStackListener,
|
||||||
ShellExecutor mainExecutor) {
|
ShellExecutor mainExecutor) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
mIsDesktopMode = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
|
||||||
mTaskStackListener = taskStackListener;
|
mTaskStackListener = taskStackListener;
|
||||||
mMainExecutor = mainExecutor;
|
mMainExecutor = mainExecutor;
|
||||||
}
|
}
|
||||||
@@ -176,10 +179,15 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
|||||||
notifyRecentTasksChanged();
|
notifyRecentTasksChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onTaskRemoved(TaskInfo taskInfo) {
|
public void onTaskAdded(ActivityManager.RunningTaskInfo taskInfo) {
|
||||||
|
notifyRunningTaskAppeared(taskInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onTaskRemoved(ActivityManager.RunningTaskInfo taskInfo) {
|
||||||
// Remove any split pairs associated with this task
|
// Remove any split pairs associated with this task
|
||||||
removeSplitPair(taskInfo.taskId);
|
removeSplitPair(taskInfo.taskId);
|
||||||
notifyRecentTasksChanged();
|
notifyRecentTasksChanged();
|
||||||
|
notifyRunningTaskVanished(taskInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onTaskWindowingModeChanged(TaskInfo taskInfo) {
|
public void onTaskWindowingModeChanged(TaskInfo taskInfo) {
|
||||||
@@ -189,19 +197,50 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void notifyRecentTasksChanged() {
|
void notifyRecentTasksChanged() {
|
||||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENT_TASKS, "Notify recent tasks changed");
|
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENT_TASKS, "Notify recent tasks changed");
|
||||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
if (mListener == null) {
|
||||||
mCallbacks.get(i).run();
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mListener.onRecentTasksChanged();
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.w(TAG, "Failed call notifyRecentTasksChanged", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerRecentTasksListener(Runnable listener) {
|
/**
|
||||||
if (!mCallbacks.contains(listener)) {
|
* Notify the running task listener that a task appeared on desktop environment.
|
||||||
mCallbacks.add(listener);
|
*/
|
||||||
|
private void notifyRunningTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
|
||||||
|
if (mListener == null || !mIsDesktopMode || taskInfo.realActivity == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mListener.onRunningTaskAppeared(taskInfo);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.w(TAG, "Failed call onRunningTaskAppeared", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unregisterRecentTasksListener(Runnable listener) {
|
/**
|
||||||
mCallbacks.remove(listener);
|
* Notify the running task listener that a task was removed on desktop environment.
|
||||||
|
*/
|
||||||
|
private void notifyRunningTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
|
||||||
|
if (mListener == null || !mIsDesktopMode || taskInfo.realActivity == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mListener.onRunningTaskVanished(taskInfo);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.w(TAG, "Failed call onRunningTaskVanished", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerRecentTasksListener(IRecentTasksListener listener) {
|
||||||
|
mListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unregisterRecentTasksListener() {
|
||||||
|
mListener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -280,19 +319,28 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
|||||||
private RecentTasksController mController;
|
private RecentTasksController mController;
|
||||||
private final SingleInstanceRemoteListener<RecentTasksController,
|
private final SingleInstanceRemoteListener<RecentTasksController,
|
||||||
IRecentTasksListener> mListener;
|
IRecentTasksListener> mListener;
|
||||||
private final Runnable mRecentTasksListener =
|
private final IRecentTasksListener mRecentTasksListener = new IRecentTasksListener.Stub() {
|
||||||
new Runnable() {
|
@Override
|
||||||
@Override
|
public void onRecentTasksChanged() throws RemoteException {
|
||||||
public void run() {
|
mListener.call(l -> l.onRecentTasksChanged());
|
||||||
mListener.call(l -> l.onRecentTasksChanged());
|
}
|
||||||
}
|
|
||||||
};
|
@Override
|
||||||
|
public void onRunningTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
|
||||||
|
mListener.call(l -> l.onRunningTaskAppeared(taskInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRunningTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
|
||||||
|
mListener.call(l -> l.onRunningTaskVanished(taskInfo));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public IRecentTasksImpl(RecentTasksController controller) {
|
public IRecentTasksImpl(RecentTasksController controller) {
|
||||||
mController = controller;
|
mController = controller;
|
||||||
mListener = new SingleInstanceRemoteListener<>(controller,
|
mListener = new SingleInstanceRemoteListener<>(controller,
|
||||||
c -> c.registerRecentTasksListener(mRecentTasksListener),
|
c -> c.registerRecentTasksListener(mRecentTasksListener),
|
||||||
c -> c.unregisterRecentTasksListener(mRecentTasksListener));
|
c -> c.unregisterRecentTasksListener());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -331,5 +379,16 @@ public class RecentTasksController implements TaskStackListenerCallback,
|
|||||||
true /* blocking */);
|
true /* blocking */);
|
||||||
return out[0];
|
return out[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActivityManager.RunningTaskInfo[] getRunningTasks(int maxNum) {
|
||||||
|
final ActivityManager.RunningTaskInfo[][] tasks =
|
||||||
|
new ActivityManager.RunningTaskInfo[][] {null};
|
||||||
|
executeRemoteCallWithTaskPermission(mController, "getRunningTasks",
|
||||||
|
(controller) -> tasks[0] = ActivityTaskManager.getInstance().getTasks(maxNum)
|
||||||
|
.toArray(new ActivityManager.RunningTaskInfo[0]),
|
||||||
|
true /* blocking */);
|
||||||
|
return tasks[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,11 +30,13 @@ import static org.mockito.Mockito.reset;
|
|||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import static java.lang.Integer.MAX_VALUE;
|
import static java.lang.Integer.MAX_VALUE;
|
||||||
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
|
|
||||||
@@ -77,6 +79,7 @@ public class RecentTasksControllerTest extends ShellTestCase {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
mMainExecutor = new TestShellExecutor();
|
mMainExecutor = new TestShellExecutor();
|
||||||
|
when(mContext.getPackageManager()).thenReturn(mock(PackageManager.class));
|
||||||
mRecentTasksController = spy(new RecentTasksController(mContext, mTaskStackListener,
|
mRecentTasksController = spy(new RecentTasksController(mContext, mTaskStackListener,
|
||||||
mMainExecutor));
|
mMainExecutor));
|
||||||
mShellTaskOrganizer = new ShellTaskOrganizer(mMainExecutor, mContext,
|
mShellTaskOrganizer = new ShellTaskOrganizer(mMainExecutor, mContext,
|
||||||
|
|||||||
Reference in New Issue
Block a user