Merge "Replace TENSOR_QUANT16_ASYMM with TENSOR_QUANT16_SYMM"
diff --git a/camera/common/1.0/default/CameraModule.cpp b/camera/common/1.0/default/CameraModule.cpp
index 392ebbc..9c2b02b 100644
--- a/camera/common/1.0/default/CameraModule.cpp
+++ b/camera/common/1.0/default/CameraModule.cpp
@@ -466,8 +466,8 @@
 }
 
 void CameraModule::removeCamera(int cameraId) {
-    free_camera_metadata(
-        const_cast<camera_metadata_t*>(mCameraInfoMap[cameraId].static_camera_characteristics));
+    free_camera_metadata(const_cast<camera_metadata_t*>(
+        mCameraInfoMap.valueFor(cameraId).static_camera_characteristics));
     mCameraInfoMap.removeItem(cameraId);
     mDeviceVersionMap.removeItem(cameraId);
 }
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index e117a98..fd996fb 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -145,7 +145,7 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.drm</name>
-        <version>1.0</version>
+        <version>1.0-1</version>
         <interface>
             <name>ICryptoFactory</name>
             <regex-instance>.*</regex-instance>
@@ -157,7 +157,7 @@
     </hal>
     <hal format="hidl" optional="false">
         <name>android.hardware.drm</name>
-        <version>1.1</version>
+        <version>1.2</version>
         <interface>
             <name>ICryptoFactory</name>
             <regex-instance>.*</regex-instance>
diff --git a/keymaster/3.0/vts/functional/authorization_set.h b/keymaster/3.0/vts/functional/authorization_set.h
index 5f92d81..60b00e4 100644
--- a/keymaster/3.0/vts/functional/authorization_set.h
+++ b/keymaster/3.0/vts/functional/authorization_set.h
@@ -201,7 +201,7 @@
     void push_back(TypedTag<TagType::BYTES, tag> ttag, const uint8_t* data, size_t data_length) {
         hidl_vec<uint8_t> new_blob;
         new_blob.setToExternal(const_cast<uint8_t*>(data), data_length);
-        push_back(ttag, std::move(new_blob));
+        push_back(ttag, new_blob);
     }
 
     /**
@@ -225,8 +225,7 @@
     }
 
     hidl_vec<KeyParameter> hidl_data() const {
-        hidl_vec<KeyParameter> result;
-        result.setToExternal(const_cast<KeyParameter*>(data()), size());
+        hidl_vec<KeyParameter> result(begin(), end());
         return result;
     }
 
@@ -252,7 +251,7 @@
                                            size_t data_length) {
         hidl_vec<uint8_t> new_blob;
         new_blob.setToExternal(const_cast<uint8_t*>(data), data_length);
-        push_back(ttag, std::move(new_blob));
+        push_back(ttag, new_blob);
         return *this;
     }
 
diff --git a/keymaster/4.0/support/include/keymasterV4_0/authorization_set.h b/keymaster/4.0/support/include/keymasterV4_0/authorization_set.h
index ac96c86..a131423 100644
--- a/keymaster/4.0/support/include/keymasterV4_0/authorization_set.h
+++ b/keymaster/4.0/support/include/keymasterV4_0/authorization_set.h
@@ -214,9 +214,8 @@
         }
     }
 
-    const hidl_vec<KeyParameter> hidl_data() const {
-        hidl_vec<KeyParameter> result;
-        result.setToExternal(const_cast<KeyParameter*>(data()), size());
+    hidl_vec<KeyParameter> hidl_data() const {
+        hidl_vec<KeyParameter> result(begin(), end());
         return result;
     }
 
@@ -242,7 +241,7 @@
                                            size_t data_length) {
         hidl_vec<uint8_t> new_blob;
         new_blob.setToExternal(const_cast<uint8_t*>(data), data_length);
-        push_back(ttag, std::move(new_blob));
+        push_back(ttag, new_blob);
         return *this;
     }
 
diff --git a/keymaster/4.0/support/include/keymasterV4_0/keymaster_utils.h b/keymaster/4.0/support/include/keymasterV4_0/keymaster_utils.h
index 90a0f1b..5e5ae8d 100644
--- a/keymaster/4.0/support/include/keymasterV4_0/keymaster_utils.h
+++ b/keymaster/4.0/support/include/keymasterV4_0/keymaster_utils.h
@@ -33,25 +33,19 @@
 
 namespace support {
 
-inline static hidl_vec<uint8_t> blob2hidlVec(const uint8_t* data, const size_t length,
-                                             bool inPlace = true) {
-    hidl_vec<uint8_t> result;
-    result.setToExternal(const_cast<unsigned char*>(data), length, !inPlace);
+inline static hidl_vec<uint8_t> blob2hidlVec(const uint8_t* data, const size_t length) {
+    hidl_vec<uint8_t> result(data, data + length);
     return result;
 }
 
-inline static hidl_vec<uint8_t> blob2hidlVec(const std::string& value, bool inPlace = true) {
-    hidl_vec<uint8_t> result;
-    result.setToExternal(const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(value.data())),
-                         static_cast<size_t>(value.size()), !inPlace);
+inline static hidl_vec<uint8_t> blob2hidlVec(const std::string& value) {
+    hidl_vec<uint8_t> result(reinterpret_cast<const uint8_t*>(value.data()),
+                             reinterpret_cast<const uint8_t*>(value.data()) + value.size());
     return result;
 }
 
-inline static hidl_vec<uint8_t> blob2hidlVec(const std::vector<uint8_t>& blob,
-                                             bool inPlace = true) {
-    hidl_vec<uint8_t> result;
-    result.setToExternal(const_cast<uint8_t*>(blob.data()), static_cast<size_t>(blob.size()),
-                         !inPlace);
+inline static hidl_vec<uint8_t> blob2hidlVec(const std::vector<uint8_t>& blob) {
+    hidl_vec<uint8_t> result(blob.data(), blob.data() + static_cast<size_t>(blob.size()));
     return result;
 }
 
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index 14e9595..fe9b312 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -113,6 +113,8 @@
     UNIDIRECTIONAL_SEQUENCE_LSTM = 85,
     UNIDIRECTIONAL_SEQUENCE_RNN = 86,
     ROTATED_BBOX_TRANSFORM = 87,
+    ABS = 88,
+    ROI_POOLING = 89,
 };
 
 /**
diff --git a/radio/1.3/Android.bp b/radio/1.3/Android.bp
index 3c65180..7012f6b 100644
--- a/radio/1.3/Android.bp
+++ b/radio/1.3/Android.bp
@@ -24,6 +24,7 @@
         "CellConfigLte",
         "CellInfo",
         "CellInfoLte",
+        "CardStatus",
         "DataProfileInfo",
         "DataRegStateResult",
         "EmergencyNumber",
diff --git a/radio/1.3/IRadioResponse.hal b/radio/1.3/IRadioResponse.hal
index 75d1501..fecd951 100644
--- a/radio/1.3/IRadioResponse.hal
+++ b/radio/1.3/IRadioResponse.hal
@@ -72,4 +72,19 @@
      */
     oneway getDataRegistrationStateResponse_1_3(RadioResponseInfo info,
             DataRegStateResult dataRegResponse);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     * @param cardStatus ICC card status as defined by CardStatus in types.hal
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     */
+    oneway getIccCardStatusResponse_1_3(RadioResponseInfo info, CardStatus cardStatus);
 };
