Merge "NNAPI narrow evaluation for P -- HAL"
diff --git a/audio/common/4.0/types.hal b/audio/common/4.0/types.hal
index d4c6efe..4efdea3 100644
--- a/audio/common/4.0/types.hal
+++ b/audio/common/4.0/types.hal
@@ -485,7 +485,7 @@
 };
 
 @export(name="", value_prefix="AUDIO_DEVICE_")
-enum AudioDevice : uint64_t {
+enum AudioDevice : uint32_t {
     NONE                          = 0x0,
     /** reserved bits */
     BIT_IN                        = 0x80000000,
@@ -530,6 +530,7 @@
     OUT_BUS                       = 0x1000000,
     OUT_PROXY                     = 0x2000000,
     OUT_USB_HEADSET               = 0x4000000,
+    OUT_HEARING_AID               = 0x8000000,
     OUT_ECHO_CANCELLER            = 0x10000000,
     OUT_DEFAULT                   = BIT_DEFAULT,
     // Note that the 2.0 OUT_ALL* have been moved to helper functions
diff --git a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
index aa8226c..d6d9ff8 100644
--- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
@@ -270,6 +270,12 @@
 }
 
 Return<Status> ExternalCameraDeviceSession::flush() {
+    Mutex::Autolock _il(mInterfaceLock);
+    Status status = initStatus();
+    if (status != Status::OK) {
+        return status;
+    }
+    mOutputThread->flush();
     return Status::OK;
 }
 
@@ -481,7 +487,7 @@
 }
 
 //TODO: refactor with processCaptureResult
-Status ExternalCameraDeviceSession::processCaptureRequestError(HalRequest& req) {
+Status ExternalCameraDeviceSession::processCaptureRequestError(const HalRequest& req) {
     // Return V4L2 buffer to V4L2 buffer queue
     enqueueV4l2Frame(req.frameIn);
 
@@ -1483,19 +1489,23 @@
         return true;
     }
 
+    auto onDeviceError = [&](auto... args) {
+        ALOGE(args...);
+        parent->notifyError(
+                req.frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE);
+        signalRequestDone();
+        return false;
+    };
+
     if (req.frameIn->mFourcc != V4L2_PIX_FMT_MJPEG) {
-        ALOGE("%s: do not support V4L2 format %c%c%c%c", __FUNCTION__,
+        return onDeviceError("%s: do not support V4L2 format %c%c%c%c", __FUNCTION__,
                 req.frameIn->mFourcc & 0xFF,
                 (req.frameIn->mFourcc >> 8) & 0xFF,
                 (req.frameIn->mFourcc >> 16) & 0xFF,
                 (req.frameIn->mFourcc >> 24) & 0xFF);
-        parent->notifyError(
-                /*frameNum*/req.frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE);
-        return false;
     }
 
-    std::unique_lock<std::mutex> lk(mLock);
-
+    std::unique_lock<std::mutex> lk(mBufferLock);
     // Convert input V4L2 frame to YU12 of the same size
     // TODO: see if we can save some computation by converting to YV12 here
     uint8_t* inData;
@@ -1520,11 +1530,9 @@
         lk.unlock();
         Status st = parent->processCaptureRequestError(req);
         if (st != Status::OK) {
-            ALOGE("%s: failed to process capture request error!", __FUNCTION__);
-            parent->notifyError(
-                    /*frameNum*/req.frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE);
-            return false;
+            return onDeviceError("%s: failed to process capture request error!", __FUNCTION__);
         }
+        signalRequestDone();
         return true;
     }
 
@@ -1551,15 +1559,9 @@
                 int ret = createJpegLocked(halBuf, req);
 
                 if(ret != 0) {
-                    ALOGE("%s: createJpegLocked failed with %d",
-                          __FUNCTION__, ret);
                     lk.unlock();
-                    parent->notifyError(
-                            /*frameNum*/req.frameNumber,
-                            /*stream*/-1,
-                            ErrorCode::ERROR_DEVICE);
-
-                    return false;
+                    return onDeviceError("%s: createJpegLocked failed with %d",
+                          __FUNCTION__, ret);
                 }
             } break;
             case PixelFormat::YCBCR_420_888:
