From 68f49aea205a0d26f09cc457f86450e8dd3023d0 Mon Sep 17 00:00:00 2001 From: Fyodor Kupolov Date: Fri, 2 Dec 2016 17:33:21 -0800 Subject: [PATCH] Init PersistentDatablockService on the worker thread Other services do not depend on PersistentDatabalockService in the early stages of system server initialization. Initialization is now done on the FgThread. The service also ensures that init is complete before PHASE_ACTIVITY_MANAGER_READY. Change-Id: I3b9a1994e37c1e995ed04257f271c425d48c2e7c Test: Manual, device boots, service is initialized and published Bug: 33199244 --- .../server/PersistentDataBlockService.java | 29 +++++++++++++++++-- .../java/com/android/server/SystemServer.java | 2 ++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java index 080b46c24a2fd..368aaed0a28bf 100644 --- a/services/core/java/com/android/server/PersistentDataBlockService.java +++ b/services/core/java/com/android/server/PersistentDataBlockService.java @@ -47,6 +47,8 @@ import java.nio.channels.FileChannel; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; /** * Service for reading and writing blocks to a persistent partition. @@ -81,6 +83,7 @@ public class PersistentDataBlockService extends SystemService { private final Context mContext; private final String mDataBlockFile; private final Object mLock = new Object(); + private final CountDownLatch mInitDoneSignal = new CountDownLatch(1); private int mAllowedUid = -1; private long mBlockDeviceSize; @@ -110,9 +113,29 @@ public class PersistentDataBlockService extends SystemService { @Override public void onStart() { - enforceChecksumValidity(); - formatIfOemUnlockEnabled(); - publishBinderService(Context.PERSISTENT_DATA_BLOCK_SERVICE, mService); + // Do init on a separate thread, will join in PHASE_ACTIVITY_MANAGER_READY + FgThread.getHandler().post(() -> { + enforceChecksumValidity(); + formatIfOemUnlockEnabled(); + publishBinderService(Context.PERSISTENT_DATA_BLOCK_SERVICE, mService); + mInitDoneSignal.countDown(); + }); + } + + @Override + public void onBootPhase(int phase) { + // Wait for initialization in onStart to finish + if (phase == PHASE_SYSTEM_SERVICES_READY) { + try { + if (!mInitDoneSignal.await(10, TimeUnit.SECONDS)) { + throw new IllegalStateException("Service " + TAG + " init timeout"); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new IllegalStateException("Service " + TAG + " init interrupted", e); + } + } + super.onBootPhase(phase); } private void formatIfOemUnlockEnabled() { diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 1fc4378de2776..0edc91701588d 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -1484,8 +1484,10 @@ public final class SystemServer { @Override public void run() { Slog.i(TAG, "Making services ready"); + traceBeginAndSlog("StartActivityManagerReadyPhase"); mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY); + traceEnd(); traceBeginAndSlog("PhaseActivityManagerReady"); traceBeginAndSlog("StartObservingNativeCrashes");