diff --git a/radio/1.3/types.hal b/radio/1.3/types.hal
index b161e0e..d3a6f78 100644
--- a/radio/1.3/types.hal
+++ b/radio/1.3/types.hal
@@ -33,6 +33,7 @@
 import @1.2::CellInfoLte;
 import @1.2::CellInfoTdscdma;
 import @1.2::CellInfoWcdma;
+import @1.2::CardStatus;
 import @1.2::CellIdentity;
 import @1.2::DataRegStateResult;
 
@@ -325,3 +326,15 @@
      */
     bool persistent;
 };
+
+struct CardStatus {
+    @1.2::CardStatus base;
+    /**
+     * The EID is the eUICC identifier. The EID shall be stored within the ECASD and can be
+     * retrieved by the Device at any time using the standard GlobalPlatform GET DATA command.
+     *
+     * This data is mandatory and applicable only when cardState is CardState:PRESENT and SIM card
+     * supports eUICC.
+     */
+    string eid;
+};
diff --git a/sensors/2.0/default/Android.bp b/sensors/2.0/default/Android.bp
index 11612d3..db0b148 100644
--- a/sensors/2.0/default/Android.bp
+++ b/sensors/2.0/default/Android.bp
@@ -32,6 +32,7 @@
         "libhidlbase",
         "libhidltransport",
         "liblog",
+        "libpower",
         "libutils",
     ],
 }
diff --git a/sensors/2.0/default/Sensor.cpp b/sensors/2.0/default/Sensor.cpp
index d3e3f7e..168b402 100644
--- a/sensors/2.0/default/Sensor.cpp
+++ b/sensors/2.0/default/Sensor.cpp
@@ -29,14 +29,20 @@
 using ::android::hardware::sensors::V1_0::SensorStatus;
 
 Sensor::Sensor(ISensorsEventCallback* callback)
