diff options
12 files changed, 84 insertions, 740 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 6039210b69f2..0b428d43ed16 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -6333,21 +6333,6 @@ public final class Settings { public static final String WEB_ACTION_ENABLED = "web_action_enabled"; /** - * The uptime when tasks were last persisted. This is used to adjust the previous task - * active times to be relative to the current boot time. - * @hide - */ - public static final String TASK_PERSISTER_LAST_WRITE_UPTIME = "task_persister_write_uptime"; - - /** - * Used by Overview to keep track of the last visible task's active time to determine what - * should tasks be visible. - * @hide - */ - public static final String OVERVIEW_LAST_VISIBLE_TASK_ACTIVE_UPTIME = - "overview_last_visible_task_active_uptime"; - - /** * This are the settings to be backed up. * * NOTE: Settings are backed up and restored in the order they appear diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java index b9ae585c339c..19ae2954bb2a 100644 --- a/packages/SystemUI/src/com/android/systemui/Prefs.java +++ b/packages/SystemUI/src/com/android/systemui/Prefs.java @@ -49,7 +49,6 @@ public final class Prefs { Key.QS_WORK_ADDED, }) public @interface Key { - @Deprecated String OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME = "OverviewLastStackTaskActiveTime"; String DEBUG_MODE_ENABLED = "debugModeEnabled"; String HOTSPOT_TILE_LAST_USED = "HotspotTileLastUsed"; diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index a7d7df50691c..72074635999c 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -34,7 +34,6 @@ import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; -import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; @@ -47,7 +46,6 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsProto.MetricsEvent; import com.android.systemui.EventLogConstants; import com.android.systemui.EventLogTags; -import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.RecentsComponent; import com.android.systemui.SystemUI; @@ -252,19 +250,6 @@ public class Recents extends SystemUI registerWithSystemUser(); } putComponent(Recents.class, this); - - // Migrate the old stack active time if necessary, otherwise, it will already be managed - // when the tasks are loaded in the system. See TaskPersister.restoreTasksForUserLocked(). - long lastVisibleTaskActiveTime = Prefs.getLong(mContext, - Prefs.Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME, -1); - if (lastVisibleTaskActiveTime != -1) { - long uptime = SystemClock.elapsedRealtime(); - Settings.Secure.putLongForUser(mContext.getContentResolver(), - Settings.Secure.OVERVIEW_LAST_VISIBLE_TASK_ACTIVE_UPTIME, - uptime - Math.max(0, System.currentTimeMillis() - lastVisibleTaskActiveTime), - processUser); - Prefs.remove(mContext, Prefs.Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME); - } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index 1e418706dd59..7bdb1c499bd9 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -20,7 +20,6 @@ import android.app.Activity; import android.app.ActivityOptions; import android.app.TaskStackBuilder; import android.content.BroadcastReceiver; -import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -171,6 +170,13 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD if (action.equals(Intent.ACTION_SCREEN_OFF)) { // When the screen turns off, dismiss Recents to Home dismissRecentsToHomeIfVisible(false); + } else if (action.equals(Intent.ACTION_TIME_CHANGED)) { + // For the time being, if the time changes, then invalidate the + // last-stack-active-time, this ensures that we will just show the last N tasks + // the next time that Recents loads, but prevents really old tasks from showing + // up if the task time is set forward. + Prefs.putLong(RecentsActivity.this, Prefs.Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME, + 0); } } }; @@ -316,6 +322,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD // Register the broadcast receiver to handle messages when the screen is turned off IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_OFF); + filter.addAction(Intent.ACTION_TIME_CHANGED); registerReceiver(mSystemBroadcastReceiver, filter); getWindow().addPrivateFlags(LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION); @@ -793,19 +800,14 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD EventBus.getDefault().dump(prefix, writer); Recents.getTaskLoader().dump(prefix, writer); - ContentResolver cr = getContentResolver(); - long lastPersistUptime = Settings.Secure.getLong(cr, - Settings.Secure.TASK_PERSISTER_LAST_WRITE_UPTIME, 0); - long lastVisibleTaskActiveUptime = Settings.Secure.getLongForUser(cr, - Settings.Secure.OVERVIEW_LAST_VISIBLE_TASK_ACTIVE_UPTIME, - SystemClock.elapsedRealtime(), Recents.getSystemServices().getCurrentUser()); - String id = Integer.toHexString(System.identityHashCode(this)); + long lastStackActiveTime = Prefs.getLong(this, + Prefs.Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME, -1); writer.print(prefix); writer.print(TAG); writer.print(" visible="); writer.print(mIsVisible ? "Y" : "N"); - writer.print(" lastPersistUptime="); writer.print(lastPersistUptime); - writer.print(" lastVisibleTaskActiveUptime="); writer.print(lastVisibleTaskActiveUptime); + writer.print(" lastStackTaskActiveTime="); writer.print(lastStackActiveTime); + writer.print(" currentTime="); writer.print(System.currentTimeMillis()); writer.print(" [0x"); writer.print(id); writer.print("]"); writer.println(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java index 0dd9e5428ad8..b896f8a4d815 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java @@ -59,7 +59,6 @@ import android.os.Looper; import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.RemoteException; -import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; @@ -75,7 +74,6 @@ import android.view.WindowManager.KeyboardShortcutsReceiver; import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityManager; -import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.AssistUtils; import com.android.internal.os.BackgroundThread; import com.android.systemui.R; @@ -200,9 +198,6 @@ public class SystemServicesProxy { */ private List<TaskStackListener> mTaskStackListeners = new ArrayList<>(); - /** Test constructor */ - @VisibleForTesting public SystemServicesProxy() {} - /** Private constructor */ private SystemServicesProxy(Context context) { mAccm = AccessibilityManager.getInstance(context); @@ -304,7 +299,7 @@ public class SystemServicesProxy { rti.baseIntent = new Intent(); rti.baseIntent.setComponent(cn); rti.description = description; - rti.firstActiveTime = rti.lastActiveTime = SystemClock.elapsedRealtime(); + rti.firstActiveTime = rti.lastActiveTime = i; if (i % 2 == 0) { rti.taskDescription = new ActivityManager.TaskDescription(description, Bitmap.createBitmap(mDummyIcon), null, diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java index ecd48e1f8da0..1278b735a7cd 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java @@ -24,15 +24,13 @@ import android.content.pm.UserInfo; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; -import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; -import android.provider.Settings; import android.util.ArraySet; import android.util.SparseArray; import android.util.SparseIntArray; -import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsConfiguration; @@ -58,11 +56,6 @@ public class RecentsTaskLoadPlan { private static int SESSION_BEGIN_TIME = 1000 /* ms/s */ * 60 /* s/min */ * 60 /* min/hr */ * 6 /* hrs */; - @VisibleForTesting - public interface SystemTimeProvider { - public long getTime(); - } - /** The set of conditions to load tasks. */ public static class Options { public int runningTaskId = -1; @@ -74,46 +67,15 @@ public class RecentsTaskLoadPlan { public int numVisibleTaskThumbnails = 0; } - private Context mContext; - @VisibleForTesting private SystemServicesProxy mSystemServicesProxy; - - private List<ActivityManager.RecentTaskInfo> mRawTasks; - private long mLastVisibileTaskActiveTime; - private TaskStack mStack; - private ArraySet<Integer> mCurrentQuietProfiles = new ArraySet<Integer>(); - private SystemTimeProvider mTimeProvider = new SystemTimeProvider() { - @Override - public long getTime() { - return SystemClock.elapsedRealtime(); - } - }; + Context mContext; - @VisibleForTesting - public RecentsTaskLoadPlan(Context context, SystemServicesProxy ssp) { - mContext = context; - mSystemServicesProxy = ssp; - } - - @VisibleForTesting - public void setInternals(List<ActivityManager.RecentTaskInfo> tasks, - final long currentTime, long lastVisibleTaskActiveTime) { - setInternals(tasks, MIN_NUM_TASKS, currentTime, lastVisibleTaskActiveTime, - SESSION_BEGIN_TIME); - } + List<ActivityManager.RecentTaskInfo> mRawTasks; + TaskStack mStack; + ArraySet<Integer> mCurrentQuietProfiles = new ArraySet<Integer>(); - @VisibleForTesting - public void setInternals(List<ActivityManager.RecentTaskInfo> tasks, int minNumTasks, - final long currentTime, long lastVisibleTaskActiveTime, int sessionBeginTime) { - mRawTasks = tasks; - mLastVisibileTaskActiveTime = lastVisibleTaskActiveTime; - mTimeProvider = new SystemTimeProvider() { - @Override - public long getTime() { - return currentTime; - } - }; - MIN_NUM_TASKS = minNumTasks; - SESSION_BEGIN_TIME = sessionBeginTime; + /** Package level ctor */ + RecentsTaskLoadPlan(Context context) { + mContext = context; } private void updateCurrentQuietProfilesCache(int currentUserId) { @@ -141,13 +103,9 @@ public class RecentsTaskLoadPlan { public synchronized void preloadRawTasks(boolean includeFrontMostExcludedTask) { int currentUserId = UserHandle.USER_CURRENT; updateCurrentQuietProfilesCache(currentUserId); - mRawTasks = mSystemServicesProxy.getRecentTasks(ActivityManager.getMaxRecentTasksStatic(), + SystemServicesProxy ssp = Recents.getSystemServices(); + mRawTasks = ssp.getRecentTasks(ActivityManager.getMaxRecentTasksStatic(), currentUserId, includeFrontMostExcludedTask, mCurrentQuietProfiles); - mLastVisibileTaskActiveTime = RecentsDebugFlags.Static.EnableMockTasks - ? SystemClock.elapsedRealtime() - : Settings.Secure.getLongForUser(mContext.getContentResolver(), - Settings.Secure.OVERVIEW_LAST_VISIBLE_TASK_ACTIVE_UPTIME, - 0, currentUserId); // Since the raw tasks are given in most-recent to least-recent order, we need to reverse it Collections.reverse(mRawTasks); @@ -176,9 +134,12 @@ public class RecentsTaskLoadPlan { R.string.accessibility_recents_item_will_be_dismissed); String appInfoDescFormat = mContext.getString( R.string.accessibility_recents_item_open_app_info); - boolean updatedLastVisibleTaskActiveTime = false; - long newLastVisibileTaskActiveTime = 0; - long currentTime = mTimeProvider.getTime(); + long lastStackActiveTime = Prefs.getLong(mContext, + Prefs.Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME, 0); + if (RecentsDebugFlags.Static.EnableMockTasks) { + lastStackActiveTime = 0; + } + long newLastStackActiveTime = -1; int taskCount = mRawTasks.size(); for (int i = 0; i < taskCount; i++) { ActivityManager.RecentTaskInfo t = mRawTasks.get(i); @@ -187,20 +148,19 @@ public class RecentsTaskLoadPlan { Task.TaskKey taskKey = new Task.TaskKey(t.persistentId, t.stackId, t.baseIntent, t.userId, t.firstActiveTime, t.lastActiveTime); - // Only show the task if it is freeform, or later than the last visible task active time - // and either recently used, or within the last five tasks - boolean isFreeformTask = mSystemServicesProxy.isFreeformStack(t.stackId); - boolean isRecentlyUsedTask = t.lastActiveTime >= (currentTime - SESSION_BEGIN_TIME); - boolean isMoreRecentThanLastVisible = t.lastActiveTime >= mLastVisibileTaskActiveTime; - boolean isStackTask = isFreeformTask || (isMoreRecentThanLastVisible && - (isRecentlyUsedTask || i >= (taskCount - MIN_NUM_TASKS))); - boolean isLaunchTarget = t.persistentId == runningTaskId; - - // If this is the first task satisfying the stack constraints, update the baseline - // at which we show visible tasks - if (isStackTask && !updatedLastVisibleTaskActiveTime) { - newLastVisibileTaskActiveTime = t.lastActiveTime; - updatedLastVisibleTaskActiveTime = true; + // This task is only shown in the stack if it statisfies the historical time or min + // number of tasks constraints. Freeform tasks are also always shown. + boolean isFreeformTask = SystemServicesProxy.isFreeformStack(t.stackId); + boolean isStackTask = isFreeformTask || !isHistoricalTask(t) || + (t.lastActiveTime >= lastStackActiveTime && i >= (taskCount - MIN_NUM_TASKS)); + boolean isLaunchTarget = taskKey.id == runningTaskId; + + // The last stack active time is the baseline for which we show visible tasks. Since + // the system will store all the tasks, we don't want to show the tasks prior to the + // last visible ones, otherwise, as you dismiss them, the previous tasks may satisfy + // the other stack-task constraints. + if (isStackTask && newLastStackActiveTime < 0) { + newLastStackActiveTime = t.lastActiveTime; } // Load the title, icon, and color @@ -228,12 +188,9 @@ public class RecentsTaskLoadPlan { affiliatedTaskCounts.put(taskKey.id, affiliatedTaskCounts.get(taskKey.id, 0) + 1); affiliatedTasks.put(taskKey.id, taskKey); } - if (updatedLastVisibleTaskActiveTime && - newLastVisibileTaskActiveTime != mLastVisibileTaskActiveTime) { - Settings.Secure.putLongForUser(mContext.getContentResolver(), - Settings.Secure.OVERVIEW_LAST_VISIBLE_TASK_ACTIVE_UPTIME, - newLastVisibileTaskActiveTime, UserHandle.USER_CURRENT); - mLastVisibileTaskActiveTime = newLastVisibileTaskActiveTime; + if (newLastStackActiveTime != -1) { + Prefs.putLong(mContext, Prefs.Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME, + newLastStackActiveTime); } // Initialize the stacks @@ -298,4 +255,11 @@ public class RecentsTaskLoadPlan { } return false; } + + /** + * Returns whether this task is too old to be shown. + */ + private boolean isHistoricalTask(ActivityManager.RecentTaskInfo t) { + return t.lastActiveTime < (System.currentTimeMillis() - SESSION_BEGIN_TIME); + } } 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 e0eda376eac2..ba31e3e835c0 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java @@ -30,7 +30,6 @@ import android.os.HandlerThread; import android.util.Log; import android.util.LruCache; -import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.R; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsConfiguration; @@ -287,20 +286,6 @@ public class RecentsTaskLoader { } }; - @VisibleForTesting - public RecentsTaskLoader() { - mActivityInfoCache = null; - mIconCache = null; - mThumbnailCache = null; - mActivityLabelCache = null; - mContentDescriptionCache = null; - mLoadQueue = null; - mLoader = null; - - mMaxThumbnailCacheSize = 0; - mMaxIconCacheSize = 0; - } - public RecentsTaskLoader(Context context) { Resources res = context.getResources(); mDefaultTaskBarBackgroundColor = @@ -347,8 +332,7 @@ public class RecentsTaskLoader { /** Creates a new plan for loading the recent tasks. */ public RecentsTaskLoadPlan createLoadPlan(Context context) { - RecentsTaskLoadPlan plan = new RecentsTaskLoadPlan(context, - Recents.getSystemServices()); + RecentsTaskLoadPlan plan = new RecentsTaskLoadPlan(context); return plan; } @@ -471,8 +455,7 @@ public class RecentsTaskLoader { /** * Returns the cached task label if the task key is not expired, updating the cache if it is. */ - @VisibleForTesting public String getAndUpdateActivityTitle(Task.TaskKey taskKey, - ActivityManager.TaskDescription td) { + String getAndUpdateActivityTitle(Task.TaskKey taskKey, ActivityManager.TaskDescription td) { SystemServicesProxy ssp = Recents.getSystemServices(); // Return the task description label if it exists @@ -500,8 +483,7 @@ public class RecentsTaskLoader { * Returns the cached task content description if the task key is not expired, updating the * cache if it is. */ - @VisibleForTesting public String getAndUpdateContentDescription(Task.TaskKey taskKey, - Resources res) { + String getAndUpdateContentDescription(Task.TaskKey taskKey, Resources res) { SystemServicesProxy ssp = Recents.getSystemServices(); // Return the cached content description if it exists @@ -525,8 +507,8 @@ public class RecentsTaskLoader { /** * Returns the cached task icon if the task key is not expired, updating the cache if it is. */ - @VisibleForTesting public Drawable getAndUpdateActivityIcon(Task.TaskKey taskKey, - ActivityManager.TaskDescription td, Resources res, boolean loadIfNotCached) { + Drawable getAndUpdateActivityIcon(Task.TaskKey taskKey, ActivityManager.TaskDescription td, + Resources res, boolean loadIfNotCached) { SystemServicesProxy ssp = Recents.getSystemServices(); // Return the cached activity icon if it exists @@ -560,8 +542,7 @@ public class RecentsTaskLoader { /** * Returns the cached thumbnail if the task key is not expired, updating the cache if it is. */ - @VisibleForTesting public Bitmap getAndUpdateThumbnail(Task.TaskKey taskKey, - boolean loadIfNotCached) { + Bitmap getAndUpdateThumbnail(Task.TaskKey taskKey, boolean loadIfNotCached) { SystemServicesProxy ssp = Recents.getSystemServices(); // Return the cached thumbnail if it exists @@ -589,7 +570,7 @@ public class RecentsTaskLoader { * Returns the task's primary color if possible, defaulting to the default color if there is * no specified primary color. */ - @VisibleForTesting public int getActivityPrimaryColor(ActivityManager.TaskDescription td) { + int getActivityPrimaryColor(ActivityManager.TaskDescription td) { if (td != null && td.getPrimaryColor() != 0) { return td.getPrimaryColor(); } @@ -599,7 +580,7 @@ public class RecentsTaskLoader { /** * Returns the task's background color if possible. */ - @VisibleForTesting public int getActivityBackgroundColor(ActivityManager.TaskDescription td) { + int getActivityBackgroundColor(ActivityManager.TaskDescription td) { if (td != null && td.getBackgroundColor() != 0) { return td.getBackgroundColor(); } @@ -610,7 +591,7 @@ public class RecentsTaskLoader { * Returns the activity info for the given task key, retrieving one from the system if the * task key is expired. */ - @VisibleForTesting public ActivityInfo getAndUpdateActivityInfo(Task.TaskKey taskKey) { + ActivityInfo getAndUpdateActivityInfo(Task.TaskKey taskKey) { SystemServicesProxy ssp = Recents.getSystemServices(); ComponentName cn = taskKey.getComponent(); ActivityInfo activityInfo = mActivityInfoCache.get(cn); diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java index 4191f52c35e4..86a0315496a1 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java @@ -290,10 +290,7 @@ public class Task { */ public boolean isFreeformTask() { SystemServicesProxy ssp = Recents.getSystemServices(); - if (ssp != null) { - return ssp.hasFreeformWorkspaceSupport() && ssp.isFreeformStack(key.stackId); - } - return false; + return ssp.hasFreeformWorkspaceSupport() && ssp.isFreeformStack(key.stackId); } /** Notifies the callback listeners that this task has been loaded */ diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/RecentsTaskLoadPlanTest.java b/packages/SystemUI/tests/src/com/android/systemui/recents/RecentsTaskLoadPlanTest.java deleted file mode 100644 index dd78595a0aa5..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/recents/RecentsTaskLoadPlanTest.java +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.recents; - -import android.app.ActivityManager; -import android.content.pm.ActivityInfo; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import com.android.systemui.SysuiTestCase; -import com.android.systemui.recents.misc.SystemServicesProxy; -import com.android.systemui.recents.model.RecentsTaskLoadPlan; -import com.android.systemui.recents.model.RecentsTaskLoader; -import com.android.systemui.recents.model.Task; -import com.android.systemui.recents.model.TaskStack; - -import java.util.ArrayList; - -/** - * Mock task loader that does not actually load any tasks. - */ -class MockRecentsTaskNonLoader extends RecentsTaskLoader { - @Override - public String getAndUpdateActivityTitle(Task.TaskKey taskKey, ActivityManager.TaskDescription td) { - return ""; - } - - @Override - public String getAndUpdateContentDescription(Task.TaskKey taskKey, Resources res) { - return ""; - } - - @Override - public Drawable getAndUpdateActivityIcon(Task.TaskKey taskKey, ActivityManager.TaskDescription td, Resources res, boolean loadIfNotCached) { - return null; - } - - @Override - public Bitmap getAndUpdateThumbnail(Task.TaskKey taskKey, boolean loadIfNotCached) { - return null; - } - - @Override - public int getActivityPrimaryColor(ActivityManager.TaskDescription td) { - return 0; - } - - @Override - public int getActivityBackgroundColor(ActivityManager.TaskDescription td) { - return 0; - } - - @Override - public ActivityInfo getAndUpdateActivityInfo(Task.TaskKey taskKey) { - return null; - } -} - -/** - * TODO(winsonc): - * - add test to ensure excluded tasks are loaded at the front of the list - * - add test to ensure the last visible task active time is migrated from absolute to uptime - */ -public class RecentsTaskLoadPlanTest extends SysuiTestCase { - private static final String TAG = "RecentsTaskLoadPlanTest"; - - private MockRecentsTaskNonLoader mDummyLoader = new MockRecentsTaskNonLoader(); - private SystemServicesProxy mDummySsp = new SystemServicesProxy(); - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - - public void testEmptyRecents() { - RecentsTaskLoadPlan loadPlan = new RecentsTaskLoadPlan(getTestContext(), mDummySsp); - ArrayList<ActivityManager.RecentTaskInfo> tasks = new ArrayList<>(); - loadPlan.setInternals(tasks, 0 /* current */, 0 /* lastVisibleTaskActive */); - loadPlan.preloadPlan(mDummyLoader, 0 /* runningTaskId */, - false /* includeFrontMostExcludedTask */); - assertFalse("Expected task to be empty", loadPlan.getTaskStack().getStackTaskCount() > 0); - } - - public void testLessThanEqualMinTasks() { - RecentsTaskLoadPlan loadPlan = new RecentsTaskLoadPlan(getTestContext(), mDummySsp); - ArrayList<ActivityManager.RecentTaskInfo> tasks = new ArrayList<>(); - int minTasks = 3; - - resetTaskInfoList(tasks, - createTaskInfo(0, 1), - createTaskInfo(1, 2), - createTaskInfo(2, 3)); - - // Ensure that all tasks are loaded if the tasks are within the session and after the last - // visible active time (all tasks are loaded because there are < minTasks number of tasks) - loadPlan.setInternals(tasks, minTasks, 0 /* current */, 0 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksInStack(loadPlan.getTaskStack(), 0, 1, 2); - - loadPlan.setInternals(tasks, minTasks, 1 /* current */, 0 /* lastVisibleTaskActive */, - 0 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksInStack(loadPlan.getTaskStack(), 0, 1, 2); - - loadPlan.setInternals(tasks, minTasks, 1 /* current */, 0 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksInStack(loadPlan.getTaskStack(), 0, 1, 2); - - loadPlan.setInternals(tasks, minTasks, 3 /* current */, 0 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksInStack(loadPlan.getTaskStack(), 0, 1, 2); - - loadPlan.setInternals(tasks, minTasks, 3 /* current */, 1 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksInStack(loadPlan.getTaskStack(), 0, 1, 2); - - loadPlan.setInternals(tasks, minTasks, 50 /* current */, 0 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksInStack(loadPlan.getTaskStack(), 0, 1, 2); - - loadPlan.setInternals(tasks, minTasks, 150 /* current */, 0 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksInStack(loadPlan.getTaskStack(), 0, 1, 2); - - // Ensure that only tasks are not loaded if are after the last visible active time, even if - // they are within the session - loadPlan.setInternals(tasks, minTasks, 50 /* current */, 0 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksInStack(loadPlan.getTaskStack(), 0, 1, 2); - - loadPlan.setInternals(tasks, minTasks, 50 /* current */, 1 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksInStack(loadPlan.getTaskStack(), 0, 1, 2); - - loadPlan.setInternals(tasks, minTasks, 50 /* current */, 2 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0); - assertTasksInStack(loadPlan.getTaskStack(), 1, 2); - - loadPlan.setInternals(tasks, minTasks, 50 /* current */, 3 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0, 1); - assertTasksInStack(loadPlan.getTaskStack(), 2); - - loadPlan.setInternals(tasks, minTasks, 50 /* current */, 50 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0, 1, 2); - } - - public void testMoreThanMinTasks() { - RecentsTaskLoadPlan loadPlan = new RecentsTaskLoadPlan(getTestContext(), mDummySsp); - ArrayList<ActivityManager.RecentTaskInfo> tasks = new ArrayList<>(); - int minTasks = 3; - - // Create all tasks within the session - resetTaskInfoList(tasks, - createTaskInfo(0, 1), - createTaskInfo(1, 50), - createTaskInfo(2, 100), - createTaskInfo(3, 101), - createTaskInfo(4, 102), - createTaskInfo(5, 103)); - - // Ensure that only the tasks that are within the window but after the last visible active - // time is loaded, or the minTasks number of tasks are loaded if there are less than that - - // Session window shifts - loadPlan.setInternals(tasks, minTasks, 0 /* current */, 0 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksInStack(loadPlan.getTaskStack(), 0, 1, 2, 3, 4, 5); - - loadPlan.setInternals(tasks, minTasks, 1 /* current */, 0 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksInStack(loadPlan.getTaskStack(), 0, 1, 2, 3, 4, 5); - - loadPlan.setInternals(tasks, minTasks, 51 /* current */, 0 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksInStack(loadPlan.getTaskStack(), 0, 1, 2, 3, 4, 5); - - loadPlan.setInternals(tasks, minTasks, 52 /* current */, 0 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0); - assertTasksInStack(loadPlan.getTaskStack(), 1, 2, 3, 4, 5); - - loadPlan.setInternals(tasks, minTasks, 100 /* current */, 0 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0); - assertTasksInStack(loadPlan.getTaskStack(), 1, 2, 3, 4, 5); - - loadPlan.setInternals(tasks, minTasks, 101 /* current */, 0 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0, 1); - assertTasksInStack(loadPlan.getTaskStack(), 2, 3, 4, 5); - - loadPlan.setInternals(tasks, minTasks, 103 /* current */, 0 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0, 1); - assertTasksInStack(loadPlan.getTaskStack(), 2, 3, 4, 5); - - loadPlan.setInternals(tasks, minTasks, 150 /* current */, 0 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0, 1); - assertTasksInStack(loadPlan.getTaskStack(), 2, 3, 4, 5); - - loadPlan.setInternals(tasks, minTasks, 151 /* current */, 0 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0, 1, 2); - assertTasksInStack(loadPlan.getTaskStack(), 3, 4, 5); - - loadPlan.setInternals(tasks, minTasks, 200 /* current */, 0 /* lastVisibleTaskActive */, - 50 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0, 1, 2); - assertTasksInStack(loadPlan.getTaskStack(), 3, 4, 5); - - // Last visible active time shifts (everything is in window) - loadPlan.setInternals(tasks, minTasks, 150 /* current */, 0 /* lastVisibleTaskActive */, - 150 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksInStack(loadPlan.getTaskStack(), 0, 1, 2, 3, 4, 5); - - loadPlan.setInternals(tasks, minTasks, 150 /* current */, 1 /* lastVisibleTaskActive */, - 150 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksInStack(loadPlan.getTaskStack(), 0, 1, 2, 3, 4, 5); - - loadPlan.setInternals(tasks, minTasks, 150 /* current */, 2 /* lastVisibleTaskActive */, - 150 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0); - assertTasksInStack(loadPlan.getTaskStack(), 1, 2, 3, 4, 5); - - loadPlan.setInternals(tasks, minTasks, 150 /* current */, 50 /* lastVisibleTaskActive */, - 150 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0); - assertTasksInStack(loadPlan.getTaskStack(), 1, 2, 3, 4, 5); - - loadPlan.setInternals(tasks, minTasks, 150 /* current */, 51 /* lastVisibleTaskActive */, - 150 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0, 1); - assertTasksInStack(loadPlan.getTaskStack(), 2, 3, 4, 5); - - loadPlan.setInternals(tasks, minTasks, 150 /* current */, 100 /* lastVisibleTaskActive */, - 150 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0, 1); - assertTasksInStack(loadPlan.getTaskStack(), 2, 3, 4, 5); - - loadPlan.setInternals(tasks, minTasks, 150 /* current */, 101 /* lastVisibleTaskActive */, - 150 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0, 1, 2); - assertTasksInStack(loadPlan.getTaskStack(), 3, 4, 5); - - loadPlan.setInternals(tasks, minTasks, 150 /* current */, 102 /* lastVisibleTaskActive */, - 150 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0, 1, 2, 3); - assertTasksInStack(loadPlan.getTaskStack(), 4, 5); - - loadPlan.setInternals(tasks, minTasks, 150 /* current */, 103 /* lastVisibleTaskActive */, - 150 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0, 1, 2, 3, 4); - assertTasksInStack(loadPlan.getTaskStack(), 5); - - loadPlan.setInternals(tasks, minTasks, 150 /* current */, 104 /* lastVisibleTaskActive */, - 150 /* sessionBegin */); - loadPlan.preloadPlan(mDummyLoader, 0, false); - assertTasksNotInStack(loadPlan.getTaskStack(), 0, 1, 2, 3, 4, 5); - } - - private ActivityManager.RecentTaskInfo createTaskInfo(int taskId, long lastActiveTime) { - ActivityManager.RecentTaskInfo info = new ActivityManager.RecentTaskInfo(); - info.id = info.persistentId = taskId; - info.lastActiveTime = lastActiveTime; - return info; - } - - private void resetTaskInfoList(ArrayList<ActivityManager.RecentTaskInfo> tasks, - ActivityManager.RecentTaskInfo ... infos) { - tasks.clear(); - for (ActivityManager.RecentTaskInfo info : infos) { - tasks.add(info); - } - } - - private void assertTasksInStack(TaskStack stack, int... taskIds) { - for (int taskId : taskIds) { - assertNotNull("Expected task " + taskId + " in stack", stack.findTaskWithId(taskId)); - } - } - - private void assertTasksNotInStack(TaskStack stack, int... taskIds) { - for (int taskId : taskIds) { - assertNull("Expected task " + taskId + " not in stack", stack.findTaskWithId(taskId)); - } - } -} diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java index 6cdabaac361f..43eb251ba23b 100644 --- a/services/core/java/com/android/server/am/TaskPersister.java +++ b/services/core/java/com/android/server/am/TaskPersister.java @@ -17,7 +17,6 @@ package com.android.server.am; import android.annotation.NonNull; -import android.content.ContentResolver; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Debug; @@ -25,7 +24,6 @@ import android.os.Environment; import android.os.FileUtils; import android.os.Process; import android.os.SystemClock; -import android.provider.Settings; import android.util.ArraySet; import android.util.AtomicFile; import android.util.Slog; @@ -82,7 +80,7 @@ public class TaskPersister { private static final String PERSISTED_TASK_IDS_FILENAME = "persisted_taskIds.txt"; static final String IMAGE_EXTENSION = ".png"; - @VisibleForTesting static final String TAG_TASK = "task"; + private static final String TAG_TASK = "task"; private final ActivityManagerService mService; private final ActivityStackSupervisor mStackSupervisor; @@ -409,43 +407,18 @@ public class TaskPersister { return null; } - @VisibleForTesting List<TaskRecord> restoreTasksForUserLocked(final int userId) { final ArrayList<TaskRecord> tasks = new ArrayList<TaskRecord>(); ArraySet<Integer> recoveredTaskIds = new ArraySet<Integer>(); File userTasksDir = getUserTasksDir(userId); + File[] recentFiles = userTasksDir.listFiles(); if (recentFiles == null) { Slog.e(TAG, "restoreTasksForUserLocked: Unable to list files from " + userTasksDir); return tasks; } - // Get the last persist uptime so we know how to adjust the first/last active times for each - // task - ContentResolver cr = mService.mContext.getContentResolver(); - long lastPersistUptime = Settings.Secure.getLong(cr, - Settings.Secure.TASK_PERSISTER_LAST_WRITE_UPTIME, 0); - if (DEBUG) { - Slog.d(TaskPersister.TAG, "restoreTasksForUserLocked: lastPersistUptime=" + - lastPersistUptime); - } - - // Adjust the overview last visible task active time as we adjust the task active times when - // loading. See TaskRecord.restoreFromXml(). If we have not migrated yet, SystemUI will - // migrate the old value into the system setting. - if (lastPersistUptime > 0) { - long overviewLastActiveTime = Settings.Secure.getLongForUser(cr, - Settings.Secure.OVERVIEW_LAST_VISIBLE_TASK_ACTIVE_UPTIME, 0, userId); - if (DEBUG) { - Slog.d(TaskPersister.TAG, "restoreTasksForUserLocked: overviewLastActiveTime=" + - overviewLastActiveTime + " lastPersistUptime=" + lastPersistUptime); - } - Settings.Secure.putLongForUser(cr, - Settings.Secure.OVERVIEW_LAST_VISIBLE_TASK_ACTIVE_UPTIME, - -lastPersistUptime + overviewLastActiveTime, userId); - } - for (int taskNdx = 0; taskNdx < recentFiles.length; ++taskNdx) { File taskFile = recentFiles[taskNdx]; if (DEBUG) { @@ -466,11 +439,15 @@ public class TaskPersister { if (event == XmlPullParser.START_TAG) { if (DEBUG) Slog.d(TAG, "restoreTasksForUserLocked: START_TAG name=" + name); if (TAG_TASK.equals(name)) { - final TaskRecord task = TaskRecord.restoreFromXml(in, mService, - mStackSupervisor, lastPersistUptime); + final TaskRecord task = TaskRecord.restoreFromXml(in, mStackSupervisor); if (DEBUG) Slog.d(TAG, "restoreTasksForUserLocked: 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)); + final int taskId = task.taskId; if (mStackSupervisor.anyTaskForIdLocked(taskId, /* restoreFromRecents= */ false, 0) != null) { @@ -486,12 +463,6 @@ public class TaskPersister { task.isPersistable = true; tasks.add(task); recoveredTaskIds.add(taskId); - - // We've shifted the first and last active times, so we need to - // persist the new task data to disk otherwise they will not - // have the updated values. This is only done once whenever - // the recents are first loaded for the user. - wakeup(task, false); } } else { Slog.e(TAG, "restoreTasksForUserLocked: Unable to restore taskFile=" @@ -780,15 +751,6 @@ public class TaskPersister { } } } - - // Always update the task persister uptime when updating any tasks - if (DEBUG) { - Slog.d(TAG, "LazyTaskWriter: Updating last write uptime=" + - SystemClock.elapsedRealtime()); - } - Settings.Secure.putLong(mService.mContext.getContentResolver(), - Settings.Secure.TASK_PERSISTER_LAST_WRITE_UPTIME, - SystemClock.elapsedRealtime()); } } } diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index b3d802778c94..3f6db990a5b5 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -39,14 +39,12 @@ import android.graphics.Rect; import android.os.Debug; import android.os.ParcelFileDescriptor; import android.os.RemoteException; -import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; import android.service.voice.IVoiceInteractionSession; import android.util.DisplayMetrics; import android.util.Slog; -import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IVoiceInteractor; import com.android.internal.util.XmlUtils; @@ -152,10 +150,8 @@ final class TaskRecord { ComponentName realActivity; // The actual activity component that started the task. boolean realActivitySuspended; // True if the actual activity component that started the // task is suspended. - long firstActiveTime; // First time this task was active, relative to boot time. This can be - // negative if this task was last used prior to boot. - long lastActiveTime; // Last time this task was active, relative to boot time. This can be - // negative if this task was last used prior to boot. + long firstActiveTime; // First time this task was active. + long lastActiveTime; // Last time this task was active, including sleep. boolean inRecents; // Actually in the recents list? boolean isAvailable; // Is the activity available to be launched? boolean rootWasReset; // True if the intent at the root of the task had @@ -381,14 +377,14 @@ final class TaskRecord { } void touchActiveTime() { - lastActiveTime = SystemClock.elapsedRealtime(); + lastActiveTime = System.currentTimeMillis(); if (firstActiveTime == 0) { firstActiveTime = lastActiveTime; } } long getInactiveDuration() { - return SystemClock.elapsedRealtime() - lastActiveTime; + return System.currentTimeMillis() - lastActiveTime; } /** Sets the original intent, and the calling uid and package. */ @@ -459,9 +455,8 @@ final class TaskRecord { rootWasReset = true; } userId = UserHandle.getUserId(info.applicationInfo.uid); - mUserSetupComplete = mService != null && - Settings.Secure.getIntForUser(mService.mContext.getContentResolver(), - USER_SETUP_COMPLETE, 0, userId) != 0; + mUserSetupComplete = Settings.Secure.getIntForUser(mService.mContext.getContentResolver(), + USER_SETUP_COMPLETE, 0, userId) != 0; if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) { // If the activity itself has requested auto-remove, then just always do it. autoRemoveRecents = true; @@ -1173,9 +1168,7 @@ final class TaskRecord { if (lastTaskDescription != null) { lastTaskDescription.saveToXml(out); } - if (mLastThumbnailInfo != null) { - mLastThumbnailInfo.saveToXml(out); - } + mLastThumbnailInfo.saveToXml(out); out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor)); out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId)); out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId)); @@ -1197,11 +1190,9 @@ final class TaskRecord { out.endTag(null, TAG_AFFINITYINTENT); } - if (intent != null) { - out.startTag(null, TAG_INTENT); - intent.saveToXml(out); - out.endTag(null, TAG_INTENT); - } + out.startTag(null, TAG_INTENT); + intent.saveToXml(out); + out.endTag(null, TAG_INTENT); final ArrayList<ActivityRecord> activities = mActivities; final int numActivities = activities.size(); @@ -1220,9 +1211,8 @@ final class TaskRecord { } } - static TaskRecord restoreFromXml(XmlPullParser in, ActivityManagerService service, - ActivityStackSupervisor stackSupervisor, long lastPersistUptime) - throws IOException, XmlPullParserException { + static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor) + throws IOException, XmlPullParserException { Intent intent = null; Intent affinityIntent = null; ArrayList<ActivityRecord> activities = new ArrayList<>(); @@ -1335,31 +1325,6 @@ final class TaskRecord { } } - if (lastPersistUptime > 0) { - if (TaskPersister.DEBUG) { - Slog.d(TaskPersister.TAG, "TaskRecord: Adjust firstActiveTime=" + firstActiveTime + - " lastPersistUptime=" + lastPersistUptime); - Slog.d(TaskPersister.TAG, "TaskRecord: Migrate lastActiveTime=" + lastActiveTime + - " lastActiveTime=" + lastPersistUptime); - } - // The first and last task active times are relative to the last boot time, so offset - // them to be prior to the current boot time - firstActiveTime = -lastPersistUptime + firstActiveTime; - lastActiveTime = -lastPersistUptime + lastActiveTime; - } else { - // The first/last active times are still absolute clock times, so offset them to be - // relative to the current boot time - long currentTime = System.currentTimeMillis(); - if (TaskPersister.DEBUG) { - Slog.d(TaskPersister.TAG, "TaskRecord: Migrate firstActiveTime=" + firstActiveTime + - " currentTime=" + currentTime); - Slog.d(TaskPersister.TAG, "TaskRecord: Migrate lastActiveTime=" + lastActiveTime + - " currentTime=" + currentTime); - } - firstActiveTime = -Math.max(0, currentTime - firstActiveTime); - lastActiveTime = -Math.max(0, currentTime - lastActiveTime); - } - int event; while (((event = in.next()) != XmlPullParser.END_DOCUMENT) && (event != XmlPullParser.END_TAG || in.getDepth() >= outerDepth)) { @@ -1409,7 +1374,7 @@ final class TaskRecord { + ": effectiveUid=" + effectiveUid); } - final TaskRecord task = new TaskRecord(service, taskId, intent, + final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent, affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset, autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription, activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity, @@ -1812,7 +1777,7 @@ final class TaskRecord { pw.print(prefix + "hasBeenVisible=" + hasBeenVisible); pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode)); pw.print(" isResizeable=" + isResizeable()); - pw.print(" firstActiveTime=" + firstActiveTime); + pw.print(" firstActiveTime=" + lastActiveTime); pw.print(" lastActiveTime=" + lastActiveTime); pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)"); } diff --git a/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java b/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java index 7571f79ea1e3..984a484dadc2 100644 --- a/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java +++ b/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java @@ -16,36 +16,19 @@ package com.android.server.am; -import android.app.ActivityManager; -import android.content.ContentResolver; -import android.content.pm.ActivityInfo; import android.content.pm.UserInfo; import android.os.Environment; -import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; -import android.provider.Settings; import android.test.AndroidTestCase; import android.util.Log; import android.util.SparseBooleanArray; -import android.util.Xml; -import com.android.internal.util.FastXmlSerializer; -import com.android.internal.util.XmlUtils; import com.android.server.am.TaskPersister; import java.io.File; -import java.io.IOException; -import java.io.StringReader; -import java.io.StringWriter; import java.util.Random; -import libcore.io.IoUtils; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; - public class TaskPersisterTest extends AndroidTestCase { private static final String TEST_USER_NAME = "AM-Test-User"; @@ -86,140 +69,6 @@ public class TaskPersisterTest extends AndroidTestCase { taskIdsOnFile.equals(newTaskIdsOnFile)); } - public void testActiveTimeMigration() { - // Simulate a migration scenario by setting the last write uptime to zero - ContentResolver cr = getContext().getContentResolver(); - Settings.Secure.putLong(cr, - Settings.Secure.TASK_PERSISTER_LAST_WRITE_UPTIME, 0); - - // Create a dummy task record with an absolute time 1s before now - long pastOffset = 1000; - long activeTime = System.currentTimeMillis() - pastOffset; - TaskRecord tr0 = createDummyTaskRecordWithActiveTime(activeTime, activeTime); - - // Save and load the tasks with no last persist uptime (0) - String tr0XmlStr = serializeTaskRecordToXmlString(tr0); - TaskRecord xtr0 = unserializeTaskRecordFromXmlString(tr0XmlStr, 0); - - // Ensure that the absolute time has been migrated to be relative to the current elapsed - // time - assertTrue("Expected firstActiveTime to be migrated from: " + tr0.firstActiveTime + - " instead found: " + xtr0.firstActiveTime, - xtr0.firstActiveTime <= -pastOffset); - assertTrue("Expected lastActiveTime to be migrated from: " + tr0.lastActiveTime + - " instead found: " + xtr0.lastActiveTime, - xtr0.lastActiveTime <= -pastOffset); - - // Ensure that the last active uptime is not set so that SystemUI can migrate it itself - // assuming that the last persist time is zero - Settings.Secure.putLongForUser(cr, - Settings.Secure.OVERVIEW_LAST_VISIBLE_TASK_ACTIVE_UPTIME, 0, testUserId); - mTaskPersister.restoreTasksForUserLocked(testUserId); - long lastVisTaskActiveTime = Settings.Secure.getLongForUser(cr, - Settings.Secure.OVERVIEW_LAST_VISIBLE_TASK_ACTIVE_UPTIME, -1, testUserId); - assertTrue("Expected last visible task active time is zero", lastVisTaskActiveTime == 0); - } - - public void testActiveTimeOffsets() { - // Simulate a normal boot scenario by setting the last write uptime - long lastWritePastOffset = 1000; - long lastVisActivePastOffset = 500; - ContentResolver cr = getContext().getContentResolver(); - Settings.Secure.putLong(cr, - Settings.Secure.TASK_PERSISTER_LAST_WRITE_UPTIME, lastWritePastOffset); - - // Create a dummy task record with an absolute time 1s before now - long activeTime = 250; - TaskRecord tr0 = createDummyTaskRecordWithActiveTime(activeTime, activeTime); - - // Save and load the tasks with the last persist time - String tr0XmlStr = serializeTaskRecordToXmlString(tr0); - TaskRecord xtr0 = unserializeTaskRecordFromXmlString(tr0XmlStr, lastWritePastOffset); - - // Ensure that the prior elapsed time has been offset to be relative to the current boot - // time - assertTrue("Expected firstActiveTime to be offset from: " + tr0.firstActiveTime + - " instead found: " + xtr0.firstActiveTime, - xtr0.firstActiveTime <= (-lastWritePastOffset + activeTime)); - assertTrue("Expected lastActiveTime to be offset from: " + tr0.lastActiveTime + - " instead found: " + xtr0.lastActiveTime, - xtr0.lastActiveTime <= (-lastWritePastOffset + activeTime)); - - // Ensure that we update the last active uptime as well by simulating a restoreTasks call - Settings.Secure.putLongForUser(cr, - Settings.Secure.OVERVIEW_LAST_VISIBLE_TASK_ACTIVE_UPTIME, lastVisActivePastOffset, - testUserId); - mTaskPersister.restoreTasksForUserLocked(testUserId); - long lastVisTaskActiveTime = Settings.Secure.getLongForUser(cr, - Settings.Secure.OVERVIEW_LAST_VISIBLE_TASK_ACTIVE_UPTIME, Long.MAX_VALUE, - testUserId); - assertTrue("Expected last visible task active time to be offset", lastVisTaskActiveTime <= - (-lastWritePastOffset + lastVisActivePastOffset)); - } - - private TaskRecord createDummyTaskRecordWithActiveTime(long firstActiveTime, - long lastActiveTime) { - ActivityInfo info = createDummyActivityInfo(); - ActivityManager.TaskDescription td = new ActivityManager.TaskDescription(); - TaskRecord t = new TaskRecord(null, 0, info, null, td, null); - t.firstActiveTime = firstActiveTime; - t.lastActiveTime = lastActiveTime; - return t; - } - - private ActivityInfo createDummyActivityInfo() { - ActivityInfo info = new ActivityInfo(); - info.applicationInfo = getContext().getApplicationInfo(); - return info; - } - - private String serializeTaskRecordToXmlString(TaskRecord tr) { - StringWriter stringWriter = new StringWriter(); - - try { - final XmlSerializer xmlSerializer = new FastXmlSerializer(); - xmlSerializer.setOutput(stringWriter); - - xmlSerializer.startDocument(null, true); - xmlSerializer.startTag(null, TaskPersister.TAG_TASK); - tr.saveToXml(xmlSerializer); - xmlSerializer.endTag(null, TaskPersister.TAG_TASK); - xmlSerializer.endDocument(); - xmlSerializer.flush(); - } catch (Exception e) { - e.printStackTrace(); - } - - return stringWriter.toString(); - } - - private TaskRecord unserializeTaskRecordFromXmlString(String xmlStr, long lastPersistUptime) { - StringReader reader = null; - TaskRecord task = null; - try { - reader = new StringReader(xmlStr); - final XmlPullParser in = Xml.newPullParser(); - in.setInput(reader); - - int event; - while (((event = in.next()) != XmlPullParser.END_DOCUMENT) && - event != XmlPullParser.END_TAG) { - final String name = in.getName(); - if (event == XmlPullParser.START_TAG) { - if (TaskPersister.TAG_TASK.equals(name)) { - task = TaskRecord.restoreFromXml(in, null, null, lastPersistUptime); - } - } - XmlUtils.skipCurrentTag(in); - } - } catch (Exception e) { - return null; - } finally { - IoUtils.closeQuietly(reader); - } - return task; - } - private int createUser(String name, int flags) { UserInfo user = mUserManager.createUser(name, flags); if (user == null) { |