@@ -1587,21 +1589,15 @@
                         Size { halBuf.width, halBuf.height },
                         &cropAndScaled);
                 if (ret != 0) {
-                    ALOGE("%s: crop and scale failed!", __FUNCTION__);
                     lk.unlock();
-                    parent->notifyError(
-                            /*frameNum*/req.frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE);
-                    return false;
+                    return onDeviceError("%s: crop and scale failed!", __FUNCTION__);
                 }
 
                 Size sz {halBuf.width, halBuf.height};
                 ret = formatConvertLocked(cropAndScaled, outLayout, sz, outputFourcc);
                 if (ret != 0) {
-                    ALOGE("%s: format coversion failed!", __FUNCTION__);
                     lk.unlock();
-                    parent->notifyError(
-                            /*frameNum*/req.frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE);
-                    return false;
+                    return onDeviceError("%s: format coversion failed!", __FUNCTION__);
                 }
                 int relFence = sHandleImporter.unlock(*(halBuf.bufPtr));
                 if (relFence > 0) {
@@ -1609,11 +1605,8 @@
                 }
             } break;
             default:
-                ALOGE("%s: unknown output format %x", __FUNCTION__, halBuf.format);
                 lk.unlock();
-                parent->notifyError(
-                        /*frameNum*/req.frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE);
-                return false;
+                return onDeviceError("%s: unknown output format %x", __FUNCTION__, halBuf.format);
         }
     } // for each buffer
     mScaledYu12Frames.clear();
@@ -1622,18 +1615,16 @@
     lk.unlock();
     Status st = parent->processCaptureResult(req);
     if (st != Status::OK) {
-        ALOGE("%s: failed to process capture result!", __FUNCTION__);
-        parent->notifyError(
-                /*frameNum*/req.frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE);
-        return false;
+        return onDeviceError("%s: failed to process capture result!", __FUNCTION__);
     }