-    : mIsEnabled(false), mSamplingPeriodNs(0), mLastSampleTimeNs(0), mCallback(callback) {
+    : mIsEnabled(false),
+      mSamplingPeriodNs(0),
+      mLastSampleTimeNs(0),
+      mCallback(callback),
+      mMode(OperationMode::NORMAL) {
     mRunThread = std::thread(startThread, this);
 }
 
 Sensor::~Sensor() {
+    std::unique_lock<std::mutex> lock(mRunMutex);
     mStopThread = true;
     mIsEnabled = false;
     mWaitCV.notify_all();
+    lock.release();
     mRunThread.join();
 }
 
@@ -60,6 +66,7 @@
 
 void Sensor::activate(bool enable) {
     if (mIsEnabled != enable) {
+        std::unique_lock<std::mutex> lock(mRunMutex);
         mIsEnabled = enable;
         mWaitCV.notify_all();
     }
@@ -79,7 +86,7 @@
     ev.sensorType = SensorType::ADDITIONAL_INFO;
     ev.u.meta.what = MetaDataEventType::META_DATA_FLUSH_COMPLETE;
     std::vector<Event> evs{ev};
-    mCallback->postEvents(evs);
+    mCallback->postEvents(evs, isWakeUpSensor());
 
     return Result::OK;
 }
@@ -89,13 +96,14 @@
 }
 
 void Sensor::run() {
-    std::mutex runMutex;
-    std::unique_lock<std::mutex> runLock(runMutex);
+    std::unique_lock<std::mutex> runLock(mRunMutex);
     constexpr int64_t kNanosecondsInSeconds = 1000 * 1000 * 1000;
 
     while (!mStopThread) {
-        if (!mIsEnabled) {
-            mWaitCV.wait(runLock, [&] { return mIsEnabled || mStopThread; });
+        if (!mIsEnabled || mMode == OperationMode::DATA_INJECTION) {
+            mWaitCV.wait(runLock, [&] {
+                return ((mIsEnabled && mMode == OperationMode::NORMAL) || mStopThread);
+            });
         } else {
             timespec curTime;
             clock_gettime(CLOCK_REALTIME, &curTime);
@@ -105,7 +113,7 @@
             if (now >= nextSampleTime) {
                 mLastSampleTimeNs = now;
                 nextSampleTime = mLastSampleTimeNs + mSamplingPeriodNs;
-                mCallback->postEvents(readEvents());
+                mCallback->postEvents(readEvents(), isWakeUpSensor());
             }
 
             mWaitCV.wait_for(runLock, std::chrono::nanoseconds(nextSampleTime - now));
@@ -113,6 +121,10 @@
     }
 }
 
+bool Sensor::isWakeUpSensor() {
+    return mSensorInfo.flags & static_cast<uint32_t>(SensorFlagBits::WAKE_UP);
+}
+
 std::vector<Event> Sensor::readEvents() {
     std::vector<Event> events;
     Event event;
@@ -127,6 +139,33 @@
     return events;
 }
 
+void Sensor::setOperationMode(OperationMode mode) {
+    if (mMode != mode) {
+        std::unique_lock<std::mutex> lock(mRunMutex);
+        mMode = mode;
+        mWaitCV.notify_all();
+    }
+}
+
+bool Sensor::supportsDataInjection() const {
+    return mSensorInfo.flags & static_cast<uint32_t>(SensorFlagBits::DATA_INJECTION);
+}
+
+Result Sensor::injectEvent(const Event& event) {
+    Result result = Result::OK;
+    if (event.sensorType == SensorType::ADDITIONAL_INFO) {
+        // When in OperationMode::NORMAL, SensorType::ADDITIONAL_INFO is used to push operation
+        // environment data into the device.
+    } else if (!supportsDataInjection()) {
+        result = Result::INVALID_OPERATION;
+    } else if (mMode == OperationMode::DATA_INJECTION) {
+        mCallback->postEvents(std::vector<Event>{event}, isWakeUpSensor());
+    } else {
+        result = Result::BAD_VALUE;
+    }
+    return result;
+}
+
 AccelSensor::AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback) : Sensor(callback) {
     mSensorInfo.sensorHandle = sensorHandle;
     mSensorInfo.name = "Accel Sensor";
@@ -142,7 +181,8 @@
     mSensorInfo.fifoReservedEventCount = 0;
     mSensorInfo.fifoMaxEventCount = 0;
     mSensorInfo.requiredPermission = "";
-    mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::WAKE_UP);
+    mSensorInfo.flags =
+        static_cast<uint32_t>(SensorFlagBits::WAKE_UP | SensorFlagBits::DATA_INJECTION);
 };
 
 }  // namespace implementation
diff --git a/sensors/2.0/default/Sensor.h b/sensors/2.0/default/Sensor.h
index 75d9aab..3ab2299 100644
--- a/sensors/2.0/default/Sensor.h
+++ b/sensors/2.0/default/Sensor.h
@@ -21,10 +21,12 @@
 
 #include <condition_variable>
 #include <memory>
+#include <mutex>
 #include <thread>
 #include <vector>
 
 using ::android::hardware::sensors::V1_0::Event;
+using ::android::hardware::sensors::V1_0::OperationMode;
 using ::android::hardware::sensors::V1_0::Result;
 using ::android::hardware::sensors::V1_0::SensorInfo;
 using ::android::hardware::sensors::V1_0::SensorType;
