Merge "Create Java interface to SensorService." into sc-dev
diff --git a/services/core/java/com/android/server/SystemServerInitThreadPool.java b/services/core/java/com/android/server/SystemServerInitThreadPool.java
index c23f1ca..ed25452 100644
--- a/services/core/java/com/android/server/SystemServerInitThreadPool.java
+++ b/services/core/java/com/android/server/SystemServerInitThreadPool.java
@@ -38,7 +38,7 @@
 /**
  * Thread pool used during initialization of system server.
  *
- * <p>System services can {@link #submit(Runnable)} tasks for execution during boot.
+ * <p>System services can {@link #submit(Runnable, String)} tasks for execution during boot.
  * The pool will be shut down after {@link SystemService#PHASE_BOOT_COMPLETED}.
  *
  * <p>New tasks <em>should not</em> be submitted afterwards.
diff --git a/services/core/java/com/android/server/SystemService.java b/services/core/java/com/android/server/SystemService.java
index 6c81de6..39321bf 100644
--- a/services/core/java/com/android/server/SystemService.java
+++ b/services/core/java/com/android/server/SystemService.java
@@ -70,12 +70,20 @@
     /** @hide */
     protected static final boolean DEBUG_USER = false;
 
-    /*
+    /**
      * The earliest boot phase the system send to system services on boot.
      */
     public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100;
 
     /**
+     * Boot phase that blocks on SensorService availability. The service gets started
+     * asynchronously since it may take awhile to actually finish initializing.
+     *
+     * @hide
+     */
+    public static final int PHASE_WAIT_FOR_SENSOR_SERVICE = 200;
+
+    /**
      * After receiving this boot phase, services can obtain lock settings data.
      */
     public static final int PHASE_LOCK_SETTINGS_READY = 480;
diff --git a/services/core/java/com/android/server/sensors/SensorService.java b/services/core/java/com/android/server/sensors/SensorService.java
new file mode 100644
index 0000000..f7ed8e7
--- /dev/null
+++ b/services/core/java/com/android/server/sensors/SensorService.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.sensors;
+
+import android.content.Context;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.ConcurrentUtils;
+import com.android.server.SystemServerInitThreadPool;
+import com.android.server.SystemService;
+import com.android.server.utils.TimingsTraceAndSlog;
+
+import java.util.concurrent.Future;
+
+public class SensorService extends SystemService {
+    private static final String START_NATIVE_SENSOR_SERVICE = "StartNativeSensorService";
+    private final Object mLock = new Object();
+    @GuardedBy("mLock")
+    private Future<?> mSensorServiceStart;
+
+
+    /** Start the sensor service. This is a blocking call and can take time. */
+    private static native void startNativeSensorService();
+
+    public SensorService(Context ctx) {
+        super(ctx);
+        synchronized (mLock) {
+            mSensorServiceStart = SystemServerInitThreadPool.submit(() -> {
+                TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog();
+                traceLog.traceBegin(START_NATIVE_SENSOR_SERVICE);
+                startNativeSensorService();
+                traceLog.traceEnd();
+            }, START_NATIVE_SENSOR_SERVICE);
+        }
+    }
+
+    @Override
+    public void onStart() { }
+
+    @Override
+    public void onBootPhase(int phase) {
+        if (phase == SystemService.PHASE_WAIT_FOR_SENSOR_SERVICE) {
+            ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart,
+                    START_NATIVE_SENSOR_SERVICE);
+            synchronized (mLock) {
+                mSensorServiceStart = null;
+            }
+        }
+    }
+}
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 4ce9591..53401fd 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -70,6 +70,7 @@
         "com_android_server_PersistentDataBlockService.cpp",
         "com_android_server_am_LowMemDetector.cpp",
         "com_android_server_pm_PackageManagerShellCommandDataLoader.cpp",
+        "com_android_server_sensor_SensorService.cpp",
         "onload.cpp",
         ":lib_cachedAppOptimizer_native",
         ":lib_networkStatsFactory_native",
diff --git a/services/core/jni/com_android_server_SystemServer.cpp b/services/core/jni/com_android_server_SystemServer.cpp
index fb664ab..6721ecf 100644
--- a/services/core/jni/com_android_server_SystemServer.cpp
+++ b/services/core/jni/com_android_server_SystemServer.cpp
@@ -32,7 +32,6 @@
 
 #include <memtrackproxy/MemtrackProxy.h>
 #include <schedulerservice/SchedulingPolicyService.h>
-#include <sensorservice/SensorService.h>
 #include <sensorservicehidl/SensorManager.h>
 #include <stats/StatsAidl.h>
 #include <stats/StatsHal.h>
@@ -41,12 +40,10 @@
 #include <bionic/reserved_signals.h>
 
 #include <android-base/properties.h>
-#include <cutils/properties.h>
 #include <utils/Log.h>
 #include <utils/misc.h>
 #include <utils/AndroidThreads.h>
 
-using android::base::GetIntProperty;
 using namespace std::chrono_literals;
 
 namespace {
@@ -81,15 +78,6 @@
     startStatsAidlService();
 }
 