+    signalRequestDone();
     return true;
 }
 
 Status ExternalCameraDeviceSession::OutputThread::allocateIntermediateBuffers(
         const Size& v4lSize, const Size& thumbSize,
         const hidl_vec<Stream>& streams) {
-    std::lock_guard<std::mutex> lk(mLock);
+    std::lock_guard<std::mutex> lk(mBufferLock);
     if (mScaledYu12Frames.size() != 0) {
         ALOGE("%s: intermediate buffer pool has %zu inflight buffers! (expect 0)",
                 __FUNCTION__, mScaledYu12Frames.size());
@@ -1705,17 +1696,36 @@
 }
 
 Status ExternalCameraDeviceSession::OutputThread::submitRequest(const HalRequest& req) {
-    std::lock_guard<std::mutex> lk(mLock);
+    std::unique_lock<std::mutex> lk(mRequestListLock);
     // TODO: reduce object copy in this path
     mRequestList.push_back(req);
+    lk.unlock();
     mRequestCond.notify_one();
     return Status::OK;
 }
 
 void ExternalCameraDeviceSession::OutputThread::flush() {
-    std::lock_guard<std::mutex> lk(mLock);
-    // TODO: send buffer/request errors back to framework
+    auto parent = mParent.promote();
+    if (parent == nullptr) {
+       ALOGE("%s: session has been disconnected!", __FUNCTION__);
+       return;
+    }
+
+    std::unique_lock<std::mutex> lk(mRequestListLock);
+    std::list<HalRequest> reqs = mRequestList;
     mRequestList.clear();
+    if (mProcessingRequest) {
+        std::chrono::seconds timeout = std::chrono::seconds(kReqWaitTimeoutSec);
+        auto st = mRequestDoneCond.wait_for(lk, timeout);
+        if (st == std::cv_status::timeout) {
+            ALOGE("%s: wait for inflight request finish timeout!", __FUNCTION__);
+        }
+    }
+
+    lk.unlock();
+    for (const auto& req : reqs) {
+        parent->processCaptureRequestError(req);
+    }
 }
 
 void ExternalCameraDeviceSession::OutputThread::waitForNextRequest(HalRequest* out) {
@@ -1724,7 +1734,7 @@
         return;
     }
 
-    std::unique_lock<std::mutex> lk(mLock);
+    std::unique_lock<std::mutex> lk(mRequestListLock);
     while (mRequestList.empty()) {
         std::chrono::seconds timeout = std::chrono::seconds(kReqWaitTimeoutSec);
         auto st = mRequestCond.wait_for(lk, timeout);
@@ -1735,6 +1745,14 @@
     }
     *out = mRequestList.front();
     mRequestList.pop_front();
+    mProcessingRequest = true;
+}
+
+void ExternalCameraDeviceSession::OutputThread::signalRequestDone() {
+    std::unique_lock<std::mutex> lk(mRequestListLock);
+    mProcessingRequest = false;
+    lk.unlock();
+    mRequestDoneCond.notify_one();
 }
 
 void ExternalCameraDeviceSession::cleanupBuffersLocked(int id) {
@@ -2057,8 +2075,8 @@
     {
         std::lock_guard<std::mutex> lk(mV4l2BufferLock);
         mNumDequeuedV4l2Buffers--;
-        mV4L2BufferReturned.notify_one();
     }
+    mV4L2BufferReturned.notify_one();
 }
 
 Status ExternalCameraDeviceSession::configureStreams(
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
index a7eb121..43656c8 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
@@ -199,7 +199,7 @@
     Status processOneCaptureRequest(const CaptureRequest& request);
 
     Status processCaptureResult(HalRequest&);
-    Status processCaptureRequestError(HalRequest&);
+    Status processCaptureRequestError(const HalRequest&);
     void notifyShutter(uint32_t frameNumber, nsecs_t shutterTs);
     void notifyError(uint32_t frameNumber, int32_t streamId, ErrorCode ec);
     void invokeProcessCaptureResultCallback(
@@ -235,6 +235,8 @@
         static const int kReqWaitTimeoutSec = 3;
 
         void waitForNextRequest(HalRequest* out);
+        void signalRequestDone();
+
         int cropAndScaleLocked(
                 sp<AllocatedFrame>& in, const Size& outSize,
                 YCbCrLayout* out);
@@ -254,15 +256,20 @@
 
         int createJpegLocked(HalStreamBuffer &halBuf, HalRequest &req);
 
-        mutable std::mutex mLock;
-        std::condition_variable mRequestCond;
-        wp<ExternalCameraDeviceSession> mParent;
-        CroppingType mCroppingType;
+        const wp<ExternalCameraDeviceSession> mParent;
+        const CroppingType mCroppingType;
+
+        mutable std::mutex mRequestListLock;      // Protect acccess to mRequestList
+        std::condition_variable mRequestCond;     // signaled when a new request is submitted
+        std::condition_variable mRequestDoneCond; // signaled when a request is done processing
         std::list<HalRequest> mRequestList;
+        bool mProcessingRequest = false;
+
         // V4L2 frameIn
         // (MJPG decode)-> mYu12Frame
         // (Scale)-> mScaledYu12Frames
         // (Format convert) -> output gralloc frames
+        mutable std::mutex mBufferLock; // Protect access to intermediate buffers
         sp<AllocatedFrame> mYu12Frame;
         sp<AllocatedFrame> mYu12ThumbFrame;
         std::unordered_map<Size, sp<AllocatedFrame>, SizeHasher> mIntermediateBuffers;
@@ -299,6 +306,7 @@
     std::condition_variable mV4L2BufferReturned;
     size_t mNumDequeuedV4l2Buffers = 0;
 
+    // Not protected by mLock (but might be used when mLock is locked)
     sp<OutputThread> mOutputThread;
 
     // Stream ID -> Camera3Stream cache
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index ca74ae1..e78dbe8 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -116,6 +116,7 @@
 const int64_t kTorchTimeoutSec = 1;
 const int64_t kEmptyFlushTimeoutMSec = 200;
 const char kDumpOutput[] = "/dev/null";
+const uint32_t kBurstFrameCount = 10;
 
 struct AvailableStream {
     int32_t width;
@@ -719,6 +720,20 @@
         // return from HAL but framework.
         ::android::Vector<StreamBuffer> resultOutputBuffers;
 
+        InFlightRequest() :
+                shutterTimestamp(0),
+                errorCodeValid(false),
+                errorCode(ErrorCode::ERROR_BUFFER),
+                usePartialResult(false),
+                numPartialResults(0),
+                resultQueue(nullptr),
+                haveResultMetadata(false),
+                numBuffersLeft(0),
+                frameNumber(0),
+                partialResultCount(0),
+                errorStreamId(-1),
+                hasInputBuffer(false) {}
+
         InFlightRequest(ssize_t numBuffers, bool hasInput,
                 bool partialResults, uint32_t partialCount,
                 std::shared_ptr<ResultMetadataQueue> queue = nullptr) :
@@ -3547,6 +3562,151 @@
     }
 }
 
+// Generate and verify a burst containing alternating sensor sensitivity values
+TEST_F(CameraHidlTest, processCaptureRequestBurstISO) {
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                                        static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+    uint64_t bufferId = 1;
+    uint32_t frameNumber = 1;
+    ::android::hardware::hidl_vec<uint8_t> settings;
+
+    for (const auto& name : cameraDeviceNames) {
+        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+        if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
+            continue;
+        } else if (deviceVersion <= 0) {
+            ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+            ADD_FAILURE();
+            return;
+        }
+        camera_metadata_t* staticMetaBuffer;
+        Return<void> ret;
+        sp<ICameraDeviceSession> session;
+        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/);
+        ::android::hardware::camera::common::V1_0::helper::CameraMetadata staticMeta(
+                staticMetaBuffer);
+
+        camera_metadata_entry_t hwLevel = staticMeta.find(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL);
+        ASSERT_TRUE(0 < hwLevel.count);
+        if (ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED == hwLevel.data.u8[0]) {
+            //Limited devices can skip this test
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
+            continue;
+        }
+
+        camera_metadata_entry_t isoRange = staticMeta.find(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE);
+        ASSERT_EQ(isoRange.count, 2u);
+
+        ret = session->close();
+        ASSERT_TRUE(ret.isOk());
+
+        bool supportsPartialResults = false;
+        uint32_t partialResultCount = 0;
+        V3_2::Stream previewStream;
+        HalStreamConfiguration halStreamConfig;
+        configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold,
+                &session /*out*/, &previewStream /*out*/, &halStreamConfig /*out*/,
+                &supportsPartialResults /*out*/, &partialResultCount /*out*/);
+        std::shared_ptr<ResultMetadataQueue> resultQueue;
+
+        auto resultQueueRet = session->getCaptureResultMetadataQueue(
+            [&resultQueue](const auto& descriptor) {
+                resultQueue = std::make_shared<ResultMetadataQueue>(descriptor);
+                if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
+                    ALOGE("%s: HAL returns empty result metadata fmq,"
+                            " not use it", __func__);
+                    resultQueue = nullptr;
+                    // Don't use the queue onwards.
+                }
+            });
+        ASSERT_TRUE(resultQueueRet.isOk());
+        ASSERT_NE(nullptr, resultQueue);
+
+        ret = session->constructDefaultRequestSettings(RequestTemplate::PREVIEW,
+            [&](auto status, const auto& req) {
+                ASSERT_EQ(Status::OK, status);
+                settings = req; });
+        ASSERT_TRUE(ret.isOk());
+
+        ::android::hardware::camera::common::V1_0::helper::CameraMetadata requestMeta;
+        StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr};
+        sp<GraphicBuffer> buffers[kBurstFrameCount];
+        StreamBuffer outputBuffers[kBurstFrameCount];
+        CaptureRequest requests[kBurstFrameCount];
+        InFlightRequest inflightReqs[kBurstFrameCount];
+        int32_t isoValues[kBurstFrameCount];
+        hidl_vec<uint8_t> requestSettings[kBurstFrameCount];
+        for (uint32_t i = 0; i < kBurstFrameCount; i++) {
+            std::unique_lock<std::mutex> l(mLock);
+
+            isoValues[i] = ((i % 2) == 0) ? isoRange.data.i32[0] : isoRange.data.i32[1];
+            buffers[i] = new GraphicBuffer( previewStream.width, previewStream.height,
+                static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1,
+                android_convertGralloc1To0Usage( halStreamConfig.streams[0].producerUsage,
+                    halStreamConfig.streams[0].consumerUsage));
+            ASSERT_NE(nullptr, buffers[i].get());
+
+            outputBuffers[i] = {halStreamConfig.streams[0].id, bufferId + i,
+                hidl_handle( buffers[i]->getNativeBuffer()->handle), BufferStatus::OK, nullptr,
+                nullptr};
+            requestMeta.append(reinterpret_cast<camera_metadata_t *> (settings.data()));
+
+            // Disable all 3A routines
+            uint8_t mode = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
+            ASSERT_EQ(::android::OK, requestMeta.update(ANDROID_CONTROL_MODE, &mode, 1));
+            ASSERT_EQ(::android::OK, requestMeta.update(ANDROID_SENSOR_SENSITIVITY, &isoValues[i],
+                        1));
+            camera_metadata_t *metaBuffer = requestMeta.release();
+            requestSettings[i].setToExternal(reinterpret_cast<uint8_t *> (metaBuffer),
+                    get_camera_metadata_size(metaBuffer), true);
+
+            requests[i] = {frameNumber + i, 0 /* fmqSettingsSize */, requestSettings[i],
+                emptyInputBuffer, {outputBuffers[i]}};
+
+            inflightReqs[i] = {1, false, supportsPartialResults, partialResultCount, resultQueue};
+            mInflightMap.add(frameNumber + i, &inflightReqs[i]);
+        }
+
+        Status status = Status::INTERNAL_ERROR;
+        uint32_t numRequestProcessed = 0;
+        hidl_vec<BufferCache> cachesToRemove;
+        hidl_vec<CaptureRequest> burstRequest;
+        burstRequest.setToExternal(requests, kBurstFrameCount);
+        Return<void> returnStatus = session->processCaptureRequest(burstRequest, cachesToRemove,
+                [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                    status = s;
+                    numRequestProcessed = n;
+                });
+        ASSERT_TRUE(returnStatus.isOk());
+        ASSERT_EQ(Status::OK, status);
+        ASSERT_EQ(numRequestProcessed, kBurstFrameCount);
+
+        for (size_t i = 0; i < kBurstFrameCount; i++) {
+            std::unique_lock<std::mutex> l(mLock);
+            while (!inflightReqs[i].errorCodeValid && ((0 < inflightReqs[i].numBuffersLeft) ||
+                            (!inflightReqs[i].haveResultMetadata))) {
+                auto timeout = std::chrono::system_clock::now() +
+                        std::chrono::seconds(kStreamBufferTimeoutSec);
+                ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
+            }
+
+            ASSERT_FALSE(inflightReqs[i].errorCodeValid);
+            ASSERT_NE(inflightReqs[i].resultOutputBuffers.size(), 0u);
+            ASSERT_EQ(previewStream.id, inflightReqs[i].resultOutputBuffers[0].streamId);
+            ASSERT_FALSE(inflightReqs[i].collectedResult.isEmpty());
+            ASSERT_TRUE(inflightReqs[i].collectedResult.exists(ANDROID_SENSOR_SENSITIVITY));
+            camera_metadata_entry_t isoResult = inflightReqs[i].collectedResult.find(
+                    ANDROID_SENSOR_SENSITIVITY);
+            ASSERT_TRUE(isoResult.data.i32[0] == isoValues[i]);
+        }
+
+        ret = session->close();
+        ASSERT_TRUE(ret.isOk());
+    }
+}
+
 // Test whether an incorrect capture request with missing settings will
 // be reported correctly.
 TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) {
diff --git a/cas/1.0/vts/functional/Android.bp b/cas/1.0/vts/functional/Android.bp
index e1e09e9..0db9bb0 100644
--- a/cas/1.0/vts/functional/Android.bp
+++ b/cas/1.0/vts/functional/Android.bp
@@ -23,6 +23,7 @@
         "android.hardware.cas.native@1.0",
         "android.hidl.allocator@1.0",
         "android.hidl.memory@1.0",
+        "libhidlallocatorutils",
         "libhidlmemory",
     ],
     shared_libs: [
diff --git a/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp b/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp
index 053d37a..14b8bbd 100644
--- a/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp
+++ b/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp
@@ -30,6 +30,7 @@
 #include <hidl/HidlSupport.h>
 #include <hidl/HidlTransportSupport.h>
 #include <hidl/Status.h>
+#include <hidlmemory/FrameworkUtils.h>
 #include <utils/Condition.h>
 #include <utils/Mutex.h>
 
@@ -53,6 +54,7 @@
 using android::hardware::cas::V1_0::ICas;
 using android::hardware::cas::V1_0::ICasListener;
 using android::hardware::cas::V1_0::IDescramblerBase;
+using android::hardware::cas::V1_0::Status;
 using android::hardware::cas::native::V1_0::IDescrambler;
 using android::hardware::cas::native::V1_0::SubSample;
 using android::hardware::cas::native::V1_0::SharedBuffer;
@@ -61,13 +63,12 @@
 using android::hardware::cas::native::V1_0::ScramblingControl;
 using android::hardware::cas::V1_0::IMediaCasService;
 using android::hardware::cas::V1_0::HidlCasPluginDescriptor;
-using android::hardware::Void;
+using android::hardware::fromHeap;
 using android::hardware::hidl_vec;
 using android::hardware::hidl_string;
-using android::hardware::hidl_handle;
-using android::hardware::hidl_memory;
+using android::hardware::HidlMemory;
 using android::hardware::Return;
-using android::hardware::cas::V1_0::Status;
+using android::hardware::Void;
 using android::IMemory;
 using android::IMemoryHeap;
 using android::MemoryDealer;
@@ -315,7 +316,7 @@
     }
     *inMemory = mem;
 
