Merge "CCodec: flush reorder stash at flush"
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
index 1558e8b..27bd631 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
@@ -65,7 +65,20 @@
     *plugin = new ClearKeyCasPlugin(appData, callback);
     return OK;
 }
-///////////////////////////////////////////////////////////////////////////////
+
+status_t ClearKeyCasFactory::createPlugin(
+        int32_t CA_system_id,
+        void *appData,
+        CasPluginCallbackExt callback,
+        CasPlugin **plugin) {
+    if (!isSystemIdSupported(CA_system_id)) {
+        return BAD_VALUE;
+    }
+
+    *plugin = new ClearKeyCasPlugin(appData, callback);
+    return OK;
+}
+////////////////////////////////////////////////////////////////////////////////
 bool ClearKeyDescramblerFactory::isSystemIdSupported(
         int32_t CA_system_id) const {
     return CA_system_id == sClearKeySystemId;
@@ -88,6 +101,12 @@
     ALOGV("CTOR");
 }
 
+ClearKeyCasPlugin::ClearKeyCasPlugin(
+        void *appData, CasPluginCallbackExt callback)
+    : mCallbackExt(callback), mAppData(appData) {
+    ALOGV("CTOR");
+}
+
 ClearKeyCasPlugin::~ClearKeyCasPlugin() {
     ALOGV("DTOR");
     ClearKeySessionLibrary::get()->destroyPlugin(this);
@@ -167,11 +186,30 @@
     // Echo the received event to the callback.
     // Clear key plugin doesn't use any event, echo'ing for testing only.
     if (mCallback != NULL) {
-        mCallback((void*)mAppData, event, arg, (uint8_t*)eventData.data(), eventData.size());
+        mCallback((void*)mAppData, event, arg, (uint8_t*)eventData.data(),
+                    eventData.size());
+    } else if (mCallbackExt != NULL) {
+        mCallbackExt((void*)mAppData, event, arg, (uint8_t*)eventData.data(),
+                    eventData.size(), NULL);
     }
     return OK;
 }
 
+status_t ClearKeyCasPlugin::sendSessionEvent(
+        const CasSessionId &sessionId, int32_t event,
+        int arg, const CasData &eventData) {
+    ALOGV("sendSessionEvent: sessionId=%s, event=%d, arg=%d",
+          sessionIdToString(sessionId).string(), event, arg);
+    // Echo the received event to the callback.
+    // Clear key plugin doesn't use any event, echo'ing for testing only.
+    if (mCallbackExt != NULL) {
+        mCallbackExt((void*)mAppData, event, arg, (uint8_t*)eventData.data(),
+                    eventData.size(), &sessionId);
+    }
+
+    return OK;
+}
+
 status_t ClearKeyCasPlugin::provision(const String8 &str) {
     ALOGV("provision: provisionString=%s", str.string());
     Mutex::Autolock lock(mKeyFetcherLock);
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
index 389e172..f48d5b1 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
@@ -47,6 +47,11 @@
             void *appData,
             CasPluginCallback callback,
             CasPlugin **plugin) override;