@@ -38,7 +40,7 @@
 class ISensorsEventCallback {
    public:
     virtual ~ISensorsEventCallback(){};
-    virtual void postEvents(const std::vector<Event>& events) = 0;
+    virtual void postEvents(const std::vector<Event>& events, bool wakeup) = 0;
 };
 
 class Sensor {
@@ -51,11 +53,17 @@
     void activate(bool enable);
     Result flush();
 
+    void setOperationMode(OperationMode mode);
+    bool supportsDataInjection() const;
+    Result injectEvent(const Event& event);
+
    protected:
     void run();
     virtual std::vector<Event> readEvents();
     static void startThread(Sensor* sensor);
 
+    bool isWakeUpSensor();
+
     bool mIsEnabled;
     int64_t mSamplingPeriodNs;
     int64_t mLastSampleTimeNs;
@@ -63,9 +71,12 @@
 
     std::atomic_bool mStopThread;
     std::condition_variable mWaitCV;
+    std::mutex mRunMutex;
     std::thread mRunThread;
 
     ISensorsEventCallback* mCallback;
+
+    OperationMode mMode;
 };
 
 class AccelSensor : public Sensor {
diff --git a/sensors/2.0/default/Sensors.cpp b/sensors/2.0/default/Sensors.cpp
index cceb7d5..efc8b05 100644
--- a/sensors/2.0/default/Sensors.cpp
+++ b/sensors/2.0/default/Sensors.cpp
@@ -30,8 +30,16 @@
 using ::android::hardware::sensors::V1_0::RateLevel;
 using ::android::hardware::sensors::V1_0::Result;
 using ::android::hardware::sensors::V1_0::SharedMemInfo;
+using ::android::hardware::sensors::V2_0::SensorTimeout;
 
-Sensors::Sensors() : mEventQueueFlag(nullptr) {
+constexpr const char* kWakeLockName = "SensorsHAL_WAKEUP";
+
+Sensors::Sensors()
+    : mEventQueueFlag(nullptr),
+      mOutstandingWakeUpEvents(0),
+      mReadWakeLockQueueRun(false),
+      mAutoReleaseWakeLockTime(0),
+      mHasWakeLock(false) {
     std::shared_ptr<AccelSensor> accel =
         std::make_shared<AccelSensor>(1 /* sensorHandle */, this /* callback */);
     mSensors[accel->getSensorInfo().sensorHandle] = accel;
@@ -39,6 +47,8 @@
 
 Sensors::~Sensors() {
     deleteEventFlag();
+    mReadWakeLockQueueRun = false;
+    mWakeLockThread.join();
 }
 
 // Methods from ::android::hardware::sensors::V2_0::ISensors follow.
@@ -54,9 +64,11 @@
     return Void();
 }
 
-Return<Result> Sensors::setOperationMode(OperationMode /* mode */) {
-    // TODO implement
-    return Result{};
+Return<Result> Sensors::setOperationMode(OperationMode mode) {
+    for (auto sensor : mSensors) {
+        sensor.second->setOperationMode(mode);
+    }
+    return Result::OK;
 }
 
 Return<Result> Sensors::activate(int32_t sensorHandle, bool enabled) {
@@ -99,6 +111,10 @@
         result = Result::BAD_VALUE;
     }
 
+    // Start the thread to read events from the Wake Lock FMQ
+    mReadWakeLockQueueRun = true;
+    mWakeLockThread = std::thread(startReadWakeLockThread, this);
+
     return result;
 }
 
@@ -120,14 +136,18 @@
     return Result::BAD_VALUE;
 }
 
-Return<Result> Sensors::injectSensorData(const Event& /* event */) {
-    // TODO implement
-    return Result{};
+Return<Result> Sensors::injectSensorData(const Event& event) {
+    auto sensor = mSensors.find(event.sensorHandle);
+    if (sensor != mSensors.end()) {
+        return sensor->second->injectEvent(event);
+    }
+
+    return Result::BAD_VALUE;
 }
 
 Return<void> Sensors::registerDirectChannel(const SharedMemInfo& /* mem */,
                                             registerDirectChannel_cb _hidl_cb) {
-    _hidl_cb(Result::INVALID_OPERATION, 0 /* channelHandle */);
+    _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */);
     return Return<void>();
 }
 
@@ -141,15 +161,67 @@
     return Return<void>();
 }
 