-    // build hidl_memory from memory heap
+    // build HidlMemory from memory heap
     ssize_t offset;
     size_t size;
     sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
@@ -324,18 +325,14 @@
         return ::testing::AssertionFailure();
     }
 
-    native_handle_t* nativeHandle = native_handle_create(1, 0);
-    if (!nativeHandle) {
-        ALOGE("failed to create native handle!");
-        return ::testing::AssertionFailure();
-    }
-    nativeHandle->data[0] = heap->getHeapID();
-
     uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(mem->pointer()));
     memcpy(ipBuffer, kInBinaryBuffer, sizeof(kInBinaryBuffer));
 
+    // hidlMemory is not to be passed out of scope!
+    sp<HidlMemory> hidlMemory = fromHeap(heap);
+
     SharedBuffer srcBuffer = {
-            .heapBase = hidl_memory("ashmem", hidl_handle(nativeHandle), heap->getSize()),
+            .heapBase = *hidlMemory,
             .offset = (uint64_t) offset,
             .size = (uint64_t) size
     };
@@ -380,7 +377,7 @@
         return ::testing::AssertionFailure();
     }
 
-    // build hidl_memory from memory heap
+    // build HidlMemory from memory heap
     ssize_t offset;
     size_t size;
     sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
@@ -389,15 +386,11 @@
         return ::testing::AssertionFailure();
     }
 
