Merge "Support REPLAY_DATA_INJECTION mode"
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index 82d0295..a3a62a1 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -850,6 +850,11 @@
                     // Unregister call backs.
                     return 0;
                 }
+                if (!mService->isWhiteListedPackage(mPackageName)) {
+                    ALOGE("App not allowed to inject data, dropping event"
+                          "package=%s uid=%d", mPackageName.string(), mUid);
+                    return 0;
+                }
                 sensors_event_t sensor_event;
                 memcpy(&sensor_event, buf, sizeof(sensors_event_t));
                 std::shared_ptr<SensorInterface> si =
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 6504b79..0cfc72f 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -52,6 +52,7 @@
 #include "SensorEventConnection.h"
 #include "SensorRecord.h"
 #include "SensorRegistrationInfo.h"
+#include "SensorServiceUtils.h"
 
 #include <inttypes.h>
 #include <math.h>
@@ -571,7 +572,11 @@
                 // enable sensors and recover all sensor direct report
                 enableAllSensorsLocked(&connLock);
             }
-            if (mCurrentOperatingMode == DATA_INJECTION) {
+            if (mCurrentOperatingMode == REPLAY_DATA_INJECTION) {
+                dev.disableAllSensors();
+            }
+            if (mCurrentOperatingMode == DATA_INJECTION ||
+                    mCurrentOperatingMode == REPLAY_DATA_INJECTION) {
                resetToNormalModeLocked();
             }
             mWhiteListedPackage.clear();
@@ -595,6 +600,27 @@
                 // Transition to data injection mode supported only from NORMAL mode.
                 return INVALID_OPERATION;
             }
+        } else if (args.size() == 2 && args[0] == String16("replay_data_injection")
+                   && !SensorServiceUtil::isUserBuild()) {
+            if (mCurrentOperatingMode == NORMAL) {
+                dev.disableAllSensors();
+                // Use DATA_INJECTION here since this value goes to the HAL and the HAL doesn't
+                // have an understanding of replay vs. normal data injection.
+                status_t err = dev.setMode(DATA_INJECTION);
+                if (err == NO_ERROR) {
+                    mCurrentOperatingMode = REPLAY_DATA_INJECTION;
+                }
+                // Re-enable sensors.
+                dev.enableAllSensors();
+                mWhiteListedPackage.setTo(String8(args[1]));
+                return NO_ERROR;
+            } else if (mCurrentOperatingMode == REPLAY_DATA_INJECTION) {
+                // Already in REPLAY_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 (args.size() == 1 && args[0] == String16("--proto")) {
             return dumpProtoLocked(fd, &connLock);
         } else if (!mSensors.hasAnySensor()) {
@@ -658,6 +684,14 @@
                    break;
                case DATA_INJECTION:
                    result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string());
+                   break;
+               case REPLAY_DATA_INJECTION:
+                   result.appendFormat(" REPLAY_DATA_INJECTION : %s\n",
+                            mWhiteListedPackage.string());
+                   break;
+               default:
+                   result.appendFormat(" UNKNOWN\n");
+                   break;
             }
             result.appendFormat("Sensor Privacy: %s\n",
                     mSensorPrivacyPolicy->isSensorPrivacyEnabled() ? "enabled" : "disabled");
@@ -1498,8 +1532,10 @@
 
 sp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName,
         int requestedMode, const String16& opPackageName, const String16& attributionTag) {
-    // Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION.
-    if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) {
+    // Only 3 modes supported for a SensorEventConnection ... NORMAL, DATA_INJECTION and
+    // REPLAY_DATA_INJECTION.
+    if (requestedMode != NORMAL && requestedMode != DATA_INJECTION &&
+            requestedMode != REPLAY_DATA_INJECTION) {
         return nullptr;
     }
     resetTargetSdkVersionCache(opPackageName);
@@ -1520,8 +1556,9 @@
     String16 connOpPackageName =
             (opPackageName == String16("")) ? String16(connPackageName) : opPackageName;
     sp<SensorEventConnection> result(new SensorEventConnection(this, uid, connPackageName,
-            requestedMode == DATA_INJECTION, connOpPackageName, attributionTag));
-    if (requestedMode == DATA_INJECTION) {
+            requestedMode == DATA_INJECTION || requestedMode == REPLAY_DATA_INJECTION,
+            connOpPackageName, attributionTag));
+    if (requestedMode == DATA_INJECTION || requestedMode == REPLAY_DATA_INJECTION) {
         mConnectionHolder.addEventConnectionIfNotPresent(result);
         // Add the associated file descriptor to the Looper for polling whenever there is data to
         // be injected.
@@ -1880,8 +1917,8 @@
     }
 
     ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);
-    if (mCurrentOperatingMode != NORMAL
-           && !isWhiteListedPackage(connection->getPackageName())) {
+    if (mCurrentOperatingMode != NORMAL && mCurrentOperatingMode != REPLAY_DATA_INJECTION &&
+           !isWhiteListedPackage(connection->getPackageName())) {
         return INVALID_OPERATION;
     }
 
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 78df501..64bc377 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -102,8 +102,7 @@
        // 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: Allow exactly one
-       // client to inject sensor data at a time.
+       // that do not support injection will give an error.
        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
@@ -116,10 +115,14 @@
        // corresponding parameters if the application hasn't unregistered for sensors in the mean
        // time.  NOTE: Non allowlisted app whose sensors were previously deactivated may still
        // receive events if a allowlisted app requests data from the same sensor.
-       RESTRICTED = 2
+       RESTRICTED = 2,
+       // Mostly equivalent to DATA_INJECTION with the difference being that the injected data is
+       // delivered to all requesting apps rather than just the package allowed to inject data.
+       // This mode is only allowed to be used on development builds.
+       REPLAY_DATA_INJECTION = 3,
 
       // State Transitions supported.
-      //     RESTRICTED   <---  NORMAL   ---> DATA_INJECTION
+      //     RESTRICTED   <---  NORMAL   ---> DATA_INJECTION/REPLAY_DATA_INJECTION
       //                  --->           <---
 
       // Shell commands to switch modes in SensorService.
diff --git a/services/sensorservice/SensorServiceUtils.cpp b/services/sensorservice/SensorServiceUtils.cpp
index 6bad962..46b4b5b 100644
--- a/services/sensorservice/SensorServiceUtils.cpp
+++ b/services/sensorservice/SensorServiceUtils.cpp
@@ -16,6 +16,7 @@
 
 #include "SensorServiceUtils.h"
 
+#include <android-base/properties.h>
 #include <hardware/sensors.h>
 
 namespace android {
@@ -76,5 +77,10 @@
     }
 }
 
+bool isUserBuild() {
+    std::string buildType = android::base::GetProperty("ro.build.type", "user");
+    return "user" == buildType;
+}
+
 } // namespace SensorServiceUtil
 } // namespace android;
diff --git a/services/sensorservice/SensorServiceUtils.h b/services/sensorservice/SensorServiceUtils.h
index 49457cf..a6e0d6b 100644
--- a/services/sensorservice/SensorServiceUtils.h
+++ b/services/sensorservice/SensorServiceUtils.h
@@ -38,6 +38,11 @@
 
 size_t eventSizeBySensorType(int type);
 
+/**
+ * Returns true if on a user (production) build.
+ */
+bool isUserBuild();
+
 } // namespace SensorServiceUtil
 } // namespace android;