From f115451175bfba2ff83b9279cfc4df2fb4235cdb Mon Sep 17 00:00:00 2001 From: Gavin Corkery Date: Thu, 5 Sep 2019 11:48:55 +0100 Subject: [PATCH] Block until userdata backup/restore has taken place Currently, userdata backup/restore is performed on a handler thread. This means that we cannot guarantee that an application will not begin running during a backup/restore, as we have no guarantees of when the backup logic will actually execute. In the onUnlockUser case we can block until the handler thread has completed its work by using a CountdownLatch. In the general case we will keep snapshotAndRestoreUserData on the handler thread, using Package Manager's token to decide when to unfreeze Test: atest RollbackTest Test: atest StagedRollbackTest Bug: 124032231 Change-Id: I4c818833e48a549e8a3aa8401539f44c14b89b57 --- .../server/rollback/RollbackManagerServiceImpl.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java index ddbd9c9266d07..6947a71a5e6f9 100644 --- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java @@ -564,6 +564,10 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { } void onUnlockUser(int userId) { + // In order to ensure that no package begins running while a backup or restore is taking + // place, onUnlockUser must remain blocked until all pending backups and restores have + // completed. + CountDownLatch latch = new CountDownLatch(1); getHandler().post(() -> { final List rollbacks; synchronized (mLock) { @@ -576,7 +580,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { for (Rollback rollback : changed) { saveRollback(rollback); } + latch.countDown(); }); + + try { + latch.await(); + } catch (InterruptedException ie) { + throw new IllegalStateException("RollbackManagerHandlerThread interrupted"); + } } private void updateRollbackLifetimeDurationInMillis() {