OSDN Git Service

Enable data injection mode in SensorService.
authorAravind Akella <aakella@google.com>
Fri, 17 Apr 2015 01:57:31 +0000 (18:57 -0700)
committerAravind Akella <aakella@google.com>
Fri, 24 Apr 2015 00:42:37 +0000 (17:42 -0700)
Change-Id: I0cd32a017235c31c54816e4a357ce3b988350ed6

include/gui/ISensorServer.h
include/gui/SensorEventQueue.h
include/gui/SensorManager.h
libs/gui/ISensorServer.cpp
libs/gui/SensorEventQueue.cpp
libs/gui/SensorManager.cpp
services/sensorservice/SensorDevice.cpp
services/sensorservice/SensorDevice.h
services/sensorservice/SensorService.cpp
services/sensorservice/SensorService.h

index 9a29cb5..ee3484c 100644 (file)
@@ -38,7 +38,9 @@ public:
     DECLARE_META_INTERFACE(SensorServer);
 
     virtual Vector<Sensor> getSensorList() = 0;
-    virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName) = 0;
+    virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
+             int mode) = 0;
+    virtual status_t enableDataInjection(int enable) = 0;
 };
 
 // ----------------------------------------------------------------------------
index 02b3d38..b70957b 100644 (file)
@@ -77,6 +77,8 @@ public:
     status_t flush() const;
     // Send an ack for every wake_up sensor event that is set to WAKE_UP_SENSOR_EVENT_NEEDS_ACK.
     void sendAck(const ASensorEvent* events, int count);
+
+    status_t injectSensorEvent(const ASensorEvent& event);
 private:
     sp<Looper> getLooper() const;
     sp<ISensorEventConnection> mSensorEventConnection;
index 1afff68..19c2bdc 100644 (file)
@@ -53,7 +53,8 @@ public:
 
     ssize_t getSensorList(Sensor const* const** list) const;
     Sensor const* getDefaultSensor(int type);
-    sp<SensorEventQueue> createEventQueue(String8 packageName = String8(""));
+    sp<SensorEventQueue> createEventQueue(String8 packageName = String8(""), int mode = 0);
+    ssize_t enableDataInjection(bool enable);
 
 private:
     // DeathRecipient interface
index 3c85ec0..140712e 100644 (file)
@@ -35,6 +35,7 @@ namespace android {
 enum {
     GET_SENSOR_LIST = IBinder::FIRST_CALL_TRANSACTION,
     CREATE_SENSOR_EVENT_CONNECTION,
+    ENABLE_DATA_INJECTION
 };
 
 class BpSensorServer : public BpInterface<ISensorServer>
@@ -63,14 +64,24 @@ public:
         return v;
     }
 
-    virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName)
+    virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
+             int mode)
     {
         Parcel data, reply;
         data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
         data.writeString8(packageName);
+        data.writeInt32(mode);
         remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply);
         return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
     }
+
+    virtual status_t enableDataInjection(int enable) {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
+        data.writeInt32(enable);
+        remote()->transact(ENABLE_DATA_INJECTION, data, &reply);
+        return reply.readInt32();
+    }
 };
 
 // Out-of-line virtual method definition to trigger vtable emission in this
@@ -98,10 +109,18 @@ status_t BnSensorServer::onTransact(
         case CREATE_SENSOR_EVENT_CONNECTION: {
             CHECK_INTERFACE(ISensorServer, data, reply);
             String8 packageName = data.readString8();
-            sp<ISensorEventConnection> connection(createSensorEventConnection(packageName));
+            int32_t mode = data.readInt32();
+            sp<ISensorEventConnection> connection(createSensorEventConnection(packageName, mode));
             reply->writeStrongBinder(IInterface::asBinder(connection));
             return NO_ERROR;
         }
+        case ENABLE_DATA_INJECTION: {
+            CHECK_INTERFACE(ISensorServer, data, reply);
+            int32_t enable = data.readInt32();
+            status_t ret = enableDataInjection(enable);
+            reply->writeInt32(static_cast<int32_t>(ret));
+            return NO_ERROR;
+        }
     }
     return BBinder::onTransact(code, data, reply, flags);
 }
index 76ae470..b5b5d68 100644 (file)
@@ -149,6 +149,16 @@ status_t SensorEventQueue::setEventRate(Sensor const* sensor, nsecs_t ns) const
     return mSensorEventConnection->setEventRate(sensor->getHandle(), ns);
 }
 
