Merge changes Ieab560be,Icb294e1b,Ia664c15b

* changes:
  CCodec: fix C2OMXNode assumption that components are in the same process
  CCodec: Allow bitrate to be not set in CQ mode for video encoders
  C2SoftHEVCEnc: Add support for constant quality encoding
diff --git a/media/codec2/hidl/1.0/utils/Android.bp b/media/codec2/hidl/1.0/utils/Android.bp
index 0bb2418..97dde71 100644
--- a/media/codec2/hidl/1.0/utils/Android.bp
+++ b/media/codec2/hidl/1.0/utils/Android.bp
@@ -33,6 +33,7 @@
         "android.hardware.media.bufferpool@2.0",
         "android.hardware.media.c2@1.0",
         "android.hardware.media.omx@1.0",
+        "android.hidl.safe_union@1.0",
         "libbase",
         "libcodec2",
         "libcodec2_vndk",
diff --git a/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/types.h b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/types.h
index b9f3aa8..817d148 100644
--- a/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/types.h
+++ b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/types.h
@@ -22,6 +22,7 @@
 #include <android/hardware/media/bufferpool/2.0/types.h>
 #include <android/hardware/media/c2/1.0/IComponentStore.h>
 #include <android/hardware/media/c2/1.0/types.h>
+#include <android/hidl/safe_union/1.0/types.h>
 #include <gui/IGraphicBufferProducer.h>
 
 #include <C2Component.h>
diff --git a/media/codec2/hidl/1.0/utils/types.cpp b/media/codec2/hidl/1.0/utils/types.cpp
index 031e637..74320e7 100644
--- a/media/codec2/hidl/1.0/utils/types.cpp
+++ b/media/codec2/hidl/1.0/utils/types.cpp
@@ -120,9 +120,9 @@
     return true;
 }
 