-    native_handle_t* nativeHandle = native_handle_create(1, 0);
-    if (!nativeHandle) {
-        ALOGE("failed to create native handle!");
-        return ::testing::AssertionFailure();
-    }
-    nativeHandle->data[0] = heap->getHeapID();
+    // hidlMemory is not to be passed out of scope!
+    sp<HidlMemory> hidlMemory = fromHeap(heap);
 
     SharedBuffer srcBuffer = {
-            .heapBase = hidl_memory("ashmem", hidl_handle(nativeHandle), heap->getSize()),
+            .heapBase = *hidlMemory,
             .offset = (uint64_t) offset + params.imemOffset,
             .size = (uint64_t) params.imemSize,
     };
diff --git a/current.txt b/current.txt
index a5ab307..de2511e 100644
--- a/current.txt
+++ b/current.txt
@@ -255,4 +255,5 @@
 fb92e2b40f8e9d494e8fd3b4ac18499a3216342e7cff160714c3bbf3660b6e79 android.hardware.gnss@1.0::IGnssConfiguration
 251594ea9b27447bfa005ebd806e58fb0ae4aad84a69938129c9800ec0c64eda android.hardware.gnss@1.0::IGnssMeasurementCallback
 4e7169919d24fbe5573e5bcd683d0bd7abf553a4e6c34c41f9dfc1e12050db07 android.hardware.gnss@1.0::IGnssNavigationMessageCallback
