Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cbf4004f authored by Aravind Akella's avatar Aravind Akella Committed by Ian Pedowitz
Browse files

Bug fix in SensorManager.

If SensorService hasn't started when SensorManager instance is requested, keep retrying for a
longer duration.

Bug: 22529981
Change-Id: I3c506d962b61347085fc80b2c5832289539d6853
(cherry picked from commit e2806cb4)
parent 68b84a1c
Loading
Loading
Loading
Loading
+2 −51
Original line number Diff line number Diff line
@@ -51,57 +51,7 @@ 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);
    static SensorManager& getInstanceForPackage(const String16& packageName);
    ~SensorManager();

    ssize_t getSensorList(Sensor const* const** list) const;
@@ -113,6 +63,7 @@ private:
    // DeathRecipient interface
    void sensorManagerDied();

    SensorManager(const String16& opPackageName);
    status_t assertStateLocked() const;

private:
+59 −3
Original line number Diff line number Diff line
@@ -36,6 +36,58 @@
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)
{
@@ -59,12 +111,12 @@ void SensorManager::sensorManagerDied()

status_t SensorManager::assertStateLocked() const {
    if (mSensorServer == NULL) {
        // try for one second
        // try for 10 seconds before giving up ...
        const String16 name("sensorservice");
        for (int i=0 ; i<4 ; i++) {
        for (int i = 0;i < 10; i++) {
            status_t err = getService(name, &mSensorServer);
            if (err == NAME_NOT_FOUND) {
                usleep(250000);
                sleep(1);
                continue;
            }
            if (err != NO_ERROR) {
@@ -83,6 +135,10 @@ status_t SensorManager::assertStateLocked() const {
            DeathObserver(SensorManager& mgr) : mSensorManger(mgr) { }
        };

        if (mSensorServer == NULL) {
            ALOGE("FATAL getsensorservice returned NULL");
        }

        mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));
        IInterface::asBinder(mSensorServer)->linkToDeath(mDeathObserver);