-void Sensors::postEvents(const std::vector<Event>& events) {
-    std::lock_guard<std::mutex> l(mLock);
+void Sensors::postEvents(const std::vector<Event>& events, bool wakeup) {
+    std::lock_guard<std::mutex> lock(mWriteLock);
+    if (mEventQueue->write(events.data(), events.size())) {
+        mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
 
-    // TODO: read events from the Wake Lock FMQ in the right place
-    std::vector<uint32_t> tmp(mWakeLockQueue->availableToRead());
-    mWakeLockQueue->read(tmp.data(), mWakeLockQueue->availableToRead());
+        if (wakeup) {
+            // Keep track of the number of outstanding WAKE_UP events in order to properly hold
+            // a wake lock until the framework has secured a wake lock
+            updateWakeLock(events.size(), 0 /* eventsHandled */);
+        }
+    }
+}
 
-    mEventQueue->write(events.data(), events.size());
-    mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
+void Sensors::updateWakeLock(int32_t eventsWritten, int32_t eventsHandled) {
+    std::lock_guard<std::mutex> lock(mWakeLockLock);
+    int32_t newVal = mOutstandingWakeUpEvents + eventsWritten - eventsHandled;
+    if (newVal < 0) {
+        mOutstandingWakeUpEvents = 0;
+    } else {
+        mOutstandingWakeUpEvents = newVal;
+    }
+
+    if (eventsWritten > 0) {
+        // Update the time at which the last WAKE_UP event was sent
+        mAutoReleaseWakeLockTime = ::android::uptimeMillis() +
+                                   static_cast<uint32_t>(SensorTimeout::WAKE_LOCK_SECONDS) * 1000;
+    }
+
+    if (!mHasWakeLock && mOutstandingWakeUpEvents > 0 &&
+        acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLockName) == 0) {
+        mHasWakeLock = true;
+    } else if (mHasWakeLock) {
+        // Check if the wake lock should be released automatically if
+        // SensorTimeout::WAKE_LOCK_SECONDS has elapsed since the last WAKE_UP event was written to
+        // the Wake Lock FMQ.
+        if (::android::uptimeMillis() > mAutoReleaseWakeLockTime) {
+            ALOGD("No events read from wake lock FMQ for %d seconds, auto releasing wake lock",
+                  SensorTimeout::WAKE_LOCK_SECONDS);
+            mOutstandingWakeUpEvents = 0;
+        }
+
+        if (mOutstandingWakeUpEvents == 0 && release_wake_lock(kWakeLockName) == 0) {
+            mHasWakeLock = false;
+        }
+    }
+}
+
+void Sensors::readWakeLockFMQ() {
+    while (mReadWakeLockQueueRun.load()) {
+        constexpr int64_t kReadTimeoutNs = 500 * 1000 * 1000;  // 500 ms
+        uint32_t eventsHandled = 0;
+
+        // Read events from the Wake Lock FMQ. Timeout after a reasonable amount of time to ensure
+        // that any held wake lock is able to be released if it is held for too long.
+        mWakeLockQueue->readBlocking(&eventsHandled, 1 /* count */, kReadTimeoutNs);
+        updateWakeLock(0 /* eventsWritten */, eventsHandled);
+    }
+}
+
+void Sensors::startReadWakeLockThread(Sensors* sensors) {
+    sensors->readWakeLockFMQ();
 }
 
 void Sensors::deleteEventFlag() {
diff --git a/sensors/2.0/default/Sensors.h b/sensors/2.0/default/Sensors.h
index f543935..eba3f97 100644
--- a/sensors/2.0/default/Sensors.h
+++ b/sensors/2.0/default/Sensors.h
@@ -21,10 +21,13 @@
 
 #include <android/hardware/sensors/2.0/ISensors.h>
 #include <fmq/MessageQueue.h>
+#include <hardware_legacy/power.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
 
+#include <atomic>
 #include <memory>
+#include <thread>
 
 namespace android {
 namespace hardware {
@@ -80,7 +83,7 @@
     Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate,
                                     configDirectReport_cb _hidl_cb) override;
 
-    void postEvents(const std::vector<Event>& events) override;
+    void postEvents(const std::vector<Event>& events, bool wakeup) override;
 
    private:
     /**
@@ -88,6 +91,18 @@
      */
     void deleteEventFlag();
 
+    /**
+     * Function to read the Wake Lock FMQ and release the wake lock when appropriate
+     */
+    void readWakeLockFMQ();
+
+    static void startReadWakeLockThread(Sensors* sensors);
+
+    /**
+     * Responsible for acquiring and releasing a wake lock when there are unhandled WAKE_UP events
+     */
+    void updateWakeLock(int32_t eventsWritten, int32_t eventsHandled);
+
     using EventMessageQueue = MessageQueue<Event, kSynchronizedReadWrite>;
     using WakeLockMessageQueue = MessageQueue<uint32_t, kSynchronizedReadWrite>;
 
@@ -117,9 +132,39 @@
     std::map<int32_t, std::shared_ptr<Sensor>> mSensors;
 
     /**
-     * Lock to protect writes and reads to the FMQs
+     * Lock to protect writes to the FMQs
      */
-    std::mutex mLock;
+    std::mutex mWriteLock;
+
+    /**
+     * Lock to protect acquiring and releasing the wake lock
+     */
+    std::mutex mWakeLockLock;
+
+    /**
+     * Track the number of WAKE_UP events that have not been handled by the framework
+     */
+    uint32_t mOutstandingWakeUpEvents;
+
+    /**
+     * A thread to read the Wake Lock FMQ
+     */
+    std::thread mWakeLockThread;
+
+    /**
+     * Flag to indicate that the Wake Lock Thread should continue to run
+     */
+    std::atomic_bool mReadWakeLockQueueRun;
+
+    /**
+     * Track the time when the wake lock should automatically be released
+     */
+    int64_t mAutoReleaseWakeLockTime;
+
+    /**
+     * Flag to indicate if a wake lock has been acquired
+     */
+    bool mHasWakeLock;
 };
 
 }  // namespace implementation
diff --git a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
index 3e5837b..ac020ad 100644
--- a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
+++ b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
@@ -18,6 +18,7 @@
 
 #include "SensorsHidlEnvironmentV2_0.h"
 #include "sensors-vts-utils/SensorsHidlTestBase.h"
+#include "sensors-vts-utils/SensorsTestSharedMemory.h"
 
 #include <android/hardware/sensors/2.0/ISensors.h>
 #include <android/hardware/sensors/2.0/types.h>
@@ -26,6 +27,7 @@
 
 #include <cinttypes>
 #include <condition_variable>
+#include <cstring>
 #include <map>
 #include <vector>
 
@@ -34,7 +36,9 @@
 using ::android::hardware::Void;
 using ::android::hardware::sensors::V1_0::MetaDataEventType;
 using ::android::hardware::sensors::V1_0::OperationMode;
+using ::android::hardware::sensors::V1_0::SensorsEventFormatOffset;
 using ::android::hardware::sensors::V1_0::SensorStatus;
+using ::android::hardware::sensors::V1_0::SharedMemType;
 using ::android::hardware::sensors::V1_0::Vec3;
 
 class EventCallback : public IEventCallback {
@@ -164,7 +168,17 @@
     void activateAllSensors(bool enable);
     std::vector<SensorInfo> getNonOneShotSensors();
     std::vector<SensorInfo> getOneShotSensors();
+    std::vector<SensorInfo> getInjectEventSensors();
     int32_t getInvalidSensorHandle();
+    void verifyDirectChannel(SharedMemType memType);
+    void verifyRegisterDirectChannel(const SensorInfo& sensor, SharedMemType memType,
+                                     std::shared_ptr<SensorsTestSharedMemory> mem,
+                                     int32_t* directChannelHandle);
+    void verifyConfigure(const SensorInfo& sensor, SharedMemType memType,
+                         int32_t directChannelHandle);
+    void verifyUnregisterDirectChannel(const SensorInfo& sensor, SharedMemType memType,
+                                       int32_t directChannelHandle);
+    void checkRateLevel(const SensorInfo& sensor, int32_t directChannelHandle, RateLevel rateLevel);
 };
 
 Return<Result> SensorsHidlTest::activate(int32_t sensorHandle, bool enabled) {
@@ -243,6 +257,16 @@
     return sensors;
 }
 