-static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {
-    char propBuf[PROPERTY_VALUE_MAX];
-    property_get("system_init.startsensorservice", propBuf, "1");
-    if (strcmp(propBuf, "1") == 0) {
-        SensorService::publish(false /* allowIsolated */,
-                               IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
-    }
-}
-
 static void android_server_SystemServer_startMemtrackProxyService(JNIEnv* env,
                                                                   jobject /* clazz */) {
     using aidl::android::hardware::memtrack::MemtrackProxy;
@@ -163,7 +151,6 @@
 static const JNINativeMethod gMethods[] = {
         /* name, signature, funcPtr */
         {"startIStatsService", "()V", (void*)android_server_SystemServer_startIStatsService},
-        {"startSensorService", "()V", (void*)android_server_SystemServer_startSensorService},
         {"startMemtrackProxyService", "()V",
          (void*)android_server_SystemServer_startMemtrackProxyService},
         {"startHidlServices", "()V", (void*)android_server_SystemServer_startHidlServices},
diff --git a/services/core/jni/com_android_server_sensor_SensorService.cpp b/services/core/jni/com_android_server_sensor_SensorService.cpp
new file mode 100644
index 0000000..acad1bc
--- /dev/null
+++ b/services/core/jni/com_android_server_sensor_SensorService.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "SensorService"
+
+#include <nativehelper/JNIHelp.h>
+#include "android_runtime/AndroidRuntime.h"
+#include "core_jni_helpers.h"
+#include "jni.h"
+
+#include <cutils/properties.h>
+#include <sensorservice/SensorService.h>
+#include <utils/Log.h>
+#include <utils/misc.h>
+
+namespace android {
+
+static void startNativeSensorService(JNIEnv* env, jclass clazz) {
+    char propBuf[PROPERTY_VALUE_MAX];
+    property_get("system_init.startsensorservice", propBuf, "1");
+    if (strcmp(propBuf, "1") == 0) {
+        SensorService::publish(false /* allowIsolated */,
+                               IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
+    }
+}
+
+static const JNINativeMethod methods[] = {
+        {"startNativeSensorService", "()V", (void*)startNativeSensorService},
+};
+
+int register_android_server_sensor_SensorService(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "com/android/server/sensors/SensorService", methods,
+                                    NELEM(methods));
+}
+
+}; // namespace android
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index b043e64..b8961d5 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -62,6 +62,7 @@
 int register_android_server_FaceService(JNIEnv* env);
 int register_android_server_GpuService(JNIEnv* env);
 int register_android_server_stats_pull_StatsPullAtomService(JNIEnv* env);
+int register_android_server_sensor_SensorService(JNIEnv* env);
 };
 
 using namespace android;
@@ -117,5 +118,6 @@
     register_android_server_FaceService(env);
     register_android_server_GpuService(env);
     register_android_server_stats_pull_StatsPullAtomService(env);
+    register_android_server_sensor_SensorService(env);
     return JNI_VERSION_1_4;
 }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 8dc5011..1e4b248 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -179,6 +179,7 @@
 import com.android.server.security.FileIntegrityService;
 import com.android.server.security.KeyAttestationApplicationIdProviderService;
 import com.android.server.security.KeyChainSystemService;
+import com.android.server.sensors.SensorService;
 import com.android.server.signedconfig.SignedConfigService;
 import com.android.server.soundtrigger.SoundTriggerService;
 import com.android.server.soundtrigger_middleware.SoundTriggerMiddlewareService;
@@ -427,7 +428,6 @@
     private final long mRuntimeStartElapsedTime;
     private final long mRuntimeStartUptime;
 
-    private static final String START_SENSOR_SERVICE = "StartSensorService";
     private static final String START_HIDL_SERVICES = "StartHidlServices";
     private static final String START_BLOB_STORE_SERVICE = "startBlobStoreManagerService";
 
@@ -435,7 +435,6 @@
     private static final String SYSPROP_START_ELAPSED = "sys.system_server.start_elapsed";
     private static final String SYSPROP_START_UPTIME = "sys.system_server.start_uptime";
 
-    private Future<?> mSensorServiceStart;
     private Future<?> mZygotePreload;
     private Future<?> mBlobStoreServiceStart;
 
@@ -449,9 +448,6 @@
     /** Start the IStats services. This is a blocking call and can take time. */
     private static native void startIStatsService();
 
-    /** Start the sensor service. This is a blocking call and can take time. */
-    private static native void startSensorService();
-
     /**
      * Start the memtrack proxy service.
      */
@@ -1229,15 +1225,9 @@
 
         // The sensor service needs access to package manager service, app ops
         // service, and permissions service, therefore we start it after them.
-        // Start sensor service in a separate thread. Completion should be checked
-        // before using it.
-        mSensorServiceStart = SystemServerInitThreadPool.submit(() -> {
-            TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog();
-            traceLog.traceBegin(START_SENSOR_SERVICE);
-            startSensorService();
-            traceLog.traceEnd();
-        }, START_SENSOR_SERVICE);
-
+        t.traceBegin("StartSensorService");
+        mSystemServiceManager.startService(SensorService.class);
+        t.traceEnd();
         t.traceEnd(); // startBootstrapServices
     }
 
@@ -1474,8 +1464,7 @@
 
             t.traceBegin("StartWindowManagerService");
             // WMS needs sensor service ready
-            ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
-            mSensorServiceStart = null;
+            mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_SENSOR_SERVICE);
             wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
                     new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
             ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
@@ -1493,8 +1482,8 @@
             t.traceEnd();
 
             // Start receiving calls from HIDL services. Start in in a separate thread
-            // because it need to connect to SensorManager. This have to start
-            // after START_SENSOR_SERVICE is done.
+            // because it need to connect to SensorManager. This has to start
+            // after PHASE_WAIT_FOR_SENSOR_SERVICE is done.
             SystemServerInitThreadPool.submit(() -> {
                 TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog();
                 traceLog.traceBegin(START_HIDL_SERVICES);