blob: 63b7dfbc2a3b347622f0031c1cbae93d68382084 [file] [log] [blame]
/*
* 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 "NativeSensorService"
#include <android-base/properties.h>
#include <android_runtime/AndroidRuntime.h>
#include <core_jni_helpers.h>
#include <cutils/properties.h>
#include <jni.h>
#include <sensorservice/SensorService.h>
#include <utils/Log.h>
#include <utils/misc.h>
#include <mutex>
#define PROXIMITY_ACTIVE_CLASS \
"com/android/server/sensors/SensorManagerInternal$ProximityActiveListener"
namespace android {
static JavaVM* sJvm = nullptr;
static jmethodID sMethodIdOnProximityActive;
class NativeSensorService {
public:
NativeSensorService(JNIEnv* env, jobject listener);
void registerProximityActiveListener();
void unregisterProximityActiveListener();
private:
sp<SensorService> mService;
class ProximityActiveListenerDelegate : public SensorService::ProximityActiveListener {
public:
ProximityActiveListenerDelegate(JNIEnv* env, jobject listener);
~ProximityActiveListenerDelegate();
void onProximityActive(bool isActive) override;
private:
jobject mListener;
};
sp<ProximityActiveListenerDelegate> mProximityActiveListenerDelegate;
};
NativeSensorService::NativeSensorService(JNIEnv* env, jobject listener)
: mProximityActiveListenerDelegate(new ProximityActiveListenerDelegate(env, listener)) {
if (base::GetBoolProperty("system_init.startsensorservice", true)) {
sp<IServiceManager> sm(defaultServiceManager());
mService = new SensorService();
sm->addService(String16(SensorService::getServiceName()), mService,
false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
}
}
void NativeSensorService::registerProximityActiveListener() {
if (mService == nullptr) {
ALOGD("Dropping registerProximityActiveListener, sensor service not available.");
return;
}
mService->addProximityActiveListener(mProximityActiveListenerDelegate);
}
void NativeSensorService::unregisterProximityActiveListener() {
if (mService == nullptr) {
ALOGD("Dropping unregisterProximityActiveListener, sensor service not available.");
return;
}
mService->removeProximityActiveListener(mProximityActiveListenerDelegate);
}
NativeSensorService::ProximityActiveListenerDelegate::ProximityActiveListenerDelegate(
JNIEnv* env, jobject listener)
: mListener(env->NewGlobalRef(listener)) {}
NativeSensorService::ProximityActiveListenerDelegate::~ProximityActiveListenerDelegate() {
AndroidRuntime::getJNIEnv()->DeleteGlobalRef(mListener);
}
void NativeSensorService::ProximityActiveListenerDelegate::onProximityActive(bool isActive) {
auto jniEnv = GetOrAttachJNIEnvironment(sJvm);
jniEnv->CallVoidMethod(mListener, sMethodIdOnProximityActive, static_cast<jboolean>(isActive));
}
static jlong startSensorServiceNative(JNIEnv* env, jclass, jobject listener) {
NativeSensorService* service = new NativeSensorService(env, listener);
return reinterpret_cast<jlong>(service);
}
static void registerProximityActiveListenerNative(JNIEnv* env, jclass, jlong ptr) {
auto* service = reinterpret_cast<NativeSensorService*>(ptr);
service->registerProximityActiveListener();
}
static void unregisterProximityActiveListenerNative(JNIEnv* env, jclass, jlong ptr) {
auto* service = reinterpret_cast<NativeSensorService*>(ptr);
service->unregisterProximityActiveListener();
}
static const JNINativeMethod methods[] = {
{
"startSensorServiceNative", "(L" PROXIMITY_ACTIVE_CLASS ";)J",
reinterpret_cast<void*>(startSensorServiceNative)
},
{
"registerProximityActiveListenerNative", "(J)V",
reinterpret_cast<void*>(registerProximityActiveListenerNative)
},
{
"unregisterProximityActiveListenerNative", "(J)V",
reinterpret_cast<void*>(unregisterProximityActiveListenerNative)
},
};
int register_android_server_sensor_SensorService(JavaVM* vm, JNIEnv* env) {
sJvm = vm;
jclass listenerClass = FindClassOrDie(env, PROXIMITY_ACTIVE_CLASS);
sMethodIdOnProximityActive = GetMethodIDOrDie(env, listenerClass, "onProximityActive", "(Z)V");
return jniRegisterNativeMethods(env, "com/android/server/sensors/SensorService", methods,
NELEM(methods));
}
}; // namespace android