MediaCas: add MediaCasService

This CL adds API only without implementation.

bug: 22804304
Change-Id: Ibb5a29cc616ec0af81957b2bfe1419c482591753
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 6c6c369..eac532b 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -60,10 +60,10 @@
         libui liblog libcutils libutils libbinder libsonivox libicuuc libicui18n libexpat \
         libcamera_client libstagefright_foundation \
         libgui libdl libaudioutils libaudioclient \
-        libmedia_helper \
+        libmedia_helper libmediadrm \
         libhidlbase \
 
-LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbinder libsonivox
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbinder libsonivox libmediadrm
 
 # for memory heap analysis
 LOCAL_STATIC_LIBRARIES := libc_malloc_debug_backtrace libc_logging
diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp
index bfc43a6..f08fabb 100644
--- a/media/libmedia/IMediaExtractor.cpp
+++ b/media/libmedia/IMediaExtractor.cpp
@@ -21,6 +21,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <android/media/ICas.h>
 #include <binder/IPCThreadState.h>
 #include <binder/Parcel.h>
 #include <media/IMediaExtractor.h>
@@ -35,6 +36,7 @@
     GETMETADATA,
     FLAGS,
     GETDRMTRACKINFO,
+    SETMEDIACAS,
     SETUID,
     NAME,
     GETMETRICS
@@ -114,6 +116,21 @@
         ALOGV("getDrmTrackInfo NOT IMPLEMENTED");
         return NULL;
     }
+
+    virtual status_t setMediaCas(const sp<ICas> & cas) {
+        ALOGV("setMediaCas");
+
+        Parcel data, reply;
+        data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
+        data.writeStrongBinder(IInterface::asBinder(cas));
+
+        status_t err = remote()->transact(SETMEDIACAS, data, &reply);
+        if (err != NO_ERROR) {
+            return err;
+        }
+        return reply.readInt32();
+    }
+
     virtual void setUID(uid_t uid __unused) {
         ALOGV("setUID NOT IMPLEMENTED");
     }
@@ -185,6 +202,21 @@
             status_t ret = getMetrics(reply);
             return ret;
         }
+        case SETMEDIACAS: {
+            ALOGV("setMediaCas");
+            CHECK_INTERFACE(IMediaExtractor, data, reply);
+
+            sp<IBinder> casBinder;
+            status_t err = data.readNullableStrongBinder(&casBinder);
+            if (err != NO_ERROR) {
+                ALOGE("Error reading cas from parcel");
+                return err;
+            }
+            sp<ICas> cas = interface_cast<ICas>(casBinder);
+
+            reply->writeInt32(setMediaCas(cas));
+            return OK;
+        }
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libmedia/MediaDefs.cpp b/media/libmedia/MediaDefs.cpp
index 2ae71f7..544a6ae 100644
--- a/media/libmedia/MediaDefs.cpp
+++ b/media/libmedia/MediaDefs.cpp
@@ -29,6 +29,7 @@
 const char *MEDIA_MIMETYPE_VIDEO_MPEG2 = "video/mpeg2";
 const char *MEDIA_MIMETYPE_VIDEO_RAW = "video/raw";
 const char *MEDIA_MIMETYPE_VIDEO_DOLBY_VISION = "video/dolby-vision";
+const char *MEDIA_MIMETYPE_VIDEO_SCRAMBLED = "video/scrambled";
 
 const char *MEDIA_MIMETYPE_AUDIO_AMR_NB = "audio/3gpp";
 const char *MEDIA_MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb";
@@ -48,6 +49,7 @@
 const char *MEDIA_MIMETYPE_AUDIO_MSGSM = "audio/gsm";
 const char *MEDIA_MIMETYPE_AUDIO_AC3 = "audio/ac3";
 const char *MEDIA_MIMETYPE_AUDIO_EAC3 = "audio/eac3";
+const char *MEDIA_MIMETYPE_AUDIO_SCRAMBLED = "audio/scrambled";
 
 const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mp4";
 const char *MEDIA_MIMETYPE_CONTAINER_WAV = "audio/x-wav";
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index d044754..4300140 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -93,6 +93,7 @@
         libui \
         libutils \
         libvorbisidec \