+0e6e80ddd5c312726e20b003af438325a2d7c305a60a8c8d8e229df2306d50df android.hardware.radio@1.0::types
 b280c4704dfcc548a9bf127b59b7c3578f460c50cce70a06b66fe0df8b27cff0 android.hardware.wifi@1.0::types
diff --git a/drm/1.0/vts/functional/drm_hal_vendor_test.cpp b/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
index 47c6950..d03b2af 100644
--- a/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
+++ b/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
@@ -97,6 +97,27 @@
 
 static drm_vts::VendorModules* gVendorModules = nullptr;
 
+// Test environment for drm
+class DrmHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+   public:
+    // get the test environment singleton
+    static DrmHidlEnvironment* Instance() {
+        static DrmHidlEnvironment* instance = new DrmHidlEnvironment;
+        return instance;
+    }
+
+    void registerTestServices() override {
+        registerTestService<ICryptoFactory>();
+        registerTestService<IDrmFactory>();
+        setServiceCombMode(::testing::HalServiceCombMode::NO_COMBINATION);
+    }
+
+   private:
+    DrmHidlEnvironment() {}
+
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(DrmHidlEnvironment);
+};
+
 class DrmHalVendorFactoryTest : public testing::TestWithParam<std::string> {
    public:
     DrmHalVendorFactoryTest()
@@ -1598,6 +1619,10 @@
         std::cerr << "WARNING: No vendor modules found in " << kModulePath <<
                 ", all vendor tests will be skipped" << std::endl;
     }