+std::vector<SensorInfo> SensorsHidlTest::getInjectEventSensors() {
+    std::vector<SensorInfo> sensors;
+    for (const SensorInfo& info : getSensorsList()) {
+        if (info.flags & static_cast<uint32_t>(SensorFlagBits::DATA_INJECTION)) {
+            sensors.push_back(info);
+        }
+    }
+    return sensors;
+}
+
 int32_t SensorsHidlTest::getInvalidSensorHandle() {
     // Find a sensor handle that does not exist in the sensor list
     int32_t maxHandle = 0;
@@ -297,63 +321,71 @@
     });
 }
 
-// Test if sensor list returned is valid
+// Test that SetOperationMode returns the expected value
 TEST_F(SensorsHidlTest, SetOperationMode) {
-    std::vector<SensorInfo> sensorList = getSensorsList();
-
-    bool needOperationModeSupport =
-        std::any_of(sensorList.begin(), sensorList.end(),
-                    [](const auto& s) { return (s.flags & SensorFlagBits::DATA_INJECTION) != 0; });
-    if (!needOperationModeSupport) {
-        return;
+    std::vector<SensorInfo> sensors = getInjectEventSensors();
+    if (getInjectEventSensors().size() > 0) {
+        ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
+        ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::DATA_INJECTION));
+        ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
+    } else {
+        ASSERT_EQ(Result::BAD_VALUE, getSensors()->setOperationMode(OperationMode::DATA_INJECTION));
     }
-
-    ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
-    ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::DATA_INJECTION));
-    ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
 }
 
-// Test if sensor list returned is valid
+// Test that an injected event is written back to the Event FMQ
 TEST_F(SensorsHidlTest, InjectSensorEventData) {
-    std::vector<SensorInfo> sensorList = getSensorsList();
-    std::vector<SensorInfo> sensorSupportInjection;
-
-    bool needOperationModeSupport =
-        std::any_of(sensorList.begin(), sensorList.end(), [&sensorSupportInjection](const auto& s) {
-            bool ret = (s.flags & SensorFlagBits::DATA_INJECTION) != 0;
-            if (ret) {
-                sensorSupportInjection.push_back(s);
-            }
-            return ret;
-        });
-    if (!needOperationModeSupport) {
+    std::vector<SensorInfo> sensors = getInjectEventSensors();
+    if (sensors.size() == 0) {
         return;
     }
 
-    ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
     ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::DATA_INJECTION));
 
-    for (const auto& s : sensorSupportInjection) {
-        switch (s.type) {
-            case SensorType::ACCELEROMETER:
-            case SensorType::GYROSCOPE:
-            case SensorType::MAGNETIC_FIELD: {
-                usleep(100000);  // sleep 100ms
+    EventCallback callback;
+    getEnvironment()->registerCallback(&callback);
 
-                Event dummy;
-                dummy.timestamp = android::elapsedRealtimeNano();
-                dummy.sensorType = s.type;
-                dummy.sensorHandle = s.sensorHandle;
-                Vec3 v = {1, 2, 3, SensorStatus::ACCURACY_HIGH};
-                dummy.u.vec3 = v;
+    // AdditionalInfo event should not be sent to Event FMQ
+    Event additionalInfoEvent;
+    additionalInfoEvent.sensorType = SensorType::ADDITIONAL_INFO;
+    additionalInfoEvent.timestamp = android::elapsedRealtimeNano();
 
-                EXPECT_EQ(Result::OK, getSensors()->injectSensorData(dummy));
-                break;
-            }
-            default:
-                break;
-        }
+    Event injectedEvent;
+    injectedEvent.timestamp = android::elapsedRealtimeNano();
+    Vec3 data = {1, 2, 3, SensorStatus::ACCURACY_HIGH};
+    injectedEvent.u.vec3 = data;
+
+    for (const auto& s : sensors) {
+        additionalInfoEvent.sensorHandle = s.sensorHandle;
+        EXPECT_EQ(Result::OK, getSensors()->injectSensorData(additionalInfoEvent));
+
+        injectedEvent.sensorType = s.type;
+        injectedEvent.sensorHandle = s.sensorHandle;
+        EXPECT_EQ(Result::OK, getSensors()->injectSensorData(injectedEvent));
     }
+
+    // Wait for events to be written back to the Event FMQ
+    callback.waitForEvents(sensors, 1000 /* timeoutMs */);
+
+    for (const auto& s : sensors) {
+        auto events = callback.getEvents(s.sensorHandle);
+        auto lastEvent = events.back();
+
+        // Verify that only a single event has been received
+        ASSERT_EQ(events.size(), 1);
+
+        // Verify that the event received matches the event injected and is not the additional
+        // info event
+        ASSERT_EQ(lastEvent.sensorType, s.type);
+        ASSERT_EQ(lastEvent.sensorType, s.type);
+        ASSERT_EQ(lastEvent.timestamp, injectedEvent.timestamp);
+        ASSERT_EQ(lastEvent.u.vec3.x, injectedEvent.u.vec3.x);
+        ASSERT_EQ(lastEvent.u.vec3.y, injectedEvent.u.vec3.y);
+        ASSERT_EQ(lastEvent.u.vec3.z, injectedEvent.u.vec3.z);
+        ASSERT_EQ(lastEvent.u.vec3.status, injectedEvent.u.vec3.status);
+    }
+
+    getEnvironment()->unregisterCallback();
     ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
 }
 
@@ -789,6 +821,128 @@
     getEnvironment()->unregisterCallback();
 }
 
