Loading services/core/java/com/android/server/wm/TaskSnapshotPersister.java +29 −4 Original line number Original line Diff line number Diff line Loading @@ -28,12 +28,14 @@ import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Bitmap.Config; import android.os.Process; import android.os.Process; import android.os.SystemClock; import android.os.SystemClock; import android.os.UserManagerInternal; import android.util.ArraySet; import android.util.ArraySet; import android.util.AtomicFile; import android.util.AtomicFile; import android.util.Slog; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import com.android.server.wm.nano.WindowManagerProtos.TaskSnapshotProto; import com.android.server.wm.nano.WindowManagerProtos.TaskSnapshotProto; import java.io.File; import java.io.File; Loading Loading @@ -72,6 +74,7 @@ class TaskSnapshotPersister { private final float mLowResScaleFactor; private final float mLowResScaleFactor; private boolean mEnableLowResSnapshots; private boolean mEnableLowResSnapshots; private final boolean mUse16BitFormat; private final boolean mUse16BitFormat; private final UserManagerInternal mUserManagerInternal; /** /** * The list of ids of the tasks that have been persisted since {@link #removeObsoleteFiles} was * The list of ids of the tasks that have been persisted since {@link #removeObsoleteFiles} was Loading @@ -82,6 +85,8 @@ class TaskSnapshotPersister { TaskSnapshotPersister(WindowManagerService service, DirectoryResolver resolver) { TaskSnapshotPersister(WindowManagerService service, DirectoryResolver resolver) { mDirectoryResolver = resolver; mDirectoryResolver = resolver; mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); final float highResTaskSnapshotScale = service.mContext.getResources().getFloat( final float highResTaskSnapshotScale = service.mContext.getResources().getFloat( com.android.internal.R.dimen.config_highResTaskSnapshotScale); com.android.internal.R.dimen.config_highResTaskSnapshotScale); final float lowResTaskSnapshotScale = service.mContext.getResources().getFloat( final float lowResTaskSnapshotScale = service.mContext.getResources().getFloat( Loading Loading @@ -191,7 +196,7 @@ class TaskSnapshotPersister { return; return; } } } } SystemClock.sleep(100); SystemClock.sleep(DELAY_MS); } } } } Loading Loading @@ -233,7 +238,7 @@ class TaskSnapshotPersister { private boolean createDirectory(int userId) { private boolean createDirectory(int userId) { final File dir = getDirectory(userId); final File dir = getDirectory(userId); return dir.exists() || dir.mkdirs(); return dir.exists() || dir.mkdir(); } } private void deleteSnapshot(int taskId, int userId) { private void deleteSnapshot(int taskId, int userId) { Loading @@ -258,18 +263,26 @@ class TaskSnapshotPersister { android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); while (true) { while (true) { WriteQueueItem next; WriteQueueItem next; boolean isReadyToWrite = false; synchronized (mLock) { synchronized (mLock) { if (mPaused) { if (mPaused) { next = null; next = null; } else { } else { next = mWriteQueue.poll(); next = mWriteQueue.poll(); if (next != null) { if (next != null) { if (next.isReady()) { isReadyToWrite = true; next.onDequeuedLocked(); next.onDequeuedLocked(); } else { mWriteQueue.addLast(next); } } } } } } } if (next != null) { if (next != null) { if (isReadyToWrite) { next.write(); next.write(); } SystemClock.sleep(DELAY_MS); SystemClock.sleep(DELAY_MS); } } synchronized (mLock) { synchronized (mLock) { Loading @@ -289,6 +302,13 @@ class TaskSnapshotPersister { }; }; private abstract class WriteQueueItem { private abstract class WriteQueueItem { /** * @return {@code true} if item is ready to have {@link WriteQueueItem#write} called */ boolean isReady() { return true; } abstract void write(); abstract void write(); /** /** Loading Loading @@ -327,6 +347,11 @@ class TaskSnapshotPersister { mStoreQueueItems.remove(this); mStoreQueueItems.remove(this); } } @Override boolean isReady() { return mUserManagerInternal.isUserUnlocked(mUserId); } @Override @Override void write() { void write() { if (!createDirectory(mUserId)) { if (!createDirectory(mUserId)) { Loading services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java +21 −0 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.graphics.GraphicBuffer.USAGE_SW_READ_RARELY; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import static org.mockito.Mockito.when; Loading @@ -39,10 +40,15 @@ import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Rect; import android.os.UserManager; import android.os.UserManager; import android.os.UserManagerInternal; import android.view.Surface; import android.view.Surface; import com.android.server.LocalServices; import org.junit.After; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.Before; import org.junit.BeforeClass; import java.io.File; import java.io.File; import java.util.function.Predicate; import java.util.function.Predicate; Loading Loading @@ -70,11 +76,26 @@ class TaskSnapshotPersisterTestBase extends WindowTestsBase { mLowResScale = lowResScale; mLowResScale = lowResScale; } } @BeforeClass public static void setUpOnce() { final UserManagerInternal userManager = mock(UserManagerInternal.class); LocalServices.addService(UserManagerInternal.class, userManager); } @AfterClass public static void tearDownOnce() { LocalServices.removeServiceForTest(UserManagerInternal.class); } @Before @Before public void setUp() { public void setUp() { final UserManager um = UserManager.get(getInstrumentation().getTargetContext()); final UserManager um = UserManager.get(getInstrumentation().getTargetContext()); mTestUserId = um.getUserHandle(); mTestUserId = um.getUserHandle(); final UserManagerInternal userManagerInternal = LocalServices.getService(UserManagerInternal.class); when(userManagerInternal.isUserUnlocked(mTestUserId)).thenReturn(true); mContextSpy = spy(new ContextWrapper(mWm.mContext)); mContextSpy = spy(new ContextWrapper(mWm.mContext)); mResourcesSpy = spy(mContextSpy.getResources()); mResourcesSpy = spy(mContextSpy.getResources()); when(mContextSpy.getResources()).thenReturn(mResourcesSpy); when(mContextSpy.getResources()).thenReturn(mResourcesSpy); Loading Loading
services/core/java/com/android/server/wm/TaskSnapshotPersister.java +29 −4 Original line number Original line Diff line number Diff line Loading @@ -28,12 +28,14 @@ import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Bitmap.Config; import android.os.Process; import android.os.Process; import android.os.SystemClock; import android.os.SystemClock; import android.os.UserManagerInternal; import android.util.ArraySet; import android.util.ArraySet; import android.util.AtomicFile; import android.util.AtomicFile; import android.util.Slog; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import com.android.server.wm.nano.WindowManagerProtos.TaskSnapshotProto; import com.android.server.wm.nano.WindowManagerProtos.TaskSnapshotProto; import java.io.File; import java.io.File; Loading Loading @@ -72,6 +74,7 @@ class TaskSnapshotPersister { private final float mLowResScaleFactor; private final float mLowResScaleFactor; private boolean mEnableLowResSnapshots; private boolean mEnableLowResSnapshots; private final boolean mUse16BitFormat; private final boolean mUse16BitFormat; private final UserManagerInternal mUserManagerInternal; /** /** * The list of ids of the tasks that have been persisted since {@link #removeObsoleteFiles} was * The list of ids of the tasks that have been persisted since {@link #removeObsoleteFiles} was Loading @@ -82,6 +85,8 @@ class TaskSnapshotPersister { TaskSnapshotPersister(WindowManagerService service, DirectoryResolver resolver) { TaskSnapshotPersister(WindowManagerService service, DirectoryResolver resolver) { mDirectoryResolver = resolver; mDirectoryResolver = resolver; mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); final float highResTaskSnapshotScale = service.mContext.getResources().getFloat( final float highResTaskSnapshotScale = service.mContext.getResources().getFloat( com.android.internal.R.dimen.config_highResTaskSnapshotScale); com.android.internal.R.dimen.config_highResTaskSnapshotScale); final float lowResTaskSnapshotScale = service.mContext.getResources().getFloat( final float lowResTaskSnapshotScale = service.mContext.getResources().getFloat( Loading Loading @@ -191,7 +196,7 @@ class TaskSnapshotPersister { return; return; } } } } SystemClock.sleep(100); SystemClock.sleep(DELAY_MS); } } } } Loading Loading @@ -233,7 +238,7 @@ class TaskSnapshotPersister { private boolean createDirectory(int userId) { private boolean createDirectory(int userId) { final File dir = getDirectory(userId); final File dir = getDirectory(userId); return dir.exists() || dir.mkdirs(); return dir.exists() || dir.mkdir(); } } private void deleteSnapshot(int taskId, int userId) { private void deleteSnapshot(int taskId, int userId) { Loading @@ -258,18 +263,26 @@ class TaskSnapshotPersister { android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); while (true) { while (true) { WriteQueueItem next; WriteQueueItem next; boolean isReadyToWrite = false; synchronized (mLock) { synchronized (mLock) { if (mPaused) { if (mPaused) { next = null; next = null; } else { } else { next = mWriteQueue.poll(); next = mWriteQueue.poll(); if (next != null) { if (next != null) { if (next.isReady()) { isReadyToWrite = true; next.onDequeuedLocked(); next.onDequeuedLocked(); } else { mWriteQueue.addLast(next); } } } } } } } if (next != null) { if (next != null) { if (isReadyToWrite) { next.write(); next.write(); } SystemClock.sleep(DELAY_MS); SystemClock.sleep(DELAY_MS); } } synchronized (mLock) { synchronized (mLock) { Loading @@ -289,6 +302,13 @@ class TaskSnapshotPersister { }; }; private abstract class WriteQueueItem { private abstract class WriteQueueItem { /** * @return {@code true} if item is ready to have {@link WriteQueueItem#write} called */ boolean isReady() { return true; } abstract void write(); abstract void write(); /** /** Loading Loading @@ -327,6 +347,11 @@ class TaskSnapshotPersister { mStoreQueueItems.remove(this); mStoreQueueItems.remove(this); } } @Override boolean isReady() { return mUserManagerInternal.isUserUnlocked(mUserId); } @Override @Override void write() { void write() { if (!createDirectory(mUserId)) { if (!createDirectory(mUserId)) { Loading
services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java +21 −0 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.graphics.GraphicBuffer.USAGE_SW_READ_RARELY; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import static org.mockito.Mockito.when; Loading @@ -39,10 +40,15 @@ import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Rect; import android.os.UserManager; import android.os.UserManager; import android.os.UserManagerInternal; import android.view.Surface; import android.view.Surface; import com.android.server.LocalServices; import org.junit.After; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.Before; import org.junit.BeforeClass; import java.io.File; import java.io.File; import java.util.function.Predicate; import java.util.function.Predicate; Loading Loading @@ -70,11 +76,26 @@ class TaskSnapshotPersisterTestBase extends WindowTestsBase { mLowResScale = lowResScale; mLowResScale = lowResScale; } } @BeforeClass public static void setUpOnce() { final UserManagerInternal userManager = mock(UserManagerInternal.class); LocalServices.addService(UserManagerInternal.class, userManager); } @AfterClass public static void tearDownOnce() { LocalServices.removeServiceForTest(UserManagerInternal.class); } @Before @Before public void setUp() { public void setUp() { final UserManager um = UserManager.get(getInstrumentation().getTargetContext()); final UserManager um = UserManager.get(getInstrumentation().getTargetContext()); mTestUserId = um.getUserHandle(); mTestUserId = um.getUserHandle(); final UserManagerInternal userManagerInternal = LocalServices.getService(UserManagerInternal.class); when(userManagerInternal.isUserUnlocked(mTestUserId)).thenReturn(true); mContextSpy = spy(new ContextWrapper(mWm.mContext)); mContextSpy = spy(new ContextWrapper(mWm.mContext)); mResourcesSpy = spy(mContextSpy.getResources()); mResourcesSpy = spy(mContextSpy.getResources()); when(mContextSpy.getResources()).thenReturn(mResourcesSpy); when(mContextSpy.getResources()).thenReturn(mResourcesSpy); Loading