+status_t SensorEventQueue::injectSensorEvent(const ASensorEvent& event) {
+   // Blocking call.
+   ssize_t size = ::send(mSensorChannel->getFd(), &event, sizeof(event), MSG_NOSIGNAL);
+   if (size < 0) {
+       ALOGE("injectSensorEvent failure %zd %d", size, mSensorChannel->getFd());
+       return size;
+   }
+   return NO_ERROR;
+}
+
 void SensorEventQueue::sendAck(const ASensorEvent* events, int count) {
     for (int i = 0; i < count; ++i) {
         if (events[i].flags & WAKE_UP_SENSOR_EVENT_NEEDS_ACK) {
index 142c6ec..cedcf56 100644 (file)
@@ -100,8 +100,6 @@ status_t SensorManager::assertStateLocked() const {
     return NO_ERROR;
 }
 
-
-
 ssize_t SensorManager::getSensorList(Sensor const* const** list) const
 {
     Mutex::Autolock _l(mLock);
@@ -139,18 +137,17 @@ Sensor const* SensorManager::getDefaultSensor(int type)
     return NULL;
 }
 
-sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName)
-{
+sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName, int mode) {
     sp<SensorEventQueue> queue;
 
     Mutex::Autolock _l(mLock);
     while (assertStateLocked() == NO_ERROR) {
         sp<ISensorEventConnection> connection =
-                mSensorServer->createSensorEventConnection(packageName);
+                mSensorServer->createSensorEventConnection(packageName, mode);
         if (connection == NULL) {
-            // SensorService just died.
-            ALOGE("createEventQueue: connection is NULL. SensorService died.");
-            continue;
+            // SensorService just died or the app doesn't have required permissions.
+            ALOGE("createEventQueue: connection is NULL.");
+            return NULL;
         }
         queue = new SensorEventQueue(connection);
         break;
@@ -158,5 +155,13 @@ sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName)
     return queue;
 }
 
+status_t SensorManager::enableDataInjection(bool enable) {
+    Mutex::Autolock _l(mLock);
+    if (assertStateLocked() == NO_ERROR) {
+        return mSensorServer->enableDataInjection(enable);
+    }
+    return INVALID_OPERATION;
+}
+
 // ----------------------------------------------------------------------------
 }; // namespace android
index 30a244b..3bcbd58 100644 (file)
@@ -367,7 +367,7 @@ void SensorDevice::enableAllSensors() {
 
 void SensorDevice::disableAllSensors() {
     Mutex::Autolock _l(mLock);
-    for (size_t i = 0; i< mActivationCount.size(); ++i) {
+   for (size_t i = 0; i< mActivationCount.size(); ++i) {
         const Info& info = mActivationCount.valueAt(i);
         // Check if this sensor has been activated previously and disable it.
         if (info.batchParams.size() > 0) {
@@ -386,6 +386,27 @@ void SensorDevice::disableAllSensors() {
     }
 }
 
+status_t SensorDevice::injectSensorData(const sensors_event_t *injected_sensor_event, size_t count) {
+      ALOGD_IF(DEBUG_CONNECTIONS,
+              "sensor_event handle=%d ts=%lld data=%.2f, %.2f, %.2f %.2f %.2f %.2f",
+               injected_sensor_event->sensor,
+               injected_sensor_event->timestamp, injected_sensor_event->data[0],
+               injected_sensor_event->data[1], injected_sensor_event->data[2],
+               injected_sensor_event->data[3], injected_sensor_event->data[4],
+               injected_sensor_event->data[5]);
+      if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) {
+          return INVALID_OPERATION;
+      }
+      return mSensorDevice->inject_sensor_data(mSensorDevice, injected_sensor_event);
+}
+
+status_t SensorDevice::setMode(uint32_t mode) {
+     if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) {
+          return INVALID_OPERATION;
+     }
+     return mSensorModule->set_operation_mode(mode);
+}
+
 // ---------------------------------------------------------------------------
 
 int SensorDevice::Info::numActiveClients() {
index cf33a59..4b3fe85 100644 (file)
@@ -98,9 +98,11 @@ public:
     // 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);
+    status_t setMode(uint32_t mode);
     void disableAllSensors();
     void enableAllSensors();
     void autoDisable(void *ident, int handle);
+    status_t injectSensorData(const sensors_event_t *event, size_t count);
     void dump(String8& result);
 };
 
index 2336d88..c8dc6ec 100644 (file)
@@ -64,6 +64,9 @@ namespace android {
  */
 
 const char* SensorService::WAKE_LOCK_NAME = "SensorService";
+// Permissions.
+static const String16 sDataInjectionPermission("android.permission.HARDWARE_TEST");
+static const String16 sDump("android.permission.DUMP");
 
 SensorService::SensorService()
     : mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
@@ -74,7 +77,6 @@ SensorService::SensorService()
 void SensorService::onFirstRef()
 {
     ALOGD("nuSensorService starting...");
-
     SensorDevice& dev(SensorDevice::getInstance());
 
     if (dev.initCheck() == NO_ERROR) {
@@ -190,7 +192,7 @@ void SensorService::onFirstRef()
             mSensorEventBuffer = new sensors_event_t[minBufferSize];
             mSensorEventScratch = new sensors_event_t[minBufferSize];
             mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
-            mMode = NORMAL;
+            mCurrentOperatingMode = NORMAL;
 
             mAckReceiver = new SensorEventAckReceiver(this);
             mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
@@ -229,8 +231,6 @@ SensorService::~SensorService()
         delete mSensorMap.valueAt(i);
 }
 
-static const String16 sDump("android.permission.DUMP");
-
 status_t SensorService::dump(int fd, const Vector<String16>& args)
 {
     String8 result;
@@ -245,8 +245,8 @@ status_t SensorService::dump(int fd, const Vector<String16>& args)
         }
         Mutex::Autolock _l(mLock);
         SensorDevice& dev(SensorDevice::getInstance());
-        if (args[0] == String16("restrict") && mMode == NORMAL) {
-            mMode = RESTRICTED;
+        if (args[0] == String16("restrict") && mCurrentOperatingMode == NORMAL) {
+            mCurrentOperatingMode = RESTRICTED;
             dev.disableAllSensors();
             // Clear all pending flush connections for all active sensors. If one of the active
             // connections has called flush() and the underlying sensor has been disabled before a
@@ -254,8 +254,8 @@ status_t SensorService::dump(int fd, const Vector<String16>& args)
             for (size_t i=0 ; i< mActiveSensors.size(); ++i) {
                 mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
             }
-        } else if (args[0] == String16("enable") && mMode == RESTRICTED) {
-            mMode = NORMAL;
+        } else if (args[0] == String16("enable") && mCurrentOperatingMode == RESTRICTED) {
+            mCurrentOperatingMode = NORMAL;
             dev.enableAllSensors();
         }
         return status_t(NO_ERROR);
@@ -363,7 +363,7 @@ status_t SensorService::dump(int fd, const Vector<String16>& args)
                             mSocketBufferSize/sizeof(sensors_event_t));
         result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" : "not held");
         result.appendFormat("Mode :");
-        switch(mMode) {
+        switch(mCurrentOperatingMode) {
            case NORMAL:
                result.appendFormat(" NORMAL\n");
                break;
@@ -403,8 +403,9 @@ void SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnecti
                 sensor->autoDisable(connection.get(), handle);
                 cleanupWithoutDisableLocked(connection, handle);
             }
+
         }
-    }
+   }
 }
 
 bool SensorService::threadLoop()
@@ -685,13 +686,76 @@ Vector<Sensor> SensorService::getSensorList()
     return accessibleSensorList;
 }
 
-sp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName)
-{
+sp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName,
+        int requestedMode) {
+    // Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION.
+    if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) {
+        return NULL;
+    }
+    // DATA_INJECTION mode needs to have the required permissions set.
+    if (requestedMode == DATA_INJECTION && !hasDataInjectionPermissions()) {
+        return NULL;
+    }
+
+    Mutex::Autolock _l(mLock);
     uid_t uid = IPCThreadState::self()->getCallingUid();