+void SensorsHidlTest::checkRateLevel(const SensorInfo& sensor, int32_t directChannelHandle,
+                                     RateLevel rateLevel) {
+    configDirectReport(sensor.sensorHandle, directChannelHandle, rateLevel,
+                       [&](Result result, int32_t reportToken) {
+                           if (isDirectReportRateSupported(sensor, rateLevel)) {
+                               ASSERT_EQ(result, Result::OK);
+                               ASSERT_GT(reportToken, 0);
+                           } else {
+                               ASSERT_EQ(result, Result::BAD_VALUE);
+                           }
+                       });
+}
+
+void SensorsHidlTest::verifyRegisterDirectChannel(const SensorInfo& sensor, SharedMemType memType,
+                                                  std::shared_ptr<SensorsTestSharedMemory> mem,
+                                                  int32_t* directChannelHandle) {
+    char* buffer = mem->getBuffer();
+    memset(buffer, 0xff, mem->getSize());
+
+    registerDirectChannel(mem->getSharedMemInfo(), [&](Result result, int32_t channelHandle) {
+        if (isDirectChannelTypeSupported(sensor, memType)) {
+            ASSERT_EQ(result, Result::OK);
+            ASSERT_GT(channelHandle, 0);
+
+            // Verify that the memory has been zeroed
+            for (size_t i = 0; i < mem->getSize(); i++) {
+                ASSERT_EQ(buffer[i], 0x00);
+            }
+        } else {
+            ASSERT_EQ(result, Result::INVALID_OPERATION);
+            ASSERT_EQ(channelHandle, -1);
+        }
+        *directChannelHandle = channelHandle;
+    });
+}
+
+void SensorsHidlTest::verifyConfigure(const SensorInfo& sensor, SharedMemType memType,
+                                      int32_t directChannelHandle) {
+    if (isDirectChannelTypeSupported(sensor, memType)) {
+        // Verify that each rate level is properly supported
+        checkRateLevel(sensor, directChannelHandle, RateLevel::NORMAL);
+        checkRateLevel(sensor, directChannelHandle, RateLevel::FAST);
+        checkRateLevel(sensor, directChannelHandle, RateLevel::VERY_FAST);
+        checkRateLevel(sensor, directChannelHandle, RateLevel::STOP);
+
+        // Verify that a sensor handle of -1 is only acceptable when using RateLevel::STOP
+        configDirectReport(
+            -1 /* sensorHandle */, directChannelHandle, RateLevel::NORMAL,
+            [](Result result, int32_t /* reportToken */) { ASSERT_EQ(result, Result::BAD_VALUE); });
+        configDirectReport(
+            -1 /* sensorHandle */, directChannelHandle, RateLevel::STOP,
+            [](Result result, int32_t /* reportToken */) { ASSERT_EQ(result, Result::OK); });
+    } else {
+        // Direct channel is not supported for this SharedMemType
+        configDirectReport(sensor.sensorHandle, directChannelHandle, RateLevel::NORMAL,
+                           [](Result result, int32_t /* reportToken */) {
+                               ASSERT_EQ(result, Result::INVALID_OPERATION);
+                           });
+    }
+}
+
+void SensorsHidlTest::verifyUnregisterDirectChannel(const SensorInfo& sensor, SharedMemType memType,
+                                                    int32_t directChannelHandle) {
+    Result result = unregisterDirectChannel(directChannelHandle);
+    if (isDirectChannelTypeSupported(sensor, memType)) {
+        ASSERT_EQ(result, Result::OK);
+    } else {
+        ASSERT_EQ(result, Result::INVALID_OPERATION);
+    }
+}
+
+void SensorsHidlTest::verifyDirectChannel(SharedMemType memType) {
+    constexpr size_t kEventSize = static_cast<size_t>(SensorsEventFormatOffset::TOTAL_LENGTH);
+    constexpr size_t kNumEvents = 1;
+    constexpr size_t kMemSize = kNumEvents * kEventSize;
+
+    std::shared_ptr<SensorsTestSharedMemory> mem(
+        SensorsTestSharedMemory::create(memType, kMemSize));
+    ASSERT_NE(mem, nullptr);
+
+    for (const SensorInfo& sensor : getSensorsList()) {
+        int32_t directChannelHandle = 0;
+        verifyRegisterDirectChannel(sensor, memType, mem, &directChannelHandle);
+        verifyConfigure(sensor, memType, directChannelHandle);
+        verifyUnregisterDirectChannel(sensor, memType, directChannelHandle);
+    }
+}
+
+TEST_F(SensorsHidlTest, DirectChannelAshmem) {
+    verifyDirectChannel(SharedMemType::ASHMEM);
+}
+
+TEST_F(SensorsHidlTest, DirectChannelGralloc) {
+    verifyDirectChannel(SharedMemType::GRALLOC);
+}
+
+TEST_F(SensorsHidlTest, ConfigureDirectChannelWithInvalidHandle) {
+    for (const SensorInfo& sensor : getSensorsList()) {
+        if (isDirectChannelTypeSupported(sensor, SharedMemType::ASHMEM) ||
+            isDirectChannelTypeSupported(sensor, SharedMemType::GRALLOC)) {
+            // Find a supported rate level
+            RateLevel rate = RateLevel::STOP;
+            if (isDirectReportRateSupported(sensor, RateLevel::NORMAL)) {
+                rate = RateLevel::NORMAL;
+            } else if (isDirectReportRateSupported(sensor, RateLevel::FAST)) {
+                rate = RateLevel::FAST;
+            } else if (isDirectReportRateSupported(sensor, RateLevel::VERY_FAST)) {
+                rate = RateLevel::VERY_FAST;
+            }
+
+            // Ensure that at least one rate level is supported
+            ASSERT_NE(rate, RateLevel::STOP);
+
+            // Verify that an invalid channel handle produces a BAD_VALUE result
+            configDirectReport(sensor.sensorHandle, -1, rate,
+                               [](Result result, int32_t /* reportToken */) {
+                                   ASSERT_EQ(result, Result::BAD_VALUE);
+                               });
+        }
+    }
+}
+
 int main(int argc, char** argv) {
     ::testing::AddGlobalTestEnvironment(SensorsHidlEnvironmentV2_0::Instance());
     ::testing::InitGoogleTest(&argc, argv);
diff --git a/sensors/common/vts/utils/SensorsTestSharedMemory.cpp b/sensors/common/vts/utils/SensorsTestSharedMemory.cpp
index 5096498..819e297 100644
--- a/sensors/common/vts/utils/SensorsTestSharedMemory.cpp
+++ b/sensors/common/vts/utils/SensorsTestSharedMemory.cpp
@@ -35,6 +35,10 @@
     return mBuffer;
 }
 