+        libmediadrm \
 
 LOCAL_STATIC_LIBRARIES := \
         libstagefright_color_conversion \
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 03010ab..6674e2c 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -23,6 +23,7 @@
 #include "include/SharedMemoryBuffer.h"
 #include "include/SoftwareRenderer.h"
 
+#include <android/media/IDescrambler.h>
 #include <binder/IMemory.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
@@ -680,8 +681,17 @@
 
 status_t MediaCodec::configure(
         const sp<AMessage> &format,
+        const sp<Surface> &nativeWindow,
+        const sp<ICrypto> &crypto,
+        uint32_t flags) {
+    return configure(format, nativeWindow, crypto, NULL, flags);
+}
+
+status_t MediaCodec::configure(
+        const sp<AMessage> &format,
         const sp<Surface> &surface,
         const sp<ICrypto> &crypto,
+        const sp<IDescrambler> &descrambler,
         uint32_t flags) {
     sp<AMessage> msg = new AMessage(kWhatConfigure, this);
 
@@ -710,8 +720,12 @@
     msg->setInt32("flags", flags);
     msg->setObject("surface", surface);
 
-    if (crypto != NULL) {
-        msg->setPointer("crypto", crypto.get());
+    if (crypto != NULL || descrambler != NULL) {
+        if (crypto != NULL) {
+            msg->setPointer("crypto", crypto.get());
+        } else {
+            msg->setPointer("descrambler", descrambler.get());
+        }
         if (mAnalyticsItem != NULL) {
             // XXX: save indication that it's crypto in some way...
             mAnalyticsItem->setInt32("crypto", 1);
@@ -1992,6 +2006,13 @@
             ALOGV("kWhatConfigure: New mCrypto: %p (%d)",
                     mCrypto.get(), (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
 
+            void *descrambler;
+            if (!msg->findPointer("descrambler", &descrambler)) {
+                descrambler = NULL;
+            }
+
+            mDescrambler = static_cast<IDescrambler *>(descrambler);
+
             uint32_t flags;
             CHECK(msg->findInt32("flags", (int32_t *)&flags));
 
@@ -2592,6 +2613,7 @@
                     mCrypto.get(), (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
         }
         mCrypto.clear();
+        mDescrambler.clear();
         handleSetSurface(NULL);
 
         mInputFormat.clear();
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 1c1acb0..ea3ed28 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -35,6 +35,7 @@
 #include <media/stagefright/MediaSource.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/Utils.h>
+#include <android/media/ICas.h>
 
 namespace android {
 
@@ -82,6 +83,10 @@
         return ERROR_UNSUPPORTED;
     }
 
+    if (mCas != NULL) {
+        mImpl->setMediaCas(mCas);
+    }
+
     status_t err = updateDurationAndBitrate();
     if (err == OK) {
         mDataSource = dataSource;
@@ -114,6 +119,10 @@
         return ERROR_UNSUPPORTED;
     }
 
+    if (mCas != NULL) {
+        mImpl->setMediaCas(mCas);
+    }
+
     err = updateDurationAndBitrate();
     if (err == OK) {
         mDataSource = fileSource;
@@ -140,6 +149,10 @@
         return ERROR_UNSUPPORTED;
     }
 
+    if (mCas != NULL) {
+        mImpl->setMediaCas(mCas);
+    }
+
     err = updateDurationAndBitrate();
     if (err == OK) {
         mDataSource = source;
@@ -148,6 +161,27 @@
     return err;
 }
 
+status_t NuMediaExtractor::setMediaCas(const sp<ICas> &cas) {
+    ALOGV("setMediaCas: cas=%p", cas.get());
+
+    Mutex::Autolock autoLock(mLock);
+
+    if (cas == NULL) {
+        return BAD_VALUE;
+    }
+
+    if (mImpl != NULL) {
+        mImpl->setMediaCas(cas);
+        status_t err = updateDurationAndBitrate();
+        if (err != OK) {
+            return err;
+        }
+    }
+
+    mCas = cas;
+    return OK;
+}
+
 status_t NuMediaExtractor::updateDurationAndBitrate() {
     if (mImpl->countTracks() > kMaxTrackCount) {
         return ERROR_UNSUPPORTED;