diff options
8 files changed, 161 insertions, 95 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 65de4ca5f59a..021a85e540f1 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -857,7 +857,7 @@ public class ActivityManager { if (mIcon != null) { return mIcon; } - return loadTaskDescriptionIcon(mIconFilename); + return loadTaskDescriptionIcon(mIconFilename, UserHandle.myUserId()); } /** @hide */ @@ -871,11 +871,11 @@ public class ActivityManager { } /** @hide */ - public static Bitmap loadTaskDescriptionIcon(String iconFilename) { + public static Bitmap loadTaskDescriptionIcon(String iconFilename, int userId) { if (iconFilename != null) { try { return ActivityManagerNative.getDefault(). - getTaskDescriptionIcon(iconFilename); + getTaskDescriptionIcon(iconFilename, userId); } catch (RemoteException e) { } } diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 4449e4fa8665..f60d9c75c5e4 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -2489,7 +2489,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM case GET_TASK_DESCRIPTION_ICON_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String filename = data.readString(); - Bitmap icon = getTaskDescriptionIcon(filename); + int userId = data.readInt(); + Bitmap icon = getTaskDescriptionIcon(filename, userId); reply.writeNoException(); if (icon == null) { reply.writeInt(0); @@ -5987,11 +5988,12 @@ class ActivityManagerProxy implements IActivityManager } @Override - public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException { + public Bitmap getTaskDescriptionIcon(String filename, int userId) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeString(filename); + data.writeInt(userId); mRemote.transact(GET_TASK_DESCRIPTION_ICON_TRANSACTION, data, reply, 0); reply.readException(); final Bitmap icon = reply.readInt() == 0 ? null : Bitmap.CREATOR.createFromParcel(reply); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index b69a4802d6c7..0eac65745de7 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -497,7 +497,7 @@ public interface IActivityManager extends IInterface { public void resizeTask(int taskId, Rect bounds, int resizeMode) throws RemoteException; public Rect getTaskBounds(int taskId) throws RemoteException; - public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException; + public Bitmap getTaskDescriptionIcon(String filename, int userId) throws RemoteException; public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) throws RemoteException; diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java index bba453a09172..e5bcc1c59eed 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java @@ -239,7 +239,8 @@ class BackgroundTaskLoader implements Runnable { SystemServicesProxy ssp, Resources res) { Bitmap tdIcon = iconBitmap != null ? iconBitmap - : ActivityManager.TaskDescription.loadTaskDescriptionIcon(iconFilename); + : ActivityManager.TaskDescription.loadTaskDescriptionIcon(iconFilename, + taskKey.userId); if (tdIcon != null) { return ssp.getBadgedIcon(new BitmapDrawable(res, tdIcon), taskKey.userId); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 566065c02852..f549fca9151e 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -8732,12 +8732,19 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override - public Bitmap getTaskDescriptionIcon(String filename) { - if (!FileUtils.isValidExtFilename(filename) - || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { - throw new IllegalArgumentException("Bad filename: " + filename); - } - return mTaskPersister.getTaskDescriptionIcon(filename); + public Bitmap getTaskDescriptionIcon(String filePath, int userId) { + if (userId != UserHandle.getCallingUserId()) { + enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, + "getTaskDescriptionIcon"); + } + final File passedIconFile = new File(filePath); + final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId), + passedIconFile.getName()); + if (!legitIconFile.getPath().equals(filePath) + || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { + throw new IllegalArgumentException("Bad file path: " + filePath); + } + return mTaskPersister.getTaskDescriptionIcon(filePath); } @Override diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index aa04bd70c714..ea8a12f81bab 100755 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -61,6 +61,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; +import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.lang.ref.WeakReference; @@ -1212,8 +1213,10 @@ final class ActivityRecord { if (_taskDescription.getIconFilename() == null && (icon = _taskDescription.getIcon()) != null) { final String iconFilename = createImageFilename(createTime, task.taskId); - mStackSupervisor.mService.mTaskPersister.saveImage(icon, iconFilename); - _taskDescription.setIconFilename(iconFilename); + final File iconFile = new File(TaskPersister.getUserImagesDir(userId), iconFilename); + final String iconFilePath = iconFile.getAbsolutePath(); + mStackSupervisor.mService.mTaskPersister.saveImage(icon, iconFilePath); + _taskDescription.setIconFilename(iconFilePath); } taskDescription = _taskDescription; } diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java index 150baf0e89d5..9a0007555eb5 100644 --- a/services/core/java/com/android/server/am/TaskPersister.java +++ b/services/core/java/com/android/server/am/TaskPersister.java @@ -16,10 +16,11 @@ package com.android.server.am; -import android.content.pm.IPackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Debug; +import android.os.Environment; +import android.os.FileUtils; import android.os.SystemClock; import android.util.ArraySet; import android.util.AtomicFile; @@ -27,7 +28,6 @@ import android.util.Slog; import android.util.Xml; import android.os.Process; -import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; @@ -44,6 +44,7 @@ import java.io.StringWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; +import java.util.List; import libcore.io.IoUtils; @@ -54,8 +55,10 @@ public class TaskPersister { /** When not flushing don't write out files faster than this */ private static final long INTER_WRITE_DELAY_MS = 500; - /** When not flushing delay this long before writing the first file out. This gives the next - * task being launched a chance to load its resources without this occupying IO bandwidth. */ + /** + * When not flushing delay this long before writing the first file out. This gives the next task + * being launched a chance to load its resources without this occupying IO bandwidth. + */ private static final long PRE_TASK_DELAY_MS = 3000; /** The maximum number of entries to keep in the queue before draining it automatically. */ @@ -72,24 +75,23 @@ public class TaskPersister { private static final String TAG_TASK = "task"; - static File sImagesDir; - static File sTasksDir; - private final ActivityManagerService mService; private final ActivityStackSupervisor mStackSupervisor; private final RecentTasks mRecentTasks; - /** Value determines write delay mode as follows: - * < 0 We are Flushing. No delays between writes until the image queue is drained and all - * tasks needing persisting are written to disk. There is no delay between writes. - * == 0 We are Idle. Next writes will be delayed by #PRE_TASK_DELAY_MS. - * > 0 We are Actively writing. Next write will be at this time. Subsequent writes will be - * delayed by #INTER_WRITE_DELAY_MS. */ + /** + * Value determines write delay mode as follows: < 0 We are Flushing. No delays between writes + * until the image queue is drained and all tasks needing persisting are written to disk. There + * is no delay between writes. == 0 We are Idle. Next writes will be delayed by + * #PRE_TASK_DELAY_MS. > 0 We are Actively writing. Next write will be at this time. Subsequent + * writes will be delayed by #INTER_WRITE_DELAY_MS. + */ private long mNextWriteTime = 0; private final LazyTaskWriterThread mLazyTaskWriterThread; private static class WriteQueueItem {} + private static class TaskWriteQueueItem extends WriteQueueItem { final TaskRecord mTask; @@ -97,12 +99,13 @@ public class TaskPersister { mTask = task; } } + private static class ImageWriteQueueItem extends WriteQueueItem { - final String mFilename; + final String mFilePath; Bitmap mImage; - ImageWriteQueueItem(String filename, Bitmap image) { - mFilename = filename; + ImageWriteQueueItem(String filePath, Bitmap image) { + mFilePath = filePath; mImage = image; } } @@ -111,19 +114,18 @@ public class TaskPersister { TaskPersister(File systemDir, ActivityStackSupervisor stackSupervisor, RecentTasks recentTasks) { - sTasksDir = new File(systemDir, TASKS_DIRNAME); - if (!sTasksDir.exists()) { - if (DEBUG) Slog.d(TAG, "Creating tasks directory " + sTasksDir); - if (!sTasksDir.mkdir()) { - Slog.e(TAG, "Failure creating tasks directory " + sTasksDir); + + final File legacyImagesDir = new File(systemDir, IMAGES_DIRNAME); + if (legacyImagesDir.exists()) { + if (!FileUtils.deleteContents(legacyImagesDir) || !legacyImagesDir.delete()) { + Slog.i(TAG, "Failure deleting legacy images directory: " + legacyImagesDir); } } - sImagesDir = new File(systemDir, IMAGES_DIRNAME); - if (!sImagesDir.exists()) { - if (DEBUG) Slog.d(TAG, "Creating images directory " + sTasksDir); - if (!sImagesDir.mkdir()) { - Slog.e(TAG, "Failure creating images directory " + sImagesDir); + final File legacyTasksDir = new File(systemDir, TASKS_DIRNAME); + if (legacyTasksDir.exists()) { + if (!FileUtils.deleteContents(legacyTasksDir) || !legacyTasksDir.delete()) { + Slog.i(TAG, "Failure deleting legacy tasks directory: " + legacyTasksDir); } } @@ -144,8 +146,8 @@ public class TaskPersister { for (int queueNdx = mWriteQueue.size() - 1; queueNdx >= 0; --queueNdx) { final WriteQueueItem item = mWriteQueue.get(queueNdx); if (item instanceof ImageWriteQueueItem && - ((ImageWriteQueueItem) item).mFilename.startsWith(taskString)) { - if (DEBUG) Slog.d(TAG, "Removing " + ((ImageWriteQueueItem) item).mFilename + + ((ImageWriteQueueItem) item).mFilePath.startsWith(taskString)) { + if (DEBUG) Slog.d(TAG, "Removing " + ((ImageWriteQueueItem) item).mFilePath + " from write queue"); mWriteQueue.remove(queueNdx); } @@ -213,14 +215,14 @@ public class TaskPersister { } } - void saveImage(Bitmap image, String filename) { + void saveImage(Bitmap image, String filePath) { synchronized (this) { int queueNdx; for (queueNdx = mWriteQueue.size() - 1; queueNdx >= 0; --queueNdx) { final WriteQueueItem item = mWriteQueue.get(queueNdx); if (item instanceof ImageWriteQueueItem) { ImageWriteQueueItem imageWriteQueueItem = (ImageWriteQueueItem) item; - if (imageWriteQueueItem.mFilename.equals(filename)) { + if (imageWriteQueueItem.mFilePath.equals(filePath)) { // replace the Bitmap with the new one. imageWriteQueueItem.mImage = image; break; @@ -228,14 +230,14 @@ public class TaskPersister { } } if (queueNdx < 0) { - mWriteQueue.add(new ImageWriteQueueItem(filename, image)); + mWriteQueue.add(new ImageWriteQueueItem(filePath, image)); } if (mWriteQueue.size() > MAX_WRITE_QUEUE_LENGTH) { mNextWriteTime = FLUSH_QUEUE; } else if (mNextWriteTime == 0) { mNextWriteTime = SystemClock.uptimeMillis() + PRE_TASK_DELAY_MS; } - if (DEBUG) Slog.d(TAG, "saveImage: filename=" + filename + " now=" + + if (DEBUG) Slog.d(TAG, "saveImage: filePath=" + filePath + " now=" + SystemClock.uptimeMillis() + " mNextWriteTime=" + mNextWriteTime + " Callers=" + Debug.getCallers(4)); notifyAll(); @@ -244,22 +246,22 @@ public class TaskPersister { yieldIfQueueTooDeep(); } - Bitmap getTaskDescriptionIcon(String filename) { + Bitmap getTaskDescriptionIcon(String filePath) { // See if it is in the write queue - final Bitmap icon = getImageFromWriteQueue(filename); + final Bitmap icon = getImageFromWriteQueue(filePath); if (icon != null) { return icon; } - return restoreImage(filename); + return restoreImage(filePath); } - Bitmap getImageFromWriteQueue(String filename) { + Bitmap getImageFromWriteQueue(String filePath) { synchronized (this) { for (int queueNdx = mWriteQueue.size() - 1; queueNdx >= 0; --queueNdx) { final WriteQueueItem item = mWriteQueue.get(queueNdx); if (item instanceof ImageWriteQueueItem) { ImageWriteQueueItem imageWriteQueueItem = (ImageWriteQueueItem) item; - if (imageWriteQueueItem.mFilename.equals(filename)) { + if (imageWriteQueueItem.mFilePath.equals(filePath)) { return imageWriteQueueItem.mImage; } } @@ -275,7 +277,7 @@ public class TaskPersister { xmlSerializer.setOutput(stringWriter); if (DEBUG) xmlSerializer.setFeature( - "http://xmlpull.org/v1/doc/features.html#indent-output", true); + "http://xmlpull.org/v1/doc/features.html#indent-output", true); // save task xmlSerializer.startDocument(null, true); @@ -321,19 +323,22 @@ public class TaskPersister { return null; } - ArrayList<TaskRecord> restoreTasksLocked(final int [] validUserIds) { - final ArrayList<TaskRecord> tasks = new ArrayList<TaskRecord>(); + private List<TaskRecord> restoreTasksForUserLocked(final int userId) { + final List<TaskRecord> tasks = new ArrayList<TaskRecord>(); ArraySet<Integer> recoveredTaskIds = new ArraySet<Integer>(); - File[] recentFiles = sTasksDir.listFiles(); + File userTasksDir = getUserTasksDir(userId); + + File[] recentFiles = userTasksDir.listFiles(); if (recentFiles == null) { - Slog.e(TAG, "Unable to list files from " + sTasksDir); + Slog.e(TAG, "restoreTasksForUser: Unable to list files from " + userTasksDir); return tasks; } for (int taskNdx = 0; taskNdx < recentFiles.length; ++taskNdx) { File taskFile = recentFiles[taskNdx]; - if (DEBUG) Slog.d(TAG, "restoreTasksLocked: taskFile=" + taskFile.getName()); + if (DEBUG) Slog.d(TAG, "restoreTasksForUser: userId=" + userId + + ", taskFile=" + taskFile.getName()); BufferedReader reader = null; boolean deleteFile = false; try { @@ -348,30 +353,29 @@ public class TaskPersister { if (event == XmlPullParser.START_TAG) { if (DEBUG) Slog.d(TAG, "restoreTasksLocked: START_TAG name=" + name); if (TAG_TASK.equals(name)) { - final TaskRecord task = - TaskRecord.restoreFromXml(in, mStackSupervisor); - if (DEBUG) Slog.d(TAG, "restoreTasksLocked: restored task=" + - task); + final TaskRecord task = TaskRecord.restoreFromXml(in, mStackSupervisor); + if (DEBUG) Slog.d(TAG, "restoreTasksLocked: restored task=" + + task); if (task != null) { // XXX Don't add to write queue... there is no reason to write // out the stuff we just read, if we don't write it we will // read the same thing again. - //mWriteQueue.add(new TaskWriteQueueItem(task)); + // mWriteQueue.add(new TaskWriteQueueItem(task)); final int taskId = task.taskId; mStackSupervisor.setNextTaskId(taskId); // Check if it's a valid user id. Don't add tasks for removed users. - if (ArrayUtils.contains(validUserIds, task.userId)) { + if (userId == task.userId) { task.isPersistable = true; tasks.add(task); recoveredTaskIds.add(taskId); } } else { - Slog.e(TAG, "Unable to restore taskFile=" + taskFile + ": " + - fileToString(taskFile)); + Slog.e(TAG, "restoreTasksForUser: Unable to restore taskFile=" + + taskFile + ": " + fileToString(taskFile)); } } else { - Slog.wtf(TAG, "restoreTasksLocked Unknown xml event=" + event + - " name=" + name); + Slog.wtf(TAG, "restoreTasksForUser: Unknown xml event=" + event + + " name=" + name); } } XmlUtils.skipCurrentTag(in); @@ -390,10 +394,19 @@ public class TaskPersister { } if (!DEBUG) { - removeObsoleteFiles(recoveredTaskIds); + removeObsoleteFiles(recoveredTaskIds, userTasksDir.listFiles()); } + return tasks; + } + + ArrayList<TaskRecord> restoreTasksLocked(final int[] validUserIds) { + final ArrayList<TaskRecord> tasks = new ArrayList<TaskRecord>(); - // Fixup task affiliation from taskIds + for (int userId : validUserIds) { + tasks.addAll(restoreTasksForUserLocked(userId)); + } + + // Fix up task affiliation from taskIds for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { final TaskRecord task = tasks.get(taskNdx); task.setPrevAffiliate(taskIdToTask(task.mPrevAffiliateTaskId, tasks)); @@ -420,7 +433,7 @@ public class TaskPersister { } private static void removeObsoleteFiles(ArraySet<Integer> persistentTaskIds, File[] files) { - if (DEBUG) Slog.d(TAG, "removeObsoleteFile: persistentTaskIds=" + persistentTaskIds + + if (DEBUG) Slog.d(TAG, "removeObsoleteFiles: persistentTaskIds=" + persistentTaskIds + " files=" + files); if (files == null) { Slog.e(TAG, "File error accessing recents directory (too many files open?)."); @@ -434,14 +447,14 @@ public class TaskPersister { final int taskId; try { taskId = Integer.valueOf(filename.substring(0, taskIdEnd)); - if (DEBUG) Slog.d(TAG, "removeObsoleteFile: Found taskId=" + taskId); + if (DEBUG) Slog.d(TAG, "removeObsoleteFiles: Found taskId=" + taskId); } catch (Exception e) { - Slog.wtf(TAG, "removeObsoleteFile: Can't parse file=" + file.getName()); + Slog.wtf(TAG, "removeObsoleteFiles: Can't parse file=" + file.getName()); file.delete(); continue; } if (!persistentTaskIds.contains(taskId)) { - if (DEBUG) Slog.d(TAG, "removeObsoleteFile: deleting file=" + file.getName()); + if (DEBUG) Slog.d(TAG, "removeObsoleteFiles: deleting file=" + file.getName()); file.delete(); } } @@ -449,13 +462,39 @@ public class TaskPersister { } private void removeObsoleteFiles(ArraySet<Integer> persistentTaskIds) { - removeObsoleteFiles(persistentTaskIds, sTasksDir.listFiles()); - removeObsoleteFiles(persistentTaskIds, sImagesDir.listFiles()); + for (int userId : mService.getRunningUserIds()) { + removeObsoleteFiles(persistentTaskIds, getUserImagesDir(userId).listFiles()); + removeObsoleteFiles(persistentTaskIds, getUserTasksDir(userId).listFiles()); + } } static Bitmap restoreImage(String filename) { if (DEBUG) Slog.d(TAG, "restoreImage: restoring " + filename); - return BitmapFactory.decodeFile(sImagesDir + File.separator + filename); + return BitmapFactory.decodeFile(filename); + } + + static File getUserTasksDir(int userId) { + File userTasksDir = new File(Environment.getUserSystemDirectory(userId), TASKS_DIRNAME); + + if (!userTasksDir.exists()) { + if (!userTasksDir.mkdir()) { + Slog.e(TAG, "Failure creating tasks directory for user " + userId + ": " + + userTasksDir); + } + } + return userTasksDir; + } + + static File getUserImagesDir(int userId) { + File userImagesDir = new File(Environment.getUserSystemDirectory(userId), IMAGES_DIRNAME); + + if (!userImagesDir.exists()) { + if (!userImagesDir.mkdir()) { + Slog.e(TAG, "Failure creating images directory for user " + userId + ": " + + userImagesDir); + } + } + return userImagesDir; } private class LazyTaskWriterThread extends Thread { @@ -508,7 +547,6 @@ public class TaskPersister { INTER_WRITE_DELAY_MS + " msec. (" + mNextWriteTime + ")"); } - while (mWriteQueue.isEmpty()) { if (mNextWriteTime != 0) { mNextWriteTime = 0; // idle. @@ -542,15 +580,15 @@ public class TaskPersister { if (item instanceof ImageWriteQueueItem) { ImageWriteQueueItem imageWriteQueueItem = (ImageWriteQueueItem) item; - final String filename = imageWriteQueueItem.mFilename; + final String filePath = imageWriteQueueItem.mFilePath; final Bitmap bitmap = imageWriteQueueItem.mImage; - if (DEBUG) Slog.d(TAG, "writing bitmap: filename=" + filename); + if (DEBUG) Slog.d(TAG, "writing bitmap: filename=" + filePath); FileOutputStream imageFile = null; try { - imageFile = new FileOutputStream(new File(sImagesDir, filename)); + imageFile = new FileOutputStream(new File(filePath)); bitmap.compress(Bitmap.CompressFormat.PNG, 100, imageFile); } catch (Exception e) { - Slog.e(TAG, "saveImage: unable to save " + filename, e); + Slog.e(TAG, "saveImage: unable to save " + filePath, e); } finally { IoUtils.closeQuietly(imageFile); } @@ -575,18 +613,21 @@ public class TaskPersister { FileOutputStream file = null; AtomicFile atomicFile = null; try { - atomicFile = new AtomicFile(new File(sTasksDir, String.valueOf( - task.taskId) + RECENTS_FILENAME + TASK_EXTENSION)); + atomicFile = new AtomicFile(new File( + getUserTasksDir(task.userId), + String.valueOf(task.taskId) + RECENTS_FILENAME + + TASK_EXTENSION)); file = atomicFile.startWrite(); file.write(stringWriter.toString().getBytes()); file.write('\n'); atomicFile.finishWrite(file); + } catch (IOException e) { if (file != null) { atomicFile.failWrite(file); } - Slog.e(TAG, "Unable to open " + atomicFile + " for persisting. " + - e); + Slog.e(TAG, + "Unable to open " + atomicFile + " for persisting. " + e); } } } diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index b2140806b4aa..0d574069e69e 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -27,15 +27,23 @@ import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER; import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; -import static com.android.server.am.ActivityManagerDebugConfig.*; -import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS; +import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_ADD_REMOVE; +import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK; +import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS; +import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS; +import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; +import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE; +import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.StackId; -import android.app.ActivityManager.TaskThumbnail; import android.app.ActivityManager.TaskDescription; import android.app.ActivityManager.TaskThumbnail; import android.app.ActivityManager.TaskThumbnailInfo; @@ -58,8 +66,10 @@ import android.os.UserHandle; import android.service.voice.IVoiceInteractionSession; import android.util.DisplayMetrics; import android.util.Slog; + import com.android.internal.app.IVoiceInteractor; import com.android.internal.util.XmlUtils; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; @@ -237,7 +247,8 @@ final class TaskRecord { mService = service; mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX + TaskPersister.IMAGE_EXTENSION; - mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename); + userId = UserHandle.getUserId(info.applicationInfo.uid); + mLastThumbnailFile = new File(TaskPersister.getUserImagesDir(userId), mFilename); mLastThumbnailInfo = new TaskThumbnailInfo(); taskId = _taskId; mAffiliatedTaskId = _taskId; @@ -256,7 +267,8 @@ final class TaskRecord { mService = service; mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX + TaskPersister.IMAGE_EXTENSION; - mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename); + userId = UserHandle.getUserId(info.applicationInfo.uid); + mLastThumbnailFile = new File(TaskPersister.getUserImagesDir(userId), mFilename); mLastThumbnailInfo = thumbnailInfo; taskId = _taskId; mAffiliatedTaskId = _taskId; @@ -276,7 +288,6 @@ final class TaskRecord { taskType = APPLICATION_ACTIVITY_TYPE; mTaskToReturnTo = HOME_ACTIVITY_TYPE; - userId = UserHandle.getUserId(info.applicationInfo.uid); lastTaskDescription = _taskDescription; mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1; } @@ -294,7 +305,7 @@ final class TaskRecord { mService = service; mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX + TaskPersister.IMAGE_EXTENSION; - mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename); + mLastThumbnailFile = new File(TaskPersister.getUserImagesDir(_userId), mFilename); mLastThumbnailInfo = lastThumbnailInfo; taskId = _taskId; intent = _intent; @@ -537,7 +548,7 @@ final class TaskRecord { mLastThumbnailFile.delete(); } } else { - mService.mTaskPersister.saveImage(thumbnail, mFilename); + mService.mTaskPersister.saveImage(thumbnail, mLastThumbnailFile.getAbsolutePath()); } return true; } @@ -549,7 +560,8 @@ final class TaskRecord { thumbs.thumbnailInfo = mLastThumbnailInfo; thumbs.thumbnailFileDescriptor = null; if (mLastThumbnail == null) { - thumbs.mainThumbnail = mService.mTaskPersister.getImageFromWriteQueue(mFilename); + thumbs.mainThumbnail = mService.mTaskPersister.getImageFromWriteQueue( + mLastThumbnailFile.getAbsolutePath()); } // Only load the thumbnail file if we don't have a thumbnail if (thumbs.mainThumbnail == null && mLastThumbnailFile.exists()) { |