Merge "Add maxVirtualDisplaySize to configStore"
diff --git a/audio/2.0/vts/functional/Android.bp b/audio/2.0/vts/functional/Android.bp
index 02f9330..f5ab76f 100644
--- a/audio/2.0/vts/functional/Android.bp
+++ b/audio/2.0/vts/functional/Android.bp
@@ -22,6 +22,7 @@
         "libbase",
         "liblog",
         "libhidlbase",
+        "libhidltransport",
         "libutils",
         "libcutils",
         "android.hardware.audio@2.0",
diff --git a/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp b/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
index e50b912..6270c9c 100644
--- a/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
+++ b/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
@@ -50,6 +50,7 @@
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::MQDescriptorSync;
+using ::android::hardware::audio::V2_0::AudioDrain;
 using ::android::hardware::audio::V2_0::DeviceAddress;
 using ::android::hardware::audio::V2_0::IDevice;
 using ::android::hardware::audio::V2_0::IPrimaryDevice;
@@ -57,9 +58,11 @@
 using ::android::hardware::audio::V2_0::IDevicesFactory;
 using ::android::hardware::audio::V2_0::IStream;
 using ::android::hardware::audio::V2_0::IStreamIn;
+using ::android::hardware::audio::V2_0::TimeSpec;
 using ReadParameters = ::android::hardware::audio::V2_0::IStreamIn::ReadParameters;
 using ReadStatus = ::android::hardware::audio::V2_0::IStreamIn::ReadStatus;
 using ::android::hardware::audio::V2_0::IStreamOut;
+using ::android::hardware::audio::V2_0::IStreamOutCallback;
 using ::android::hardware::audio::V2_0::MmapBufferInfo;
 using ::android::hardware::audio::V2_0::MmapPosition;
 using ::android::hardware::audio::V2_0::ParameterValue;
@@ -790,9 +793,9 @@
                checkGetParameter(stream.get(), {"Non existing key"} /* keys */,
                                  {Result::INVALID_ARGUMENTS}))
 
