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_os_NativeHandle.h>
21 #include <android_runtime/AndroidRuntime.h>
22 #include <core_jni_helpers.h>
23 #include <cutils/native_handle.h>
24 #include <cutils/properties.h>
25 #include <jni.h>
26 #include <nativehelper/JNIPlatformHelp.h>
27 #include <sensorservice/SensorService.h>
28 #include <string.h>
29 #include <utils/Log.h>
30 #include <utils/misc.h>
31
32 #include <mutex>
33
34 #include "android_util_Binder.h"
35
36 #define PROXIMITY_ACTIVE_CLASS \
37 "com/android/server/sensors/SensorManagerInternal$ProximityActiveListener"
38
39 #define RUNTIME_SENSOR_CALLBACK_CLASS \
40 "com/android/server/sensors/SensorManagerInternal$RuntimeSensorCallback"
41
42 namespace android {
43
44 static JavaVM* sJvm = nullptr;
45 static jmethodID sMethodIdOnProximityActive;
46 static jmethodID sMethodIdRuntimeSensorOnConfigurationChanged;
47 static jmethodID sMethodIdRuntimeSensorOnDirectChannelCreated;
48 static jmethodID sMethodIdRuntimeSensorOnDirectChannelDestroyed;
49 static jmethodID sMethodIdRuntimeSensorOnDirectChannelConfigured;
50
51 class NativeSensorService {
52 public:
53 NativeSensorService(JNIEnv* env, jobject listener);
54
55 void registerProximityActiveListener();
56 void unregisterProximityActiveListener();
57 jint registerRuntimeSensor(JNIEnv* env, jint deviceId, jint type, jstring name, jstring vendor,
58 jfloat maximumRange, jfloat resolution, jfloat power, jint minDelay,
59 jint maxDelay, jint flags, jobject callback);
60 void unregisterRuntimeSensor(jint handle);
61 jboolean sendRuntimeSensorEvent(JNIEnv* env, jint handle, jint type, jlong timestamp,
62 jfloatArray values);
63
64 private:
65 sp<SensorService> mService;
66
67 class ProximityActiveListenerDelegate : public SensorService::ProximityActiveListener {
68 public:
69 ProximityActiveListenerDelegate(JNIEnv* env, jobject listener);
70 ~ProximityActiveListenerDelegate();
71
72 void onProximityActive(bool isActive) override;
73
74 private:
75 jobject mListener;
76 };
77 sp<ProximityActiveListenerDelegate> mProximityActiveListenerDelegate;
78
79 class RuntimeSensorCallbackDelegate : public SensorService::RuntimeSensorCallback {
80 public:
81 RuntimeSensorCallbackDelegate(JNIEnv* env, jobject callback);
82 ~RuntimeSensorCallbackDelegate();
83
84 status_t onConfigurationChanged(int32_t handle, bool enabled, int64_t samplingPeriodNs,
85 int64_t batchReportLatencyNs) override;
86 int onDirectChannelCreated(int fd) override;
87 void onDirectChannelDestroyed(int channelHandle) override;
88 int onDirectChannelConfigured(int channelHandle, int sensorHandle, int rateLevel) override;
89
90 private:
91 jobject mCallback;
92 };
93 };
94
NativeSensorService(JNIEnv * env,jobject listener)95 NativeSensorService::NativeSensorService(JNIEnv* env, jobject listener)
96 : mProximityActiveListenerDelegate(new ProximityActiveListenerDelegate(env, listener)) {
97 if (base::GetBoolProperty("system_init.startsensorservice", true)) {
98 sp<IServiceManager> sm(defaultServiceManager());
99 mService = new SensorService();
100 sm->addService(String16(SensorService::getServiceName()), mService,
101 false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
102 }
103 }
104
registerProximityActiveListener()105 void NativeSensorService::registerProximityActiveListener() {
106 if (mService == nullptr) {
107 ALOGD("Dropping registerProximityActiveListener, sensor service not available.");
108 return;
109 }
110 mService->addProximityActiveListener(mProximityActiveListenerDelegate);
111 }
112
unregisterProximityActiveListener()113 void NativeSensorService::unregisterProximityActiveListener() {
114 if (mService == nullptr) {
115 ALOGD("Dropping unregisterProximityActiveListener, sensor service not available.");
116 return;
117 }
118
119 mService->removeProximityActiveListener(mProximityActiveListenerDelegate);
120 }
121
registerRuntimeSensor(JNIEnv * env,jint deviceId,jint type,jstring name,jstring vendor,jfloat maximumRange,jfloat resolution,jfloat power,jint minDelay,jint maxDelay,jint flags,jobject callback)122 jint NativeSensorService::registerRuntimeSensor(JNIEnv* env, jint deviceId, jint type, jstring name,
123 jstring vendor, jfloat maximumRange,
124 jfloat resolution, jfloat power, jint minDelay,
125 jint maxDelay, jint flags, jobject callback) {
126 if (mService == nullptr) {
127 ALOGD("Dropping registerRuntimeSensor, sensor service not available.");
128 return -1;
129 }
130
131 sensor_t sensor{
132 .name = env->GetStringUTFChars(name, 0),
133 .vendor = env->GetStringUTFChars(vendor, 0),
134 .version = sizeof(sensor_t),
135 .type = type,
136 .maxRange = maximumRange,
137 .resolution = resolution,
138 .power = power,
139 .minDelay = minDelay,
140 .maxDelay = maxDelay,
141 #ifdef __LP64__
142 .flags = static_cast<uint64_t>(flags),
143 #else
144 .flags = static_cast<uint32_t>(flags),
145 #endif
146 };
147
148 sp<RuntimeSensorCallbackDelegate> callbackDelegate(
149 new RuntimeSensorCallbackDelegate(env, callback));
150 return mService->registerRuntimeSensor(sensor, deviceId, callbackDelegate);
151 }
152
unregisterRuntimeSensor(jint handle)153 void NativeSensorService::unregisterRuntimeSensor(jint handle) {
154 if (mService == nullptr) {
155 ALOGD("Dropping unregisterProximityActiveListener, sensor service not available.");
156 return;
157 }
158
159 mService->unregisterRuntimeSensor(handle);
160 }
161
sendRuntimeSensorEvent(JNIEnv * env,jint handle,jint type,jlong timestamp,jfloatArray values)162 jboolean NativeSensorService::sendRuntimeSensorEvent(JNIEnv* env, jint handle, jint type,
163 jlong timestamp, jfloatArray values) {
164 if (mService == nullptr) {
165 ALOGD("Dropping sendRuntimeSensorEvent, sensor service not available.");
166 return false;
167 }
168 if (values == nullptr) {
169 ALOGD("Dropping sendRuntimeSensorEvent, no values.");
170 return false;
171 }
172
173 sensors_event_t event{
174 .version = sizeof(sensors_event_t),
175 .timestamp = timestamp,
176 .sensor = handle,
177 .type = type,
178 };
179
180 int valuesLength = env->GetArrayLength(values);
181 jfloat* sensorValues = env->GetFloatArrayElements(values, nullptr);
182
183 switch (type) {
184 case SENSOR_TYPE_ACCELEROMETER:
185 case SENSOR_TYPE_MAGNETIC_FIELD:
186 case SENSOR_TYPE_ORIENTATION:
187 case SENSOR_TYPE_GYROSCOPE:
188 case SENSOR_TYPE_GRAVITY:
189 case SENSOR_TYPE_LINEAR_ACCELERATION: {
190 if (valuesLength != 3) {
191 ALOGD("Dropping sendRuntimeSensorEvent, wrong number of values.");
192 return false;
193 }
194 event.acceleration.x = sensorValues[0];
195 event.acceleration.y = sensorValues[1];
196 event.acceleration.z = sensorValues[2];
197 break;
198 }
199 case SENSOR_TYPE_DEVICE_ORIENTATION:
200 case SENSOR_TYPE_LIGHT:
201 case SENSOR_TYPE_PRESSURE:
202 case SENSOR_TYPE_TEMPERATURE:
203 case SENSOR_TYPE_PROXIMITY:
204 case SENSOR_TYPE_RELATIVE_HUMIDITY:
205 case SENSOR_TYPE_AMBIENT_TEMPERATURE:
206 case SENSOR_TYPE_SIGNIFICANT_MOTION:
207 case SENSOR_TYPE_STEP_DETECTOR:
208 case SENSOR_TYPE_TILT_DETECTOR:
209 case SENSOR_TYPE_WAKE_GESTURE:
210 case SENSOR_TYPE_GLANCE_GESTURE:
211 case SENSOR_TYPE_PICK_UP_GESTURE:
212 case SENSOR_TYPE_WRIST_TILT_GESTURE:
213 case SENSOR_TYPE_STATIONARY_DETECT:
214 case SENSOR_TYPE_MOTION_DETECT:
215 case SENSOR_TYPE_HEART_BEAT:
216 case SENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT: {
217 if (valuesLength != 1) {
218 ALOGD("Dropping sendRuntimeSensorEvent, wrong number of values.");
219 return false;
220 }
221 event.data[0] = sensorValues[0];
222 break;
223 }
224 default: {
225 if (valuesLength > 16) {
226 ALOGD("Dropping sendRuntimeSensorEvent, number of values exceeds the maximum.");
227 return false;
228 }
229 memcpy(event.data, sensorValues, valuesLength * sizeof(float));
230 }
231 }
232
233 status_t err = mService->sendRuntimeSensorEvent(event);
234 return err == OK;
235 }
236
ProximityActiveListenerDelegate(JNIEnv * env,jobject listener)237 NativeSensorService::ProximityActiveListenerDelegate::ProximityActiveListenerDelegate(
238 JNIEnv* env, jobject listener)
239 : mListener(env->NewGlobalRef(listener)) {}
240
~ProximityActiveListenerDelegate()241 NativeSensorService::ProximityActiveListenerDelegate::~ProximityActiveListenerDelegate() {
242 AndroidRuntime::getJNIEnv()->DeleteGlobalRef(mListener);
243 }
244
onProximityActive(bool isActive)245 void NativeSensorService::ProximityActiveListenerDelegate::onProximityActive(bool isActive) {
246 auto jniEnv = GetOrAttachJNIEnvironment(sJvm);
247 jniEnv->CallVoidMethod(mListener, sMethodIdOnProximityActive, static_cast<jboolean>(isActive));
248 }
249
RuntimeSensorCallbackDelegate(JNIEnv * env,jobject callback)250 NativeSensorService::RuntimeSensorCallbackDelegate::RuntimeSensorCallbackDelegate(JNIEnv* env,
251 jobject callback)
252 : mCallback(env->NewGlobalRef(callback)) {}
253
~RuntimeSensorCallbackDelegate()254 NativeSensorService::RuntimeSensorCallbackDelegate::~RuntimeSensorCallbackDelegate() {
255 AndroidRuntime::getJNIEnv()->DeleteGlobalRef(mCallback);
256 }
257
onConfigurationChanged(int32_t handle,bool enabled,int64_t samplingPeriodNs,int64_t batchReportLatencyNs)258 status_t NativeSensorService::RuntimeSensorCallbackDelegate::onConfigurationChanged(
259 int32_t handle, bool enabled, int64_t samplingPeriodNs, int64_t batchReportLatencyNs) {
260 auto jniEnv = GetOrAttachJNIEnvironment(sJvm);
261 return jniEnv->CallIntMethod(mCallback, sMethodIdRuntimeSensorOnConfigurationChanged,
262 static_cast<jint>(handle), static_cast<jboolean>(enabled),
263 static_cast<jint>(ns2us(samplingPeriodNs)),
264 static_cast<jint>(ns2us(batchReportLatencyNs)));
265 }
266
onDirectChannelCreated(int fd)267 int NativeSensorService::RuntimeSensorCallbackDelegate::onDirectChannelCreated(int fd) {
268 if (fd <= 0) {
269 return 0;
270 }
271 auto jniEnv = GetOrAttachJNIEnvironment(sJvm);
272 jobject jfd = jniCreateFileDescriptor(jniEnv, fd);
273 jobject parcelFileDescriptor = newParcelFileDescriptor(jniEnv, jfd);
274 return jniEnv->CallIntMethod(mCallback, sMethodIdRuntimeSensorOnDirectChannelCreated,
275 parcelFileDescriptor);
276 }
277
onDirectChannelDestroyed(int channelHandle)278 void NativeSensorService::RuntimeSensorCallbackDelegate::onDirectChannelDestroyed(
279 int channelHandle) {
280 auto jniEnv = GetOrAttachJNIEnvironment(sJvm);
281 return jniEnv->CallVoidMethod(mCallback, sMethodIdRuntimeSensorOnDirectChannelDestroyed,
282 static_cast<jint>(channelHandle));
283 }
284
onDirectChannelConfigured(int channelHandle,int sensorHandle,int rateLevel)285 int NativeSensorService::RuntimeSensorCallbackDelegate::onDirectChannelConfigured(int channelHandle,
286 int sensorHandle,
287 int rateLevel) {
288 auto jniEnv = GetOrAttachJNIEnvironment(sJvm);
289 return jniEnv->CallIntMethod(mCallback, sMethodIdRuntimeSensorOnDirectChannelConfigured,
290 static_cast<jint>(channelHandle), static_cast<jint>(sensorHandle),
291 static_cast<jint>(rateLevel));
292 }
293
startSensorServiceNative(JNIEnv * env,jclass,jobject listener)294 static jlong startSensorServiceNative(JNIEnv* env, jclass, jobject listener) {
295 NativeSensorService* service = new NativeSensorService(env, listener);
296 return reinterpret_cast<jlong>(service);
297 }
298
registerProximityActiveListenerNative(JNIEnv * env,jclass,jlong ptr)299 static void registerProximityActiveListenerNative(JNIEnv* env, jclass, jlong ptr) {
300 auto* service = reinterpret_cast<NativeSensorService*>(ptr);
301 service->registerProximityActiveListener();
302 }
303
unregisterProximityActiveListenerNative(JNIEnv * env,jclass,jlong ptr)304 static void unregisterProximityActiveListenerNative(JNIEnv* env, jclass, jlong ptr) {
305 auto* service = reinterpret_cast<NativeSensorService*>(ptr);
306 service->unregisterProximityActiveListener();
307 }
308
registerRuntimeSensorNative(JNIEnv * env,jclass,jlong ptr,jint deviceId,jint type,jstring name,jstring vendor,jfloat maximumRange,jfloat resolution,jfloat power,jint minDelay,jint maxDelay,jint flags,jobject callback)309 static jint registerRuntimeSensorNative(JNIEnv* env, jclass, jlong ptr, jint deviceId, jint type,
310 jstring name, jstring vendor, jfloat maximumRange,
311 jfloat resolution, jfloat power, jint minDelay,
312 jint maxDelay, jint flags, jobject callback) {
313 auto* service = reinterpret_cast<NativeSensorService*>(ptr);
314 return service->registerRuntimeSensor(env, deviceId, type, name, vendor, maximumRange,
315 resolution, power, minDelay, maxDelay, flags, callback);
316 }
317
unregisterRuntimeSensorNative(JNIEnv * env,jclass,jlong ptr,jint handle)318 static void unregisterRuntimeSensorNative(JNIEnv* env, jclass, jlong ptr, jint handle) {
319 auto* service = reinterpret_cast<NativeSensorService*>(ptr);
320 service->unregisterRuntimeSensor(handle);
321 }
322
sendRuntimeSensorEventNative(JNIEnv * env,jclass,jlong ptr,jint handle,jint type,jlong timestamp,jfloatArray values)323 static jboolean sendRuntimeSensorEventNative(JNIEnv* env, jclass, jlong ptr, jint handle, jint type,
324 jlong timestamp, jfloatArray values) {
325 auto* service = reinterpret_cast<NativeSensorService*>(ptr);
326 return service->sendRuntimeSensorEvent(env, handle, type, timestamp, values);
327 }
328
329 static const JNINativeMethod methods[] = {
330 {"startSensorServiceNative", "(L" PROXIMITY_ACTIVE_CLASS ";)J",
331 reinterpret_cast<void*>(startSensorServiceNative)},
332 {"registerProximityActiveListenerNative", "(J)V",
333 reinterpret_cast<void*>(registerProximityActiveListenerNative)},
334 {"unregisterProximityActiveListenerNative", "(J)V",
335 reinterpret_cast<void*>(unregisterProximityActiveListenerNative)},
336 {"registerRuntimeSensorNative",
337 "(JIILjava/lang/String;Ljava/lang/String;FFFIIIL" RUNTIME_SENSOR_CALLBACK_CLASS ";)I",
338 reinterpret_cast<void*>(registerRuntimeSensorNative)},
339 {"unregisterRuntimeSensorNative", "(JI)V",
340 reinterpret_cast<void*>(unregisterRuntimeSensorNative)},
341 {"sendRuntimeSensorEventNative", "(JIIJ[F)Z",
342 reinterpret_cast<void*>(sendRuntimeSensorEventNative)},
343 };
344
register_android_server_sensor_SensorService(JavaVM * vm,JNIEnv * env)345 int register_android_server_sensor_SensorService(JavaVM* vm, JNIEnv* env) {
346 sJvm = vm;
347 jclass listenerClass = FindClassOrDie(env, PROXIMITY_ACTIVE_CLASS);
348 sMethodIdOnProximityActive = GetMethodIDOrDie(env, listenerClass, "onProximityActive", "(Z)V");
349 jclass runtimeSensorCallbackClass = FindClassOrDie(env, RUNTIME_SENSOR_CALLBACK_CLASS);
350 sMethodIdRuntimeSensorOnConfigurationChanged =
351 GetMethodIDOrDie(env, runtimeSensorCallbackClass, "onConfigurationChanged", "(IZII)I");
352 sMethodIdRuntimeSensorOnDirectChannelCreated =
353 GetMethodIDOrDie(env, runtimeSensorCallbackClass, "onDirectChannelCreated",
354 "(Landroid/os/ParcelFileDescriptor;)I");
355 sMethodIdRuntimeSensorOnDirectChannelDestroyed =
356 GetMethodIDOrDie(env, runtimeSensorCallbackClass, "onDirectChannelDestroyed", "(I)V");
357 sMethodIdRuntimeSensorOnDirectChannelConfigured =
358 GetMethodIDOrDie(env, runtimeSensorCallbackClass, "onDirectChannelConfigured",
359 "(III)I");
360
361 return jniRegisterNativeMethods(env, "com/android/server/sensors/SensorService", methods,
362 NELEM(methods));
363 }
364
365 }; // namespace android
366