+size_t SensorsTestSharedMemory::getSize() const {
+    return mSize;
+}
+
 std::vector<Event> SensorsTestSharedMemory::parseEvents(int64_t lastCounter, size_t offset) const {
     constexpr size_t kEventSize = static_cast<size_t>(SensorsEventFormatOffset::TOTAL_LENGTH);
     constexpr size_t kOffsetSize = static_cast<size_t>(SensorsEventFormatOffset::SIZE_FIELD);
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsTestSharedMemory.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsTestSharedMemory.h
index 055b8e7..002f42c 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsTestSharedMemory.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsTestSharedMemory.h
@@ -33,6 +33,7 @@
     static SensorsTestSharedMemory* create(SharedMemType type, size_t size);
     SharedMemInfo getSharedMemInfo() const;
     char* getBuffer() const;
+    size_t getSize() const;
     std::vector<Event> parseEvents(int64_t lastCounter = -1, size_t offset = 0) const;
     virtual ~SensorsTestSharedMemory();
 
diff --git a/wifi/supplicant/1.2/Android.bp b/wifi/supplicant/1.2/Android.bp
index bafd148..93ce573 100644
--- a/wifi/supplicant/1.2/Android.bp
+++ b/wifi/supplicant/1.2/Android.bp
@@ -7,6 +7,8 @@
         enabled: true,
     },
     srcs: [
+        "ISupplicant.hal",
+        "ISupplicantStaIface.hal",
         "ISupplicantStaNetwork.hal",
     ],
     interfaces: [
diff --git a/wifi/supplicant/1.2/ISupplicant.hal b/wifi/supplicant/1.2/ISupplicant.hal
new file mode 100644
index 0000000..b0ec65d
--- /dev/null
+++ b/wifi/supplicant/1.2/ISupplicant.hal
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant@1.2;
+
+import @1.1::ISupplicant;
+
+/**
+ * Interface exposed by the supplicant HIDL service registered
+ * with the hardware service manager.
+ * This is the root level object for any the supplicant interactions.
+ * To use 1.2 features you must cast specific interfaces returned from the
+ * 1.1 HAL. For example V1_1::ISupplicant::addIface() adds V1_1::ISupplicantIface,
+ * which can be cast to V1_2::ISupplicantStaIface.
+ */
+interface ISupplicant extends @1.1::ISupplicant {
+};
diff --git a/wifi/supplicant/1.2/ISupplicantStaIface.hal b/wifi/supplicant/1.2/ISupplicantStaIface.hal
new file mode 100644
index 0000000..a338c6a
--- /dev/null
+++ b/wifi/supplicant/1.2/ISupplicantStaIface.hal
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant@1.2;
+
+import @1.0::SupplicantStatus;
+import @1.1::ISupplicantStaIface;
+import @1.2::ISupplicantStaNetwork;
+
+/**
+ * Interface exposed by the supplicant for each station mode network
+ * interface (e.g wlan0) it controls.
+ */
+interface ISupplicantStaIface extends @1.1::ISupplicantStaIface {
+
+    /**
+     * Get Key management capabilities of the device
+     *
+     * @return status Status of the operation, and a bitmap of key management mask.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    getKeyMgmtCapabilities()
+        generates (SupplicantStatus status, bitfield<KeyMgmtMask> keyMgmtMask);
+};
+
diff --git a/wifi/supplicant/1.2/ISupplicantStaNetwork.hal b/wifi/supplicant/1.2/ISupplicantStaNetwork.hal
index 85b233d..6fd0d51 100644
--- a/wifi/supplicant/1.2/ISupplicantStaNetwork.hal
+++ b/wifi/supplicant/1.2/ISupplicantStaNetwork.hal
@@ -256,17 +256,4 @@
      */
     setSaePasswordId(string saePasswordId)
         generates (SupplicantStatus status);
-
-    /**
-     * Get Key management capabilities of the device
-     *
-     * @return status Status of the operation, and a string.
-     *         Possible status codes:
-     *         |SupplicantStatusCode.SUCCESS|,
-     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
-     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
-     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
-     */
-    getKeyMgmtCapabilities()
-        generates (SupplicantStatus status, bitfield<KeyMgmtMask> keyMgmtMask);
 };