+    ::testing::AddGlobalTestEnvironment(DrmHidlEnvironment::Instance());
     ::testing::InitGoogleTest(&argc, argv);
-    return RUN_ALL_TESTS();
+    DrmHidlEnvironment::Instance()->init(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    ALOGI("Test result = %d", status);
+    return status;
 }
diff --git a/drm/1.1/vts/functional/drm_hal_clearkey_test.cpp b/drm/1.1/vts/functional/drm_hal_clearkey_test.cpp
index a8ed0e5..061f2cd 100644
--- a/drm/1.1/vts/functional/drm_hal_clearkey_test.cpp
+++ b/drm/1.1/vts/functional/drm_hal_clearkey_test.cpp
@@ -106,6 +106,12 @@
 
     virtual void HidlTearDown() override { ALOGI("TearDown DrmHidlEnvironment"); }
 
+    void registerTestServices() override {
+        registerTestService<ICryptoFactory>();
+        registerTestService<IDrmFactory>();
+        setServiceCombMode(::testing::HalServiceCombMode::NO_COMBINATION);
+    }
+
    private:
     DrmHidlEnvironment() {}
 
diff --git a/radio/1.0/types.hal b/radio/1.0/types.hal
index 4d22bc0..6787a82 100644
--- a/radio/1.0/types.hal
+++ b/radio/1.0/types.hal
@@ -1292,10 +1292,9 @@
                                           // from cell to device.
                                           // Approximate distance is calculated using
                                           // 300m/us * timingAdvance.
