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

Commit dd5c5cb3 authored by Peng Xu's avatar Peng Xu
Browse files

Set sensor operation parameter implementation

Set operation parameter to sensor HAL. Possible paramters include
local geomagnetic field, local gravity acceleration, device dock
state, whether device should run in high performance mode, and
if a magnetic field calibration guide is in progress.

Bug: 30958130
Test: Tested with marlin. Modified hal implementation can get local
      geomagnetic field.

Change-Id: Idaedd9e616d01383ba244cc64cf3e319ce02191f
parent 8348f6d6
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ enum {
    ENABLE_DATA_INJECTION,
    GET_DYNAMIC_SENSOR_LIST,
    CREATE_SENSOR_DIRECT_CONNECTION,
    SET_OPERATION_PARAMETER,
};

class BpSensorServer : public BpInterface<ISensorServer>
@@ -117,6 +118,23 @@ public:
        remote()->transact(CREATE_SENSOR_DIRECT_CONNECTION, data, &reply);
        return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
    }

    virtual int setOperationParameter(
            int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints) {
        Parcel data, reply;
        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
        data.writeInt32(type);
        data.writeUint32(static_cast<uint32_t>(floats.size()));
        for (auto i : floats) {
            data.writeFloat(i);
        }
        data.writeUint32(static_cast<uint32_t>(ints.size()));
        for (auto i : ints) {
            data.writeInt32(i);
        }
        remote()->transact(SET_OPERATION_PARAMETER, data, &reply);
        return reply.readInt32();
    }
};

// Out-of-line virtual method definition to trigger vtable emission in this
@@ -183,6 +201,26 @@ status_t BnSensorServer::onTransact(
            reply->writeStrongBinder(IInterface::asBinder(ch));
            return NO_ERROR;
        }
        case SET_OPERATION_PARAMETER: {
            CHECK_INTERFACE(ISensorServer, data, reply);
            int32_t type;
            Vector<float> floats;
            Vector<int32_t> ints;

            type = data.readInt32();
            floats.resize(data.readUint32());
            for (auto &i : floats) {
                i = data.readFloat();
            }
            ints.resize(data.readUint32());
            for (auto &i : ints) {
                i = data.readInt32();
            }

            int32_t ret = setOperationParameter(type, floats, ints);
            reply->writeInt32(ret);
            return NO_ERROR;
        }
    }
    return BBinder::onTransact(code, data, reply, flags);
}
+9 −0
Original line number Diff line number Diff line
@@ -304,5 +304,14 @@ int SensorManager::configureDirectChannel(int channelNativeHandle, int sensorHan
    return ret;
}

int SensorManager::setOperationParameter(
        int type, const Vector<float> &floats, const Vector<int32_t> &ints) {
    Mutex::Autolock _l(mLock);
    if (assertStateLocked() != NO_ERROR) {
        return NO_INIT;
    }
    return mSensorServer->setOperationParameter(type, floats, ints);
}

// ----------------------------------------------------------------------------
}; // namespace android
+3 −0
Original line number Diff line number Diff line
@@ -50,6 +50,9 @@ public:

    virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName,
            uint32_t size, int32_t type, int32_t format, const native_handle_t *resource) = 0;

    virtual int setOperationParameter(
            int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints) = 0;
};

// ----------------------------------------------------------------------------
+1 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ public:
    int createDirectChannel(size_t size, int channelType, const native_handle_t *channelData);
    void destroyDirectChannel(int channelNativeHandle);
    int configureDirectChannel(int channelNativeHandle, int sensorHandle, int rateLevel);
    int setOperationParameter(int type, const Vector<float> &floats, const Vector<int32_t> &ints);

private:
    // DeathRecipient interface
+84 −9
Original line number Diff line number Diff line
@@ -13,23 +13,19 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cutils/properties.h>

#include <binder/AppOpsManager.h>
#include <binder/BinderService.h>
#include <binder/IServiceManager.h>
#include <binder/PermissionCache.h>