-// C2FieldSupportedValues::range's type -> FieldSupportedValues::Range
+// C2FieldSupportedValues::range's type -> ValueRange
 bool objcpy(
-        FieldSupportedValues::Range* d,
+        ValueRange* d,
         const decltype(C2FieldSupportedValues::range)& s) {
     d->min = static_cast<PrimitiveValue>(s.min.u64);
     d->max = static_cast<PrimitiveValue>(s.max.u64);
@@ -135,45 +135,45 @@
 // C2FieldSupportedValues -> FieldSupportedValues
 bool objcpy(FieldSupportedValues *d, const C2FieldSupportedValues &s) {
     switch (s.type) {
-    case C2FieldSupportedValues::EMPTY:
-        d->type = FieldSupportedValues::Type::EMPTY;
-        d->values.resize(0);
-        break;
-    case C2FieldSupportedValues::RANGE:
-        d->type = FieldSupportedValues::Type::RANGE;
-        if (!objcpy(&d->range, s.range)) {
-            LOG(ERROR) << "Invalid C2FieldSupportedValues::range.";
-            return false;
+    case C2FieldSupportedValues::EMPTY: {
+            d->empty(::android::hidl::safe_union::V1_0::Monostate{});
+            break;
         }
-        d->values.resize(0);
-        break;
-    default:
-        switch (s.type) {
-        case C2FieldSupportedValues::VALUES:
-            d->type = FieldSupportedValues::Type::VALUES;
-            break;
-        case C2FieldSupportedValues::FLAGS:
-            d->type = FieldSupportedValues::Type::FLAGS;
-            break;
-        default:
-            LOG(DEBUG) << "Unrecognized C2FieldSupportedValues::type_t "
-                       << "with underlying value " << underlying_value(s.type)
-                       << ".";
-            d->type = static_cast<FieldSupportedValues::Type>(s.type);
-            if (!objcpy(&d->range, s.range)) {
+    case C2FieldSupportedValues::RANGE: {
+            ValueRange range{};
+            if (!objcpy(&range, s.range)) {
                 LOG(ERROR) << "Invalid C2FieldSupportedValues::range.";
+                d->range(range);
                 return false;
             }
+            d->range(range);
+            break;
         }
-        copyVector<uint64_t>(&d->values, s.values);
+    case C2FieldSupportedValues::VALUES: {
+            hidl_vec<PrimitiveValue> values;
+            copyVector<uint64_t>(&values, s.values);
+            d->values(values);
+            break;
+        }
+    case C2FieldSupportedValues::FLAGS: {
+            hidl_vec<PrimitiveValue> flags;
+            copyVector<uint64_t>(&flags, s.values);
+            d->flags(flags);
+            break;
+        }
+    default:
+        LOG(DEBUG) << "Unrecognized C2FieldSupportedValues::type_t "
+                   << "with underlying value " << underlying_value(s.type)
+                   << ".";
+        return false;
     }
     return true;
 }
 
-// FieldSupportedValues::Range -> C2FieldSupportedValues::range's type
+// ValueRange -> C2FieldSupportedValues::range's type
 bool objcpy(
         decltype(C2FieldSupportedValues::range)* d,
-        const FieldSupportedValues::Range& s) {
+        const ValueRange& s) {
     d->min.u64 = static_cast<uint64_t>(s.min);
     d->max.u64 = static_cast<uint64_t>(s.max);
     d->step.u64 = static_cast<uint64_t>(s.step);
@@ -184,37 +184,33 @@
 
 // FieldSupportedValues -> C2FieldSupportedValues
 bool objcpy(C2FieldSupportedValues *d, const FieldSupportedValues &s) {
-    switch (s.type) {
-    case FieldSupportedValues::Type::EMPTY:
-        d->type = C2FieldSupportedValues::EMPTY;
-        break;
-    case FieldSupportedValues::Type::RANGE:
-        d->type = C2FieldSupportedValues::RANGE;
-        if (!objcpy(&d->range, s.range)) {
-            LOG(ERROR) << "Invalid FieldSupportedValues::range.";
-            return false;
+    switch (s.getDiscriminator()) {
+    case FieldSupportedValues::hidl_discriminator::empty: {
+            d->type = C2FieldSupportedValues::EMPTY;
+            break;
         }
-        d->values.resize(0);
-        break;
-    default:
-        switch (s.type) {
-        case FieldSupportedValues::Type::VALUES:
-            d->type = C2FieldSupportedValues::VALUES;
-            break;
-        case FieldSupportedValues::Type::FLAGS:
-            d->type = C2FieldSupportedValues::FLAGS;
-            break;
-        default:
-            LOG(DEBUG) << "Unrecognized FieldSupportedValues::Type "
-                       << "with underlying value " << underlying_value(s.type)
-                       << ".";
-            d->type = static_cast<C2FieldSupportedValues::type_t>(s.type);
-            if (!objcpy(&d->range, s.range)) {
+    case FieldSupportedValues::hidl_discriminator::range: {
+            d->type = C2FieldSupportedValues::RANGE;
+            if (!objcpy(&d->range, s.range())) {
                 LOG(ERROR) << "Invalid FieldSupportedValues::range.";
                 return false;
             }
+            d->values.resize(0);
+            break;
         }
-        copyVector<uint64_t>(&d->values, s.values);
+    case FieldSupportedValues::hidl_discriminator::values: {
+            d->type = C2FieldSupportedValues::VALUES;
+            copyVector<uint64_t>(&d->values, s.values());
+            break;
+        }
+    case FieldSupportedValues::hidl_discriminator::flags: {
+            d->type = C2FieldSupportedValues::FLAGS;
+            copyVector<uint64_t>(&d->values, s.flags());
+            break;
+        }
+    default:
+        LOG(WARNING) << "Unrecognized FieldSupportedValues::getDiscriminator()";
+        return false;
     }
     return true;
 }
diff --git a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp
index 1f36270..d73b731 100644
--- a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp
@@ -127,4 +127,12 @@
             queueCondition.notify_all();
         }
     }
-}
\ No newline at end of file
+}
+
+// Return current time in micro seconds
+int64_t getNowUs() {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+
+    return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll;
+}
diff --git a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h
index fca2902..c577dac 100644
--- a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h
+++ b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h
@@ -201,4 +201,6 @@
     std::list<std::unique_ptr<C2Work>>& workQueue, bool& eos, bool& csd,
     uint32_t& framesReceived);
 
+int64_t getNowUs();
+
 #endif  // MEDIA_C2_HIDL_TEST_COMMON_H
diff --git a/media/codec2/hidl/1.0/vts/functional/component/VtsHidlC2V1_0TargetComponentTest.cpp b/media/codec2/hidl/1.0/vts/functional/component/VtsHidlC2V1_0TargetComponentTest.cpp
index ec803d7..74548b5 100644
--- a/media/codec2/hidl/1.0/vts/functional/component/VtsHidlC2V1_0TargetComponentTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/component/VtsHidlC2V1_0TargetComponentTest.cpp
@@ -26,6 +26,32 @@
 #include <VtsHalHidlTargetTestBase.h>
 #include "media_c2_hidl_test_common.h"
 
+/* Time_Out for start(), stop(), reset(), release(), flush(), queue() are
+ * defined in hardware/interfaces/media/c2/1.0/IComponent.hal. Adding 50ms
+ * extra in case of timeout is 500ms, 1ms extra in case timeout is 1ms/5ms. All
+ * timeout is calculated in us.
+ */
+#define START_TIME_OUT                  550000
+#define STOP_TIME_OUT                   550000
+#define RESET_TIME_OUT                  550000
+#define RELEASE_TIME_OUT                550000
+#define FLUSH_TIME_OUT                  6000
+#define QUEUE_TIME_OUT                  2000
+
+// Time_Out for config(), query(), querySupportedParams() are defined in
+// hardware/interfaces/media/c2/1.0/IConfigurable.hal.
+#define CONFIG_TIME_OUT                 6000
+#define QUERY_TIME_OUT                  6000
+#define QUERYSUPPORTEDPARAMS_TIME_OUT   2000
+
+#define CHECK_TIMEOUT(timeConsumed, TIME_OUT, FuncName)          \
+    if (timeConsumed > TIME_OUT) {                               \
+        ALOGW(                                                   \
+            "TIMED_OUT %s  timeConsumed=%" PRId64 " us is "      \
+            "greater than threshold %d us",                      \
+            FuncName, timeConsumed, TIME_OUT);                   \
+    }
+
 static ComponentTestEnvironment* gEnv = nullptr;
 
 namespace {
@@ -244,6 +270,93 @@
     std::make_pair(C2FrameData::FLAG_CODEC_CONFIG, false),
     std::make_pair(C2FrameData::FLAG_END_OF_STREAM, false)));
 
+// Test API's Timeout
+TEST_F(Codec2ComponentHidlTest, Timeout) {
+    ALOGV("Timeout Test");
+    c2_status_t err = C2_OK;
+
+    int64_t startTime = getNowUs();
+    err = mComponent->start();
+    int64_t timeConsumed = getNowUs() - startTime;
+    CHECK_TIMEOUT(timeConsumed, START_TIME_OUT, "start()");
+    ALOGV("mComponent->start() timeConsumed=%" PRId64 " us", timeConsumed);
+    ASSERT_EQ(err, C2_OK);
+
+    startTime = getNowUs();
+    err = mComponent->reset();
+    timeConsumed = getNowUs() - startTime;
+    CHECK_TIMEOUT(timeConsumed, RESET_TIME_OUT, "reset()");
+    ALOGV("mComponent->reset() timeConsumed=%" PRId64 " us", timeConsumed);
+    ASSERT_EQ(err, C2_OK);
+
+    err = mComponent->start();
+    ASSERT_EQ(err, C2_OK);
+
+    // Query supported params by the component
+    std::vector<std::shared_ptr<C2ParamDescriptor>> params;
+    startTime = getNowUs();
+    err = mComponent->querySupportedParams(&params);
+    timeConsumed = getNowUs() - startTime;
+    CHECK_TIMEOUT(timeConsumed, QUERYSUPPORTEDPARAMS_TIME_OUT,
+                  "querySupportedParams()");
+    ALOGV("mComponent->querySupportedParams() timeConsumed=%" PRId64 " us",
+          timeConsumed);
+    ASSERT_EQ(err, C2_OK);
+
+    std::vector<std::unique_ptr<C2Param>> queried;
+    std::vector<std::unique_ptr<C2SettingResult>> failures;
+    // Query and config all the supported params
+    for (std::shared_ptr<C2ParamDescriptor> p : params) {
+        startTime = getNowUs();
+        err = mComponent->query({}, {p->index()}, C2_DONT_BLOCK, &queried);
+        timeConsumed = getNowUs() - startTime;
+        CHECK_TIMEOUT(timeConsumed, QUERY_TIME_OUT, "query()");
+        EXPECT_NE(queried.size(), 0u);
+        EXPECT_EQ(err, C2_OK);
+        ALOGV("mComponent->query() for %s timeConsumed=%" PRId64 " us",
+              p->name().c_str(), timeConsumed);
+
+        startTime = getNowUs();
+        err = mComponent->config({queried[0].get()}, C2_DONT_BLOCK, &failures);
+        timeConsumed = getNowUs() - startTime;
+        CHECK_TIMEOUT(timeConsumed, CONFIG_TIME_OUT, "config()");
+        ASSERT_EQ(err, C2_OK);
+        ASSERT_EQ(failures.size(), 0u);
+        ALOGV("mComponent->config() for %s timeConsumed=%" PRId64 " us",
+              p->name().c_str(), timeConsumed);
+    }
+
+    std::list<std::unique_ptr<C2Work>> workList;
+    startTime = getNowUs();
+    err = mComponent->queue(&workList);
+    timeConsumed = getNowUs() - startTime;
+    ALOGV("mComponent->queue() timeConsumed=%" PRId64 " us", timeConsumed);
+    CHECK_TIMEOUT(timeConsumed, QUEUE_TIME_OUT, "queue()");
+    ASSERT_EQ(err, C2_OK);
+
+    startTime = getNowUs();
+    err = mComponent->flush(C2Component::FLUSH_COMPONENT, &workList);
+    timeConsumed = getNowUs() - startTime;
+    ALOGV("mComponent->flush() timeConsumed=%" PRId64 " us", timeConsumed);
+    CHECK_TIMEOUT(timeConsumed, FLUSH_TIME_OUT, "flush()");
+    ASSERT_EQ(err, C2_OK);
+
+    startTime = getNowUs();
+    err = mComponent->stop();
+    timeConsumed = getNowUs() - startTime;
+    ALOGV("mComponent->stop() timeConsumed=%" PRId64 " us", timeConsumed);
+    CHECK_TIMEOUT(timeConsumed, STOP_TIME_OUT, "stop()");
+    ASSERT_EQ(err, C2_OK);
+
+    startTime = getNowUs();
+    err = mComponent->release();
+    timeConsumed = getNowUs() - startTime;
+    ALOGV("mComponent->release() timeConsumed=%" PRId64 " us", timeConsumed);
+    CHECK_TIMEOUT(timeConsumed, RELEASE_TIME_OUT, "release()");
+    ASSERT_EQ(err, C2_OK);
+
+}
+
 }  // anonymous namespace
 
 // TODO: Add test for Invalid work,
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index a6fa333..55a525e 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -2483,6 +2483,7 @@
             bool post = true;
             if (!configs->empty()) {
                 sp<ABuffer> config = configs->front();
+                configs->pop_front();
                 if (buffer->capacity() >= config->size()) {
                     memcpy(buffer->base(), config->data(), config->size());
                     buffer->setRange(0, config->size());
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index b8f88cf..43260c2 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -3297,7 +3297,8 @@
         // output threads.
         // If output is 0 here, sessionId is neither SESSION_OUTPUT_STAGE nor SESSION_OUTPUT_MIX
         // because of code checking output when entering the function.
-        // Note: io is never 0 when creating an effect on an input
+        // Note: io is never AUDIO_IO_HANDLE_NONE when creating an effect on an input by APM.
+        // An AudioEffect created from the Java API will have io as AUDIO_IO_HANDLE_NONE.
         if (io == AUDIO_IO_HANDLE_NONE) {
             // look for the thread where the specified audio session is present
             io = findIoHandleBySessionId_l(sessionId, mPlaybackThreads);
@@ -3307,6 +3308,25 @@
             if (io == AUDIO_IO_HANDLE_NONE) {
                 io = findIoHandleBySessionId_l(sessionId, mMmapThreads);
             }
+
+            // If you wish to create a Record preprocessing AudioEffect in Java,
+            // you MUST create an AudioRecord first and keep it alive so it is picked up above.
+            // Otherwise it will fail when created on a Playback thread by legacy
+            // handling below.  Ditto with Mmap, the associated Mmap track must be created
+            // before creating the AudioEffect or the io handle must be specified.
+            //
+            // Detect if the effect is created after an AudioRecord is destroyed.
+            if (getOrphanEffectChain_l(sessionId).get() != nullptr) {
+                ALOGE("%s: effect %s with no specified io handle is denied because the AudioRecord"
+                        " for session %d no longer exists",
+                         __func__, desc.name, sessionId);
+                lStatus = PERMISSION_DENIED;
+                goto Exit;
+            }
+
+            // Legacy handling of creating an effect on an expired or made-up
+            // session id.  We think that it is a Playback effect.
+            //
             // If no output thread contains the requested session ID, default to
             // first output. The effect chain will be moved to the correct output
             // thread when a track with the same session ID is created
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index e94fb49..984d9fe 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -7245,7 +7245,7 @@
                 } else {
                     // FIXME could do a partial drop of framesOut
                     if (activeTrack->mFramesToDrop > 0) {
-                        activeTrack->mFramesToDrop -= framesOut;
+                        activeTrack->mFramesToDrop -= (ssize_t)framesOut;
                         if (activeTrack->mFramesToDrop <= 0) {
                             activeTrack->clearSyncStartEvent();
                         }
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index 635de6f..5b4e2eb 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -334,6 +334,13 @@
 void AudioInputDescriptor::updateClientRecordingConfiguration(
     int event, const sp<RecordClientDescriptor>& client)
 {
+    // do not send callback if starting and no device is selected yet to avoid
+    // double callbacks from startInput() before and after the device is selected
+    if (event ==  RECORD_CONFIG_EVENT_START
+            && mPatchHandle == AUDIO_PATCH_HANDLE_NONE) {
+        return;
+    }
+
     const audio_config_base_t sessionConfig = client->config();
     const record_client_info_t recordClientInfo{client->uid(), client->session(),
                                                 client->source(), client->portId(),
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index c971299..762a4b1 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -2025,7 +2025,7 @@
         mSoundTriggerSessions.indexOfKey(session) > 0;
     *portId = AudioPort::getNextUniqueId();
 
-    clientDesc = new RecordClientDescriptor(*portId, uid, session, *attr, *config,
+    clientDesc = new RecordClientDescriptor(*portId, uid, session, attributes, *config,
                                             requestedDeviceId, attributes.source, flags,
                                             isSoundTrigger);
     inputDesc = mInputs.valueFor(*input);
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index ea6ca39..93e3c44 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1127,9 +1127,10 @@
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
+    // startAudioSource should be created as the calling uid
+    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
     AutoCallerClear acc;
-    return mAudioPolicyManager->startAudioSource(source, attributes, portId,
-                                                 IPCThreadState::self()->getCallingUid());
+    return mAudioPolicyManager->startAudioSource(source, attributes, portId, callingUid);
 }
 
 status_t AudioPolicyService::stopAudioSource(audio_port_handle_t portId)