split libsensor our of libgui
Test: compile & run
Bug: treble cleanup
Change-Id: I5b2c2a14f7d3b364d25695cf0901c5b08cfb0fc9
diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp
new file mode 100644
index 0000000..b6e9fa1
--- /dev/null
+++ b/libs/sensor/SensorManager.cpp
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2010 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 "Sensors"
+
+#include <sensor/SensorManager.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <cutils/native_handle.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Singleton.h>
+
+#include <binder/IBinder.h>
+#include <binder/IServiceManager.h>
+
+#include <sensor/ISensorServer.h>
+#include <sensor/ISensorEventConnection.h>
+#include <sensor/Sensor.h>
+#include <sensor/SensorEventQueue.h>
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+android::Mutex android::SensorManager::sLock;
+std::map<String16, SensorManager*> android::SensorManager::sPackageInstances;
+
+SensorManager& SensorManager::getInstanceForPackage(const String16& packageName) {
+ Mutex::Autolock _l(sLock);
+ SensorManager* sensorManager;
+ std::map<String16, SensorManager*>::iterator iterator =
+ sPackageInstances.find(packageName);
+
+ if (iterator != sPackageInstances.end()) {
+ sensorManager = iterator->second;
+ } else {
+ String16 opPackageName = packageName;
+
+ // It is possible that the calling code has no access to the package name.
+ // In this case we will get the packages for the calling UID and pick the
+ // first one for attributing the app op. This will work correctly for
+ // runtime permissions as for legacy apps we will toggle the app op for
+ // all packages in the UID. The caveat is that the operation may be attributed
+ // to the wrong package and stats based on app ops may be slightly off.
+ if (opPackageName.size() <= 0) {
+ sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
+ if (binder != 0) {
+ const uid_t uid = IPCThreadState::self()->getCallingUid();
+ Vector<String16> packages;
+ interface_cast<IPermissionController>(binder)->getPackagesForUid(uid, packages);
+ if (!packages.isEmpty()) {
+ opPackageName = packages[0];
+ } else {
+ ALOGE("No packages for calling UID");
+ }
+ } else {
+ ALOGE("Cannot get permission service");
+ }
+ }
+
+ sensorManager = new SensorManager(opPackageName);
+
+ // If we had no package name, we looked it up from the UID and the sensor
+ // manager instance we created should also be mapped to the empty package
+ // name, to avoid looking up the packages for a UID and get the same result.
+ if (packageName.size() <= 0) {
+ sPackageInstances.insert(std::make_pair(String16(), sensorManager));
+ }
+
+ // Stash the per package sensor manager.
+ sPackageInstances.insert(std::make_pair(opPackageName, sensorManager));
+ }
+
+ return *sensorManager;
+}
+
+SensorManager::SensorManager(const String16& opPackageName)
+ : mSensorList(0), mOpPackageName(opPackageName), mDirectConnectionHandle(1) {
+ // okay we're not locked here, but it's not needed during construction
+ assertStateLocked();
+}
+
+SensorManager::~SensorManager() {
+ free(mSensorList);
+}
+
+void SensorManager::sensorManagerDied() {
+ Mutex::Autolock _l(mLock);
+ mSensorServer.clear();
+ free(mSensorList);
+ mSensorList = NULL;
+ mSensors.clear();
+}
+
+status_t SensorManager::assertStateLocked() {
+ bool initSensorManager = false;
+ if (mSensorServer == NULL) {
+ initSensorManager = true;
+ } else {
+ // Ping binder to check if sensorservice is alive.
+ status_t err = IInterface::asBinder(mSensorServer)->pingBinder();
+ if (err != NO_ERROR) {
+ initSensorManager = true;
+ }
+ }
+ if (initSensorManager) {
+ // try for 300 seconds (60*5(getService() tries for 5 seconds)) before giving up ...
+ const String16 name("sensorservice");
+ for (int i = 0; i < 60; i++) {
+ status_t err = getService(name, &mSensorServer);
+ if (err == NAME_NOT_FOUND) {
+ sleep(1);
+ continue;
+ }
+ if (err != NO_ERROR) {
+ return err;
+ }
+ break;
+ }
+
+ class DeathObserver : public IBinder::DeathRecipient {
+ SensorManager& mSensorManager;
+ virtual void binderDied(const wp<IBinder>& who) {
+ ALOGW("sensorservice died [%p]", who.unsafe_get());
+ mSensorManager.sensorManagerDied();
+ }
+ public:
+ explicit DeathObserver(SensorManager& mgr) : mSensorManager(mgr) { }
+ };
+
+ LOG_ALWAYS_FATAL_IF(mSensorServer.get() == NULL, "getService(SensorService) NULL");
+
+ mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));
+ IInterface::asBinder(mSensorServer)->linkToDeath(mDeathObserver);
+
+ mSensors = mSensorServer->getSensorList(mOpPackageName);
+ size_t count = mSensors.size();
+ mSensorList =
+ static_cast<Sensor const**>(malloc(count * sizeof(Sensor*)));
+ LOG_ALWAYS_FATAL_IF(mSensorList == NULL, "mSensorList NULL");
+
+ for (size_t i=0 ; i<count ; i++) {
+ mSensorList[i] = mSensors.array() + i;
+ }
+ }
+
+ return NO_ERROR;
+}
+
+ssize_t SensorManager::getSensorList(Sensor const* const** list) {
+ Mutex::Autolock _l(mLock);
+ status_t err = assertStateLocked();
+ if (err < 0) {
+ return static_cast<ssize_t>(err);
+ }
+ *list = mSensorList;
+ return static_cast<ssize_t>(mSensors.size());
+}
+
+ssize_t SensorManager::getDynamicSensorList(Vector<Sensor> & dynamicSensors) {
+ Mutex::Autolock _l(mLock);
+ status_t err = assertStateLocked();
+ if (err < 0) {
+ return static_cast<ssize_t>(err);
+ }
+
+ dynamicSensors = mSensorServer->getDynamicSensorList(mOpPackageName);
+ size_t count = dynamicSensors.size();
+
+ return static_cast<ssize_t>(count);
+}
+
+Sensor const* SensorManager::getDefaultSensor(int type)
+{
+ Mutex::Autolock _l(mLock);
+ if (assertStateLocked() == NO_ERROR) {
+ bool wakeUpSensor = false;
+ // For the following sensor types, return a wake-up sensor. These types are by default
+ // defined as wake-up sensors. For the rest of the sensor types defined in sensors.h return
+ // a non_wake-up version.
+ if (type == SENSOR_TYPE_PROXIMITY || type == SENSOR_TYPE_SIGNIFICANT_MOTION ||
+ type == SENSOR_TYPE_TILT_DETECTOR || type == SENSOR_TYPE_WAKE_GESTURE ||
+ type == SENSOR_TYPE_GLANCE_GESTURE || type == SENSOR_TYPE_PICK_UP_GESTURE ||
+ type == SENSOR_TYPE_WRIST_TILT_GESTURE ||
+ type == SENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT) {
+ wakeUpSensor = true;
+ }
+ // For now we just return the first sensor of that type we find.
+ // in the future it will make sense to let the SensorService make
+ // that decision.
+ for (size_t i=0 ; i<mSensors.size() ; i++) {
+ if (mSensorList[i]->getType() == type &&
+ mSensorList[i]->isWakeUpSensor() == wakeUpSensor) {
+ return mSensorList[i];
+ }
+ }
+ }
+ return NULL;
+}
+
+sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName, int mode) {
+ sp<SensorEventQueue> queue;
+
+ Mutex::Autolock _l(mLock);
+ while (assertStateLocked() == NO_ERROR) {
+ sp<ISensorEventConnection> connection =
+ mSensorServer->createSensorEventConnection(packageName, mode, mOpPackageName);
+ if (connection == NULL) {
+ // SensorService just died or the app doesn't have required permissions.
+ ALOGE("createEventQueue: connection is NULL.");
+ return NULL;
+ }
+ queue = new SensorEventQueue(connection);
+ break;
+ }
+ return queue;
+}
+
+bool SensorManager::isDataInjectionEnabled() {
+ Mutex::Autolock _l(mLock);
+ if (assertStateLocked() == NO_ERROR) {
+ return mSensorServer->isDataInjectionEnabled();
+ }
+ return false;
+}
+
+int SensorManager::createDirectChannel(
+ size_t size, int channelType, const native_handle_t *resourceHandle) {
+ Mutex::Autolock _l(mLock);
+ if (assertStateLocked() != NO_ERROR) {
+ return NO_INIT;
+ }
+
+ switch (channelType) {
+ case SENSOR_DIRECT_MEM_TYPE_ASHMEM: {
+ sp<ISensorEventConnection> conn =
+ mSensorServer->createSensorDirectConnection(mOpPackageName,
+ static_cast<uint32_t>(size),
+ static_cast<int32_t>(channelType),
+ SENSOR_DIRECT_FMT_SENSORS_EVENT, resourceHandle);
+ if (conn == nullptr) {
+ return NO_MEMORY;
+ }
+ int nativeHandle = mDirectConnectionHandle++;
+ mDirectConnection.emplace(nativeHandle, conn);
+ return nativeHandle;
+ }
+ case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
+ LOG_FATAL("%s: Finish implementation of ION and GRALLOC or remove", __FUNCTION__);
+ return BAD_VALUE;
+ default:
+ ALOGE("Bad channel shared memory type %d", channelType);
+ return BAD_VALUE;
+ }
+}
+
+void SensorManager::destroyDirectChannel(int channelNativeHandle) {
+ Mutex::Autolock _l(mLock);
+ if (assertStateLocked() == NO_ERROR) {
+ mDirectConnection.erase(channelNativeHandle);
+ }
+}
+
+int SensorManager::configureDirectChannel(int channelNativeHandle, int sensorHandle, int rateLevel) {
+ Mutex::Autolock _l(mLock);
+ if (assertStateLocked() != NO_ERROR) {
+ return NO_INIT;
+ }
+
+ auto i = mDirectConnection.find(channelNativeHandle);
+ if (i == mDirectConnection.end()) {
+ ALOGE("Cannot find the handle in client direct connection table");
+ return BAD_VALUE;
+ }
+
+ int ret;
+ ret = i->second->configureChannel(sensorHandle, rateLevel);
+ ALOGE_IF(ret < 0, "SensorManager::configureChannel (%d, %d) returns %d",
+ static_cast<int>(sensorHandle), static_cast<int>(rateLevel),
+ static_cast<int>(ret));
+ return ret;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android