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
This commit is contained in:
Jeff Sharkey
2016-06-29 16:00:55 -06:00
committed by Jeff Sharkey
parent ae5a14bc99
commit 479212cf50
7 changed files with 15 additions and 14 deletions

View File

@@ -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();
}

View File

@@ -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<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 @@ class ActivityManagerProxy implements IActivityManager
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 @@ class ActivityManagerProxy implements IActivityManager
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;

View File

@@ -136,7 +136,7 @@ public interface IActivityManager extends IInterface {
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;

View File

@@ -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.
}

View File

@@ -9077,7 +9077,8 @@ public final class ActivityManagerService extends ActivityManagerNative
}
@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 @@ 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);
}
}

View File

@@ -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)

View File

@@ -43,7 +43,7 @@ public class ActivityManagerTest extends AndroidTestCase {
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;