-    sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName));
+    sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName,
+            requestedMode == DATA_INJECTION));
+    if (requestedMode == DATA_INJECTION) {
+        if (mActiveConnections.indexOf(result) < 0) {
+            mActiveConnections.add(result);
+        }
+        // Add the associated file descriptor to the Looper for polling whenever there is data to
+        // be injected.
+        result->updateLooperRegistration(mLooper);
+    }
     return result;
 }
 
+status_t SensorService::enableDataInjection(int requestedMode) {
+    if (!hasDataInjectionPermissions()) {
+        return INVALID_OPERATION;
+    }
+    Mutex::Autolock _l(mLock);
+    ALOGD_IF(DEBUG_CONNECTIONS, "SensorService::enableDataInjection %d", requestedMode);
+    SensorDevice& dev(SensorDevice::getInstance());
+    status_t err(NO_ERROR);
+    if (requestedMode == DATA_INJECTION) {
+        if (mCurrentOperatingMode == NORMAL) {
+           dev.disableAllSensors();
+           err = dev.setMode(requestedMode);
+           if (err == NO_ERROR) {
+               mCurrentOperatingMode = DATA_INJECTION;
+           } else {
+               // Re-enable sensors.
+               dev.enableAllSensors();
+           }
+       } else if (mCurrentOperatingMode == DATA_INJECTION) {
+           // Already in DATA_INJECTION mode. Treat this as a no_op.
+           return NO_ERROR;
+       } else {
+           // Transition to data injection mode supported only from NORMAL mode.
+           return INVALID_OPERATION;
+       }
+    } else if (requestedMode == NORMAL && mCurrentOperatingMode != NORMAL) {
+       err = resetToNormalModeLocked();
+    }
+    return err;
+}
+
+status_t SensorService::resetToNormalMode() {
+    Mutex::Autolock _l(mLock);
+    return resetToNormalModeLocked();
+}
+
+status_t SensorService::resetToNormalModeLocked() {
+    SensorDevice& dev(SensorDevice::getInstance());
+    dev.enableAllSensors();
+    status_t err = dev.setMode(NORMAL);
+    mCurrentOperatingMode = NORMAL;
+    return err;
+}
+
 void SensorService::cleanupConnection(SensorEventConnection* c)
 {
     Mutex::Autolock _l(mLock);
@@ -753,7 +817,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection,
     }
 
     Mutex::Autolock _l(mLock);
