Init of OverlayManagerService on a parallel thread
Expensive parts of initialization (like idmap) are now done on a separate
init thread.
The service waits for init to complete in PHASE_SYSTEM_SERVICES_READY,
before affected apps can start.
Boot time saving: ~300ms on marlin.
Test: rebooted and verified that OverlayManagerService init is completed
before any app process is started
Bug: 35949883
Change-Id: Ibdf0174c50cfa95fc8f1cb014ad0a03ff49f4d1f
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index a692559..1af541d 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -53,9 +53,11 @@
import android.util.Slog;
import android.util.SparseArray;
+import com.android.internal.util.ConcurrentUtils;
import com.android.server.FgThread;
import com.android.server.IoThread;
import com.android.server.LocalServices;
+import com.android.server.SystemServerInitThreadPool;
import com.android.server.SystemService;
import com.android.server.pm.Installer;
import com.android.server.pm.UserManagerService;
@@ -74,6 +76,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -219,6 +222,8 @@
private final AtomicBoolean mPersistSettingsScheduled = new AtomicBoolean(false);
+ private Future<?> mInitCompleteSignal;
+
public OverlayManagerService(@NonNull final Context context,
@NonNull final Installer installer) {
super(context);
@@ -230,28 +235,29 @@
mSettings = new OverlayManagerSettings();
mImpl = new OverlayManagerServiceImpl(mPackageManager, im, mSettings,
getDefaultOverlayPackages());
+ mInitCompleteSignal = SystemServerInitThreadPool.get().submit(() -> {
+ final IntentFilter packageFilter = new IntentFilter();
+ packageFilter.addAction(ACTION_PACKAGE_ADDED);
+ packageFilter.addAction(ACTION_PACKAGE_CHANGED);
+ packageFilter.addAction(ACTION_PACKAGE_REMOVED);
+ packageFilter.addDataScheme("package");
+ getContext().registerReceiverAsUser(new PackageReceiver(), UserHandle.ALL,
+ packageFilter, null, null);
- final IntentFilter packageFilter = new IntentFilter();
- packageFilter.addAction(ACTION_PACKAGE_ADDED);
- packageFilter.addAction(ACTION_PACKAGE_CHANGED);
- packageFilter.addAction(ACTION_PACKAGE_REMOVED);
- packageFilter.addDataScheme("package");
- getContext().registerReceiverAsUser(new PackageReceiver(), UserHandle.ALL,
- packageFilter, null, null);
+ final IntentFilter userFilter = new IntentFilter();
+ userFilter.addAction(ACTION_USER_REMOVED);
+ getContext().registerReceiverAsUser(new UserReceiver(), UserHandle.ALL,
+ userFilter, null, null);
- final IntentFilter userFilter = new IntentFilter();
- userFilter.addAction(ACTION_USER_REMOVED);
- getContext().registerReceiverAsUser(new UserReceiver(), UserHandle.ALL,
- userFilter, null, null);
+ restoreSettings();
+ onSwitchUser(UserHandle.USER_SYSTEM);
+ schedulePersistSettings();
- restoreSettings();
- onSwitchUser(UserHandle.USER_SYSTEM);
- schedulePersistSettings();
+ mSettings.addChangeListener(new OverlayChangeListener());
- mSettings.addChangeListener(new OverlayChangeListener());
-
- publishBinderService(Context.OVERLAY_SERVICE, mService);
- publishLocalService(OverlayManagerService.class, this);
+ publishBinderService(Context.OVERLAY_SERVICE, mService);
+ publishLocalService(OverlayManagerService.class, this);
+ }, "Init OverlayManagerService");
}
@Override
@@ -260,6 +266,15 @@
}
@Override
+ public void onBootPhase(int phase) {
+ if (phase == PHASE_SYSTEM_SERVICES_READY) {
+ ConcurrentUtils.waitForFutureNoInterrupt(mInitCompleteSignal,
+ "Wait for OverlayManagerService init");
+ mInitCompleteSignal = null;
+ }
+ }
+
+ @Override
public void onSwitchUser(final int newUserId) {
// ensure overlays in the settings are up-to-date, and propagate
// any asset changes to the rest of the system