+    virtual status_t createPlugin(
+            int32_t CA_system_id,
+            void *appData,
+            CasPluginCallbackExt callback,
+            CasPlugin **plugin) override;
 };
 
 class ClearKeyDescramblerFactory : public DescramblerFactory {
@@ -63,6 +68,7 @@
 class ClearKeyCasPlugin : public CasPlugin {
 public:
     ClearKeyCasPlugin(void *appData, CasPluginCallback callback);
+    ClearKeyCasPlugin(void *appData, CasPluginCallbackExt callback);
     virtual ~ClearKeyCasPlugin();
 
     virtual status_t setPrivateData(
@@ -85,6 +91,10 @@
     virtual status_t sendEvent(
             int32_t event, int32_t arg, const CasData &eventData) override;
 
+    virtual status_t sendSessionEvent(
+            const CasSessionId &sessionId,
+            int32_t event, int32_t arg, const CasData &eventData) override;
+
     virtual status_t provision(const String8 &str) override;
 
     virtual status_t refreshEntitlements(
@@ -94,6 +104,7 @@
     Mutex mKeyFetcherLock;
     std::unique_ptr<KeyFetcher> mKeyFetcher;
     CasPluginCallback mCallback;
+    CasPluginCallbackExt mCallbackExt;
     void* mAppData;
 };
 
diff --git a/drm/mediacas/plugins/mock/MockCasPlugin.cpp b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
index 8404a83..2964791 100644
--- a/drm/mediacas/plugins/mock/MockCasPlugin.cpp
+++ b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
@@ -60,6 +60,19 @@
     return OK;
 }
 
+status_t MockCasFactory::createPlugin(
+        int32_t CA_system_id,
+        void* /*appData*/,
+        CasPluginCallbackExt /*callback*/,
+        CasPlugin **plugin) {
+    if (!isSystemIdSupported(CA_system_id)) {
+        return BAD_VALUE;
+    }
+
+    *plugin = new MockCasPlugin();
+    return OK;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 bool MockDescramblerFactory::isSystemIdSupported(int32_t CA_system_id) const {
@@ -170,6 +183,16 @@
     return OK;
 }
 
+status_t MockCasPlugin::sendSessionEvent(
+        const CasSessionId &sessionId, int32_t event,
+        int /*arg*/, const CasData& /*eventData*/) {
+    ALOGV("sendSessionEvent: sessionId=%s, event=%d",
+          arrayToString(sessionId).string(), event);
+    Mutex::Autolock lock(mLock);
+
+    return OK;
+}
+
 status_t MockCasPlugin::provision(const String8 &str) {
     ALOGV("provision: provisionString=%s", str.string());
     Mutex::Autolock lock(mLock);
diff --git a/drm/mediacas/plugins/mock/MockCasPlugin.h b/drm/mediacas/plugins/mock/MockCasPlugin.h
index 8106990..74b540c 100644
--- a/drm/mediacas/plugins/mock/MockCasPlugin.h
+++ b/drm/mediacas/plugins/mock/MockCasPlugin.h
@@ -42,6 +42,11 @@
             void *appData,
             CasPluginCallback callback,
             CasPlugin **plugin) override;
+    virtual status_t createPlugin(
+            int32_t CA_system_id,
+            void *appData,
+            CasPluginCallbackExt callback,
+            CasPlugin **plugin) override;
 };
 
 class MockDescramblerFactory : public DescramblerFactory {
@@ -80,7 +85,11 @@
     virtual status_t sendEvent(
             int32_t event, int32_t arg, const CasData &eventData) override;
 
-    virtual status_t provision(const String8 &str) override;
+    virtual status_t sendSessionEvent(
+            const CasSessionId &sessionId,
+            int32_t event, int32_t arg, const CasData &eventData) override;
+
+     virtual status_t provision(const String8 &str) override;
 
     virtual status_t refreshEntitlements(
             int32_t refreshType, const CasData &refreshData) override;
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Android.bp b/drm/mediadrm/plugins/clearkey/hidl/Android.bp
index b44a6c7..e91e918 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/hidl/Android.bp
@@ -14,8 +14,8 @@
 // limitations under the License.
 //
 
-cc_binary {
-    name: "android.hardware.drm@1.2-service.clearkey",
+cc_defaults {
+    name: "clearkey_service_defaults",
     vendor: true,
 
     srcs: [
@@ -33,13 +33,11 @@
         "MemoryFileSystem.cpp",
         "Session.cpp",
         "SessionLibrary.cpp",
-        "service.cpp",
     ],
 
     relative_install_path: "hw",
 
     cflags: ["-Wall", "-Werror"],
-    init_rc: ["android.hardware.drm@1.2-service.clearkey.rc"],
 
     shared_libs: [
         "android.hardware.drm@1.0",
@@ -80,3 +78,16 @@
     },
     srcs: ["protos/DeviceFiles.proto"],
 }
+cc_binary {
+    name: "android.hardware.drm@1.2-service.clearkey",
+    defaults: ["clearkey_service_defaults"],
+    srcs: ["service.cpp"],
+    init_rc: ["android.hardware.drm@1.2-service.clearkey.rc"],
+}
+cc_binary {
+    name: "android.hardware.drm@1.2-service-lazy.clearkey",
+    overrides: ["android.hardware.drm@1.2-service.clearkey"],
+    defaults: ["clearkey_service_defaults"],
+    srcs: ["serviceLazy.cpp"],
+    init_rc: ["android.hardware.drm@1.2-service-lazy.clearkey.rc"],
+}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc
new file mode 100644
index 0000000..9afd3d7
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc
@@ -0,0 +1,14 @@
+service vendor.drm-clearkey-hal-1-2 /vendor/bin/hw/android.hardware.drm@1.2-service-lazy.clearkey
+    interface android.hardware.drm@1.0::ICryptoFactory clearkey
+    interface android.hardware.drm@1.0::IDrmFactory clearkey
+    interface android.hardware.drm@1.1::ICryptoFactory clearkey
+    interface android.hardware.drm@1.1::IDrmFactory clearkey
+    interface android.hardware.drm@1.2::ICryptoFactory clearkey
+    interface android.hardware.drm@1.2::IDrmFactory clearkey
+    disabled
+    oneshot
+    class hal
+    user media
+    group media mediadrm
+    ioprio rt 4
+    writepid /dev/cpuset/foreground/tasks
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc
index ac184f7..5ba669d 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc
@@ -1,4 +1,10 @@
 service vendor.drm-clearkey-hal-1-2 /vendor/bin/hw/android.hardware.drm@1.2-service.clearkey
+    interface android.hardware.drm@1.0::ICryptoFactory clearkey
+    interface android.hardware.drm@1.0::IDrmFactory clearkey
+    interface android.hardware.drm@1.1::ICryptoFactory clearkey
+    interface android.hardware.drm@1.1::IDrmFactory clearkey
+    interface android.hardware.drm@1.2::ICryptoFactory clearkey
+    interface android.hardware.drm@1.2::IDrmFactory clearkey
     class hal
     user media
     group media mediadrm
diff --git a/drm/mediadrm/plugins/clearkey/hidl/service.cpp b/drm/mediadrm/plugins/clearkey/hidl/service.cpp
index 4ca31f3..b39ea01 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/service.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/service.cpp
@@ -13,13 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#define LOG_TAG "android.hardware.drm@1.2-service.clearkey"
-
 #include <CryptoFactory.h>
 #include <DrmFactory.h>
 
 #include <android-base/logging.h>
 #include <binder/ProcessState.h>
+#include <hidl/HidlLazyUtils.h>
 #include <hidl/HidlTransportSupport.h>
 
 using ::android::hardware::configureRpcThreadpool;
@@ -31,14 +30,7 @@
 using android::hardware::drm::V1_2::clearkey::CryptoFactory;
 using android::hardware::drm::V1_2::clearkey::DrmFactory;
 
-
 int main(int /* argc */, char** /* argv */) {
-    ALOGD("android.hardware.drm@1.2-service.clearkey starting...");
-
-    // The DRM HAL may communicate to other vendor components via
-    // /dev/vndbinder
-    android::ProcessState::initWithDriver("/dev/vndbinder");
-
     sp<IDrmFactory> drmFactory = new DrmFactory;
     sp<ICryptoFactory> cryptoFactory = new CryptoFactory;
 
diff --git a/drm/mediadrm/plugins/clearkey/hidl/serviceLazy.cpp b/drm/mediadrm/plugins/clearkey/hidl/serviceLazy.cpp
new file mode 100644
index 0000000..99fd883
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/serviceLazy.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2019 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.
+ */
+#include <CryptoFactory.h>
+#include <DrmFactory.h>
+
+#include <android-base/logging.h>
+#include <binder/ProcessState.h>
+#include <hidl/HidlLazyUtils.h>
+#include <hidl/HidlTransportSupport.h>
+
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
+using ::android::sp;
+
+using android::hardware::drm::V1_2::ICryptoFactory;
+using android::hardware::drm::V1_2::IDrmFactory;
+using android::hardware::drm::V1_2::clearkey::CryptoFactory;
+using android::hardware::drm::V1_2::clearkey::DrmFactory;
+using android::hardware::LazyServiceRegistrar;
+
+int main(int /* argc */, char** /* argv */) {
+    sp<IDrmFactory> drmFactory = new DrmFactory;
+    sp<ICryptoFactory> cryptoFactory = new CryptoFactory;
+
+    configureRpcThreadpool(8, true /* callerWillJoin */);
+
+    // Setup hwbinder service
+    LazyServiceRegistrar serviceRegistrar;
+
+    // Setup hwbinder service
+    CHECK_EQ(serviceRegistrar.registerService(drmFactory, "clearkey"), android::NO_ERROR)
+        << "Failed to register Clearkey Factory HAL";
+    CHECK_EQ(serviceRegistrar.registerService(cryptoFactory, "clearkey"), android::NO_ERROR)
+        << "Failed to register Clearkey Crypto  HAL";
+
+    joinRpcThreadpool();
+}
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 237f9c8..ac54116 100755
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -1635,9 +1635,8 @@
         case FOURCC(".mp3"):
         case 0x6D730055: // "ms U" mp3 audio
         {
-            if (mIsQT && chunk_type == FOURCC("mp4a")
-                    && depth >= 1 && mPath[depth - 1] == FOURCC("wave")) {
-                // Ignore mp4a embedded in QT wave atom
+            if (mIsQT && depth >= 1 && mPath[depth - 1] == FOURCC("wave")) {
+                // Ignore all atoms embedded in QT wave atom
                 *offset += chunk_size;
                 break;
             }
@@ -1666,7 +1665,7 @@
             off64_t stop_offset = *offset + chunk_size;
             *offset = data_offset + sizeof(buffer);
 
-            if (mIsQT && chunk_type == FOURCC("mp4a")) {
+            if (mIsQT) {
                 if (version == 1) {
                     if (mDataSource->readAt(*offset, buffer, 16) < 16) {
                         return ERROR_IO;
@@ -1995,6 +1994,13 @@
 
             *offset += chunk_size;
 
+            if (depth >= 1 && mPath[depth - 1] != FOURCC("stbl")) {
+                char chunk[5];
+                MakeFourCCString(mPath[depth - 1], chunk);
+                ALOGW("stts's parent box (%s) is not stbl, skip it.", chunk);
+                break;
+            }
+
             status_t err =
                 mLastTrack->sampleTable->setTimeToSampleParams(
                         data_offset, chunk_data_size);
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/extractors/ogg/OggExtractor.cpp
index 596c1c8..ba40690 100644
--- a/media/extractors/ogg/OggExtractor.cpp
+++ b/media/extractors/ogg/OggExtractor.cpp
@@ -983,7 +983,7 @@
         size_t denom = numerator - kMaxNumTOCEntries;
 
         size_t accum = 0;
-        for (ssize_t i = mTableOfContents.size() - 1; i >= 0; --i) {
+        for (ssize_t i = mTableOfContents.size(); i > 0; --i) {
             accum += denom;
             if (accum >= numerator) {
                 mTableOfContents.removeAt(i);
diff --git a/media/libstagefright/codecs/g711/dec/SoftG711.cpp b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
index c14983a..877cb5a 100644
--- a/media/libstagefright/codecs/g711/dec/SoftG711.cpp
+++ b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
@@ -23,6 +23,8 @@
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MediaDefs.h>
 
+#define MAX_CHANNEL_COUNT            6  /* maximum number of audio channels that can be decoded */
+
 namespace android {
 
 template<class T>
@@ -184,7 +186,7 @@
                 return OMX_ErrorUndefined;
             }
 
-            if (pcmParams->nChannels < 1 || pcmParams->nChannels > 2) {
+            if (pcmParams->nChannels < 1 || pcmParams->nChannels > MAX_CHANNEL_COUNT) {
                 return OMX_ErrorUndefined;
             }
 
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index 85d9bce..e0b233d 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -332,10 +332,8 @@
         if (moduleDevice) {
             if (encodedFormat != AUDIO_FORMAT_DEFAULT) {
                 moduleDevice->setEncodedFormat(encodedFormat);
-                if (moduleDevice->address() != devAddress) {
-                    moduleDevice->setAddress(devAddress);
-                }
             }
+            moduleDevice->setAddress(devAddress);
             if (allowToCreate) {
                 moduleDevice->attach(hwModule);
             }
diff --git a/services/mediacodec/seccomp_policy/mediacodec-arm.policy b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
index edf4dab..0aa5acc 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-arm.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
@@ -13,6 +13,8 @@
 ppoll: 1
 mmap2: 1
 getrandom: 1
+memfd_create: 1
+ftruncate64: 1
 
 # mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
 # parser support for '<' is in this needs to be modified to also prevent
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
index 588141a..b9adbd9 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
@@ -21,6 +21,8 @@
 ppoll: 1
 mprotect: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
 mmap2: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
+memfd_create: 1
+ftruncate64: 1
 
 # mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
 # parser support for '<' is in this needs to be modified to also prevent
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy b/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
index 1bee1b5..7abb432 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
@@ -26,6 +26,8 @@
 fstat: 1
 newfstatat: 1
 fstatfs: 1
+memfd_create: 1
+ftruncate64: 1
 
 # mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
 # parser support for '<' is in this needs to be modified to also prevent