Merge "MediaCas: fixes for playback tests" into oc-dev
diff --git a/drm/libmediadrm/CasImpl.cpp b/drm/libmediadrm/CasImpl.cpp
index de15244..fcedd6b 100644
--- a/drm/libmediadrm/CasImpl.cpp
+++ b/drm/libmediadrm/CasImpl.cpp
@@ -49,13 +49,24 @@
     return result;
 }
 
+struct CasImpl::PluginHolder : public RefBase {
+public:
+    explicit PluginHolder(CasPlugin *plugin) : mPlugin(plugin) {}
+    ~PluginHolder() { if (mPlugin != NULL) delete mPlugin; }
+    CasPlugin* get() { return mPlugin; }
+
+private:
+    CasPlugin *mPlugin;
+    DISALLOW_EVIL_CONSTRUCTORS(PluginHolder);
+};
+
 CasImpl::CasImpl(const sp<ICasListener> &listener)
-    : mPlugin(NULL), mListener(listener) {
-    ALOGV("CTOR: mPlugin=%p", mPlugin);
+    : mPluginHolder(NULL), mListener(listener) {
+    ALOGV("CTOR");
 }
 
 CasImpl::~CasImpl() {
-    ALOGV("DTOR: mPlugin=%p", mPlugin);
+    ALOGV("DTOR");
     release();
 }
 
@@ -76,7 +87,7 @@
 
 void CasImpl::init(const sp<SharedLibrary>& library, CasPlugin *plugin) {
     mLibrary = library;
-    mPlugin = plugin;
+    mPluginHolder = new PluginHolder(plugin);
 }
 
 void CasImpl::onEvent(
@@ -95,13 +106,20 @@
 
 Status CasImpl::setPrivateData(const CasData& pvtData) {
     ALOGV("setPrivateData");
-    return getBinderStatus(mPlugin->setPrivateData(pvtData));
+    sp<PluginHolder> holder = mPluginHolder;
+    if (holder == NULL) {
+        return getBinderStatus(INVALID_OPERATION);
+    }
+    return getBinderStatus(holder->get()->setPrivateData(pvtData));
 }
 
 Status CasImpl::openSession(int32_t program_number, CasSessionId* sessionId) {
     ALOGV("openSession: program_number=%d", program_number);
-
-    status_t err = mPlugin->openSession(program_number, sessionId);
+    sp<PluginHolder> holder = mPluginHolder;
+    if (holder == NULL) {
+        return getBinderStatus(INVALID_OPERATION);
+    }
+    status_t err = holder->get()->openSession(program_number, sessionId);
 
     ALOGV("openSession: session opened for program_number=%d, sessionId=%s",
             program_number, sessionIdToString(*sessionId).string());
@@ -115,8 +133,11 @@
         CasSessionId* sessionId) {
     ALOGV("openSession: program_number=%d, elementary_PID=%d",
             program_number, elementary_PID);
-
-    status_t err = mPlugin->openSession(
+    sp<PluginHolder> holder = mPluginHolder;
+    if (holder == NULL) {
+        return getBinderStatus(INVALID_OPERATION);
+    }
+    status_t err = holder->get()->openSession(
             program_number, elementary_PID, sessionId);
 
     ALOGV("openSession: session opened for "
@@ -131,69 +152,92 @@
         const CasSessionId &sessionId, const CasData& pvtData) {
     ALOGV("setSessionPrivateData: sessionId=%s",
             sessionIdToString(sessionId).string());
-
-    return getBinderStatus(mPlugin->setSessionPrivateData(sessionId, pvtData));
+    sp<PluginHolder> holder = mPluginHolder;
+    if (holder == NULL) {
+        return getBinderStatus(INVALID_OPERATION);
+    }
+    return getBinderStatus(holder->get()->setSessionPrivateData(sessionId, pvtData));
 }
 
 Status CasImpl::closeSession(const CasSessionId &sessionId) {
     ALOGV("closeSession: sessionId=%s",
             sessionIdToString(sessionId).string());
-
-    return getBinderStatus(mPlugin->closeSession(sessionId));
+    sp<PluginHolder> holder = mPluginHolder;
+    if (holder == NULL) {
+        return getBinderStatus(INVALID_OPERATION);
+    }
+    return getBinderStatus(holder->get()->closeSession(sessionId));
 }
 
 Status CasImpl::processEcm(const CasSessionId &sessionId, const ParcelableCasData& ecm) {
     ALOGV("processEcm: sessionId=%s",
             sessionIdToString(sessionId).string());
+    sp<PluginHolder> holder = mPluginHolder;
+    if (holder == NULL) {
+        return getBinderStatus(INVALID_OPERATION);
+    }
 
-    return getBinderStatus(mPlugin->processEcm(sessionId, ecm));
+    return getBinderStatus(holder->get()->processEcm(sessionId, ecm));
 }
 
 Status CasImpl::processEmm(const ParcelableCasData& emm) {
     ALOGV("processEmm");
+    sp<PluginHolder> holder = mPluginHolder;
+    if (holder == NULL) {
+        return getBinderStatus(INVALID_OPERATION);
+    }
 
-    return getBinderStatus(mPlugin->processEmm(emm));
+    return getBinderStatus(holder->get()->processEmm(emm));
 }
 
 Status CasImpl::sendEvent(
         int32_t event, int32_t arg, const ::std::unique_ptr<CasData> &eventData) {
     ALOGV("sendEvent");
+    sp<PluginHolder> holder = mPluginHolder;
+    if (holder == NULL) {
+        return getBinderStatus(INVALID_OPERATION);
+    }
 
     status_t err;
     if (eventData == nullptr) {
-        err = mPlugin->sendEvent(event, arg, CasData());
+        err = holder->get()->sendEvent(event, arg, CasData());
     } else {
-        err = mPlugin->sendEvent(event, arg, *eventData);
+        err = holder->get()->sendEvent(event, arg, *eventData);
     }
     return getBinderStatus(err);
 }
 
 Status CasImpl::provision(const String16& provisionString) {
     ALOGV("provision: provisionString=%s", String8(provisionString).string());
+    sp<PluginHolder> holder = mPluginHolder;
+    if (holder == NULL) {
+        return getBinderStatus(INVALID_OPERATION);
+    }
 
-    return getBinderStatus(mPlugin->provision(String8(provisionString)));
+    return getBinderStatus(holder->get()->provision(String8(provisionString)));
 }
 
 Status CasImpl::refreshEntitlements(
         int32_t refreshType, const ::std::unique_ptr<CasData> &refreshData) {
     ALOGV("refreshEntitlements");
+    sp<PluginHolder> holder = mPluginHolder;
+    if (holder == NULL) {
+        return getBinderStatus(INVALID_OPERATION);
+    }
 
     status_t err;
     if (refreshData == nullptr) {
-        err = mPlugin->refreshEntitlements(refreshType, CasData());
+        err = holder->get()->refreshEntitlements(refreshType, CasData());
     } else {
-        err = mPlugin->refreshEntitlements(refreshType, *refreshData);
+        err = holder->get()->refreshEntitlements(refreshType, *refreshData);
     }
     return getBinderStatus(err);
 }
 
 Status CasImpl::release() {
-    ALOGV("release: mPlugin=%p", mPlugin);
-
-    if (mPlugin != NULL) {
-        delete mPlugin;
-        mPlugin = NULL;
-    }
+    ALOGV("release: plugin=%p",
+            mPluginHolder == NULL ? mPluginHolder->get() : NULL);
+    mPluginHolder.clear();
     return Status::ok();
 }
 
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
index 221b74b..f4c3577 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
@@ -84,7 +84,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 ClearKeyCasPlugin::ClearKeyCasPlugin(
         uint64_t appData, CasPluginCallback callback)
-    : mAppData(appData), mCallback(callback) {
+    : mCallback(callback), mAppData(appData) {
     ALOGV("CTOR");
 }
 
@@ -93,7 +93,7 @@
     ClearKeySessionLibrary::get()->destroyPlugin(this);
 }
 
-status_t ClearKeyCasPlugin::setPrivateData(const CasData &data) {
+status_t ClearKeyCasPlugin::setPrivateData(const CasData &/*data*/) {
     ALOGV("setPrivateData");
 
     return OK;
@@ -142,7 +142,7 @@
 }
 
 status_t ClearKeyCasPlugin::setSessionPrivateData(
-        const CasSessionId &sessionId, const CasData &data) {
+        const CasSessionId &sessionId, const CasData & /*data*/) {
     ALOGV("setSessionPrivateData: sessionId=%s",
             sessionIdToString(sessionId).string());
     sp<ClearKeyCasSession> session =
@@ -167,7 +167,7 @@
     return session->updateECM(mKeyFetcher.get(), (void*)ecm.data(), ecm.size());
 }
 
-status_t ClearKeyCasPlugin::processEmm(const CasEmm& emm) {
+status_t ClearKeyCasPlugin::processEmm(const CasEmm& /*emm*/) {
     ALOGV("processEmm");
     Mutex::Autolock lock(mKeyFetcherLock);
 
@@ -212,8 +212,8 @@
 }
 
 status_t ClearKeyCasPlugin::refreshEntitlements(
-        int32_t refreshType, const CasData &refreshData) {
-    ALOGV("refreshEntitlements");
+        int32_t refreshType, const CasData &/*refreshData*/) {
+    ALOGV("refreshEntitlements: refreshType=%d", refreshType);
     Mutex::Autolock lock(mKeyFetcherLock);
 
     return OK;
@@ -344,7 +344,7 @@
                 AES_BLOCK_SIZE * 8, &mKeyInfo[keyIndex].contentKey);
         mKeyInfo[keyIndex].valid = (result == 0);
         if (!mKeyInfo[keyIndex].valid) {
-            ALOGE("updateECM: failed to set key %d, key_id=%d",
+            ALOGE("updateECM: failed to set key %zu, key_id=%d",
                     keyIndex, keys[keyIndex].key_id);
         }
     }
@@ -356,6 +356,10 @@
         bool secure, DescramblerPlugin::ScramblingControl scramblingControl,
         size_t numSubSamples, const DescramblerPlugin::SubSample *subSamples,
         const void *srcPtr, void *dstPtr, AString * /* errorDetailMsg */) {
+    if (secure) {
+        return ERROR_DRM_CANNOT_HANDLE;
+    }
+
     AES_KEY contentKey;
 
     if (scramblingControl != DescramblerPlugin::kScrambling_Unscrambled) {
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp b/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp
index 210bab3..cb69f91 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "ClearKeyFetcher"
 
 #include <algorithm>
+#include <inttypes.h>
 #include <string>
 
 #include "ClearKeyFetcher.h"
@@ -70,7 +71,7 @@
         bool same_parity = (((container.descriptor(0).id() & 0x01) ^
                 (container.descriptor(1).id() & 0x01)) == 0);
         if (same_parity) {
-            ALOGW("asset_id=%llu: malformed Ecm, "
+            ALOGW("asset_id=%" PRIu64 ": malformed Ecm, "
                     "content keys have same parity, id0=%d, id1=%d",
                     container.descriptor(0).ecm().asset_id(),
                     container.descriptor(0).id(),
@@ -88,7 +89,7 @@
     // asset_id change. If it sends an EcmContainer with 2 Ecms with different
     // asset_ids (old and new) then it might be best to prefetch the Emm.
     if ((asset_.id() != 0) && (*asset_id != asset_.id())) {
-        ALOGW("Asset_id change from %llu to %llu", asset_.id(), *asset_id);
+        ALOGW("Asset_id change from %" PRIu64 " to %" PRIu64, asset_.id(), *asset_id);
         asset_.Clear();
     }
 
diff --git a/drm/mediacas/plugins/clearkey/ecm_generator.cpp b/drm/mediacas/plugins/clearkey/ecm_generator.cpp
index f1aa973..7d29659 100644
--- a/drm/mediacas/plugins/clearkey/ecm_generator.cpp
+++ b/drm/mediacas/plugins/clearkey/ecm_generator.cpp
@@ -80,7 +80,7 @@
     CHECK(default_fields);
 
     if (ecm->size() < kTotalEcmSize) {
-        ALOGE("Short ECM: expected_length=%zu, actual_length=%zu",
+        ALOGE("Short ECM: expected_length=%d, actual_length=%zu",
                 kTotalEcmSize, ecm->size());
         return BAD_VALUE;
     }
diff --git a/include/media/CasImpl.h b/include/media/CasImpl.h
index 80c901e..3c07092 100644
--- a/include/media/CasImpl.h
+++ b/include/media/CasImpl.h
@@ -84,8 +84,9 @@
     virtual Status release() override;
 
 private:
+    struct PluginHolder;
     sp<SharedLibrary> mLibrary;
-    CasPlugin *mPlugin;
+    sp<PluginHolder> mPluginHolder;
     sp<ICasListener> mListener;
 
     DISALLOW_EVIL_CONSTRUCTORS(CasImpl);
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index b933002..6bac1db 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -577,7 +577,7 @@
     // fill in CryptoInfo fields for AnotherPacketSource::read()
     // MediaCas doesn't use cryptoMode, but set to non-zero value here.
     scrambledAccessUnit->meta()->setInt32(
-            "cryptoMode", CryptoPlugin::kMode_AES_CBC);
+            "cryptoMode", CryptoPlugin::kMode_AES_CTR);
     scrambledAccessUnit->meta()->setInt32("cryptoKey", keyId);
     scrambledAccessUnit->meta()->setBuffer("clearBytes", clearSizes);
     scrambledAccessUnit->meta()->setBuffer("encBytes", encSizes);