-                                          // Range: 0 to 0x7FFFFFFE
-                                          // INT_MAX : 0x7FFFFFFF denotes invalid value.
-                                          // Reference: 3GPP 36.321 section 6.1.3.5
-                                          // also: http://www.cellular-planningoptimization.com/2010/02/timing-advance-with-calculation.html
+                                          // Range: 0 to 1282 inclusive.
+                                          // INT_MAX : 0x7FFFFFFF denotes unknown value.
+                                          // Reference: 3GPP 36.213 section 4.2.3
 };
 
 struct TdScdmaSignalStrength {
diff --git a/radio/1.2/IRadio.hal b/radio/1.2/IRadio.hal
index 11809e5..6463b0f 100644
--- a/radio/1.2/IRadio.hal
+++ b/radio/1.2/IRadio.hal
@@ -50,7 +50,7 @@
      *
      * @param serial Serial number of request.
      * @param indicationFilter 32-bit bitmap of IndicationFilter. Bits set to 1 indicate the
-     *        indications are enabled. See @1.2::IndicationFilter for the definition of each bit.
+     *     indications are enabled. See @1.2::IndicationFilter for the definition of each bit.
      *
      * Response callback is IRadioResponse.setIndicationFilterResponse()
      */
@@ -68,12 +68,12 @@
      *
      * @param serial Serial number of request.
      * @param hysteresisMs A hysteresis time in milliseconds to prevent flapping. A value of 0
-     *                     disables hysteresis.
+     *     disables hysteresis.
      * @param hysteresisDb An interval in dB defining the required magnitude change between reports.
-     *                     hysteresisDb must be smaller than the smallest threshold delta. An
-     *                     interval value of 0 disables hysteresis.
+     *     hysteresisDb must be smaller than the smallest threshold delta. An
+     *     interval value of 0 disables hysteresis.
      * @param thresholdsDbm A vector of trigger thresholds in dBm. A vector size of 0 disables the
-     *                      use of thresholds for reporting.
+     *     use of thresholds for reporting.
      * @param accessNetwork The type of network for which to apply these thresholds.
      */
     oneway setSignalStrengthReportingCriteria(int32_t serial, int32_t hysteresisMs,
@@ -91,18 +91,17 @@
      *
      * @param serial Serial number of request.
      * @param hysteresisMs A hysteresis time in milliseconds to prevent flapping. A value of 0
-     *                     disables hysteresis.
+     *     disables hysteresis.
      * @param hysteresisDlKbps An interval in kbps defining the required magnitude change between DL
-     *                         reports. hysteresisDlKbps must be smaller than the smallest threshold
-     *                         delta. A value of 0 disables hysteresis.
+     *     reports. hysteresisDlKbps must be smaller than the smallest threshold delta. A value of 0
+     *     disables hysteresis.
      * @param hysteresisUlKbps An interval in kbps defining the required magnitude change between UL
-     *                         reports. hysteresisUlKbps must be smaller than the smallest threshold
-     *                         delta. A value of 0 disables hysteresis.
+     *     reports. hysteresisUlKbps must be smaller than the smallest threshold delta. A value of 0
+     *     disables hysteresis.
      * @param thresholdsDownlinkKbps A vector of trigger thresholds in kbps for downlink reports. A
-     *                               vector size of 0 disables the use of DL thresholds for
-     *                               reporting.
+     *     vector size of 0 disables the use of DL thresholds for reporting.
      * @param thresholdsUplinkKbps A vector of trigger thresholds in kbps for uplink reports. A
-     *                             vector size of 0 disables the use of UL thresholds for reporting.
+     *     vector size of 0 disables the use of UL thresholds for reporting.
      * @param accessNetwork The type of network for which to apply these thresholds.
      */
     oneway setLinkCapacityReportingCriteria(int32_t serial, int32_t hysteresisMs,
diff --git a/radio/1.2/types.hal b/radio/1.2/types.hal
index 8b38f42..b68895e 100644
--- a/radio/1.2/types.hal
+++ b/radio/1.2/types.hal
@@ -361,11 +361,17 @@
 
 struct LinkCapacityEstimate {
     /**
-     * Estimated downlink capacity in kbps.
+     * Estimated downlink capacity in kbps. This bandwidth estimate shall be the estimated
+     * maximum sustainable link bandwidth (as would be measured at the Upper PDCP or SNDCP SAP).
+     * If the DL Aggregate Maximum Bit Rate is known, this value shall not exceed the DL-AMBR
+     * for the Internet PDN connection.
      */
     uint32_t downlinkCapacityKbps;
     /**
-     * Estimated uplink capacity in kbps.
+     * Estimated uplink capacity in kbps. This bandwidth estimate shall be the estimated
+     * maximum sustainable link bandwidth (as would be measured at the Upper PDCP or SNDCP SAP).
+     * If the UL Aggregate Maximum Bit Rate is known, this value shall not exceed the UL-AMBR
+     * for the Internet PDN connection.
      */
     uint32_t uplinkCapacityKbps;
 };