diff options
| -rw-r--r-- | cmds/atrace/atrace.cpp | 1 | ||||
| -rw-r--r-- | cmds/dumpstate/dumpstate.c | 14 | ||||
| -rw-r--r-- | include/gui/SensorManager.h | 26 | ||||
| -rw-r--r-- | libs/gui/SensorManager.cpp | 93 | ||||
| -rw-r--r-- | services/sensorservice/CorrectedGyroSensor.cpp | 4 | ||||
| -rw-r--r-- | services/sensorservice/Fusion.cpp | 167 | ||||
| -rw-r--r-- | services/sensorservice/Fusion.h | 21 | ||||
| -rw-r--r-- | services/sensorservice/GravitySensor.cpp | 8 | ||||
| -rw-r--r-- | services/sensorservice/OrientationSensor.cpp | 4 | ||||
| -rw-r--r-- | services/sensorservice/RotationVectorSensor.cpp | 69 | ||||
| -rw-r--r-- | services/sensorservice/RotationVectorSensor.h | 17 | ||||
| -rw-r--r-- | services/sensorservice/SensorFusion.cpp | 162 | ||||
| -rw-r--r-- | services/sensorservice/SensorFusion.h | 46 | ||||
| -rw-r--r--[-rwxr-xr-x] | services/sensorservice/SensorService.cpp | 126 | ||||
| -rw-r--r-- | services/sensorservice/SensorService.h | 2 | ||||
| -rw-r--r-- | services/surfaceflinger/Android.mk | 4 | ||||
| -rw-r--r-- | services/surfaceflinger/main_surfaceflinger.cpp | 7 |
17 files changed, 192 insertions, 579 deletions
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp index 9a5a81e59a..55282cf9aa 100644 --- a/cmds/atrace/atrace.cpp +++ b/cmds/atrace/atrace.cpp @@ -93,6 +93,7 @@ static const TracingCategory k_categories[] = { { "sched", "CPU Scheduling", 0, { { REQ, "/sys/kernel/debug/tracing/events/sched/sched_switch/enable" }, { REQ, "/sys/kernel/debug/tracing/events/sched/sched_wakeup/enable" }, + { OPT, "/sys/kernel/debug/tracing/events/sched/sched_blocked_reason/enable" }, } }, { "irq", "IRQ Events", 0, { { REQ, "/sys/kernel/debug/tracing/events/irq/enable" }, diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c index b88b60551a..a2e4f4bd59 100644 --- a/cmds/dumpstate/dumpstate.c +++ b/cmds/dumpstate/dumpstate.c @@ -262,6 +262,8 @@ static unsigned long logcat_timeout(char *name) { /* End copy from system/core/logd/LogBuffer.cpp */ +static const unsigned long logcat_min_timeout = 40000; /* ms */ + /* dumps the current system state to stdout */ static void dumpstate() { unsigned long timeout; @@ -334,18 +336,18 @@ static void dumpstate() { // dump_file("EVENT LOG TAGS", "/etc/event-log-tags"); // calculate timeout timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash"); - if (timeout < 20000) { - timeout = 20000; + if (timeout < logcat_min_timeout) { + timeout = logcat_min_timeout; } run_command("SYSTEM LOG", timeout / 1000, "logcat", "-v", "threadtime", "-d", "*:v", NULL); timeout = logcat_timeout("events"); - if (timeout < 20000) { - timeout = 20000; + if (timeout < logcat_min_timeout) { + timeout = logcat_min_timeout; } run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events", "-v", "threadtime", "-d", "*:v", NULL); timeout = logcat_timeout("radio"); - if (timeout < 20000) { - timeout = 20000; + if (timeout < logcat_min_timeout) { + timeout = logcat_min_timeout; } run_command("RADIO LOG", timeout / 1000, "logcat", "-b", "radio", "-v", "threadtime", "-d", "*:v", NULL); diff --git a/include/gui/SensorManager.h b/include/gui/SensorManager.h index f039caf36f..0cff46c076 100644 --- a/include/gui/SensorManager.h +++ b/include/gui/SensorManager.h @@ -22,11 +22,9 @@ #include <stdint.h> #include <sys/types.h> -#include <binder/BinderService.h> #include <binder/IBinder.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> -#include <binder/PermissionCache.h> #include <utils/Errors.h> #include <utils/RefBase.h> @@ -56,8 +54,7 @@ public: static SensorManager& getInstanceForPackage(const String16& packageName); ~SensorManager(); - ssize_t getSensorList(Sensor const* const** list); - ssize_t getAvailableSensorList(Sensor const* const** list); + ssize_t getSensorList(Sensor const* const** list) const; Sensor const* getDefaultSensor(int type); sp<SensorEventQueue> createEventQueue(String8 packageName = String8(""), int mode = 0); bool isDataInjectionEnabled(); @@ -67,27 +64,18 @@ private: void sensorManagerDied(); SensorManager(const String16& opPackageName); - status_t assertStateLocked(); - void updateAvailableSensorList(); + status_t assertStateLocked() const; private: static Mutex sLock; static std::map<String16, SensorManager*> sPackageInstances; - Mutex mLock; - sp<ISensorServer> mSensorServer; - - // for Java API - Sensor const** mSensorList; - - // for NDK API - Sensor const** mAvailableSensorList; - ssize_t mNumAvailableSensor; - - Vector<Sensor> mSensors; - sp<IBinder::DeathRecipient> mDeathObserver; + mutable Mutex mLock; + mutable sp<ISensorServer> mSensorServer; + mutable Sensor const** mSensorList; + mutable Vector<Sensor> mSensors; + mutable sp<IBinder::DeathRecipient> mDeathObserver; const String16 mOpPackageName; - bool mBodyPermission; }; // ---------------------------------------------------------------------------- diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp index 4277032fa7..33608b5bd2 100644 --- a/libs/gui/SensorManager.cpp +++ b/libs/gui/SensorManager.cpp @@ -89,8 +89,7 @@ SensorManager& SensorManager::getInstanceForPackage(const String16& packageName) } SensorManager::SensorManager(const String16& opPackageName) - : mSensorList(NULL), mAvailableSensorList(NULL), mNumAvailableSensor(0), - mOpPackageName(opPackageName), mBodyPermission(false) + : mSensorList(0), mOpPackageName(opPackageName) { // okay we're not locked here, but it's not needed during construction assertStateLocked(); @@ -99,9 +98,6 @@ SensorManager::SensorManager(const String16& opPackageName) SensorManager::~SensorManager() { free(mSensorList); - if (mAvailableSensorList) { - free(mAvailableSensorList); - } } void SensorManager::sensorManagerDied() @@ -110,14 +106,10 @@ void SensorManager::sensorManagerDied() mSensorServer.clear(); free(mSensorList); mSensorList = NULL; - if (mAvailableSensorList) { - free(mAvailableSensorList); - mAvailableSensorList = NULL; - } mSensors.clear(); } -status_t SensorManager::assertStateLocked() { +status_t SensorManager::assertStateLocked() const { bool initSensorManager = false; if (mSensorServer == NULL) { initSensorManager = true; @@ -167,14 +159,13 @@ status_t SensorManager::assertStateLocked() { for (size_t i=0 ; i<count ; i++) { mSensorList[i] = mSensors.array() + i; } - - updateAvailableSensorList(); } return NO_ERROR; } -ssize_t SensorManager::getSensorList(Sensor const* const** list) { +ssize_t SensorManager::getSensorList(Sensor const* const** list) const +{ Mutex::Autolock _l(mLock); status_t err = assertStateLocked(); if (err < 0) { @@ -184,76 +175,10 @@ ssize_t SensorManager::getSensorList(Sensor const* const** list) { return static_cast<ssize_t>(mSensors.size()); } -void SensorManager::updateAvailableSensorList() { - const int uid = static_cast<int>(IPCThreadState::self()->getCallingUid()); - const int pid = static_cast<int>(IPCThreadState::self()->getCallingPid()); - const String16 BODY_SENSOR_PERMISSION("android.permission.BODY_SENSORS"); - const String8 BODY_SENSOR_PERMISSION8("android.permission.BODY_SENSORS"); - - bool bodySensorPermission = false; - - sp<IBinder> binder = defaultServiceManager()->getService(String16("permission")); - if (binder != NULL) { - bodySensorPermission = interface_cast<IPermissionController>(binder)-> - checkPermission(BODY_SENSOR_PERMISSION, pid, uid); - } - - // only update if app got BODY_SENSORS permission after last call or the sensor list has not - // been populated. - // - // it is not possible for the reverse transition, as the app will be killed when permission is - // revoked. - if ( (bodySensorPermission && !mBodyPermission) || mAvailableSensorList == NULL) { - - // allocate only when necessary - if (mAvailableSensorList == NULL) { - // allocate a list big enough to fit all sensors (including those requires permission - // that the app do not have; - mAvailableSensorList = - static_cast<Sensor const**>(malloc(mSensors.size() * sizeof(Sensor*))); - - // first populate all sensors that do not need body sensor permission - ssize_t& n = mNumAvailableSensor; - for (size_t i = 0; i < mSensors.size() ; i++) { - if (mSensors[i].getRequiredPermission() != BODY_SENSOR_PERMISSION8) { - mAvailableSensorList[n++] = mSensors.array() + i; - } - } - } - - if (bodySensorPermission) { - // if the app just got the sensor permission back, fill the sensor at the end of list - ssize_t& n = mNumAvailableSensor; - for (size_t i = 0; i < mSensors.size() ; i++) { - if (mSensors[i].getRequiredPermission() == BODY_SENSOR_PERMISSION8) { - mAvailableSensorList[n++] = mSensors.array() + i; - } - } - } - - mBodyPermission = bodySensorPermission; - } -} - -ssize_t SensorManager::getAvailableSensorList(Sensor const* const** list) { - Mutex::Autolock _l(mLock); - status_t err = assertStateLocked(); - if (err < 0) { - return static_cast<ssize_t>(err); - } - - updateAvailableSensorList(); - - *list = mAvailableSensorList; - return mNumAvailableSensor; -} - -Sensor const* SensorManager::getDefaultSensor(int type) { +Sensor const* SensorManager::getDefaultSensor(int type) +{ Mutex::Autolock _l(mLock); if (assertStateLocked() == NO_ERROR) { - - updateAvailableSensorList(); - 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 @@ -267,9 +192,9 @@ Sensor const* SensorManager::getDefaultSensor(int type) { // in the future it will make sense to let the SensorService make // that decision. for (size_t i=0 ; i<mSensors.size() ; i++) { - if (mAvailableSensorList[i]->getType() == type && - mAvailableSensorList[i]->isWakeUpSensor() == wakeUpSensor) { - return mAvailableSensorList[i]; + if (mSensorList[i]->getType() == type && + mSensorList[i]->isWakeUpSensor() == wakeUpSensor) { + return mSensorList[i]; } } } diff --git a/services/sensorservice/CorrectedGyroSensor.cpp b/services/sensorservice/CorrectedGyroSensor.cpp index 7b1f3460ea..b07d5448a6 100644 --- a/services/sensorservice/CorrectedGyroSensor.cpp +++ b/services/sensorservice/CorrectedGyroSensor.cpp @@ -58,12 +58,12 @@ bool CorrectedGyroSensor::process(sensors_event_t* outEvent, status_t CorrectedGyroSensor::activate(void* ident, bool enabled) { mSensorDevice.activate(ident, mGyro.getHandle(), enabled); - return mSensorFusion.activate(FUSION_9AXIS, ident, enabled); + return mSensorFusion.activate(ident, enabled); } status_t CorrectedGyroSensor::setDelay(void* ident, int /*handle*/, int64_t ns) { mSensorDevice.setDelay(ident, mGyro.getHandle(), ns); - return mSensorFusion.setDelay(FUSION_9AXIS, ident, ns); + return mSensorFusion.setDelay(ident, ns); } Sensor CorrectedGyroSensor::getSensor() const { diff --git a/services/sensorservice/Fusion.cpp b/services/sensorservice/Fusion.cpp index 359d289773..4f63c31d16 100644 --- a/services/sensorservice/Fusion.cpp +++ b/services/sensorservice/Fusion.cpp @@ -24,44 +24,28 @@ namespace android { // ----------------------------------------------------------------------- -/*==================== BEGIN FUSION SENSOR PARAMETER =========================*/ - -/* Note: - * If a platform uses software fusion, it is necessary to tune the following - * parameters to fit the hardware sensors prior to release. - * - * The DEFAULT_ parameters will be used in FUSION_9AXIS and FUSION_NOMAG mode. - * The GEOMAG_ parameters will be used in FUSION_NOGYRO mode. - */ - /* - * GYRO_VAR gives the measured variance of the gyro's output per + * gyroVAR gives the measured variance of the gyro's output per * Hz (or variance at 1 Hz). This is an "intrinsic" parameter of the gyro, * which is independent of the sampling frequency. * * The variance of gyro's output at a given sampling period can be * calculated as: - * variance(T) = GYRO_VAR / T + * variance(T) = gyroVAR / T * * The variance of the INTEGRATED OUTPUT at a given sampling period can be * calculated as: - * variance_integrate_output(T) = GYRO_VAR * T + * variance_integrate_output(T) = gyroVAR * T + * */ -static const float DEFAULT_GYRO_VAR = 1e-7; // (rad/s)^2 / Hz -static const float DEFAULT_GYRO_BIAS_VAR = 1e-12; // (rad/s)^2 / s (guessed) -static const float GEOMAG_GYRO_VAR = 1e-4; // (rad/s)^2 / Hz -static const float GEOMAG_GYRO_BIAS_VAR = 1e-8; // (rad/s)^2 / s (guessed) +static const float gyroVAR = 1e-7; // (rad/s)^2 / Hz +static const float biasVAR = 1e-8; // (rad/s)^2 / s (guessed) /* * Standard deviations of accelerometer and magnetometer */ -static const float DEFAULT_ACC_STDEV = 0.015f; // m/s^2 (measured 0.08 / CDD 0.05) -static const float DEFAULT_MAG_STDEV = 0.1f; // uT (measured 0.7 / CDD 0.5) -static const float GEOMAG_ACC_STDEV = 0.05f; // m/s^2 (measured 0.08 / CDD 0.05) -static const float GEOMAG_MAG_STDEV = 0.1f; // uT (measured 0.7 / CDD 0.5) - - -/* ====================== END FUSION SENSOR PARAMETER ========================*/ +static const float accSTDEV = 0.05f; // m/s^2 (measured 0.08 / CDD 0.05) +static const float magSTDEV = 0.5f; // uT (measured 0.7 / CDD 0.5) static const float SYMMETRY_TOLERANCE = 1e-10f; @@ -70,8 +54,7 @@ static const float SYMMETRY_TOLERANCE = 1e-10f; * ill-conditioning and div by zeros. * Threshhold: 10% of g, in m/s^2 */ -static const float NOMINAL_GRAVITY = 9.81f; -static const float FREE_FALL_THRESHOLD = 0.1f * (NOMINAL_GRAVITY); +static const float FREE_FALL_THRESHOLD = 0.981f; static const float FREE_FALL_THRESHOLD_SQ = FREE_FALL_THRESHOLD*FREE_FALL_THRESHOLD; @@ -104,9 +87,6 @@ static const float MIN_VALID_CROSS_PRODUCT_MAG = 1.0e-3; static const float MIN_VALID_CROSS_PRODUCT_MAG_SQ = MIN_VALID_CROSS_PRODUCT_MAG*MIN_VALID_CROSS_PRODUCT_MAG; -static const float W_EPS = 1e-4f; -static const float SQRT_3 = 1.732f; -static const float WVEC_EPS = 1e-4f/SQRT_3; // ----------------------------------------------------------------------- template <typename TYPE, size_t C, size_t R> @@ -193,7 +173,7 @@ Fusion::Fusion() { init(); } -void Fusion::init(int mode) { +void Fusion::init() { mInitState = 0; mGyroRate = 0; @@ -203,19 +183,6 @@ void Fusion::init(int mode) { mCount[2] = 0; mData = 0; - mMode = mode; - - if (mMode != FUSION_NOGYRO) { //normal or game rotation - mParam.gyroVar = DEFAULT_GYRO_VAR; - mParam.gyroBiasVar = DEFAULT_GYRO_BIAS_VAR; - mParam.accStdev = DEFAULT_ACC_STDEV; - mParam.magStdev = DEFAULT_MAG_STDEV; - } else { - mParam.gyroVar = GEOMAG_GYRO_VAR; - mParam.gyroBiasVar = GEOMAG_GYRO_BIAS_VAR; - mParam.accStdev = GEOMAG_ACC_STDEV; - mParam.magStdev = GEOMAG_MAG_STDEV; - } } void Fusion::initFusion(const vec4_t& q, float dT) @@ -238,11 +205,11 @@ void Fusion::initFusion(const vec4_t& q, float dT) const float dT3 = dT2*dT; // variance of integrated output at 1/dT Hz (random drift) - const float q00 = mParam.gyroVar * dT + 0.33333f * mParam.gyroBiasVar * dT3; + const float q00 = gyroVAR * dT + 0.33333f * biasVAR * dT3; // variance of drift rate ramp - const float q11 = mParam.gyroBiasVar * dT; - const float q10 = 0.5f * mParam.gyroBiasVar * dT2; + const float q11 = biasVAR * dT; + const float q10 = 0.5f * biasVAR * dT2; const float q01 = q10; GQGt[0][0] = q00; // rad^2 @@ -256,9 +223,7 @@ void Fusion::initFusion(const vec4_t& q, float dT) } bool Fusion::hasEstimate() const { - return ((mInitState & MAG) || (mMode == FUSION_NOMAG)) && - ((mInitState & GYRO) || (mMode == FUSION_NOGYRO)) && - (mInitState & ACC); + return (mInitState == (MAG|ACC|GYRO)); } bool Fusion::checkInitComplete(int what, const vec3_t& d, float dT) { @@ -269,9 +234,6 @@ bool Fusion::checkInitComplete(int what, const vec3_t& d, float dT) { mData[0] += d * (1/length(d)); mCount[0]++; mInitState |= ACC; - if (mMode == FUSION_NOGYRO ) { - mGyroRate = dT; - } } else if (what == MAG) { mData[1] += d * (1/length(d)); mCount[1]++; @@ -280,29 +242,25 @@ bool Fusion::checkInitComplete(int what, const vec3_t& d, float dT) { mGyroRate = dT; mData[2] += d*dT; mCount[2]++; - mInitState |= GYRO; + if (mCount[2] == 64) { + // 64 samples is good enough to estimate the gyro drift and + // doesn't take too much time. + mInitState |= GYRO; + } } - if (hasEstimate()) { + if (mInitState == (MAG|ACC|GYRO)) { // Average all the values we collected so far mData[0] *= 1.0f/mCount[0]; - if (mMode != FUSION_NOMAG) { - mData[1] *= 1.0f/mCount[1]; - } + mData[1] *= 1.0f/mCount[1]; mData[2] *= 1.0f/mCount[2]; // calculate the MRPs from the data collection, this gives us // a rough estimate of our initial state mat33_t R; - vec3_t up(mData[0]); - vec3_t east; - - if (mMode != FUSION_NOMAG) { - east = normalize(cross_product(mData[1], up)); - } else { - east = getOrthogonal(up); - } - + vec3_t up(mData[0]); + vec3_t east(cross_product(mData[1], up)); + east *= 1/length(east); vec3_t north(cross_product(up, east)); R << east << north << up; const vec4_t q = matrixToQuat(R); @@ -320,43 +278,21 @@ void Fusion::handleGyro(const vec3_t& w, float dT) { predict(w, dT); } -status_t Fusion::handleAcc(const vec3_t& a, float dT) { - if (!checkInitComplete(ACC, a, dT)) - return BAD_VALUE; - +status_t Fusion::handleAcc(const vec3_t& a) { // ignore acceleration data if we're close to free-fall - const float l = length(a); - if (l < FREE_FALL_THRESHOLD) { + if (length_squared(a) < FREE_FALL_THRESHOLD_SQ) { return BAD_VALUE; } - const float l_inv = 1.0f/l; - - if ( mMode == FUSION_NOGYRO ) { - //geo mag - vec3_t w_dummy; - w_dummy = x1; //bias - predict(w_dummy, dT); - } - - if ( mMode == FUSION_NOMAG) { - vec3_t m; - m = getRotationMatrix()*Bm; - update(m, Bm, mParam.magStdev); - } - - vec3_t unityA = a * l_inv; - const float d = sqrtf(fabsf(l- NOMINAL_GRAVITY)); - const float p = l_inv * mParam.accStdev*expf(d); + if (!checkInitComplete(ACC, a)) + return BAD_VALUE; - update(unityA, Ba, p); + const float l = 1/length(a); + update(a*l, Ba, accSTDEV*l); return NO_ERROR; } status_t Fusion::handleMag(const vec3_t& m) { - if (!checkInitComplete(MAG, m)) - return BAD_VALUE; - // the geomagnetic-field should be between 30uT and 60uT // reject if too large to avoid spurious magnetic sources const float magFieldSq = length_squared(m); @@ -368,6 +304,9 @@ status_t Fusion::handleMag(const vec3_t& m) { return BAD_VALUE; } + if (!checkInitComplete(MAG, m)) + return BAD_VALUE; + // Orthogonalize the magnetic field to the gravity field, mapping it into // tangent to Earth. const vec3_t up( getRotationMatrix() * Ba ); @@ -385,10 +324,10 @@ status_t Fusion::handleMag(const vec3_t& m) { // then pass it in as the update. vec3_t north( cross_product(up, east) ); - const float l_inv = 1 / length(north); - north *= l_inv; + const float l = 1 / length(north); + north *= l; - update(north, Bm, mParam.magStdev*l_inv); + update(north, Bm, magSTDEV*l); return NO_ERROR; } @@ -433,11 +372,8 @@ mat34_t Fusion::getF(const vec4_t& q) { void Fusion::predict(const vec3_t& w, float dT) { const vec4_t q = x0; const vec3_t b = x1; - vec3_t we = w - b; + const vec3_t we = w - b; - if (length(we) < WVEC_EPS) { - we = (we[0]>0.f)?WVEC_EPS:-WVEC_EPS; - } // q(k+1) = O(we)*q(k) // -------------------- // @@ -470,7 +406,7 @@ void Fusion::predict(const vec3_t& w, float dT) { const mat33_t wx2(wx*wx); const float lwedT = length(we)*dT; const float hlwedT = 0.5f*lwedT; - const float ilwe = 1.f/length(we); + const float ilwe = 1/length(we); const float k0 = (1-cosf(lwedT))*(ilwe*ilwe); const float k1 = sinf(lwedT); const float k2 = cosf(hlwedT); @@ -486,7 +422,6 @@ void Fusion::predict(const vec3_t& w, float dT) { Phi[1][0] = wx*k0 - I33dT - wx2*(ilwe*ilwe*ilwe)*(lwedT-k1); x0 = O*q; - if (x0.w < 0) x0 = -x0; @@ -531,37 +466,15 @@ void Fusion::update(const vec3_t& z, const vec3_t& Bi, float sigma) { const vec3_t e(z - Bb); const vec3_t dq(K[0]*e); + const vec3_t db(K[1]*e); q += getF(q)*(0.5f*dq); x0 = normalize_quat(q); - - if (mMode != FUSION_NOMAG) { - const vec3_t db(K[1]*e); - x1 += db; - } + x1 += db; checkState(); } -vec3_t Fusion::getOrthogonal(const vec3_t &v) { - vec3_t w; - if (fabsf(v[0])<= fabsf(v[1]) && fabsf(v[0]) <= fabsf(v[2])) { - w[0]=0.f; - w[1] = v[2]; - w[2] = -v[1]; - } else if (fabsf(v[1]) <= fabsf(v[2])) { - w[0] = v[2]; - w[1] = 0.f; - w[2] = -v[0]; - }else { - w[0] = v[1]; - w[1] = -v[0]; - w[2] = 0.f; - } - return normalize(w); -} - - // ----------------------------------------------------------------------- }; // namespace android diff --git a/services/sensorservice/Fusion.h b/services/sensorservice/Fusion.h index 602779f539..7062999b75 100644 --- a/services/sensorservice/Fusion.h +++ b/services/sensorservice/Fusion.h @@ -27,13 +27,6 @@ namespace android { typedef mat<float, 3, 4> mat34_t; -enum FUSION_MODE{ - FUSION_9AXIS, // use accel gyro mag - FUSION_NOMAG, // use accel gyro (game rotation, gravity) - FUSION_NOGYRO, // use accel mag (geomag rotation) - NUM_FUSION_MODE -}; - class Fusion { /* * the state vector is made of two sub-vector containing respectively: @@ -62,9 +55,9 @@ class Fusion { public: Fusion(); - void init(int mode = FUSION_9AXIS); + void init(); void handleGyro(const vec3_t& w, float dT); - status_t handleAcc(const vec3_t& a, float dT); + status_t handleAcc(const vec3_t& a); status_t handleMag(const vec3_t& m); vec4_t getAttitude() const; vec3_t getBias() const; @@ -72,21 +65,12 @@ public: bool hasEstimate() const; private: - struct Parameter { - float gyroVar; - float gyroBiasVar; - float accStdev; - float magStdev; - } mParam; - mat<mat33_t, 2, 2> Phi; vec3_t Ba, Bm; uint32_t mInitState; float mGyroRate; vec<vec3_t, 3> mData; size_t mCount[3]; - int mMode; - enum { ACC=0x1, MAG=0x2, GYRO=0x4 }; bool checkInitComplete(int, const vec3_t& w, float d = 0); void initFusion(const vec4_t& q0, float dT); @@ -94,7 +78,6 @@ private: void predict(const vec3_t& w, float dT); void update(const vec3_t& z, const vec3_t& Bi, float sigma); static mat34_t getF(const vec4_t& p); - static vec3_t getOrthogonal(const vec3_t &v); }; }; // namespace android diff --git a/services/sensorservice/GravitySensor.cpp b/services/sensorservice/GravitySensor.cpp index f8279d262d..3cb3745202 100644 --- a/services/sensorservice/GravitySensor.cpp +++ b/services/sensorservice/GravitySensor.cpp @@ -47,9 +47,9 @@ bool GravitySensor::process(sensors_event_t* outEvent, const static double NS2S = 1.0 / 1000000000.0; if (event.type == SENSOR_TYPE_ACCELEROMETER) { vec3_t g; - if (!mSensorFusion.hasEstimate(FUSION_NOMAG)) + if (!mSensorFusion.hasEstimate()) return false; - const mat33_t R(mSensorFusion.getRotationMatrix(FUSION_NOMAG)); + const mat33_t R(mSensorFusion.getRotationMatrix()); // FIXME: we need to estimate the length of gravity because // the accelerometer may have a small scaling error. This // translates to an offset in the linear-acceleration sensor. @@ -67,11 +67,11 @@ bool GravitySensor::process(sensors_event_t* outEvent, } status_t GravitySensor::activate(void* ident, bool enabled) { - return mSensorFusion.activate(FUSION_NOMAG, ident, enabled); + return mSensorFusion.activate(ident, enabled); } status_t GravitySensor::setDelay(void* ident, int /*handle*/, int64_t ns) { - return mSensorFusion.setDelay(FUSION_NOMAG, ident, ns); + return mSensorFusion.setDelay(ident, ns); } Sensor GravitySensor::getSensor() const { diff --git a/services/sensorservice/OrientationSensor.cpp b/services/sensorservice/OrientationSensor.cpp index d55f336c00..6d85cca0f6 100644 --- a/services/sensorservice/OrientationSensor.cpp +++ b/services/sensorservice/OrientationSensor.cpp @@ -66,11 +66,11 @@ bool OrientationSensor::process(sensors_event_t* outEvent, } status_t OrientationSensor::activate(void* ident, bool enabled) { - return mSensorFusion.activate(FUSION_9AXIS, ident, enabled); + return mSensorFusion.activate(ident, enabled); } status_t OrientationSensor::setDelay(void* ident, int /*handle*/, int64_t ns) { - return mSensorFusion.setDelay(FUSION_9AXIS, ident, ns); + return mSensorFusion.setDelay(ident, ns); } Sensor OrientationSensor::getSensor() const { diff --git a/services/sensorservice/RotationVectorSensor.cpp b/services/sensorservice/RotationVectorSensor.cpp index 238845bd83..cb305ebf8d 100644 --- a/services/sensorservice/RotationVectorSensor.cpp +++ b/services/sensorservice/RotationVectorSensor.cpp @@ -27,10 +27,9 @@ namespace android { // --------------------------------------------------------------------------- -RotationVectorSensor::RotationVectorSensor(int mode) +RotationVectorSensor::RotationVectorSensor() : mSensorDevice(SensorDevice::getInstance()), - mSensorFusion(SensorFusion::getInstance()), - mMode(mode) + mSensorFusion(SensorFusion::getInstance()) { } @@ -38,15 +37,15 @@ bool RotationVectorSensor::process(sensors_event_t* outEvent, const sensors_event_t& event) { if (event.type == SENSOR_TYPE_ACCELEROMETER) { - if (mSensorFusion.hasEstimate(mMode)) { - const vec4_t q(mSensorFusion.getAttitude(mMode)); + if (mSensorFusion.hasEstimate()) { + const vec4_t q(mSensorFusion.getAttitude()); *outEvent = event; outEvent->data[0] = q.x; outEvent->data[1] = q.y; outEvent->data[2] = q.z; outEvent->data[3] = q.w; - outEvent->sensor = getSensorToken(); - outEvent->type = getSensorType(); + outEvent->sensor = '_rov'; + outEvent->type = SENSOR_TYPE_ROTATION_VECTOR; return true; } } @@ -54,20 +53,20 @@ bool RotationVectorSensor::process(sensors_event_t* outEvent, } status_t RotationVectorSensor::activate(void* ident, bool enabled) { - return mSensorFusion.activate(mMode, ident, enabled); + return mSensorFusion.activate(ident, enabled); } status_t RotationVectorSensor::setDelay(void* ident, int /*handle*/, int64_t ns) { - return mSensorFusion.setDelay(mMode, ident, ns); + return mSensorFusion.setDelay(ident, ns); } Sensor RotationVectorSensor::getSensor() const { sensor_t hwSensor; - hwSensor.name = getSensorName(); + hwSensor.name = "Rotation Vector Sensor"; hwSensor.vendor = "AOSP"; hwSensor.version = 3; - hwSensor.handle = getSensorToken(); - hwSensor.type = getSensorType(); + hwSensor.handle = '_rov'; + hwSensor.type = SENSOR_TYPE_ROTATION_VECTOR; hwSensor.maxRange = 1; hwSensor.resolution = 1.0f / (1<<24); hwSensor.power = mSensorFusion.getPowerUsage(); @@ -76,48 +75,6 @@ Sensor RotationVectorSensor::getSensor() const { return sensor; } -int RotationVectorSensor::getSensorType() const { - switch(mMode) { - case FUSION_9AXIS: - return SENSOR_TYPE_ROTATION_VECTOR; - case FUSION_NOMAG: - return SENSOR_TYPE_GAME_ROTATION_VECTOR; - case FUSION_NOGYRO: - return SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR; - default: - assert(0); - return 0; - } -} - -const char* RotationVectorSensor::getSensorName() const { - switch(mMode) { - case FUSION_9AXIS: - return "Rotation Vector Sensor"; - case FUSION_NOMAG: - return "Game Rotation Vector Sensor"; - case FUSION_NOGYRO: - return "GeoMag Rotation Vector Sensor"; - default: - assert(0); - return NULL; - } -} - -int RotationVectorSensor::getSensorToken() const { - switch(mMode) { - case FUSION_9AXIS: - return '_rov'; - case FUSION_NOMAG: - return '_gar'; - case FUSION_NOGYRO: - return '_geo'; - default: - assert(0); - return 0; - } -} - // --------------------------------------------------------------------------- GyroDriftSensor::GyroDriftSensor() @@ -145,11 +102,11 @@ bool GyroDriftSensor::process(sensors_event_t* outEvent, } status_t GyroDriftSensor::activate(void* ident, bool enabled) { - return mSensorFusion.activate(FUSION_9AXIS, ident, enabled); + return mSensorFusion.activate(ident, enabled); } status_t GyroDriftSensor::setDelay(void* ident, int /*handle*/, int64_t ns) { - return mSensorFusion.setDelay(FUSION_9AXIS, ident, ns); + return mSensorFusion.setDelay(ident, ns); } Sensor GyroDriftSensor::getSensor() const { diff --git a/services/sensorservice/RotationVectorSensor.h b/services/sensorservice/RotationVectorSensor.h index 1fc316be80..bb97fe189e 100644 --- a/services/sensorservice/RotationVectorSensor.h +++ b/services/sensorservice/RotationVectorSensor.h @@ -35,14 +35,9 @@ namespace android { class RotationVectorSensor : public SensorInterface { SensorDevice& mSensorDevice; SensorFusion& mSensorFusion; - int mMode; - - int getSensorType() const; - const char* getSensorName() const ; - int getSensorToken() const ; public: - RotationVectorSensor(int mode = FUSION_9AXIS); + RotationVectorSensor(); virtual bool process(sensors_event_t* outEvent, const sensors_event_t& event); virtual status_t activate(void* ident, bool enabled); @@ -51,16 +46,6 @@ public: virtual bool isVirtual() const { return true; } }; -class GameRotationVectorSensor : public RotationVectorSensor { -public: - GameRotationVectorSensor() : RotationVectorSensor(FUSION_NOMAG) {} -}; - -class GeoMagRotationVectorSensor : public RotationVectorSensor { -public: - GeoMagRotationVectorSensor() : RotationVectorSensor(FUSION_NOGYRO) {} -}; - class GyroDriftSensor : public SensorInterface { SensorDevice& mSensorDevice; SensorFusion& mSensorFusion; diff --git a/services/sensorservice/SensorFusion.cpp b/services/sensorservice/SensorFusion.cpp index 9863f62853..6d93009176 100644 --- a/services/sensorservice/SensorFusion.cpp +++ b/services/sensorservice/SensorFusion.cpp @@ -25,17 +25,11 @@ ANDROID_SINGLETON_STATIC_INSTANCE(SensorFusion) SensorFusion::SensorFusion() : mSensorDevice(SensorDevice::getInstance()), - mAttitude(mAttitudes[FUSION_9AXIS]), - mGyroTime(0), mAccTime(0) + mEnabled(false), mGyroTime(0) { sensor_t const* list; Sensor uncalibratedGyro; ssize_t count = mSensorDevice.getSensorList(&list); - - mEnabled[FUSION_9AXIS] = false; - mEnabled[FUSION_NOMAG] = false; - mEnabled[FUSION_NOGYRO] = false; - if (count > 0) { for (size_t i=0 ; i<size_t(count) ; i++) { if (list[i].type == SENSOR_TYPE_ACCELEROMETER) { @@ -61,121 +55,81 @@ SensorFusion::SensorFusion() // and power/cpu usage. mEstimatedGyroRate = 200; mTargetDelayNs = 1000000000LL/mEstimatedGyroRate; - - for (int i = 0; i<NUM_FUSION_MODE; ++i) { - mFusions[i].init(i); - } + mFusion.init(); } } void SensorFusion::process(const sensors_event_t& event) { - if (event.type == mGyro.getType()) { - float dT; - if ( event.timestamp - mGyroTime> 0 && - event.timestamp - mGyroTime< (int64_t)(5e7) ) { //0.05sec - - dT = (event.timestamp - mGyroTime) / 1000000000.0f; + if (mGyroTime != 0) { + const float dT = (event.timestamp - mGyroTime) / 1000000000.0f; + mFusion.handleGyro(vec3_t(event.data), dT); // here we estimate the gyro rate (useful for debugging) const float freq = 1 / dT; if (freq >= 100 && freq<1000) { // filter values obviously wrong const float alpha = 1 / (1 + dT); // 1s time-constant mEstimatedGyroRate = freq + (mEstimatedGyroRate - freq)*alpha; } - - const vec3_t gyro(event.data); - for (int i = 0; i<NUM_FUSION_MODE; ++i) { - if (mEnabled[i]) { - // fusion in no gyro mode will ignore - mFusions[i].handleGyro(gyro, dT); - } - } } mGyroTime = event.timestamp; } else if (event.type == SENSOR_TYPE_MAGNETIC_FIELD) { const vec3_t mag(event.data); - for (int i = 0; i<NUM_FUSION_MODE; ++i) { - if (mEnabled[i]) { - mFusions[i].handleMag(mag);// fusion in no mag mode will ignore - } - } + mFusion.handleMag(mag); } else if (event.type == SENSOR_TYPE_ACCELEROMETER) { - float dT; - if ( event.timestamp - mAccTime> 0 && - event.timestamp - mAccTime< (int64_t)(1e8) ) { //0.1sec - dT = (event.timestamp - mAccTime) / 1000000000.0f; - - const vec3_t acc(event.data); - for (int i = 0; i<NUM_FUSION_MODE; ++i) { - if (mEnabled[i]) { - mFusions[i].handleAcc(acc, dT); - mAttitudes[i] = mFusions[i].getAttitude(); - } - } - } - mAccTime = event.timestamp; + const vec3_t acc(event.data); + mFusion.handleAcc(acc); + mAttitude = mFusion.getAttitude(); } } template <typename T> inline T min(T a, T b) { return a<b ? a : b; } template <typename T> inline T max(T a, T b) { return a>b ? a : b; } -status_t SensorFusion::activate(int mode, void* ident, bool enabled) { +status_t SensorFusion::activate(void* ident, bool enabled) { ALOGD_IF(DEBUG_CONNECTIONS, - "SensorFusion::activate(mode=%d, ident=%p, enabled=%d)", - mode, ident, enabled); + "SensorFusion::activate(ident=%p, enabled=%d)", + ident, enabled); - const ssize_t idx = mClients[mode].indexOf(ident); + const ssize_t idx = mClients.indexOf(ident); if (enabled) { if (idx < 0) { - mClients[mode].add(ident); + mClients.add(ident); } } else { if (idx >= 0) { - mClients[mode].removeItemsAt(idx); + mClients.removeItemsAt(idx); } } - const bool newState = mClients[mode].size() != 0; - if (newState != mEnabled[mode]) { - mEnabled[mode] = newState; + mSensorDevice.activate(ident, mAcc.getHandle(), enabled); + mSensorDevice.activate(ident, mMag.getHandle(), enabled); + mSensorDevice.activate(ident, mGyro.getHandle(), enabled); + + const bool newState = mClients.size() != 0; + if (newState != mEnabled) { + mEnabled = newState; if (newState) { - mFusions[mode].init(mode); + mFusion.init(); + mGyroTime = 0; } } - - mSensorDevice.activate(ident, mAcc.getHandle(), enabled); - if (mode != FUSION_NOMAG) { - mSensorDevice.activate(ident, mMag.getHandle(), enabled); - } - if (mode != FUSION_NOGYRO) { - mSensorDevice.activate(ident, mGyro.getHandle(), enabled); - } - return NO_ERROR; } -status_t SensorFusion::setDelay(int mode, void* ident, int64_t ns) { +status_t SensorFusion::setDelay(void* ident, int64_t ns) { // Call batch with timeout zero instead of setDelay(). - if (ns > (int64_t)5e7) { - ns = (int64_t)(5e7); - } mSensorDevice.batch(ident, mAcc.getHandle(), 0, ns, 0); - if (mode != FUSION_NOMAG) { - mSensorDevice.batch(ident, mMag.getHandle(), 0, ms2ns(20), 0); - } - if (mode != FUSION_NOGYRO) { - mSensorDevice.batch(ident, mGyro.getHandle(), 0, mTargetDelayNs, 0); - } + mSensorDevice.batch(ident, mMag.getHandle(), 0, ms2ns(20), 0); + mSensorDevice.batch(ident, mGyro.getHandle(), 0, mTargetDelayNs, 0); return NO_ERROR; } -float SensorFusion::getPowerUsage(int mode) const { +float SensorFusion::getPowerUsage() const { float power = mAcc.getPowerUsage() + - ((mode != FUSION_NOMAG) ? mMag.getPowerUsage() : 0) + - ((mode != FUSION_NOGYRO) ? mGyro.getPowerUsage() : 0); + mMag.getPowerUsage() + + mGyro.getPowerUsage(); return power; } @@ -184,55 +138,21 @@ int32_t SensorFusion::getMinDelay() const { } void SensorFusion::dump(String8& result) { - const Fusion& fusion_9axis(mFusions[FUSION_9AXIS]); + const Fusion& fusion(mFusion); result.appendFormat("9-axis fusion %s (%zd clients), gyro-rate=%7.2fHz, " "q=< %g, %g, %g, %g > (%g), " "b=< %g, %g, %g >\n", - mEnabled[FUSION_9AXIS] ? "enabled" : "disabled", - mClients[FUSION_9AXIS].size(), - mEstimatedGyroRate, - fusion_9axis.getAttitude().x, - fusion_9axis.getAttitude().y, - fusion_9axis.getAttitude().z, - fusion_9axis.getAttitude().w, - length(fusion_9axis.getAttitude()), - fusion_9axis.getBias().x, - fusion_9axis.getBias().y, - fusion_9axis.getBias().z); - - const Fusion& fusion_nomag(mFusions[FUSION_NOMAG]); - result.appendFormat("game fusion(no mag) %s (%zd clients), " - "gyro-rate=%7.2fHz, " - "q=< %g, %g, %g, %g > (%g), " - "b=< %g, %g, %g >\n", - mEnabled[FUSION_NOMAG] ? "enabled" : "disabled", - mClients[FUSION_NOMAG].size(), - mEstimatedGyroRate, - fusion_nomag.getAttitude().x, - fusion_nomag.getAttitude().y, - fusion_nomag.getAttitude().z, - fusion_nomag.getAttitude().w, - length(fusion_nomag.getAttitude()), - fusion_nomag.getBias().x, - fusion_nomag.getBias().y, - fusion_nomag.getBias().z); - - const Fusion& fusion_nogyro(mFusions[FUSION_NOGYRO]); - result.appendFormat("geomag fusion (no gyro) %s (%zd clients), " - "gyro-rate=%7.2fHz, " - "q=< %g, %g, %g, %g > (%g), " - "b=< %g, %g, %g >\n", - mEnabled[FUSION_NOGYRO] ? "enabled" : "disabled", - mClients[FUSION_NOGYRO].size(), + mEnabled ? "enabled" : "disabled", + mClients.size(), mEstimatedGyroRate, - fusion_nogyro.getAttitude().x, - fusion_nogyro.getAttitude().y, - fusion_nogyro.getAttitude().z, - fusion_nogyro.getAttitude().w, - length(fusion_nogyro.getAttitude()), - fusion_nogyro.getBias().x, - fusion_nogyro.getBias().y, - fusion_nogyro.getBias().z); + fusion.getAttitude().x, + fusion.getAttitude().y, + fusion.getAttitude().z, + fusion.getAttitude().w, + length(fusion.getAttitude()), + fusion.getBias().x, + fusion.getBias().y, + fusion.getBias().z); } // --------------------------------------------------------------------------- diff --git a/services/sensorservice/SensorFusion.h b/services/sensorservice/SensorFusion.h index ad636d5dad..432adbcfd0 100644 --- a/services/sensorservice/SensorFusion.h +++ b/services/sensorservice/SensorFusion.h @@ -42,52 +42,30 @@ class SensorFusion : public Singleton<SensorFusion> { Sensor mAcc; Sensor mMag; Sensor mGyro; - - Fusion mFusions[NUM_FUSION_MODE]; // normal, no_mag, no_gyro - - bool mEnabled[NUM_FUSION_MODE]; - - vec4_t &mAttitude; - vec4_t mAttitudes[NUM_FUSION_MODE]; - - SortedVector<void*> mClients[3]; - + Fusion mFusion; + bool mEnabled; float mEstimatedGyroRate; nsecs_t mTargetDelayNs; - nsecs_t mGyroTime; - nsecs_t mAccTime; + vec4_t mAttitude; + SortedVector<void*> mClients; SensorFusion(); public: void process(const sensors_event_t& event); - bool isEnabled() const { - return mEnabled[FUSION_9AXIS] || - mEnabled[FUSION_NOMAG] || - mEnabled[FUSION_NOGYRO]; - } - - bool hasEstimate(int mode = FUSION_9AXIS) const { - return mFusions[mode].hasEstimate(); - } - - mat33_t getRotationMatrix(int mode = FUSION_9AXIS) const { - return mFusions[mode].getRotationMatrix(); - } - - vec4_t getAttitude(int mode = FUSION_9AXIS) const { - return mAttitudes[mode]; - } - - vec3_t getGyroBias() const { return mFusions[FUSION_9AXIS].getBias(); } + bool isEnabled() const { return mEnabled; } + bool hasEstimate() const { return mFusion.hasEstimate(); } + mat33_t getRotationMatrix() const { return mFusion.getRotationMatrix(); } + vec4_t getAttitude() const { return mAttitude; } + vec3_t getGyroBias() const { return mFusion.getBias(); } float getEstimatedRate() const { return mEstimatedGyroRate; } - status_t activate(int mode, void* ident, bool enabled); - status_t setDelay(int mode, void* ident, int64_t ns); + status_t activate(void* ident, bool enabled); + status_t setDelay(void* ident, int64_t ns); - float getPowerUsage(int mode=FUSION_9AXIS) const; + float getPowerUsage() const; int32_t getMinDelay() const; void dump(String8& result); diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index c73af3a427..2f6455847a 100755..100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -88,14 +88,11 @@ void SensorService::onFirstRef() uint32_t virtualSensorsNeeds = (1<<SENSOR_TYPE_GRAVITY) | (1<<SENSOR_TYPE_LINEAR_ACCELERATION) | - (1<<SENSOR_TYPE_ROTATION_VECTOR) | - (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR) | - (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR); + (1<<SENSOR_TYPE_ROTATION_VECTOR); mLastEventSeen.setCapacity(count); for (ssize_t i=0 ; i<count ; i++) { - bool useThisSensor=true; - + registerSensor( new HardwareSensor(list[i]) ); switch (list[i].type) { case SENSOR_TYPE_ACCELEROMETER: hasAccel = true; @@ -113,18 +110,9 @@ void SensorService::onFirstRef() case SENSOR_TYPE_GRAVITY: case SENSOR_TYPE_LINEAR_ACCELERATION: case SENSOR_TYPE_ROTATION_VECTOR: - case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR: - case SENSOR_TYPE_GAME_ROTATION_VECTOR: - if (IGNORE_HARDWARE_FUSION) { - useThisSensor = false; - } else { - virtualSensorsNeeds &= ~(1<<list[i].type); - } + virtualSensorsNeeds &= ~(1<<list[i].type); break; } - if (useThisSensor) { - registerSensor( new HardwareSensor(list[i]) ); - } } // it's safe to instantiate the SensorFusion object here @@ -136,15 +124,26 @@ void SensorService::onFirstRef() mUserSensorList = mSensorList; if (hasGyro && hasAccel && hasMag) { + Sensor aSensor; + // Add Android virtual sensors if they're not already // available in the HAL - Sensor aSensor; aSensor = registerVirtualSensor( new RotationVectorSensor() ); if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) { mUserSensorList.add(aSensor); } + aSensor = registerVirtualSensor( new GravitySensor(list, count) ); + if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) { + mUserSensorList.add(aSensor); + } + + aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) ); + if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) { + mUserSensorList.add(aSensor); + } + aSensor = registerVirtualSensor( new OrientationSensor() ); if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) { // if we are doing our own rotation-vector, also add @@ -152,46 +151,11 @@ void SensorService::onFirstRef() mUserSensorList.replaceAt(aSensor, orientationIndex); } - aSensor = registerVirtualSensor( - new LinearAccelerationSensor(list, count) ); - if (virtualSensorsNeeds & - (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) { - mUserSensorList.add(aSensor); - } - // virtual debugging sensors are not added to mUserSensorList registerVirtualSensor( new CorrectedGyroSensor(list, count) ); registerVirtualSensor( new GyroDriftSensor() ); } - if (hasAccel && hasGyro) { - Sensor aSensor; - - aSensor = registerVirtualSensor( - new GravitySensor(list, count) ); - if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) { - mUserSensorList.add(aSensor); - } - - aSensor = registerVirtualSensor( - new GameRotationVectorSensor() ); - if (virtualSensorsNeeds & - (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR)) { - mUserSensorList.add(aSensor); - } - } - - if (hasAccel && hasMag) { - Sensor aSensor; - - aSensor = registerVirtualSensor( - new GeoMagRotationVectorSensor() ); - if (virtualSensorsNeeds & - (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR)) { - mUserSensorList.add(aSensor); - } - } - // debugging sensor list mUserSensorListDebug = mSensorList; @@ -759,7 +723,14 @@ Vector<Sensor> SensorService::getSensorList(const String16& opPackageName) Vector<Sensor> accessibleSensorList; for (size_t i = 0; i < initialSensorList.size(); i++) { Sensor sensor = initialSensorList[i]; - accessibleSensorList.add(sensor); + if (canAccessSensor(sensor, "getSensorList", opPackageName)) { + accessibleSensorList.add(sensor); + } else { + ALOGI("Skipped sensor %s because it requires permission %s and app op %d", + sensor.getName().string(), + sensor.getRequiredPermission().string(), + sensor.getRequiredAppOp()); + } } return accessibleSensorList; } @@ -1655,26 +1626,21 @@ status_t SensorService::SensorEventConnection::sendEvents( reAllocateCacheLocked(scratch, count); return status_t(NO_ERROR); } - if (count >= mMaxCacheSize) { - //count is larger than MaxCacheSize, - //so copy the end MaxCacheSize data in scratch buffer to cache - countFlushCompleteEventsLocked(mEventCache, mCacheSize); - countFlushCompleteEventsLocked(scratch, count - mMaxCacheSize); - memcpy(&mEventCache[0], &scratch[count-mMaxCacheSize], - mMaxCacheSize * sizeof(sensors_event_t)); - mCacheSize = mMaxCacheSize; - } else { - //count is smaller than MaxCacheSize, so numEventsDropped data in cache - //should be dropped, then copy the scratch to the end of cache - int numEventsDropped = count + mCacheSize - mMaxCacheSize; - countFlushCompleteEventsLocked(mEventCache, numEventsDropped); - memmove(mEventCache, &mEventCache[numEventsDropped], + // Some events need to be dropped. + int remaningCacheSize = mMaxCacheSize - mCacheSize; + if (remaningCacheSize != 0) { + memcpy(&mEventCache[mCacheSize], scratch, + remaningCacheSize * sizeof(sensors_event_t)); + } + int numEventsDropped = count - remaningCacheSize; + countFlushCompleteEventsLocked(mEventCache, numEventsDropped); + // Drop the first "numEventsDropped" in the cache. + memmove(mEventCache, &mEventCache[numEventsDropped], (mCacheSize - numEventsDropped) * sizeof(sensors_event_t)); - memcpy(&mEventCache[mCacheSize - numEventsDropped], scratch, - count * sizeof(sensors_event_t)); - mCacheSize = mMaxCacheSize; - } + // Copy the remainingEvents in scratch buffer to the end of cache. + memcpy(&mEventCache[mCacheSize - numEventsDropped], scratch + remaningCacheSize, + numEventsDropped * sizeof(sensors_event_t)); } return status_t(NO_ERROR); } @@ -1693,7 +1659,6 @@ status_t SensorService::SensorEventConnection::sendEvents( reinterpret_cast<ASensorEvent const*>(scratch), count); if (size < 0) { // Write error, copy events to local cache. - ALOGE("write failed, size=%d err=%d:%s ", size, errno, strerror(errno)); if (index_wake_up_event >= 0) { // If there was a wake_up sensor_event, reset the flag. scratch[index_wake_up_event].flags &= ~WAKE_UP_SENSOR_EVENT_NEEDS_ACK; @@ -1709,21 +1674,8 @@ status_t SensorService::SensorEventConnection::sendEvents( mEventCache = new sensors_event_t[mMaxCacheSize]; mCacheSize = 0; } - //here mCacheSize must be 0 because if (mCacheSize != 0) has been executed above - if (count <= mMaxCacheSize) { - //count is no more than free size of cache, - //copy the scratch to the end of cache - memcpy(&mEventCache[0], scratch, count * sizeof(sensors_event_t)); - mCacheSize = count; - } else { - //count is larger than free size of cache, - //so just copy the free size of scratch to the end of cache - ALOGI("count > MaxCache count=%d mMaxCacheSize=%d", count, mMaxCacheSize); - countFlushCompleteEventsLocked(scratch, count - mMaxCacheSize); - memcpy(&mEventCache[0], &scratch[count - mMaxCacheSize], - mMaxCacheSize * sizeof(sensors_event_t)); - mCacheSize = mMaxCacheSize; - } + memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t)); + mCacheSize += count; // Add this file descriptor to the looper to get a callback when this fd is available for // writing. @@ -1776,7 +1728,6 @@ void SensorService::SensorEventConnection::sendPendingFlushEventsLocked() { } ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1); if (size < 0) { - ALOGE("write failed, size=%d err=%d:%s ", size, errno, strerror(errno)); if (wakeUpSensor) --mWakeLockRefCount; return; } @@ -1812,7 +1763,6 @@ void SensorService::SensorEventConnection::writeToSocketFromCache() { reinterpret_cast<ASensorEvent const*>(mEventCache + numEventsSent), numEventsToWrite); if (size < 0) { - ALOGE("write failed, size=%d err=%d:%s ", size, errno, strerror(errno)); if (index_wake_up_event >= 0) { // If there was a wake_up sensor_event, reset the flag. mEventCache[index_wake_up_event + numEventsSent].flags &= diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h index 7d81d6e104..9a573ae78c 100644 --- a/services/sensorservice/SensorService.h +++ b/services/sensorservice/SensorService.h @@ -46,7 +46,7 @@ #endif // --------------------------------------------------------------------------- -#define IGNORE_HARDWARE_FUSION false + #define DEBUG_CONNECTIONS false // Max size is 100 KB which is enough to accept a batch of about 1000 events. #define MAX_SOCKET_BUFFER_SIZE_BATCHED 100 * 1024 diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 1eb23616c3..1901ef982c 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -122,6 +122,10 @@ LOCAL_LDFLAGS := -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--e LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\" LOCAL_CPPFLAGS := -std=c++11 +ifneq ($(ENABLE_CPUSETS),) + LOCAL_CFLAGS += -DENABLE_CPUSETS +endif + LOCAL_SRC_FILES := \ main_surfaceflinger.cpp diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp index a74bc4cd91..6fa8b5317b 100644 --- a/services/surfaceflinger/main_surfaceflinger.cpp +++ b/services/surfaceflinger/main_surfaceflinger.cpp @@ -41,6 +41,13 @@ int main(int, char**) { set_sched_policy(0, SP_FOREGROUND); +#ifdef ENABLE_CPUSETS + // Put most SurfaceFlinger threads in the system-background cpuset + // Keeps us from unnecessarily using big cores + // Do this after the binder thread pool init + set_cpuset_policy(0, SP_SYSTEM); +#endif + // initialize before clients can connect flinger->init(); |