Merge "HDCP: add enums for HDCP module capabilities" into klp-dev
diff --git a/include/android/sensor.h b/include/android/sensor.h
index 32c5c0a..129ea3e 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -106,6 +106,30 @@
uint8_t reserved[3];
} ASensorVector;
+typedef struct AMetaDataEvent {
+ int32_t what;
+ int32_t sensor;
+} AMetaDataEvent;
+
+typedef struct AUncalibratedEvent {
+ union {
+ float uncalib[3];
+ struct {
+ float x_uncalib;
+ float y_uncalib;
+ float z_uncalib;
+ };
+ };
+ union {
+ float bias[3];
+ struct {
+ float x_bias;
+ float y_bias;
+ float z_bias;
+ };
+ };
+} AUncalibratedEvent;
+
/* NOTE: Must match hardware/sensors.h */
typedef struct ASensorEvent {
int32_t version; /* sizeof(struct ASensorEvent) */
@@ -123,6 +147,10 @@
float distance;
float light;
float pressure;
+ float relative_humidity;
+ AUncalibratedEvent uncalibrated_gyro;
+ AUncalibratedEvent uncalibrated_magnetic;
+ AMetaDataEvent meta_data;
};
union {
uint64_t data[8];
@@ -132,7 +160,6 @@
int32_t reserved1[4];
} ASensorEvent;
-
struct ASensorManager;
typedef struct ASensorManager ASensorManager;
diff --git a/include/gui/ISensorEventConnection.h b/include/gui/ISensorEventConnection.h
index 749065e..00eecc4 100644
--- a/include/gui/ISensorEventConnection.h
+++ b/include/gui/ISensorEventConnection.h
@@ -36,8 +36,10 @@
DECLARE_META_INTERFACE(SensorEventConnection);
virtual sp<BitTube> getSensorChannel() const = 0;
- virtual status_t enableDisable(int handle, bool enabled) = 0;
+ virtual status_t enableDisable(int handle, bool enabled, nsecs_t samplingPeriodNs,
+ nsecs_t maxBatchReportLatencyNs, int reservedFlags) = 0;
virtual status_t setEventRate(int handle, nsecs_t ns) = 0;
+ virtual status_t flushSensor(int handle) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/gui/Sensor.h b/include/gui/Sensor.h
index 9197372..0c81426 100644
--- a/include/gui/Sensor.h
+++ b/include/gui/Sensor.h
@@ -53,7 +53,7 @@
};
Sensor();
- Sensor(struct sensor_t const* hwSensor);
+ Sensor(struct sensor_t const* hwSensor, int halVersion = 0);
~Sensor();
const String8& getName() const;
@@ -67,6 +67,8 @@
int32_t getMinDelay() const;
nsecs_t getMinDelayNs() const;
int32_t getVersion() const;
+ int32_t getFifoReservedEventCount() const;
+ int32_t getFifoMaxEventCount() const;
// LightFlattenable protocol
inline bool isFixedSize() const { return false; }
@@ -85,6 +87,8 @@
float mPower;
int32_t mMinDelay;
int32_t mVersion;
+ int32_t mFifoReservedEventCount;
+ int32_t mFifoMaxEventCount;
};
// ----------------------------------------------------------------------------
diff --git a/include/gui/SensorEventQueue.h b/include/gui/SensorEventQueue.h
index 759b5cb..8d8493b 100644
--- a/include/gui/SensorEventQueue.h
+++ b/include/gui/SensorEventQueue.h
@@ -68,8 +68,10 @@
status_t setEventRate(Sensor const* sensor, nsecs_t ns) const;
// these are here only to support SensorManager.java
- status_t enableSensor(int32_t handle, int32_t us) const;
+ status_t enableSensor(int32_t handle, int32_t samplingPeriodUs, int maxBatchReportLatencyUs,
+ int reservedFlags) const;
status_t disableSensor(int32_t handle) const;
+ status_t flushSensor(int32_t handle) const;
private:
sp<Looper> getLooper() const;
diff --git a/include/ui/TMatHelpers.h b/include/ui/TMatHelpers.h
index b778af0..cead10a 100644
--- a/include/ui/TMatHelpers.h
+++ b/include/ui/TMatHelpers.h
@@ -26,6 +26,7 @@
#include <stdint.h>
#include <sys/types.h>
+#include <math.h>
#include <utils/Debug.h>
#include <utils/String8.h>
@@ -172,6 +173,83 @@
}; // namespace matrix
// -------------------------------------------------------------------------------------
+
+/*
+ * TMatProductOperators implements basic arithmetic and basic compound assignments
+ * operators on a vector of type BASE<T>.
+ *
+ * BASE only needs to implement operator[] and size().
+ * By simply inheriting from TMatProductOperators<BASE, T> BASE will automatically
+ * get all the functionality here.
+ */
+
+template <template<typename T> class BASE, typename T>
+class TMatProductOperators {
+public:
+ // multiply by a scalar
+ BASE<T>& operator *= (T v) {
+ BASE<T>& lhs(static_cast< BASE<T>& >(*this));
+ for (size_t r=0 ; r<lhs.row_size() ; r++) {
+ lhs[r] *= v;
+ }
+ return lhs;
+ }
+
+ // divide by a scalar
+ BASE<T>& operator /= (T v) {
+ BASE<T>& lhs(static_cast< BASE<T>& >(*this));
+ for (size_t r=0 ; r<lhs.row_size() ; r++) {
+ lhs[r] /= v;
+ }
+ return lhs;
+ }
+
+ // matrix * matrix, result is a matrix of the same type than the lhs matrix
+ template<typename U>
+ friend BASE<T> PURE operator *(const BASE<T>& lhs, const BASE<U>& rhs) {
+ return matrix::multiply<BASE<T> >(lhs, rhs);
+ }
+};
+
+
+/*
+ * TMatSquareFunctions implements functions on a matrix of type BASE<T>.
+ *
+ * BASE only needs to implement:
+ * - operator[]
+ * - col_type
+ * - row_type
+ * - COL_SIZE
+ * - ROW_SIZE
+ *
+ * By simply inheriting from TMatSquareFunctions<BASE, T> BASE will automatically
+ * get all the functionality here.
+ */
+
+template<template<typename U> class BASE, typename T>
+class TMatSquareFunctions {
+public:
+ /*
+ * NOTE: the functions below ARE NOT member methods. They are friend functions
+ * with they definition inlined with their declaration. This makes these
+ * template functions available to the compiler when (and only when) this class
+ * is instantiated, at which point they're only templated on the 2nd parameter
+ * (the first one, BASE<T> being known).
+ */
+ friend BASE<T> PURE inverse(const BASE<T>& m) { return matrix::inverse(m); }
+ friend BASE<T> PURE transpose(const BASE<T>& m) { return matrix::transpose(m); }
+ friend T PURE trace(const BASE<T>& m) { return matrix::trace(m); }
+};
+
+template <template<typename T> class BASE, typename T>
+class TMatDebug {
+public:
+ String8 asString() const {
+ return matrix::asString(*this);
+ }
+};
+
+// -------------------------------------------------------------------------------------
}; // namespace android
#undef PURE
diff --git a/include/ui/TVecHelpers.h b/include/ui/TVecHelpers.h
index 081c69c..bb7dbfc 100644
--- a/include/ui/TVecHelpers.h
+++ b/include/ui/TVecHelpers.h
@@ -57,16 +57,16 @@
};
/*
- * TVecArithmeticOperators implements basic arithmetic and basic compound assignments
+ * TVec{Add|Product}Operators implements basic arithmetic and basic compound assignments
* operators on a vector of type BASE<T>.
*
* BASE only needs to implement operator[] and size().
- * By simply inheriting from TVecArithmeticOperators<BASE, T> BASE will automatically
+ * By simply inheriting from TVec{Add|Product}Operators<BASE, T> BASE will automatically
* get all the functionality here.
*/
template <template<typename T> class BASE, typename T>
-class TVecArithmeticOperators {
+class TVecAddOperators {
public:
/* compound assignment from a another vector of the same size but different
* element type.
@@ -87,22 +87,6 @@
}
return rhs;
}
- template <typename OTHER>
- BASE<T>& operator *= (const BASE<OTHER>& v) {
- BASE<T>& rhs = static_cast<BASE<T>&>(*this);
- for (size_t i=0 ; i<BASE<T>::size() ; i++) {
- rhs[i] *= v[i];
- }
- return rhs;
- }
- template <typename OTHER>
- BASE<T>& operator /= (const BASE<OTHER>& v) {
- BASE<T>& rhs = static_cast<BASE<T>&>(*this);
- for (size_t i=0 ; i<BASE<T>::size() ; i++) {
- rhs[i] /= v[i];
- }
- return rhs;
- }
/* compound assignment from a another vector of the same type.
* These operators can be used for implicit conversion and handle operations
@@ -123,6 +107,73 @@
}
return rhs;
}
+
+ /*
+ * NOTE: the functions below ARE NOT member methods. They are friend functions
+ * with they definition inlined with their declaration. This makes these
+ * template functions available to the compiler when (and only when) this class
+ * is instantiated, at which point they're only templated on the 2nd parameter
+ * (the first one, BASE<T> being known).
+ */
+
+ /* The operators below handle operation between vectors of the same side
+ * but of a different element type.
+ */
+ template<typename RT>
+ friend inline
+ BASE<T> PURE operator +(const BASE<T>& lv, const BASE<RT>& rv) {
+ return BASE<T>(lv) += rv;
+ }
+ template<typename RT>
+ friend inline
+ BASE<T> PURE operator -(const BASE<T>& lv, const BASE<RT>& rv) {
+ return BASE<T>(lv) -= rv;
+ }
+
+ /* The operators below (which are not templates once this class is instanced,
+ * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
+ * These handle operations like "vector * scalar" and "scalar * vector" by
+ * letting the compiler implicitly convert a scalar to a vector (assuming
+ * the BASE<T> allows it).
+ */
+ friend inline
+ BASE<T> PURE operator +(const BASE<T>& lv, const BASE<T>& rv) {
+ return BASE<T>(lv) += rv;
+ }
+ friend inline
+ BASE<T> PURE operator -(const BASE<T>& lv, const BASE<T>& rv) {
+ return BASE<T>(lv) -= rv;
+ }
+};
+
+template <template<typename T> class BASE, typename T>
+class TVecProductOperators {
+public:
+ /* compound assignment from a another vector of the same size but different
+ * element type.
+ */
+ template <typename OTHER>
+ BASE<T>& operator *= (const BASE<OTHER>& v) {
+ BASE<T>& rhs = static_cast<BASE<T>&>(*this);
+ for (size_t i=0 ; i<BASE<T>::size() ; i++) {
+ rhs[i] *= v[i];
+ }
+ return rhs;
+ }
+ template <typename OTHER>
+ BASE<T>& operator /= (const BASE<OTHER>& v) {
+ BASE<T>& rhs = static_cast<BASE<T>&>(*this);
+ for (size_t i=0 ; i<BASE<T>::size() ; i++) {
+ rhs[i] /= v[i];
+ }
+ return rhs;
+ }
+
+ /* compound assignment from a another vector of the same type.
+ * These operators can be used for implicit conversion and handle operations
+ * like "vector *= scalar" by letting the compiler implicitly convert a scalar
+ * to a vector (assuming the BASE<T> allows it).
+ */
BASE<T>& operator *= (const BASE<T>& v) {
BASE<T>& rhs = static_cast<BASE<T>&>(*this);
for (size_t i=0 ; i<BASE<T>::size() ; i++) {
@@ -151,16 +202,6 @@
*/
template<typename RT>
friend inline
- BASE<T> PURE operator +(const BASE<T>& lv, const BASE<RT>& rv) {
- return BASE<T>(lv) += rv;
- }
- template<typename RT>
- friend inline
- BASE<T> PURE operator -(const BASE<T>& lv, const BASE<RT>& rv) {
- return BASE<T>(lv) -= rv;
- }
- template<typename RT>
- friend inline
BASE<T> PURE operator *(const BASE<T>& lv, const BASE<RT>& rv) {
return BASE<T>(lv) *= rv;
}
@@ -177,14 +218,6 @@
* the BASE<T> allows it).
*/
friend inline
- BASE<T> PURE operator +(const BASE<T>& lv, const BASE<T>& rv) {
- return BASE<T>(lv) += rv;
- }
- friend inline
- BASE<T> PURE operator -(const BASE<T>& lv, const BASE<T>& rv) {
- return BASE<T>(lv) -= rv;
- }
- friend inline
BASE<T> PURE operator *(const BASE<T>& lv, const BASE<T>& rv) {
return BASE<T>(lv) *= rv;
}
diff --git a/include/ui/mat4.h b/include/ui/mat4.h
index 08a67c7..d9647cc 100644
--- a/include/ui/mat4.h
+++ b/include/ui/mat4.h
@@ -33,7 +33,11 @@
template <typename T>
class tmat44 : public TVecUnaryOperators<tmat44, T>,
- public TVecComparisonOperators<tmat44, T>
+ public TVecComparisonOperators<tmat44, T>,
+ public TVecAddOperators<tmat44, T>,
+ public TMatProductOperators<tmat44, T>,
+ public TMatSquareFunctions<tmat44, T>,
+ public TMatDebug<tmat44, T>
{
public:
enum no_init { NO_INIT };
@@ -108,6 +112,17 @@
template <typename A, typename B, typename C, typename D>
tmat44(const tvec4<A>& v0, const tvec4<B>& v1, const tvec4<C>& v2, const tvec4<D>& v3);
+ // construct from 16 scalars
+ template <
+ typename A, typename B, typename C, typename D,
+ typename E, typename F, typename G, typename H,
+ typename I, typename J, typename K, typename L,
+ typename M, typename N, typename O, typename P>
+ tmat44( A m00, B m01, C m02, D m03,
+ E m10, F m11, G m12, H m13,
+ I m20, J m21, K m22, L m23,
+ M m30, N m31, O m32, P m33);
+
// construct from a C array
template <typename U>
explicit tmat44(U const* rawArray);
@@ -131,33 +146,6 @@
template <typename A, typename B>
static tmat44 rotate(A radian, const tvec3<B>& about);
-
-
- /*
- * Compound assignment arithmetic operators
- */
-
- // add another matrix of the same size
- template <typename U>
- tmat44& operator += (const tmat44<U>& v);
-
- // subtract another matrix of the same size
- template <typename U>
- tmat44& operator -= (const tmat44<U>& v);
-
- // multiply by a scalar
- template <typename U>
- tmat44& operator *= (U v);
-
- // divide by a scalar
- template <typename U>
- tmat44& operator /= (U v);
-
- /*
- * debugging
- */
-
- String8 asString() const;
};
// ----------------------------------------------------------------------------------------
@@ -195,6 +183,23 @@
mValue[3] = col_type(0,0,0,v.w);
}
+// construct from 16 scalars
+template<typename T>
+template <
+ typename A, typename B, typename C, typename D,
+ typename E, typename F, typename G, typename H,
+ typename I, typename J, typename K, typename L,
+ typename M, typename N, typename O, typename P>
+tmat44<T>::tmat44( A m00, B m01, C m02, D m03,
+ E m10, F m11, G m12, H m13,
+ I m20, J m21, K m22, L m23,
+ M m30, N m31, O m32, P m33) {
+ mValue[0] = col_type(m00, m01, m02, m03);
+ mValue[1] = col_type(m10, m11, m12, m13);
+ mValue[2] = col_type(m20, m21, m22, m23);
+ mValue[3] = col_type(m30, m31, m32, m33);
+}
+
template <typename T>
template <typename U>
tmat44<T>::tmat44(const tmat44<U>& rhs) {
@@ -320,42 +325,6 @@
}
// ----------------------------------------------------------------------------------------
-// Compound assignment arithmetic operators
-// ----------------------------------------------------------------------------------------
-
-template <typename T>
-template <typename U>
-tmat44<T>& tmat44<T>::operator += (const tmat44<U>& v) {
- for (size_t r=0 ; r<row_size() ; r++)
- mValue[r] += v[r];
- return *this;
-}
-
-template <typename T>
-template <typename U>
-tmat44<T>& tmat44<T>::operator -= (const tmat44<U>& v) {
- for (size_t r=0 ; r<row_size() ; r++)
- mValue[r] -= v[r];
- return *this;
-}
-
-template <typename T>
-template <typename U>
-tmat44<T>& tmat44<T>::operator *= (U v) {
- for (size_t r=0 ; r<row_size() ; r++)
- mValue[r] *= v;
- return *this;
-}
-
-template <typename T>
-template <typename U>
-tmat44<T>& tmat44<T>::operator /= (U v) {
- for (size_t r=0 ; r<row_size() ; r++)
- mValue[r] /= v;
- return *this;
-}
-
-// ----------------------------------------------------------------------------------------
// Arithmetic operators outside of class
// ----------------------------------------------------------------------------------------
@@ -367,24 +336,6 @@
* it determines the output type (only relevant when T != U).
*/
-// matrix + matrix, result is a matrix of the same type than the lhs matrix
-template <typename T, typename U>
-tmat44<T> PURE operator +(const tmat44<T>& lhs, const tmat44<U>& rhs) {
- tmat44<T> result(tmat44<T>::NO_INIT);
- for (size_t r=0 ; r<tmat44<T>::row_size() ; r++)
- result[r] = lhs[r] + rhs[r];
- return result;
-}
-
-// matrix - matrix, result is a matrix of the same type than the lhs matrix
-template <typename T, typename U>
-tmat44<T> PURE operator -(const tmat44<T>& lhs, const tmat44<U>& rhs) {
- tmat44<T> result(tmat44<T>::NO_INIT);
- for (size_t r=0 ; r<tmat44<T>::row_size() ; r++)
- result[r] = lhs[r] - rhs[r];
- return result;
-}
-
// matrix * vector, result is a vector of the same type than the input vector
template <typename T, typename U>
typename tmat44<U>::col_type PURE operator *(const tmat44<T>& lv, const tvec4<U>& rv) {
@@ -421,47 +372,17 @@
return result;
}
-// matrix * matrix, result is a matrix of the same type than the lhs matrix
-template <typename T, typename U>
-tmat44<T> PURE operator *(const tmat44<T>& lhs, const tmat44<U>& rhs) {
- return matrix::multiply< tmat44<T> >(lhs, rhs);
-}
-
-// ----------------------------------------------------------------------------------------
-// Functions
// ----------------------------------------------------------------------------------------
-// inverse a matrix
-template <typename T>
-tmat44<T> PURE inverse(const tmat44<T>& m) {
- return matrix::inverse(m);
-}
-
-template <typename T>
-tmat44<T> PURE transpose(const tmat44<T>& m) {
- return matrix::transpose(m);
-}
-
-template <typename T>
-T PURE trace(const tmat44<T>& m) {
- return matrix::trace(m);
-}
-
-template <typename T>
-tvec4<T> PURE diag(const tmat44<T>& m) {
+/* FIXME: this should go into TMatSquareFunctions<> but for some reason
+ * BASE<T>::col_type is not accessible from there (???)
+ */
+template<typename T>
+typename tmat44<T>::col_type PURE diag(const tmat44<T>& m) {
return matrix::diag(m);
}
// ----------------------------------------------------------------------------------------
-// Debugging
-// ----------------------------------------------------------------------------------------
-
-template <typename T>
-String8 tmat44<T>::asString() const {
- return matrix::asString(*this);
-}
-
-// ----------------------------------------------------------------------------------------
typedef tmat44<float> mat4;
diff --git a/include/ui/vec2.h b/include/ui/vec2.h
index b4edfc6..c31d0e4 100644
--- a/include/ui/vec2.h
+++ b/include/ui/vec2.h
@@ -27,7 +27,8 @@
// -------------------------------------------------------------------------------------
template <typename T>
-class tvec2 : public TVecArithmeticOperators<tvec2, T>,
+class tvec2 : public TVecProductOperators<tvec2, T>,
+ public TVecAddOperators<tvec2, T>,
public TVecUnaryOperators<tvec2, T>,
public TVecComparisonOperators<tvec2, T>,
public TVecFunctions<tvec2, T>
@@ -73,6 +74,11 @@
template<typename A>
explicit tvec2(const tvec2<A>& v) : x(v.x), y(v.y) { }
+
+ template<typename A>
+ tvec2(const Impersonator< tvec2<A> >& v)
+ : x(((const tvec2<A>&)v).x),
+ y(((const tvec2<A>&)v).y) { }
};
// ----------------------------------------------------------------------------------------
diff --git a/include/ui/vec3.h b/include/ui/vec3.h
index 591b8b2..dde59a9 100644
--- a/include/ui/vec3.h
+++ b/include/ui/vec3.h
@@ -26,7 +26,8 @@
// -------------------------------------------------------------------------------------
template <typename T>
-class tvec3 : public TVecArithmeticOperators<tvec3, T>,
+class tvec3 : public TVecProductOperators<tvec3, T>,
+ public TVecAddOperators<tvec3, T>,
public TVecUnaryOperators<tvec3, T>,
public TVecComparisonOperators<tvec3, T>,
public TVecFunctions<tvec3, T>
@@ -78,6 +79,12 @@
template<typename A>
explicit tvec3(const tvec3<A>& v) : x(v.x), y(v.y), z(v.z) { }
+ template<typename A>
+ tvec3(const Impersonator< tvec3<A> >& v)
+ : x(((const tvec3<A>&)v).x),
+ y(((const tvec3<A>&)v).y),
+ z(((const tvec3<A>&)v).z) { }
+
template<typename A, typename B>
tvec3(const Impersonator< tvec2<A> >& v, B z)
: x(((const tvec2<A>&)v).x),
diff --git a/include/ui/vec4.h b/include/ui/vec4.h
index 798382d..e03d331 100644
--- a/include/ui/vec4.h
+++ b/include/ui/vec4.h
@@ -26,7 +26,8 @@
// -------------------------------------------------------------------------------------
template <typename T>
-class tvec4 : public TVecArithmeticOperators<tvec4, T>,
+class tvec4 : public TVecProductOperators<tvec4, T>,
+ public TVecAddOperators<tvec4, T>,
public TVecUnaryOperators<tvec4, T>,
public TVecComparisonOperators<tvec4, T>,
public TVecFunctions<tvec4, T>
@@ -85,6 +86,13 @@
template<typename A>
explicit tvec4(const tvec4<A>& v) : x(v.x), y(v.y), z(v.z), w(v.w) { }
+ template<typename A>
+ tvec4(const Impersonator< tvec4<A> >& v)
+ : x(((const tvec4<A>&)v).x),
+ y(((const tvec4<A>&)v).y),
+ z(((const tvec4<A>&)v).z),
+ w(((const tvec4<A>&)v).w) { }
+
template<typename A, typename B>
tvec4(const Impersonator< tvec3<A> >& v, B w)
: x(((const tvec3<A>&)v).x),
diff --git a/libs/gui/ISensorEventConnection.cpp b/libs/gui/ISensorEventConnection.cpp
index 0e51e8e..a80c661 100644
--- a/libs/gui/ISensorEventConnection.cpp
+++ b/libs/gui/ISensorEventConnection.cpp
@@ -33,7 +33,8 @@
enum {
GET_SENSOR_CHANNEL = IBinder::FIRST_CALL_TRANSACTION,
ENABLE_DISABLE,
- SET_EVENT_RATE
+ SET_EVENT_RATE,
+ FLUSH_SENSOR
};
class BpSensorEventConnection : public BpInterface<ISensorEventConnection>
@@ -52,12 +53,16 @@
return new BitTube(reply);
}
- virtual status_t enableDisable(int handle, bool enabled)
+ virtual status_t enableDisable(int handle, bool enabled, nsecs_t samplingPeriodNs,
+ nsecs_t maxBatchReportLatencyNs, int reservedFlags)
{
Parcel data, reply;
data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
data.writeInt32(handle);
data.writeInt32(enabled);
+ data.writeInt64(samplingPeriodNs);
+ data.writeInt64(maxBatchReportLatencyNs);
+ data.writeInt32(reservedFlags);
remote()->transact(ENABLE_DISABLE, data, &reply);
return reply.readInt32();
}
@@ -71,6 +76,14 @@
remote()->transact(SET_EVENT_RATE, data, &reply);
return reply.readInt32();
}
+
+ virtual status_t flushSensor(int handle) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
+ data.writeInt32(handle);
+ remote()->transact(FLUSH_SENSOR, data, &reply);
+ return reply.readInt32();
+ }
};
IMPLEMENT_META_INTERFACE(SensorEventConnection, "android.gui.SensorEventConnection");
@@ -91,7 +104,11 @@
CHECK_INTERFACE(ISensorEventConnection, data, reply);
int handle = data.readInt32();
int enabled = data.readInt32();
- status_t result = enableDisable(handle, enabled);
+ nsecs_t samplingPeriodNs = data.readInt64();
+ nsecs_t maxBatchReportLatencyNs = data.readInt64();
+ int reservedFlags = data.readInt32();
+ status_t result = enableDisable(handle, enabled, samplingPeriodNs,
+ maxBatchReportLatencyNs, reservedFlags);
reply->writeInt32(result);
return NO_ERROR;
} break;
@@ -103,6 +120,13 @@
reply->writeInt32(result);
return NO_ERROR;
} break;
+ case FLUSH_SENSOR: {
+ CHECK_INTERFACE(ISensorEventConnection, data, reply);
+ int handle = data.readInt32();
+ status_t result = flushSensor(handle);
+ reply->writeInt32(result);
+ return NO_ERROR;
+ } break;
}
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index d84c370..da6b0f9 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -32,11 +32,11 @@
Sensor::Sensor()
: mHandle(0), mType(0),
mMinValue(0), mMaxValue(0), mResolution(0),
- mPower(0), mMinDelay(0)
+ mPower(0), mMinDelay(0), mFifoReservedEventCount(0), mFifoMaxEventCount(0)
{
}
-Sensor::Sensor(struct sensor_t const* hwSensor)
+Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
{
mName = hwSensor->name;
mVendor = hwSensor->vendor;
@@ -48,6 +48,15 @@
mResolution = hwSensor->resolution;
mPower = hwSensor->power;
mMinDelay = hwSensor->minDelay;
+ // Set fifo event count zero for older devices which do not support batching. Fused
+ // sensors also have their fifo counts set to zero.
+ if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
+ mFifoReservedEventCount = hwSensor->fifoReservedEventCount;
+ mFifoMaxEventCount = hwSensor->fifoMaxEventCount;
+ } else {
+ mFifoReservedEventCount = 0;
+ mFifoMaxEventCount = 0;
+ }
}
Sensor::~Sensor()
@@ -98,12 +107,20 @@
return mVersion;
}
+int32_t Sensor::getFifoReservedEventCount() const {
+ return mFifoReservedEventCount;
+}
+
+int32_t Sensor::getFifoMaxEventCount() const {
+ return mFifoMaxEventCount;
+}
+
size_t Sensor::getFlattenedSize() const
{
size_t fixedSize =
sizeof(int32_t) * 3 +
sizeof(float) * 4 +
- sizeof(int32_t);
+ sizeof(int32_t) * 3;
size_t variableSize =
sizeof(int32_t) + FlattenableUtils::align<4>(mName.length()) +
@@ -133,6 +150,8 @@
FlattenableUtils::write(buffer, size, mResolution);
FlattenableUtils::write(buffer, size, mPower);
FlattenableUtils::write(buffer, size, mMinDelay);
+ FlattenableUtils::write(buffer, size, mFifoReservedEventCount);
+ FlattenableUtils::write(buffer, size, mFifoMaxEventCount);
return NO_ERROR;
}
@@ -163,7 +182,7 @@
size_t fixedSize =
sizeof(int32_t) * 3 +
sizeof(float) * 4 +
- sizeof(int32_t);
+ sizeof(int32_t) * 3;
if (size < fixedSize) {
return NO_MEMORY;
@@ -177,6 +196,8 @@
FlattenableUtils::read(buffer, size, mResolution);
FlattenableUtils::read(buffer, size, mPower);
FlattenableUtils::read(buffer, size, mMinDelay);
+ FlattenableUtils::read(buffer, size, mFifoReservedEventCount);
+ FlattenableUtils::read(buffer, size, mFifoMaxEventCount);
return NO_ERROR;
}
diff --git a/libs/gui/SensorEventQueue.cpp b/libs/gui/SensorEventQueue.cpp
index 8a1bf41..08b8ac8 100644
--- a/libs/gui/SensorEventQueue.cpp
+++ b/libs/gui/SensorEventQueue.cpp
@@ -107,23 +107,25 @@
}
status_t SensorEventQueue::enableSensor(Sensor const* sensor) const {
- return mSensorEventConnection->enableDisable(sensor->getHandle(), true);
+ return mSensorEventConnection->enableDisable(sensor->getHandle(), true, 0, 0, false);
}
status_t SensorEventQueue::disableSensor(Sensor const* sensor) const {
- return mSensorEventConnection->enableDisable(sensor->getHandle(), false);
+ return mSensorEventConnection->enableDisable(sensor->getHandle(), false, 0, 0, false);
}
-status_t SensorEventQueue::enableSensor(int32_t handle, int32_t us) const {
- status_t err = mSensorEventConnection->enableDisable(handle, true);
- if (err == NO_ERROR) {
- mSensorEventConnection->setEventRate(handle, us2ns(us));
- }
- return err;
+status_t SensorEventQueue::enableSensor(int32_t handle, int32_t samplingPeriodUs,
+ int maxBatchReportLatencyUs, int reservedFlags) const {
+ return mSensorEventConnection->enableDisable(handle, true, us2ns(samplingPeriodUs),
+ us2ns(maxBatchReportLatencyUs), reservedFlags);
+}
+
+status_t SensorEventQueue::flushSensor(int32_t handle) const {
+ return mSensorEventConnection->flushSensor(handle);
}
status_t SensorEventQueue::disableSensor(int32_t handle) const {
- return mSensorEventConnection->enableDisable(handle, false);
+ return mSensorEventConnection->enableDisable(handle, false, 0, 0, false);
}
status_t SensorEventQueue::setEventRate(Sensor const* sensor, nsecs_t ns) const {
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 2fa5dbd..19caa5c 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -47,7 +47,7 @@
SENSORS_HARDWARE_MODULE_ID, strerror(-err));
if (mSensorModule) {
- err = sensors_open(&mSensorModule->common, &mSensorDevice);
+ err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
ALOGE_IF(err, "couldn't open device for module %s (%s)",
SENSORS_HARDWARE_MODULE_ID, strerror(-err));
@@ -59,7 +59,9 @@
Info model;
for (size_t i=0 ; i<size_t(count) ; i++) {
mActivationCount.add(list[i].handle, model);
- mSensorDevice->activate(mSensorDevice, list[i].handle, 0);
+ mSensorDevice->activate(
+ reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
+ list[i].handle, 0);
}
}
}
@@ -76,15 +78,23 @@
Mutex::Autolock _l(mLock);
for (size_t i=0 ; i<size_t(count) ; i++) {
const Info& info = mActivationCount.valueFor(list[i].handle);
- result.appendFormat("handle=0x%08x, active-count=%d, rates(ms)={ ",
- list[i].handle,
- info.rates.size());
- for (size_t j=0 ; j<info.rates.size() ; j++) {
- result.appendFormat("%4.1f%s",
- info.rates.valueAt(j) / 1e6f,
- j<info.rates.size()-1 ? ", " : "");
+ result.appendFormat("handle=0x%08x, active-count=%d, batch_period(ms)={ ", list[i].handle,
+ info.batchParams.size());
+ for (size_t j = 0; j < info.batchParams.size(); j++) {
+ BatchParams params = info.batchParams.valueAt(j);
+ result.appendFormat("%4.1f%s", params.batchDelay / 1e6f,
+ j < info.batchParams.size() - 1 ? ", " : "");
}
- result.appendFormat(" }, selected=%4.1f ms\n", info.delay / 1e6f);
+ result.appendFormat(" }, selected=%4.1f ms\n", info.bestBatchParams.batchDelay / 1e6f);
+
+ result.appendFormat("handle=0x%08x, active-count=%d, batch_timeout(ms)={ ", list[i].handle,
+ info.batchParams.size());
+ for (size_t j = 0; j < info.batchParams.size(); j++) {
+ BatchParams params = info.batchParams.valueAt(j);
+ result.appendFormat("%4.1f%s", params.batchTimeout / 1e6f,
+ j < info.batchParams.size() - 1 ? ", " : "");
+ }
+ result.appendFormat(" }, selected=%4.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f);
}
}
@@ -102,7 +112,8 @@
if (!mSensorDevice) return NO_INIT;
ssize_t c;
do {
- c = mSensorDevice->poll(mSensorDevice, buffer, count);
+ c = mSensorDevice->poll(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
+ buffer, count);
} while (c == -EINTR);
return c;
}
@@ -110,7 +121,7 @@
void SensorDevice::autoDisable(void *ident, int handle) {
Info& info( mActivationCount.editValueFor(handle) );
Mutex::Autolock _l(mLock);
- info.rates.removeItem(ident);
+ info.removeBatchParamsForIdent(ident);
}
status_t SensorDevice::activate(void* ident, int handle, int enabled)
@@ -119,35 +130,46 @@
status_t err(NO_ERROR);
bool actuateHardware = false;
+ Mutex::Autolock _l(mLock);
Info& info( mActivationCount.editValueFor(handle) );
-
ALOGD_IF(DEBUG_CONNECTIONS,
- "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d",
- ident, handle, enabled, info.rates.size());
+ "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d",
+ ident, handle, enabled, info.batchParams.size());
if (enabled) {
- Mutex::Autolock _l(mLock);
- ALOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",
- info.rates.indexOfKey(ident));
+ ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%d", info.batchParams.indexOfKey(ident));
- if (info.rates.indexOfKey(ident) < 0) {
- info.rates.add(ident, DEFAULT_EVENTS_PERIOD);
- if (info.rates.size() == 1) {
- actuateHardware = true;
- }
+ if (info.batchParams.indexOfKey(ident) >= 0) {
+ if (info.batchParams.size() == 1) {
+ // This is the first connection, we need to activate the underlying h/w sensor.
+ actuateHardware = true;
+ }
} else {
- // sensor was already activated for this ident
+ // Log error. Every activate call should be preceded by a batch() call.
+ ALOGE("\t >>>ERROR: activate called without batch");
}
} else {
- Mutex::Autolock _l(mLock);
- ALOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",
- info.rates.indexOfKey(ident));
+ ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%d", info.batchParams.indexOfKey(ident));
- ssize_t idx = info.rates.removeItem(ident);
- if (idx >= 0) {
- if (info.rates.size() == 0) {
+ if (info.removeBatchParamsForIdent(ident) >= 0) {
+ if (info.batchParams.size() == 0) {
+ // This is the last connection, we need to de-activate the underlying h/w sensor.
actuateHardware = true;
+ } else {
+ const int halVersion = getHalDeviceVersion();
+ if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
+ // Call batch for this sensor with the previously calculated best effort
+ // batch_rate and timeout. One of the apps has unregistered for sensor
+ // events, and the best effort batch parameters might have changed.
+ ALOGD_IF(DEBUG_CONNECTIONS,
+ "\t>>> actuating h/w batch %d %d %lld %lld ", handle,
+ info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
+ info.bestBatchParams.batchTimeout);
+ mSensorDevice->batch(mSensorDevice, handle,info.bestBatchParams.flags,
+ info.bestBatchParams.batchDelay,
+ info.bestBatchParams.batchTimeout);
+ }
}
} else {
// sensor wasn't enabled for this ident
@@ -155,41 +177,130 @@
}
if (actuateHardware) {
- ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w");
+ ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle, enabled);
+ err = mSensorDevice->activate(
+ reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled);
+ ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
+ strerror(-err));
- err = mSensorDevice->activate(mSensorDevice, handle, enabled);
- ALOGE_IF(err, "Error %s sensor %d (%s)",
- enabled ? "activating" : "disabling",
- handle, strerror(-err));
-
- if (err != NO_ERROR) {
- // clean-up on failure
- if (enabled) {
- // failure when enabling the sensor
- Mutex::Autolock _l(mLock);
- info.rates.removeItem(ident);
- }
+ if (err != NO_ERROR && enabled) {
+ // Failure when enabling the sensor. Clean up on failure.
+ info.removeBatchParamsForIdent(ident);
}
}
- { // scope for the lock
- Mutex::Autolock _l(mLock);
- nsecs_t ns = info.selectDelay();
- mSensorDevice->setDelay(mSensorDevice, handle, ns);
+ // On older devices which do not support batch, call setDelay().
+ if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.batchParams.size() > 0) {
+ ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %lld ", handle,
+ info.bestBatchParams.batchDelay);
+ mSensorDevice->setDelay(
+ reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
+ handle, info.bestBatchParams.batchDelay);
}
-
return err;
}
-status_t SensorDevice::setDelay(void* ident, int handle, int64_t ns)
+status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
+ int64_t maxBatchReportLatencyNs) {
+ if (!mSensorDevice) return NO_INIT;
+
+ if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
+ samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
+ }
+
+ const int halVersion = getHalDeviceVersion();
+ if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
+ if (flags & SENSORS_BATCH_DRY_RUN) {
+ return mSensorDevice->batch(mSensorDevice, handle, flags, samplingPeriodNs,
+ maxBatchReportLatencyNs);
+ } else {
+ // Call h/w with dry run to see if the given parameters are feasible or not. Return if
+ // there is an error.
+ status_t errDryRun(NO_ERROR);
+ errDryRun = mSensorDevice->batch(mSensorDevice, handle, flags | SENSORS_BATCH_DRY_RUN,
+ samplingPeriodNs, maxBatchReportLatencyNs);
+ if (errDryRun != NO_ERROR) {
+ ALOGD_IF(DEBUG_CONNECTIONS, "SensorDevice::batch dry run error %s",
+ strerror(-errDryRun));
+ return errDryRun;
+ }
+ }
+ } else if (maxBatchReportLatencyNs != 0) {
+ // Batch is not supported on older devices.
+ return INVALID_OPERATION;
+ }
+
+ ALOGD_IF(DEBUG_CONNECTIONS,
+ "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%lld timeout=%lld",
+ ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
+
+ Mutex::Autolock _l(mLock);
+ Info& info(mActivationCount.editValueFor(handle));
+
+ if (info.batchParams.indexOfKey(ident) < 0) {
+ BatchParams params(flags, samplingPeriodNs, maxBatchReportLatencyNs);
+ info.batchParams.add(ident, params);
+ } else {
+ // A batch has already been called with this ident. Update the batch parameters.
+ info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs);
+ }
+
+ BatchParams prevBestBatchParams = info.bestBatchParams;
+ // Find the minimum of all timeouts and batch_rates for this sensor.
+ info.selectBatchParams();
+
+ ALOGD_IF(DEBUG_CONNECTIONS,
+ "\t>>> curr_period=%lld min_period=%lld curr_timeout=%lld min_timeout=%lld",
+ prevBestBatchParams.batchDelay, info.bestBatchParams.batchDelay,
+ prevBestBatchParams.batchTimeout, info.bestBatchParams.batchTimeout);
+
+ status_t err(NO_ERROR);
+ // If the min period or min timeout has changed since the last batch call, call batch.
+ if (prevBestBatchParams != info.bestBatchParams) {
+ if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
+ ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %lld %lld ", handle,
+ info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
+ info.bestBatchParams.batchTimeout);
+ err = mSensorDevice->batch(mSensorDevice, handle, info.bestBatchParams.flags,
+ info.bestBatchParams.batchDelay,
+ info.bestBatchParams.batchTimeout);
+ } else {
+ // For older devices which do not support batch, call setDelay() after activate() is
+ // called. Some older devices may not support calling setDelay before activate(), so
+ // call setDelay in SensorDevice::activate() method.
+ }
+ if (err != NO_ERROR) {
+ ALOGE("sensor batch failed %p %d %d %lld %lld err=%s", mSensorDevice, handle,
+ info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
+ info.bestBatchParams.batchTimeout, strerror(-err));
+ info.removeBatchParamsForIdent(ident);
+ }
+ }
+ return err;
+}
+
+status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs)
{
if (!mSensorDevice) return NO_INIT;
+ if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
+ samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
+ }
Mutex::Autolock _l(mLock);
Info& info( mActivationCount.editValueFor(handle) );
- status_t err = info.setDelayForIdent(ident, ns);
- if (err < 0) return err;
- ns = info.selectDelay();
- return mSensorDevice->setDelay(mSensorDevice, handle, ns);
+ // If the underlying sensor is NOT in continuous mode, setDelay() should return an error.
+ // Calling setDelay() in batch mode is an invalid operation.
+ if (info.bestBatchParams.batchTimeout != 0) {
+ return INVALID_OPERATION;
+ }
+ ssize_t index = info.batchParams.indexOfKey(ident);
+ if (index < 0) {
+ return BAD_INDEX;
+ }
+ BatchParams& params = info.batchParams.editValueAt(index);
+ params.batchDelay = samplingPeriodNs;
+ info.selectBatchParams();
+ return mSensorDevice->setDelay(reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
+ handle, info.bestBatchParams.batchDelay);
}
int SensorDevice::getHalDeviceVersion() const {
@@ -198,31 +309,58 @@
return mSensorDevice->common.version;
}
+status_t SensorDevice::flush(void* ident, int handle) {
+ if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1) {
+ return INVALID_OPERATION;
+ }
+ ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
+ return mSensorDevice->flush(mSensorDevice, handle);
+}
+
// ---------------------------------------------------------------------------
-status_t SensorDevice::Info::setDelayForIdent(void* ident, int64_t ns)
-{
- ssize_t index = rates.indexOfKey(ident);
+status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
+ int64_t samplingPeriodNs,
+ int64_t maxBatchReportLatencyNs) {
+ ssize_t index = batchParams.indexOfKey(ident);
if (index < 0) {
- ALOGE("Info::setDelayForIdent(ident=%p, ns=%lld) failed (%s)",
- ident, ns, strerror(-index));
+ ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%lld timeout=%lld) failed (%s)",
+ ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
return BAD_INDEX;
}
- rates.editValueAt(index) = ns;
+ BatchParams& params = batchParams.editValueAt(index);
+ params.flags = flags;
+ params.batchDelay = samplingPeriodNs;
+ params.batchTimeout = maxBatchReportLatencyNs;
return NO_ERROR;
}
-nsecs_t SensorDevice::Info::selectDelay()
-{
- nsecs_t ns = rates.valueAt(0);
- for (size_t i=1 ; i<rates.size() ; i++) {
- nsecs_t cur = rates.valueAt(i);
- if (cur < ns) {
- ns = cur;
+void SensorDevice::Info::selectBatchParams() {
+ BatchParams bestParams(-1, -1, -1);
+
+ if (batchParams.size() > 0) {
+ BatchParams params = batchParams.valueAt(0);
+ bestParams = params;
+ }
+
+ for (size_t i = 1; i < batchParams.size(); ++i) {
+ BatchParams params = batchParams.valueAt(i);
+ if (params.batchDelay < bestParams.batchDelay) {
+ bestParams.batchDelay = params.batchDelay;
+ }
+ if (params.batchTimeout < bestParams.batchTimeout) {
+ bestParams.batchTimeout = params.batchTimeout;
}
}
- delay = ns;
- return ns;
+ bestBatchParams = bestParams;
+}
+
+ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {
+ ssize_t idx = batchParams.removeItem(ident);
+ if (idx >= 0) {
+ selectBatchParams();
+ }
+ return idx;
}
// ---------------------------------------------------------------------------
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index b50e205..761b48c 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -31,20 +31,50 @@
namespace android {
// ---------------------------------------------------------------------------
-static const nsecs_t DEFAULT_EVENTS_PERIOD = 200000000; // 5 Hz
-
class SensorDevice : public Singleton<SensorDevice> {
friend class Singleton<SensorDevice>;
- struct sensors_poll_device_t* mSensorDevice;
+ sensors_poll_device_1_t* mSensorDevice;
struct sensors_module_t* mSensorModule;
- mutable Mutex mLock; // protect mActivationCount[].rates
+ static const nsecs_t MINIMUM_EVENTS_PERIOD = 1000000; // 1000 Hz
+ mutable Mutex mLock; // protect mActivationCount[].batchParams
// fixed-size array after construction
+
+ // Struct to store all the parameters(samplingPeriod, maxBatchReportLatency and flags) from
+ // batch call. For continous mode clients, maxBatchReportLatency is set to zero.
+ struct BatchParams {
+ int flags;
+ nsecs_t batchDelay, batchTimeout;
+ BatchParams() : flags(0), batchDelay(0), batchTimeout(0) {}
+ BatchParams(int flag, nsecs_t delay, nsecs_t timeout): flags(flag), batchDelay(delay),
+ batchTimeout(timeout) { }
+ bool operator != (const BatchParams& other) {
+ return other.batchDelay != batchDelay || other.batchTimeout != batchTimeout ||
+ other.flags != flags;
+ }
+ };
+
+ // Store batch parameters in the KeyedVector and the optimal batch_rate and timeout in
+ // bestBatchParams. For every batch() call corresponding params are stored in batchParams
+ // vector. A continuous mode request is batch(... timeout=0 ..) followed by activate(). A batch
+ // mode request is batch(... timeout > 0 ...) followed by activate().
+ // Info is a per-sensor data structure which contains the batch parameters for each client that
+ // has registered for this sensor.
struct Info {
- Info() : delay(0) { }
- KeyedVector<void*, nsecs_t> rates;
- nsecs_t delay;
- status_t setDelayForIdent(void* ident, int64_t ns);
- nsecs_t selectDelay();
+ BatchParams bestBatchParams;
+ // Key is the unique identifier(ident) for each client, value is the batch parameters
+ // requested by the client.
+ KeyedVector<void*, BatchParams> batchParams;
+
+ Info() : bestBatchParams(-1, -1, -1) {}
+ // Sets batch parameters for this ident. Returns error if this ident is not already present
+ // in the KeyedVector above.
+ status_t setBatchParamsForIdent(void* ident, int flags, int64_t samplingPeriodNs,
+ int64_t maxBatchReportLatencyNs);
+ // Finds the optimal parameters for batching and stores them in bestBatchParams variable.
+ void selectBatchParams();
+ // Removes batchParams for an ident and re-computes bestBatchParams. Returns the index of
+ // the removed ident. If index >=0, ident is present and successfully removed.
+ ssize_t removeBatchParamsForIdent(void* ident);
};
DefaultKeyedVector<int, Info> mActivationCount;
@@ -55,7 +85,11 @@
int getHalDeviceVersion() const;
ssize_t poll(sensors_event_t* buffer, size_t count);
status_t activate(void* ident, int handle, int enabled);
+ status_t batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
+ int64_t maxBatchReportLatencyNs);
+ // Call batch with timeout zero instead of calling setDelay() for newer devices.
status_t setDelay(void* ident, int handle, int64_t ns);
+ status_t flush(void* ident, int handle);
void autoDisable(void *ident, int handle);
void dump(String8& result);
};
diff --git a/services/sensorservice/SensorFusion.cpp b/services/sensorservice/SensorFusion.cpp
index 4014477..27967dc 100644
--- a/services/sensorservice/SensorFusion.cpp
+++ b/services/sensorservice/SensorFusion.cpp
@@ -102,6 +102,15 @@
}
}
+ if (enabled) {
+ ALOGD("SensorFusion calling batch ident=%p ", ident);
+ // Activating a sensor in continuous mode is equivalent to calling batch with the default
+ // period and timeout equal to ZERO, followed by a call to activate.
+ mSensorDevice.batch(ident, mAcc.getHandle(), 0, DEFAULT_EVENTS_PERIOD, 0);
+ mSensorDevice.batch(ident, mMag.getHandle(), 0, DEFAULT_EVENTS_PERIOD, 0);
+ mSensorDevice.batch(ident, mGyro.getHandle(), 0, DEFAULT_EVENTS_PERIOD, 0);
+ }
+
mSensorDevice.activate(ident, mAcc.getHandle(), enabled);
mSensorDevice.activate(ident, mMag.getHandle(), enabled);
mSensorDevice.activate(ident, mGyro.getHandle(), enabled);
diff --git a/services/sensorservice/SensorFusion.h b/services/sensorservice/SensorFusion.h
index 432adbc..b8f360f 100644
--- a/services/sensorservice/SensorFusion.h
+++ b/services/sensorservice/SensorFusion.h
@@ -37,6 +37,7 @@
class SensorFusion : public Singleton<SensorFusion> {
friend class Singleton<SensorFusion>;
+ static const nsecs_t DEFAULT_EVENTS_PERIOD = 200000000; // 5 Hz
SensorDevice& mSensorDevice;
Sensor mAcc;
diff --git a/services/sensorservice/SensorInterface.cpp b/services/sensorservice/SensorInterface.cpp
index b483b75..f1d1663 100644
--- a/services/sensorservice/SensorInterface.cpp
+++ b/services/sensorservice/SensorInterface.cpp
@@ -32,7 +32,7 @@
HardwareSensor::HardwareSensor(const sensor_t& sensor)
: mSensorDevice(SensorDevice::getInstance()),
- mSensor(&sensor)
+ mSensor(&sensor, mSensorDevice.getHalDeviceVersion())
{
ALOGI("%s", sensor.name);
}
@@ -50,6 +50,16 @@
return mSensorDevice.activate(ident, mSensor.getHandle(), enabled);
}
+status_t HardwareSensor::batch(void* ident, int handle, int flags,
+ int64_t samplingPeriodNs, int64_t maxBatchReportLatencyNs) {
+ return mSensorDevice.batch(ident, mSensor.getHandle(), flags, samplingPeriodNs,
+ maxBatchReportLatencyNs);
+}
+
+status_t HardwareSensor::flush(void* ident, int handle) {
+ return mSensorDevice.flush(ident, handle);
+}
+
status_t HardwareSensor::setDelay(void* ident, int handle, int64_t ns) {
return mSensorDevice.setDelay(ident, handle, ns);
}
diff --git a/services/sensorservice/SensorInterface.h b/services/sensorservice/SensorInterface.h
index 2e14e57..c295e22 100644
--- a/services/sensorservice/SensorInterface.h
+++ b/services/sensorservice/SensorInterface.h
@@ -38,6 +38,20 @@
virtual status_t activate(void* ident, bool enabled) = 0;
virtual status_t setDelay(void* ident, int handle, int64_t ns) = 0;
+
+ // Not all sensors need to support batching.
+ virtual status_t batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
+ int64_t maxBatchReportLatencyNs) {
+ if (maxBatchReportLatencyNs == 0) {
+ return setDelay(ident, handle, samplingPeriodNs);
+ }
+ return -EINVAL;
+ }
+
+ virtual status_t flush(void* ident, int handle) {
+ return -EINVAL;
+ }
+
virtual Sensor getSensor() const = 0;
virtual bool isVirtual() const = 0;
virtual void autoDisable(void *ident, int handle) { }
@@ -59,7 +73,10 @@
const sensors_event_t& event);
virtual status_t activate(void* ident, bool enabled);
+ virtual status_t batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
+ int64_t maxBatchReportLatencyNs);
virtual status_t setDelay(void* ident, int handle, int64_t ns);
+ virtual status_t flush(void* ident, int handle);
virtual Sensor getSensor() const;
virtual bool isVirtual() const { return false; }
virtual void autoDisable(void *ident, int handle);
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index e3d2a60..7bb6e86 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -213,6 +213,11 @@
? "on-demand | "
: "one-shot | ");
}
+ if (s.getFifoMaxEventCount() > 0) {
+ result.appendFormat("getFifoMaxEventCount=%d events | ", s.getFifoMaxEventCount());
+ } else {
+ result.append("no batching support | ");
+ }
switch (s.getType()) {
case SENSOR_TYPE_ROTATION_VECTOR:
@@ -384,7 +389,6 @@
// We have read the data, upper layers should hold the wakelock.
if (wakeLockAcquired) release_wake_lock(WAKE_LOCK_NAME);
-
} while (count >= 0 || Thread::exitPending());
ALOGW("Exiting SensorService::threadLoop => aborting...");
@@ -502,7 +506,7 @@
}
status_t SensorService::enable(const sp<SensorEventConnection>& connection,
- int handle)
+ int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags)
{
if (mInitCheck != NO_ERROR)
return mInitCheck;
@@ -511,7 +515,6 @@
if (sensor == NULL) {
return BAD_VALUE;
}
-
Mutex::Autolock _l(mLock);
SensorRecord* rec = mActiveSensors.valueFor(handle);
if (rec == 0) {
@@ -548,10 +551,24 @@
handle, connection.get());
}
- // we are setup, now enable the sensor.
- status_t err = sensor->activate(connection.get(), true);
+ nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
+ if (samplingPeriodNs < minDelayNs) {
+ samplingPeriodNs = minDelayNs;
+ }
+
+ ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d rate=%lld timeout== %lld",
+ handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
+
+ status_t err = sensor->batch(connection.get(), handle, reservedFlags, samplingPeriodNs,
+ maxBatchReportLatencyNs);
+
+ if (err == NO_ERROR) {
+ ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
+ err = sensor->activate(connection.get(), true);
+ }
+
if (err != NO_ERROR) {
- // enable has failed, reset our state.
+ // batch/activate has failed, reset our state.
cleanupWithoutDisableLocked(connection, handle);
}
return err;
@@ -618,12 +635,18 @@
ns = minDelayNs;
}
- if (ns < MINIMUM_EVENTS_PERIOD)
- ns = MINIMUM_EVENTS_PERIOD;
-
return sensor->setDelay(connection.get(), handle, ns);
}
+status_t SensorService::flushSensor(const sp<SensorEventConnection>& connection,
+ int handle) {
+ if (mInitCheck != NO_ERROR) return mInitCheck;
+ SensorInterface* sensor = mSensorMap.valueFor(handle);
+ if (sensor == NULL) {
+ return BAD_VALUE;
+ }
+ return sensor->flush(connection.get(), handle);
+}
// ---------------------------------------------------------------------------
SensorService::SensorRecord::SensorRecord(
@@ -707,11 +730,21 @@
Mutex::Autolock _l(mConnectionLock);
size_t i=0;
while (i<numEvents) {
- const int32_t curr = buffer[i].sensor;
- if (mSensorInfo.indexOf(curr) >= 0) {
+ int32_t curr = buffer[i].sensor;
+ if (buffer[i].type == SENSOR_TYPE_META_DATA) {
+ ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
+ buffer[i].meta_data.sensor);
+ // Setting curr to the correct sensor to ensure the sensor events per connection are
+ // filtered correctly. buffer[i].sensor is zero for meta_data events.
+ curr = buffer[i].meta_data.sensor;
+ }
+ if (mSensorInfo.indexOf(curr) >= 0) {
do {
- scratch[count++] = buffer[i++];
- } while ((i<numEvents) && (buffer[i].sensor == curr));
+ scratch[count] = buffer[i];
+ ++count; ++i;
+ } while ((i<numEvents) && ((buffer[i].sensor == curr) ||
+ (buffer[i].type == SENSOR_TYPE_META_DATA &&
+ buffer[i].meta_data.sensor == curr)));
} else {
i++;
}
@@ -740,11 +773,13 @@
}
status_t SensorService::SensorEventConnection::enableDisable(
- int handle, bool enabled)
+ int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
+ int reservedFlags)
{
status_t err;
if (enabled) {
- err = mService->enable(this, handle);
+ err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
+ reservedFlags);
} else {
err = mService->disable(this, handle);
}
@@ -752,11 +787,14 @@
}
status_t SensorService::SensorEventConnection::setEventRate(
- int handle, nsecs_t ns)
+ int handle, nsecs_t samplingPeriodNs)
{
- return mService->setEventRate(this, handle, ns);
+ return mService->setEventRate(this, handle, samplingPeriodNs);
}
+status_t SensorService::SensorEventConnection::flushSensor(int handle) {
+ return mService->flushSensor(this, handle);
+}
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 69e5dbb..6267dd1 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -52,7 +52,6 @@
{
friend class BinderService<SensorService>;
- static const nsecs_t MINIMUM_EVENTS_PERIOD = 1000000; // 1000 Hz
static const char* WAKE_LOCK_NAME;
static char const* getServiceName() ANDROID_API { return "sensorservice"; }
@@ -74,8 +73,10 @@
virtual ~SensorEventConnection();
virtual void onFirstRef();
virtual sp<BitTube> getSensorChannel() const;
- virtual status_t enableDisable(int handle, bool enabled);
- virtual status_t setEventRate(int handle, nsecs_t ns);
+ virtual status_t enableDisable(int handle, bool enabled, nsecs_t samplingPeriodNs,
+ nsecs_t maxBatchReportLatencyNs, int reservedFlags);
+ virtual status_t setEventRate(int handle, nsecs_t samplingPeriodNs);
+ virtual status_t flushSensor(int handle);
sp<SensorService> const mService;
sp<BitTube> const mChannel;
@@ -141,9 +142,11 @@
public:
void cleanupConnection(SensorEventConnection* connection);
- status_t enable(const sp<SensorEventConnection>& connection, int handle);
+ status_t enable(const sp<SensorEventConnection>& connection, int handle,
+ nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags);
status_t disable(const sp<SensorEventConnection>& connection, int handle);
status_t setEventRate(const sp<SensorEventConnection>& connection, int handle, nsecs_t ns);
+ status_t flushSensor(const sp<SensorEventConnection>& connection, int handle);
};
// ---------------------------------------------------------------------------