-static vector<Result> okOrNotSupported = {Result::OK, Result::INVALID_ARGUMENTS};
+static vector<Result> okOrInvalidArguments = {Result::OK, Result::INVALID_ARGUMENTS};
 TEST_IO_STREAM(setEmptySetParameter, "Set the values of an empty set of parameters",
-               ASSERT_RESULT(okOrNotSupported, stream->setParameters({})))
+               ASSERT_RESULT(okOrInvalidArguments, stream->setParameters({})))
 
 TEST_IO_STREAM(setNonExistingParameter, "Set the values of an non existing parameter",
                ASSERT_RESULT(Result::INVALID_ARGUMENTS,
@@ -921,6 +924,183 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////
+///////////////////////////////// StreamIn ///////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+TEST_P(OutputStreamTest, getLatency) {
+    doc::test("Make sure latency is over 0");
+    auto result = stream->getLatency();
+    ASSERT_TRUE(result.isOk());
+    ASSERT_GT(result, 0U);
+}
+
+TEST_P(OutputStreamTest, setVolume) {
+    doc::test("Try to set the output volume");
+    auto result = stream->setVolume(1, 1);
+    ASSERT_TRUE(result.isOk());
+    if (result == Result::NOT_SUPPORTED) {
+        doc::partialTest("setVolume is not supported");
+        return;
+    }
+    testUnitaryGain([this](float volume) { return stream->setVolume(volume, volume); });
+}
+
+static void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize, uint32_t framesCount) {
+    Result res;
+    // Ignore output parameters as the call should fail
+    ASSERT_OK(stream->prepareForWriting(frameSize, framesCount,
+                                        [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
+    EXPECT_RESULT(invalidArgsOrNotSupported, res);
+}
+
+TEST_P(OutputStreamTest, PrepareForWriteWithHugeBuffer) {
+    doc::test("Preparing a stream for writing with a 2^32 sized buffer should fail");
+    testPrepareForWriting(stream.get(), 1, std::numeric_limits<uint32_t>::max());
+}
+
+TEST_P(OutputStreamTest, PrepareForWritingCheckOverflow) {
+    doc::test("Preparing a stream for writing with a overflowing sized buffer should fail");
+    auto uintMax = std::numeric_limits<uint32_t>::max();
+    testPrepareForWriting(stream.get(), uintMax, uintMax);
+}
+
+struct Capability {
+    Capability(IStreamOut* stream) {
+        EXPECT_OK(stream->supportsPauseAndResume(returnIn(pause, resume)));
+        auto ret = stream->supportsDrain();
+        EXPECT_TRUE(ret.isOk());
+        if (ret.isOk()) {
+            drain = ret;
+        }
+    }
+    bool pause = false;
+    bool resume = false;
+    bool drain = false;
+};
+
+TEST_P(OutputStreamTest, SupportsPauseAndResumeAndDrain) {
+    Capability(stream.get());
+}
+
+TEST_P(OutputStreamTest, GetRenderPosition) {
+    uint32_t dspFrames;
+    ASSERT_OK(stream->getRenderPosition(returnIn(res, dspFrames)));
+    if (res == Result::NOT_SUPPORTED) {
+        doc::partialTest("getRenderPosition is not supported");
+        return;
+    }
+    ASSERT_OK(res);
+    ASSERT_EQ(0U, dspFrames);
+}
+
+TEST_P(OutputStreamTest, GetNextWriteTimestamp) {
+    uint64_t timestampUs;
+    ASSERT_OK(stream->getRenderPosition(returnIn(res, timestampUs)));
+    if (res == Result::NOT_SUPPORTED) {
+        doc::partialTest("getRenderPosition is not supported");
+        return;
+    }
+    ASSERT_OK(res);
+    ASSERT_EQ(0U, timestampUs);
+}
+
+/** Stub implementation of out stream callback. */
+class MockOutCallbacks : public IStreamOutCallback {
+    Return<void> onWriteReady() override { return {}; }
+    Return<void> onDrainReady() override { return {}; }
+    Return<void> onError() override { return {}; }
+};
+
+static bool isAsyncModeSupported(IStreamOut *stream) {
+    auto res = stream->setCallback(new MockOutCallbacks);
+    stream->clearCallback(); // try to restore the no callback state, ignore any error
+    auto okOrNotSupported = { Result::OK, Result::NOT_SUPPORTED };
+    EXPECT_RESULT(okOrNotSupported, res);
+    return res.isOk() ? res == Result::OK : false;
+}
+
+TEST_P(OutputStreamTest, SetCallback) {
+    if (!isAsyncModeSupported(stream.get())) {
+        doc::partialTest("The stream does not support async operations");
+        return;
+    }
+    ASSERT_OK(stream->setCallback(new MockOutCallbacks));
+    ASSERT_OK(stream->setCallback(new MockOutCallbacks));
+}
+
+TEST_P(OutputStreamTest, clearCallback) {
+    if (!isAsyncModeSupported(stream.get())) {
+        doc::partialTest("The stream does not support async operations");
+        return;
+    }
+    // TODO: Clarify if clearing a non existing callback should fail
+    ASSERT_OK(stream->setCallback(new MockOutCallbacks));
+    ASSERT_OK(stream->clearCallback());
+}
+
+TEST_P(OutputStreamTest, Resume) {
+    if (!Capability(stream.get()).resume) {
+        doc::partialTest("The output stream does not support resume");
+        return;
+    }
+    ASSERT_RESULT(Result::INVALID_STATE, stream->resume());
+}
+
+TEST_P(OutputStreamTest, Pause) {
+    if (!Capability(stream.get()).pause) {
+        doc::partialTest("The output stream does not support pause");
+        return;
+    }
+    ASSERT_RESULT(Result::INVALID_STATE, stream->resume());
+}
+
+static void testDrain(IStreamOut *stream, AudioDrain type) {
+    if (!Capability(stream).drain) {
+        doc::partialTest("The output stream does not support pause");
+        return;
+    }
+    ASSERT_RESULT(Result::OK, stream->drain(type));
+}
+
+TEST_P(OutputStreamTest, DrainAll) {
+    testDrain(stream.get(), AudioDrain::ALL);
+}
+
+TEST_P(OutputStreamTest, DrainEarlyNotify) {
+    testDrain(stream.get(), AudioDrain::EARLY_NOTIFY);
+}
+
+TEST_P(OutputStreamTest, FlushStop) {
+    ASSERT_OK(stream->flush());
+}
+
+/** Return thee difference in us of two TimeSpec */
+uint64_t operator-(TimeSpec left, TimeSpec right) {
+    auto toMicroSec = [](auto ts) { return ts.tvSec * 1e+6 + ts.tvNSec / 1e+3; };
+    return toMicroSec(left) - toMicroSec(right);
+}
+
+TEST_P(OutputStreamTest, GetPresentationPositionStop) {
+    uint64_t frames;
+    TimeSpec mesureTS;
+    ASSERT_OK(stream->getPresentationPosition(returnIn(res, frames, mesureTS)));
+    if (res == Result::NOT_SUPPORTED) {
+        doc::partialTest("getpresentationPosition is not supported");
+        return;
+    }
+    ASSERT_EQ(0U, frames);
+
+    struct timespec currentTS;
+    ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &currentTS)) << errno;
+
+    auto toMicroSec = [](uint64_t sec, auto nsec) { return sec * 1e+6 + nsec / 1e+3; };
+    auto currentTime = toMicroSec(currentTS.tv_sec, currentTS.tv_nsec);
+    auto mesureTime = toMicroSec(mesureTS.tvSec, mesureTS.tvNSec);
+    ASSERT_PRED2([](auto c, auto m){ return  c - m < 1e+6; }, currentTime, mesureTime);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
 /////////////////////////////// PrimaryDevice ////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
diff --git a/audio/2.0/vts/functional/utility/AssertOk.h b/audio/2.0/vts/functional/utility/AssertOk.h
index 39c9a1d..10b088c 100644
--- a/audio/2.0/vts/functional/utility/AssertOk.h
+++ b/audio/2.0/vts/functional/utility/AssertOk.h
@@ -29,13 +29,13 @@
     ASSERT_EQ(expected, result);
 }
 
-inline void assertResult(Result expected, Return<Result> ret) {
+inline void assertResult(Result expected, const Return<Result> &ret) {
     ASSERT_TRUE(ret.isOk());
     Result result = ret;
     assertResult(expected, result);
 }
 
-inline void assertResult(std::vector<Result> expected, Result result) {
+inline void assertResult(const std::vector<Result> &expected, Result result) {
     if (std::find(expected.begin(), expected.end(), result) != expected.end()) {
         return; // result is in expected
     }
@@ -43,13 +43,13 @@
            << " to be one of " << ::testing::PrintToString(expected);
 }
 
-inline void assertResult(std::vector<Result> expected, Return<Result> ret) {
+inline void assertResult(const std::vector<Result> &expected, const Return<Result> &ret) {
     ASSERT_TRUE(ret.isOk());
     Result result = ret;
     assertResult(expected, result);
 }
 
-inline void assertOk(Return<void> ret) {
+inline void assertOk(const Return<void> &ret) {
     ASSERT_TRUE(ret.isOk());
 }
 
@@ -57,8 +57,8 @@
     assertResult(Result::OK, result);
 }
 
-inline void assertOk(Return<Result> ret) {
-    assertResult(Result::OK, std::move(ret));
+inline void assertOk(const Return<Result> &ret) {
+    assertResult(Result::OK, ret);
 }
 
 }
@@ -68,4 +68,4 @@
 #define EXPECT_OK(ret) EXPECT_NO_FATAL_FAILURE(detail::assertOk(ret))
 
 #define ASSERT_RESULT(expected, ret) ASSERT_NO_FATAL_FAILURE(detail::assertResult(expected, ret))
-#define EXPECT_RESULT(expected, ret) ASSERT_NO_FATAL_FAILURE(detail::assertResult(expected, ret))
+#define EXPECT_RESULT(expected, ret) EXPECT_NO_FATAL_FAILURE(detail::assertResult(expected, ret))
diff --git a/biometrics/fingerprint/2.1/default/service.cpp b/biometrics/fingerprint/2.1/default/service.cpp
index d6b91c6..1697c07 100644
--- a/biometrics/fingerprint/2.1/default/service.cpp
+++ b/biometrics/fingerprint/2.1/default/service.cpp
@@ -35,7 +35,7 @@
     configureRpcThreadpool(1, true /*callerWillJoin*/);
 
     if (bio != nullptr) {
-        bio->registerAsService("fingerprint_hal");
+        bio->registerAsService();
     } else {
         ALOGE("Can't create instance of BiometricsFingerprint, nullptr");
     }
diff --git a/biometrics/fingerprint/2.1/vts/functional/VtsHalBiometricsFingerprintV2_1TargetTest.cpp b/biometrics/fingerprint/2.1/vts/functional/VtsHalBiometricsFingerprintV2_1TargetTest.cpp
index c07c3e3..cd38f2e 100644
--- a/biometrics/fingerprint/2.1/vts/functional/VtsHalBiometricsFingerprintV2_1TargetTest.cpp
+++ b/biometrics/fingerprint/2.1/vts/functional/VtsHalBiometricsFingerprintV2_1TargetTest.cpp
@@ -15,7 +15,6 @@
  */
 
 #define LOG_TAG "fingerprint_hidl_hal_test"
-#define SERVICE_NAME "fingerprint_hal"
 
 #include <android-base/logging.h>
 #include <android/hardware/biometrics/fingerprint/2.1/IBiometricsFingerprint.h>
@@ -123,7 +122,7 @@
     FingerprintHidlTest (): mCallbackCalled(false) {}
 
     virtual void SetUp() override {
-        mService = ::testing::VtsHalHidlTargetTestBase::getService<IBiometricsFingerprint>(SERVICE_NAME);
+        mService = ::testing::VtsHalHidlTargetTestBase::getService<IBiometricsFingerprint>();
 
         ASSERT_NE(mService, nullptr);
         clearErr();
diff --git a/camera/device/3.2/types.hal b/camera/device/3.2/types.hal
index fe1edbf..c7d38c1 100644
--- a/camera/device/3.2/types.hal
+++ b/camera/device/3.2/types.hal
@@ -151,6 +151,13 @@
      *      android.lens.opticalStabilizationMode (if it is supported)
      *      android.scaler.cropRegion
      *      android.statistics.faceDetectMode (if it is supported)
+     *   6. To reduce the amount of data passed across process boundaries at
+     *      high frame rate, within one batch, camera framework only propagates
+     *      the last shutter notify and the last capture results (including partial
+     *      results and final result) to the app. The shutter notifies and capture
+     *      results for the other requests in the batch are derived by
+     *      the camera framework. As a result, the HAL can return empty metadata
+     *      except for the last result in the batch.
      *
      * For more details about high speed stream requirements, see
      * android.control.availableHighSpeedVideoConfigurations and
diff --git a/drm/1.0/default/service.cpp b/drm/1.0/default/service.cpp
index d2507c4..a112aaf 100644
--- a/drm/1.0/default/service.cpp
+++ b/drm/1.0/default/service.cpp
@@ -31,7 +31,14 @@
 int main() {
     ALOGD("android.hardware.drm@1.0-service starting...");
     configureRpcThreadpool(8, true /* callerWillJoin */);
-    registerPassthroughServiceImplementation<IDrmFactory>("drm");
-    registerPassthroughServiceImplementation<ICryptoFactory>("crypto");
+    android::status_t status =
+        registerPassthroughServiceImplementation<IDrmFactory>("drm");
+    LOG_ALWAYS_FATAL_IF(
+        status != android::OK,
+        "Error while registering drm service: %d", status);
+    status = registerPassthroughServiceImplementation<ICryptoFactory>("crypto");
+    LOG_ALWAYS_FATAL_IF(
+        status != android::OK,
+        "Error while registering crypto service: %d", status);
     joinRpcThreadpool();
 }