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
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 31fe390..c96bd39e 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1507,7 +1507,7 @@
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 @@
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 cf5240b..dcac633 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -683,10 +683,10 @@
int maxNum = data.readInt();
int fl = data.readInt();
int userId = data.readInt();
- List<ActivityManager.RecentTaskInfo> list = getRecentTasks(maxNum,
+ ParceledListSlice<ActivityManager.RecentTaskInfo> list = getRecentTasks(maxNum,
fl, userId);
reply.writeNoException();
- reply.writeTypedList(list);
+ list.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
return true;
}
@@ -3740,7 +3740,7 @@
reply.recycle();
return list;
}
- public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
+ public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
int flags, int userId) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -3750,8 +3750,8 @@
data.writeInt(userId);
mRemote.transact(GET_RECENT_TASKS_TRANSACTION, data, reply, 0);
reply.readException();
- ArrayList<ActivityManager.RecentTaskInfo> list
- = reply.createTypedArrayList(ActivityManager.RecentTaskInfo.CREATOR);
+ final ParceledListSlice<ActivityManager.RecentTaskInfo> 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 5037e3e..80ba3eb 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -136,7 +136,7 @@
ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException;
public Point getAppTaskThumbnailSize() throws RemoteException;
public List<RunningTaskInfo> getTasks(int maxNum, int flags) throws RemoteException;
- public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
+ public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
int flags, int userId) throws RemoteException;
public ActivityManager.TaskThumbnail getTaskThumbnail(int taskId) throws RemoteException;
public List<RunningServiceInfo> 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 8ee34a4..8530d66 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 @@
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 08b204a..c124e5d 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 @@
}
@Override
- public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
+ public ParceledListSlice<ActivityManager.RecentTaskInfo> 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 @@
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 @@
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 61c320b..cc007ef 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 @@
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 625fe77..bd9e6d1 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 @@
private void testTaskIdsForUser(int userId) throws RemoteException {
List<ActivityManager.RecentTaskInfo> recentTasks = service.getRecentTasks(
- 100, 0, userId);
+ 100, 0, userId).getList();
if(recentTasks != null) {
for(ActivityManager.RecentTaskInfo recentTask : recentTasks) {
int taskId = recentTask.persistentId;