1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "NativeSensorService"
18
19 #include <android-base/properties.h>
20 #include <android_runtime/AndroidRuntime.h>
21 #include <core_jni_helpers.h>
22 #include <cutils/properties.h>
23 #include <jni.h>
24 #include <sensorservice/SensorService.h>
25 #include <utils/Log.h>
26 #include <utils/misc.h>
27
28 #include <mutex>
29
30 #define PROXIMITY_ACTIVE_CLASS \
31 "com/android/server/sensors/SensorManagerInternal$ProximityActiveListener"
32
33 namespace android {
34
35 static JavaVM* sJvm = nullptr;
36 static jmethodID sMethodIdOnProximityActive;
37
38 class NativeSensorService {
39 public:
40 NativeSensorService(JNIEnv* env, jobject listener);
41
42 void registerProximityActiveListener();
43 void unregisterProximityActiveListener();
44
45 private:
46 sp<SensorService> mService;
47
48 class ProximityActiveListenerDelegate : public SensorService::ProximityActiveListener {
49 public:
50 ProximityActiveListenerDelegate(JNIEnv* env, jobject listener);
51 ~ProximityActiveListenerDelegate();
52
53 void onProximityActive(bool isActive) override;
54
55 private:
56 jobject mListener;
57 };
58 sp<ProximityActiveListenerDelegate> mProximityActiveListenerDelegate;
59 };
60
NativeSensorService(JNIEnv * env,jobject listener)61 NativeSensorService::NativeSensorService(JNIEnv* env, jobject listener)
62 : mProximityActiveListenerDelegate(new ProximityActiveListenerDelegate(env, listener)) {
63 if (base::GetBoolProperty("system_init.startsensorservice", true)) {
64 sp<IServiceManager> sm(defaultServiceManager());
65 mService = new SensorService();
66 sm->addService(String16(SensorService::getServiceName()), mService,
67 false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
68 }
69 }
70
registerProximityActiveListener()71 void NativeSensorService::registerProximityActiveListener() {
72 if (mService == nullptr) {
73 ALOGD("Dropping registerProximityActiveListener, sensor service not available.");
74 return;
75 }
76 mService->addProximityActiveListener(mProximityActiveListenerDelegate);
77 }
78
unregisterProximityActiveListener()79 void NativeSensorService::unregisterProximityActiveListener() {
80 if (mService == nullptr) {
81 ALOGD("Dropping unregisterProximityActiveListener, sensor service not available.");
82 return;
83 }
84
85 mService->removeProximityActiveListener(mProximityActiveListenerDelegate);
86 }
87
ProximityActiveListenerDelegate(JNIEnv * env,jobject listener)88 NativeSensorService::ProximityActiveListenerDelegate::ProximityActiveListenerDelegate(
89 JNIEnv* env, jobject listener)
90 : mListener(env->NewGlobalRef(listener)) {}
91
~ProximityActiveListenerDelegate()92 NativeSensorService::ProximityActiveListenerDelegate::~ProximityActiveListenerDelegate() {
93 AndroidRuntime::getJNIEnv()->DeleteGlobalRef(mListener);
94 }
95
onProximityActive(bool isActive)96 void NativeSensorService::ProximityActiveListenerDelegate::onProximityActive(bool isActive) {
97 auto jniEnv = GetOrAttachJNIEnvironment(sJvm);
98 jniEnv->CallVoidMethod(mListener, sMethodIdOnProximityActive, static_cast<jboolean>(isActive));
99 }
100
startSensorServiceNative(JNIEnv * env,jclass,jobject listener)101 static jlong startSensorServiceNative(JNIEnv* env, jclass, jobject listener) {
102 NativeSensorService* service = new NativeSensorService(env, listener);
103 return reinterpret_cast<jlong>(service);
104 }
105
registerProximityActiveListenerNative(JNIEnv * env,jclass,jlong ptr)106 static void registerProximityActiveListenerNative(JNIEnv* env, jclass, jlong ptr) {
107 auto* service = reinterpret_cast<NativeSensorService*>(ptr);
108 service->registerProximityActiveListener();
109 }
110
unregisterProximityActiveListenerNative(JNIEnv * env,jclass,jlong ptr)111 static void unregisterProximityActiveListenerNative(JNIEnv* env, jclass, jlong ptr) {
112 auto* service = reinterpret_cast<NativeSensorService*>(ptr);
113 service->unregisterProximityActiveListener();
114 }
115
116 static const JNINativeMethod methods[] = {
117 {
118 "startSensorServiceNative", "(L" PROXIMITY_ACTIVE_CLASS ";)J",
119 reinterpret_cast<void*>(startSensorServiceNative)
120 },
121 {
122 "registerProximityActiveListenerNative", "(J)V",
123 reinterpret_cast<void*>(registerProximityActiveListenerNative)
124 },
125 {
126 "unregisterProximityActiveListenerNative", "(J)V",
127 reinterpret_cast<void*>(unregisterProximityActiveListenerNative)
128 },
129
130 };
131
register_android_server_sensor_SensorService(JavaVM * vm,JNIEnv * env)132 int register_android_server_sensor_SensorService(JavaVM* vm, JNIEnv* env) {
133 sJvm = vm;
134 jclass listenerClass = FindClassOrDie(env, PROXIMITY_ACTIVE_CLASS);
135 sMethodIdOnProximityActive = GetMethodIDOrDie(env, listenerClass, "onProximityActive", "(Z)V");
136 return jniRegisterNativeMethods(env, "com/android/server/sensors/SensorService", methods,
137 NELEM(methods));
138 }
139
140 }; // namespace android
141