-    if (mMode == RESTRICTED && !isWhiteListedPackage(connection->getPackageName())) {
+    if (mCurrentOperatingMode == RESTRICTED && !isWhiteListedPackage(connection->getPackageName())) {
         return INVALID_OPERATION;
     }
 
@@ -960,6 +1024,15 @@ bool SensorService::verifyCanAccessSensor(const Sensor& sensor, const char* oper
     }
 }
 
+bool SensorService::hasDataInjectionPermissions() {
+    if (!PermissionCache::checkCallingPermission(sDataInjectionPermission)) {
+        ALOGE("Permission Denial trying to activate data injection without"
+              " the required permission");
+        return false;
+    }
+    return true;
+}
+
 void SensorService::checkWakeLockState() {
     Mutex::Autolock _l(mLock);
     checkWakeLockStateLocked();
@@ -1071,9 +1144,10 @@ void SensorService::SensorRecord::clearAllPendingFlushConnections() {
 // ---------------------------------------------------------------------------
 
 SensorService::SensorEventConnection::SensorEventConnection(
-        const sp<SensorService>& service, uid_t uid, String8 packageName)
+        const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode)
     : mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
-      mDead(false), mEventCache(NULL), mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName) {
+      mDead(false), mEventCache(NULL), mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName),
+      mDataInjectionMode(isDataInjectionMode) {
     mChannel = new BitTube(mService->mSocketBufferSize);
 #if DEBUG_CONNECTIONS
     mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
@@ -1105,6 +1179,7 @@ void SensorService::SensorEventConnection::resetWakeLockRefCount() {
 
 void SensorService::SensorEventConnection::dump(String8& result) {
     Mutex::Autolock _l(mConnectionLock);
+    result.appendFormat("Operating Mode: %s\n", mDataInjectionMode ? "DATA_INJECTION" : "NORMAL");
     result.appendFormat("\t%s | WakeLockRefCount %d | uid %d | cache size %d | max cache size %d\n",
             mPackageName.string(), mWakeLockRefCount, mUid, mCacheSize, mMaxCacheSize);
     for (size_t i = 0; i < mSensorInfo.size(); ++i) {
@@ -1190,7 +1265,8 @@ void SensorService::SensorEventConnection::updateLooperRegistration(const sp<Loo
 
 void SensorService::SensorEventConnection::updateLooperRegistrationLocked(
         const sp<Looper>& looper) {
-    bool isConnectionActive = mSensorInfo.size() > 0;
+    bool isConnectionActive = (mSensorInfo.size() > 0 && !mDataInjectionMode) ||
+                              mDataInjectionMode;
     // If all sensors are unregistered OR Looper has encountered an error, we
     // can remove the Fd from the Looper if it has been previously added.
     if (!isConnectionActive || mDead) {
@@ -1204,6 +1280,7 @@ void SensorService::SensorEventConnection::updateLooperRegistrationLocked(
 
     int looper_flags = 0;
     if (mCacheSize > 0) looper_flags |= ALOOPER_EVENT_OUTPUT;
+    if (mDataInjectionMode) looper_flags |= ALOOPER_EVENT_INPUT;
     for (size_t i = 0; i < mSensorInfo.size(); ++i) {
         const int handle = mSensorInfo.keyAt(i);
         if (mService->getSensorFromHandle(handle).isWakeUpSensor()) {
@@ -1570,26 +1647,55 @@ int SensorService::SensorEventConnection::handleEvent(int fd, int events, void*
             updateLooperRegistrationLocked(mService->getLooper());
         }
         mService->checkWakeLockState();
+        if (mDataInjectionMode) {
+            // If the Looper has encountered some error in data injection mode, reset SensorService
+            // back to normal mode.
+            mService->resetToNormalMode();
+            mDataInjectionMode = false;
+        }
         return 1;
     }
 
     if (events & ALOOPER_EVENT_INPUT) {
-        uint32_t numAcks = 0;
-        ssize_t ret = ::recv(fd, &numAcks, sizeof(numAcks), MSG_DONTWAIT);
+        unsigned char buf[sizeof(sensors_event_t)];
+        ssize_t numBytesRead = ::recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
         {
            Mutex::Autolock _l(mConnectionLock);
-           // Sanity check to ensure  there are no read errors in recv, numAcks is always
-           // within the range and not zero. If any of the above don't hold reset mWakeLockRefCount
-           // to zero.
-           if (ret != sizeof(numAcks) || numAcks > mWakeLockRefCount || numAcks == 0) {
-               ALOGE("Looper read error ret=%d numAcks=%d", ret, numAcks);
-               mWakeLockRefCount = 0;
-           } else {
-               mWakeLockRefCount -= numAcks;
-           }
+           if (numBytesRead == sizeof(sensors_event_t)) {
+               if (!mDataInjectionMode) {
+                   ALOGE("Data injected in normal mode, dropping event"
+                         "package=%s uid=%d", mPackageName.string(), mUid);
+                   // Unregister call backs.
+                   return 0;
+               }
+               SensorDevice& dev(SensorDevice::getInstance());
+               sensors_event_t sensor_event;
+               memset(&sensor_event, 0, sizeof(sensor_event));
+               memcpy(&sensor_event, buf, sizeof(sensors_event_t));
+               Sensor sensor = mService->getSensorFromHandle(sensor_event.sensor);
+               sensor_event.type = sensor.getType();
+               dev.injectSensorData(&sensor_event, 1);
 #if DEBUG_CONNECTIONS
-           mTotalAcksReceived += numAcks;
+               ++mEventsReceived;
 #endif
+           } else if (numBytesRead == sizeof(uint32_t)) {
+               uint32_t numAcks = 0;
+               memcpy(&numAcks, buf, sizeof(numBytesRead));
+               // Sanity check to ensure  there are no read errors in recv, numAcks is always
+               // within the range and not zero. If any of the above don't hold reset
+               // mWakeLockRefCount to zero.
+               if (numAcks > 0 && numAcks < mWakeLockRefCount) {
+                   mWakeLockRefCount -= numAcks;
+               } else {
+                   mWakeLockRefCount = 0;
+               }
+#if DEBUG_CONNECTIONS
+               mTotalAcksReceived += numAcks;
+#endif
+           } else {
+               // Read error, reset wakelock refcount.
+               mWakeLockRefCount = 0;
+           }
         }
         // Check if wakelock can be released by sensorservice. mConnectionLock needs to be released
         // here as checkWakeLockState() will need it.
index b31eaf3..4d34471 100644 (file)
@@ -70,21 +70,33 @@ class SensorService :
        // The regular operating mode where any application can register/unregister/call flush on
        // sensors.
        NORMAL = 0,
+       // This mode is only used for testing purposes. Not all HALs support this mode. In this
+       // mode, the HAL ignores the sensor data provided by physical sensors and accepts the data
+       // that is injected from the SensorService as if it were the real sensor data. This mode
+       // is primarily used for testing various algorithms like vendor provided SensorFusion,
+       // Step Counter and Step Detector etc. Typically in this mode, there will be a client
+       // (a SensorEventConnection) which will be injecting sensor data into the HAL. Normal apps
+       // can unregister and register for any sensor that supports injection. Registering to sensors
+       // that do not support injection will give an error.
+       // TODO(aakella) : Allow exactly one client to inject sensor data at a time.
+       DATA_INJECTION = 1,
        // This mode is used only for testing sensors. Each sensor can be tested in isolation with
        // the required sampling_rate and maxReportLatency parameters without having to think about
        // the data rates requested by other applications. End user devices are always expected to be
        // in NORMAL mode. When this mode is first activated, all active sensors from all connections
        // are disabled. Calling flush() will return an error. In this mode, only the requests from
        // selected apps whose package names are whitelisted are allowed (typically CTS apps).  Only
-       // these apps can register/unregister/call flush() on sensors.  If SensorService switches to
+       // these apps can register/unregister/call flush() on sensors. If SensorService switches to
        // NORMAL mode again, all sensors that were previously registered to are activated with the
        // corresponding paramaters if the application hasn't unregistered for sensors in the mean
        // time.
        // NOTE: Non whitelisted app whose sensors were previously deactivated may still receive
        // events if a whitelisted app requests data from the same sensor.
-       RESTRICTED,
-       // TODO: This mode hasn't been implemented yet.
-       DATA_INJECTION
+       RESTRICTED = 2
+
+      // State Transitions supported.
+      //     RESTRICTED   <---  NORMAL   ---> DATA_INJECTION
+      //                  --->           <---
     };
 
     static const char* WAKE_LOCK_NAME;
@@ -100,7 +112,9 @@ class SensorService :
 
     // ISensorServer interface
     virtual Vector<Sensor> getSensorList();
-    virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName);
+    virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
+             int requestedMode);
+    virtual status_t enableDataInjection(int enable);
     virtual status_t dump(int fd, const Vector<String16>& args);
 
     class SensorEventConnection : public BnSensorEventConnection, public LooperCallback {
@@ -177,6 +191,8 @@ class SensorService :
         // mWakeLockRefCount is reset to zero. needsWakeLock method will always return false, if
         // this flag is set.
         bool mDead;
+
+        bool mDataInjectionMode;
         struct FlushInfo {
             // The number of flush complete events dropped for this sensor is stored here.
             // They are sent separately before the next batch of events.
@@ -191,14 +207,14 @@ class SensorService :
         sensors_event_t *mEventCache;
         int mCacheSize, mMaxCacheSize;
         String8 mPackageName;
-
 #if DEBUG_CONNECTIONS
         int mEventsReceived, mEventsSent, mEventsSentFromCache;
         int mTotalAcksNeeded, mTotalAcksReceived;
 #endif
 
     public:
-        SensorEventConnection(const sp<SensorService>& service, uid_t uid, String8 packageName);
+        SensorEventConnection(const sp<SensorService>& service, uid_t uid, String8 packageName,
+                 bool isDataInjectionMode);
 
         status_t sendEvents(sensors_event_t const* buffer, size_t count,
                 sensors_event_t* scratch,
@@ -257,6 +273,7 @@ class SensorService :
             sensors_event_t const* buffer, const int count);
     static bool canAccessSensor(const Sensor& sensor);
     static bool verifyCanAccessSensor(const Sensor& sensor, const char* operation);
+    static bool hasDataInjectionPermissions();
     // SensorService acquires a partial wakelock for delivering events from wake up sensors. This
     // method checks whether all the events from these wake up sensors have been delivered to the
     // corresponding applications, if yes the wakelock is released.
@@ -290,6 +307,10 @@ class SensorService :
     // allowed.
     bool isWhiteListedPackage(const String8& packageName);
 
+    // Reset the state of SensorService to NORMAL mode.
+    status_t resetToNormalMode();
+    status_t resetToNormalModeLocked();
+
     // constants
     Vector<Sensor> mSensorList;
     Vector<Sensor> mUserSensorListDebug;
@@ -311,7 +332,7 @@ class SensorService :
     bool mWakeLockAcquired;
     sensors_event_t *mSensorEventBuffer, *mSensorEventScratch;
     SensorEventConnection const **mMapFlushEventsToConnections;
-    Mode mMode;
+    Mode mCurrentOperatingMode;
 
     // The size of this vector is constant, only the items are mutable
     KeyedVector<int32_t, sensors_event_t> mLastEventSeen;