From 479212cf500193db6f1cf109ee58d72885f60a74 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Wed, 29 Jun 2016 16:00:55 -0600 Subject: [PATCH] Move getRecentTasks() to ParceledListSlice. In extreme cases the list of recent tasks can grow beyond the size of a single Binder transaction. This change moves over to ParceledListSlice which handles chunking any large results. Bug: 29635557 Change-Id: Iaf1227234f5f8c9451f73a6a5c1dc89f2067f05f --- core/java/android/app/ActivityManager.java | 4 ++-- core/java/android/app/ActivityManagerNative.java | 10 +++++----- core/java/android/app/IActivityManager.java | 2 +- .../com/android/systemui/statusbar/BaseStatusBar.java | 2 +- .../com/android/server/am/ActivityManagerService.java | 7 ++++--- .../com/android/server/media/MediaSessionStack.java | 2 +- .../src/com/android/server/am/ActivityManagerTest.java | 2 +- 7 files changed, 15 insertions(+), 14 deletions(-) diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 31fe39027fb0d..c96bd39eeffe1 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -1507,7 +1507,7 @@ public class ActivityManager { throws SecurityException { try { return ActivityManagerNative.getDefault().getRecentTasks(maxNum, - flags, UserHandle.myUserId()); + flags, UserHandle.myUserId()).getList(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1532,7 +1532,7 @@ public class ActivityManager { throws SecurityException { try { return ActivityManagerNative.getDefault().getRecentTasks(maxNum, - flags, userId); + flags, userId).getList(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index cf5240b581ae7..dcac633c4579d 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -683,10 +683,10 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM int maxNum = data.readInt(); int fl = data.readInt(); int userId = data.readInt(); - List list = getRecentTasks(maxNum, + ParceledListSlice list = getRecentTasks(maxNum, fl, userId); reply.writeNoException(); - reply.writeTypedList(list); + list.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); return true; } @@ -3740,7 +3740,7 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); return list; } - public List getRecentTasks(int maxNum, + public ParceledListSlice getRecentTasks(int maxNum, int flags, int userId) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); @@ -3750,8 +3750,8 @@ class ActivityManagerProxy implements IActivityManager data.writeInt(userId); mRemote.transact(GET_RECENT_TASKS_TRANSACTION, data, reply, 0); reply.readException(); - ArrayList list - = reply.createTypedArrayList(ActivityManager.RecentTaskInfo.CREATOR); + final ParceledListSlice list = ParceledListSlice.CREATOR + .createFromParcel(reply); data.recycle(); reply.recycle(); return list; diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 5037e3eb9dc54..80ba3eb02233e 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -136,7 +136,7 @@ public interface IActivityManager extends IInterface { ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException; public Point getAppTaskThumbnailSize() throws RemoteException; public List getTasks(int maxNum, int flags) throws RemoteException; - public List getRecentTasks(int maxNum, + public ParceledListSlice getRecentTasks(int maxNum, int flags, int userId) throws RemoteException; public ActivityManager.TaskThumbnail getTaskThumbnail(int taskId) throws RemoteException; public List getServices(int maxNum, int flags) throws RemoteException; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 8ee34a4cbd451..8530d667daa50 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -512,7 +512,7 @@ public abstract class BaseStatusBar extends SystemUI implements recentTask = ActivityManagerNative.getDefault().getRecentTasks(1, ActivityManager.RECENT_WITH_EXCLUDED | ActivityManager.RECENT_INCLUDE_PROFILES, - mCurrentUserId); + mCurrentUserId).getList(); } catch (RemoteException e) { // Abandon hope activity manager not running. } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 08b204af7fe71..c124e5d9a9bc2 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -9077,7 +9077,8 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override - public List getRecentTasks(int maxNum, int flags, int userId) { + public ParceledListSlice getRecentTasks(int maxNum, int flags, + int userId) { final int callingUid = Binder.getCallingUid(); userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId, false, ALLOW_FULL_ONLY, "getRecentTasks", null); @@ -9093,7 +9094,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) { Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents"); - return Collections.emptyList(); + return ParceledListSlice.emptyList(); } mRecentTasks.loadUserRecentsLocked(userId); @@ -9192,7 +9193,7 @@ public final class ActivityManagerService extends ActivityManagerNative maxNum--; } } - return res; + return new ParceledListSlice<>(res); } } diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java index 61c320bced3c4..cc007eff9075e 100644 --- a/services/core/java/com/android/server/media/MediaSessionStack.java +++ b/services/core/java/com/android/server/media/MediaSessionStack.java @@ -81,7 +81,7 @@ public class MediaSessionStack { ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS | ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_PROFILES | - ActivityManager.RECENT_WITH_EXCLUDED, record.getUserId()); + ActivityManager.RECENT_WITH_EXCLUDED, record.getUserId()).getList(); if (tasks != null && !tasks.isEmpty()) { ActivityManager.RecentTaskInfo recentTask = tasks.get(0); if (recentTask.baseIntent != null) diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java index 625fe77689900..bd9e6d19269be 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java @@ -43,7 +43,7 @@ public class ActivityManagerTest extends AndroidTestCase { private void testTaskIdsForUser(int userId) throws RemoteException { List recentTasks = service.getRecentTasks( - 100, 0, userId); + 100, 0, userId).getList(); if(recentTasks != null) { for(ActivityManager.RecentTaskInfo recentTask : recentTasks) { int taskId = recentTask.persistentId;