wait for sensor service before starting WMS
- Starting sensor service in separate thread led into occasional 1 sec
blocking of WMS inside PhoneWindowManager to get sensor service.
- Change startSensorService into blocking call and call it from
separate thread using SystemServerInitThreadPool.
- This does not improve best case boot-up time but fixes occasional 1 sec delay
which is happening in 10 to 20% rate. So this is potential 100 to 200ms saving for many runs.
bug: 34846045
Test: multiple reboots.
Change-Id: Ia08fa3284aed5e576acaac6fbfd74b9db9f7d63c
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index b911d2d..3eebd89 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -125,8 +125,13 @@
public final class SystemServer {
private static final String TAG = "SystemServer";
+ // Tag for timing measurement of main thread.
+ private static final String SYSTEM_SERVER_TIMING_TAG = "SystemServerTiming";
+ // Tag for timing measurement of non-main asynchronous operations.
+ private static final String SYSTEM_SERVER_TIMING_ASYNC_TAG = SYSTEM_SERVER_TIMING_TAG + "Async";
+
private static final BootTimingsTraceLog BOOT_TIMINGS_TRACE_LOG
- = new BootTimingsTraceLog("SystemServerTiming", Trace.TRACE_TAG_SYSTEM_SERVER);
+ = new BootTimingsTraceLog(SYSTEM_SERVER_TIMING_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
private static final String ENCRYPTING_STATE = "trigger_restart_min_framework";
private static final String ENCRYPTED_STATE = "1";
@@ -227,8 +232,11 @@
private boolean mFirstBoot;
private final boolean mRuntimeRestart;
+ private static final String START_SENSOR_SERVICE = "StartSensorService";
+ private Future<?> mSensorServiceStart;
+
/**
- * Start the sensor service.
+ * Start the sensor service. This is a blocking call and can take time.
*/
private static native void startSensorService();
@@ -382,7 +390,7 @@
MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis);
final int MAX_UPTIME_MILLIS = 60 * 1000;
if (uptimeMillis > MAX_UPTIME_MILLIS) {
- Slog.wtf("SystemServerTiming",
+ Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
"SystemServer init took too long. uptimeMillis=" + uptimeMillis);
}
}
@@ -584,9 +592,15 @@
// The sensor service needs access to package manager service, app ops
// service, and permissions service, therefore we start it after them.
- traceBeginAndSlog("StartSensorService");
- startSensorService();
- traceEnd();
+ // Start sensor service in a separate thread. Completion should be checked
+ // before using it.
+ mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
+ BootTimingsTraceLog traceLog = new BootTimingsTraceLog(
+ SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+ traceLog.traceBegin(START_SENSOR_SERVICE);
+ startSensorService();
+ traceLog.traceEnd();
+ }, START_SENSOR_SERVICE);
}
/**
@@ -742,6 +756,9 @@
traceEnd();
traceBeginAndSlog("StartWindowManagerService");
+ // WMS needs sensor service ready
+ ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
+ mSensorServiceStart = null;
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore, new PhoneWindowManager());
@@ -1590,7 +1607,7 @@
webviewPrep = SystemServerInitThreadPool.get().submit(() -> {
Slog.i(TAG, WEBVIEW_PREPARATION);
BootTimingsTraceLog traceLog = new BootTimingsTraceLog(
- "SystemServerTiming", Trace.TRACE_TAG_SYSTEM_SERVER);
+ SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
traceLog.traceBegin(WEBVIEW_PREPARATION);
mWebViewUpdateService.prepareWebViewInSystemServer();
traceLog.traceEnd();
@@ -1651,13 +1668,13 @@
Watchdog.getInstance().start();
traceEnd();
- if (webviewPrep != null) {
- ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION);
- }
-
// It is now okay to let the various system services start their
// third party code...
traceBeginAndSlog("PhaseThirdPartyAppsCanStart");
+ // confirm webview completion before starting 3rd party
+ if (webviewPrep != null) {
+ ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION);
+ }
mSystemServiceManager.startBootPhase(
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
traceEnd();