#include <cutils/ashmem.h>
#include <sensor/SensorEventQueue.h>

#include <cutils/properties.h>
#include <hardware/sensors.h>
#include <hardware_legacy/power.h>

#include <openssl/digest.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>
#include <sensor/SensorEventQueue.h>
#include <utils/SystemClock.h>

#include "BatteryService.h"
#include "CorrectedGyroSensor.h"
@@ -77,7 +73,8 @@ bool SensorService::sHmacGlobalKeyIsValid = false;
#define SENSOR_SERVICE_SCHED_FIFO_PRIORITY 10

// Permissions.
static const String16 sDump("android.permission.DUMP");
static const String16 sDumpPermission("android.permission.DUMP");
static const String16 sLocationHardwarePermission("android.permission.LOCATION_HARDWARE");

SensorService::SensorService()
    : mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
@@ -319,7 +316,7 @@ SensorService::~SensorService() {

status_t SensorService::dump(int fd, const Vector<String16>& args) {
    String8 result;
    if (!PermissionCache::checkCallingPermission(sDump)) {
    if (!PermissionCache::checkCallingPermission(sDumpPermission)) {
        result.appendFormat("Permission Denial: can't dump SensorService from pid=%d, uid=%d\n",
                IPCThreadState::self()->getCallingPid(),
                IPCThreadState::self()->getCallingUid());
@@ -1032,6 +1029,84 @@ sp<ISensorEventConnection> SensorService::createSensorDirectConnection(
    return conn;
}

int SensorService::setOperationParameter(
            int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints) {
    Mutex::Autolock _l(mLock);

    // check permission
    int32_t uid;
    bool hasPermission = checkCallingPermission(sLocationHardwarePermission, nullptr, &uid);
    if (!hasPermission || (uid != 1000 && uid != 0)) {
        return PERMISSION_DENIED;
    }

    bool isFloat = true;
    size_t expectSize = INT32_MAX;
    switch (type) {
        case AINFO_LOCAL_GEOMAGNETIC_FIELD:
            isFloat = true;
            expectSize = 3;
            break;
        case AINFO_LOCAL_GRAVITY:
            isFloat = true;
            expectSize = 1;
            break;
        case AINFO_DOCK_STATE:
        case AINFO_HIGH_PERFORMANCE_MODE:
        case AINFO_MAGNETIC_FIELD_CALIBRATION:
            isFloat = false;
            expectSize = 1;
            break;
        default:
            return BAD_VALUE;
    }

    // three events: first one is begin tag, last one is end tag, the one in the middle
    // is the payload.
    sensors_event_t event[3];
    int64_t timestamp = elapsedRealtimeNano();
    for (sensors_event_t* i = event; i < event + 3; i++) {
        *i = (sensors_event_t) {
            .version = sizeof(sensors_event_t),
            .sensor = 0,
            .type = SENSOR_TYPE_ADDITIONAL_INFO,
            .timestamp = timestamp++,
            .additional_info = (additional_info_event_t) {
                .serial = 0
            }
        };
    }

    event[0].additional_info.type = AINFO_BEGIN;
    event[1].additional_info.type = type;
    event[2].additional_info.type = AINFO_END;

    if (isFloat) {
        if (floats.size() != expectSize) {
            return BAD_VALUE;
        }
        for (size_t i = 0; i < expectSize; ++i) {
            event[1].additional_info.data_float[i] = floats[i];
        }
    } else {
        if (ints.size() != expectSize) {
            return BAD_VALUE;
        }
        for (size_t i = 0; i < expectSize; ++i) {
            event[1].additional_info.data_int32[i] = ints[i];
        }
    }

    SensorDevice& dev(SensorDevice::getInstance());
    for (sensors_event_t* i = event; i < event + 3; i++) {
        int ret = dev.injectSensorData(i);
        if (ret != NO_ERROR) {
            return ret;
        }
    }
    return NO_ERROR;
}

status_t SensorService::resetToNormalMode() {
    Mutex::Autolock _l(mLock);
    return resetToNormalModeLocked();
Loading