diff options
author | Svet Ganov <svetoslavganov@google.com> | 2015-05-07 10:50:59 -0700 |
---|---|---|
committer | Svetoslav <svetoslavganov@google.com> | 2015-05-07 12:50:27 -0700 |
commit | 5fa32d4b08843d0aeca567a173227e8e37322e8e (patch) | |
tree | 6110a5e82d8de8b2324ac3d6ee20a30193327d6b /include/gui | |
parent | cbe13ef59b25b6df226c09b9351f0f615bc68dda (diff) | |
download | frameworks_native-5fa32d4b08843d0aeca567a173227e8e37322e8e.zip frameworks_native-5fa32d4b08843d0aeca567a173227e8e37322e8e.tar.gz frameworks_native-5fa32d4b08843d0aeca567a173227e8e37322e8e.tar.bz2 |
Fix broken NDK sensor manager API.
Change-Id: I21bb8b0dcfd3f1c812753a9fd77dea792e7155f2
Diffstat (limited to 'include/gui')
-rw-r--r-- | include/gui/SensorManager.h | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/include/gui/SensorManager.h b/include/gui/SensorManager.h index d0c63d4..4c34e12 100644 --- a/include/gui/SensorManager.h +++ b/include/gui/SensorManager.h @@ -17,10 +17,14 @@ #ifndef ANDROID_GUI_SENSOR_MANAGER_H #define ANDROID_GUI_SENSOR_MANAGER_H +#include <map> + #include <stdint.h> #include <sys/types.h> #include <binder/IBinder.h> +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> #include <utils/Errors.h> #include <utils/RefBase.h> @@ -47,6 +51,56 @@ class SensorManager : public ASensorManager { public: + static 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(const String16& opPackageName); ~SensorManager(); @@ -62,6 +116,9 @@ private: status_t assertStateLocked() const; private: + static Mutex sLock; + static std::map<String16, SensorManager*> sPackageInstances; + mutable Mutex mLock; mutable sp<ISensorServer> mSensorServer; mutable Sensor const** mSensorList; |