Merge changes from topic 'api-review' into oc-dev

* changes:
  MediaCas: combine openSession methods
  MediaCas: changes to address API review comments
diff --git a/drm/libmediadrm/CasImpl.cpp b/drm/libmediadrm/CasImpl.cpp
index fcedd6b..1a33bb0 100644
--- a/drm/libmediadrm/CasImpl.cpp
+++ b/drm/libmediadrm/CasImpl.cpp
@@ -113,36 +113,15 @@
     return getBinderStatus(holder->get()->setPrivateData(pvtData));
 }
 
-Status CasImpl::openSession(int32_t program_number, CasSessionId* sessionId) {
-    ALOGV("openSession: program_number=%d", program_number);
+Status CasImpl::openSession(CasSessionId* sessionId) {
+    ALOGV("openSession");
     sp<PluginHolder> holder = mPluginHolder;
     if (holder == NULL) {
         return getBinderStatus(INVALID_OPERATION);
     }
-    status_t err = holder->get()->openSession(program_number, sessionId);
+    status_t err = holder->get()->openSession(sessionId);
 
-    ALOGV("openSession: session opened for program_number=%d, sessionId=%s",
-            program_number, sessionIdToString(*sessionId).string());
-
-    return getBinderStatus(err);
-}
-
-Status CasImpl::openSessionForStream(
-        int32_t program_number,
-        int32_t elementary_PID,
-        CasSessionId* sessionId) {
-    ALOGV("openSession: program_number=%d, elementary_PID=%d",
-            program_number, elementary_PID);
-    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 "
-            "program_number=%d, elementary_PID=%d, sessionId=%s",
-            program_number, elementary_PID,
+    ALOGV("openSession: session opened, sessionId=%s",
             sessionIdToString(*sessionId).string());
 
     return getBinderStatus(err);
diff --git a/drm/libmediadrm/aidl/android/media/ICas.aidl b/drm/libmediadrm/aidl/android/media/ICas.aidl
index 6b2ce4a..9746593 100644
--- a/drm/libmediadrm/aidl/android/media/ICas.aidl
+++ b/drm/libmediadrm/aidl/android/media/ICas.aidl
@@ -21,8 +21,7 @@
 /** @hide */
 interface ICas {
     void setPrivateData(in byte[] pvtData);
-    byte[] openSession(int program_number);
-    byte[] openSessionForStream(int program_number, int elementary_PID);
+    byte[] openSession();
     void closeSession(in byte[] sessionId);
     void setSessionPrivateData(in byte[] sessionId, in byte[] pvtData);
     void processEcm(in byte[] sessionId, in MediaCas.ParcelableCasData ecm);
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
index f4c3577..4ed5fce 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
@@ -110,23 +110,10 @@
     return result;
 }
 
-status_t ClearKeyCasPlugin::openSession(
-        uint16_t program_number, CasSessionId* sessionId) {
-    ALOGV("openSession: program_number=%u", program_number);
+status_t ClearKeyCasPlugin::openSession(CasSessionId* sessionId) {
+    ALOGV("openSession");
 
-    return ClearKeySessionLibrary::get()->addSession(
-            this, program_number, 0, sessionId);
-}
-
-status_t ClearKeyCasPlugin::openSession(
-        uint16_t program_number,
-        uint16_t elementary_PID,
-        CasSessionId *sessionId) {
-    ALOGV("openSession: program_number=%u, elementary_PID=%u",
-            program_number, elementary_PID);
-
-    return ClearKeySessionLibrary::get()->addSession(
-            this, program_number, elementary_PID, sessionId);
+    return ClearKeySessionLibrary::get()->addSession(this, sessionId);
 }
 
 status_t ClearKeyCasPlugin::closeSession(const CasSessionId &sessionId) {
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
index 8cf9b90..b7134e4 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
@@ -68,13 +68,7 @@
     virtual status_t setPrivateData(
             const CasData &data) override;
 
-    virtual status_t openSession(
-            uint16_t program_number, CasSessionId *sessionId) override;
-
-    virtual status_t openSession(
-            uint16_t program_number,
-            uint16_t elementary_PID,
-            CasSessionId *sessionId) override;
+    virtual status_t openSession(CasSessionId *sessionId) override;
 
     virtual status_t closeSession(
             const CasSessionId &sessionId) override;
diff --git a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp
index 4e5f479..faea008 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp
@@ -29,29 +29,14 @@
 Mutex ClearKeySessionLibrary::sSingletonLock;
 ClearKeySessionLibrary* ClearKeySessionLibrary::sSingleton = NULL;
 
-inline bool operator < (
-        const SessionInfo& lhs, const SessionInfo& rhs) {
-    if (lhs.plugin < rhs.plugin) return true;
-    else if (lhs.plugin > rhs.plugin) return false;
-
-    if (lhs.program_number < rhs.program_number) return true;
-    else if (lhs.program_number > rhs.program_number) return false;
-
-    return lhs.elementary_PID < rhs.elementary_PID;
-}
-
-ClearKeyCasSession::ClearKeyCasSession(const SessionInfo &info)
-    : mSessionInfo(info) {
+ClearKeyCasSession::ClearKeyCasSession(CasPlugin *plugin)
+    : mPlugin(plugin) {
     mKeyInfo[0].valid = mKeyInfo[1].valid = false;
 }
 
 ClearKeyCasSession::~ClearKeyCasSession() {
 }
 
-const SessionInfo& ClearKeyCasSession::getSessionInfo() const {
-    return mSessionInfo;
-}
-
 ClearKeySessionLibrary* ClearKeySessionLibrary::get() {
     Mutex::Autolock lock(sSingletonLock);
 
@@ -66,24 +51,12 @@
 ClearKeySessionLibrary::ClearKeySessionLibrary() : mNextSessionId(1) {}
 
 status_t ClearKeySessionLibrary::addSession(
-        CasPlugin *plugin,
-        uint16_t program_number,
-        uint16_t elementary_PID,
-        CasSessionId *sessionId) {
+        CasPlugin *plugin, CasSessionId *sessionId) {
     CHECK(sessionId);
 
     Mutex::Autolock lock(mSessionsLock);
 
-    SessionInfo info = {plugin, program_number, elementary_PID};
-    ssize_t index = mSessionInfoToIDMap.indexOfKey(info);
-    if (index >= 0) {
-        ALOGW("Session already exists: program_number=%u, elementary_PID=%u",
-                program_number, elementary_PID);
-        *sessionId = mSessionInfoToIDMap[index];
-        return OK;
-    }
-
-    sp<ClearKeyCasSession> session = new ClearKeyCasSession(info);
+    sp<ClearKeyCasSession> session = new ClearKeyCasSession(plugin);
 
     uint8_t *byteArray = (uint8_t *) &mNextSessionId;
     sessionId->push_back(byteArray[3]);
@@ -92,7 +65,6 @@
     sessionId->push_back(byteArray[0]);
     mNextSessionId++;
 
-    mSessionInfoToIDMap.add(info, *sessionId);
     mIDToSessionMap.add(*sessionId, session);
     return OK;
 }
@@ -117,19 +89,16 @@
     }
 
     sp<ClearKeyCasSession> session = mIDToSessionMap.valueAt(index);
-    mSessionInfoToIDMap.removeItem(session->getSessionInfo());
     mIDToSessionMap.removeItemsAt(index);
 }
 
 void ClearKeySessionLibrary::destroyPlugin(CasPlugin *plugin) {
     Mutex::Autolock lock(mSessionsLock);
 
-    for (ssize_t index = mSessionInfoToIDMap.size() - 1; index >= 0; index--) {
-        const SessionInfo &info = mSessionInfoToIDMap.keyAt(index);
-        if (info.plugin == plugin) {
-            const CasSessionId &id = mSessionInfoToIDMap.valueAt(index);
-            mIDToSessionMap.removeItem(id);
-            mSessionInfoToIDMap.removeItemsAt(index);
+    for (ssize_t index = mIDToSessionMap.size() - 1; index >= 0; index--) {
+        sp<ClearKeyCasSession> session = mIDToSessionMap.valueAt(index);
+        if (session->getPlugin() == plugin) {
+            mIDToSessionMap.removeItemsAt(index);
         }
     }
 }
diff --git a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h
index ebefa72..01f5f47 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h
+++ b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h
@@ -30,12 +30,6 @@
 namespace clearkeycas {
 class KeyFetcher;
 
-struct SessionInfo {
-    CasPlugin *plugin;
-    uint16_t program_number;
-    uint16_t elementary_PID;
-};
-
 class ClearKeyCasSession : public RefBase {
 public:
     ssize_t decrypt(
@@ -59,14 +53,14 @@
     };
     sp<ABuffer> mEcmBuffer;
     Mutex mKeyLock;
-    SessionInfo mSessionInfo;
+    CasPlugin* mPlugin;
     KeyInfo mKeyInfo[kNumKeys];
 
     friend class ClearKeySessionLibrary;
 
-    explicit ClearKeyCasSession(const SessionInfo &info);
+    explicit ClearKeyCasSession(CasPlugin *plugin);
     virtual ~ClearKeyCasSession();
-    const SessionInfo& getSessionInfo() const;
+    CasPlugin* getPlugin() const { return mPlugin; }
     status_t decryptPayload(
             const AES_KEY& key, size_t length, size_t offset, char* buffer) const;
 
@@ -77,11 +71,7 @@
 public:
     static ClearKeySessionLibrary* get();
 
-    status_t addSession(
-            CasPlugin *plugin,
-            uint16_t program_number,
-            uint16_t elementary_PID,
-            CasSessionId *sessionId);
+    status_t addSession(CasPlugin *plugin, CasSessionId *sessionId);
 
     sp<ClearKeyCasSession> findSession(const CasSessionId& sessionId);
 
@@ -96,7 +86,6 @@
     Mutex mSessionsLock;
     uint32_t mNextSessionId;
     KeyedVector<CasSessionId, sp<ClearKeyCasSession>> mIDToSessionMap;
-    KeyedVector<SessionInfo, CasSessionId> mSessionInfoToIDMap;
 
     ClearKeySessionLibrary();
     DISALLOW_EVIL_CONSTRUCTORS(ClearKeySessionLibrary);
diff --git a/drm/mediacas/plugins/mock/MockCasPlugin.cpp b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
index 12cac60..18cd9a4 100644
--- a/drm/mediacas/plugins/mock/MockCasPlugin.cpp
+++ b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
@@ -103,22 +103,9 @@
     return OK;
 }
 
-status_t MockCasPlugin::openSession(
-        uint16_t program_number, CasSessionId* sessionId) {
-    ALOGV("openSession: program_number=%u", program_number);
-    return MockSessionLibrary::get()->addSession(
-            this, program_number, 0, sessionId);
-}
-
-status_t MockCasPlugin::openSession(
-        uint16_t program_number,
-        uint16_t elementary_PID,
-        CasSessionId *sessionId) {
-    ALOGV("openSession: program_number=%u, elementary_PID=%u",
-            program_number, elementary_PID);
-
-    return MockSessionLibrary::get()->addSession(
-            this, program_number, elementary_PID, sessionId);
+status_t MockCasPlugin::openSession(CasSessionId* sessionId) {
+    ALOGV("openSession");
+    return MockSessionLibrary::get()->addSession(this, sessionId);
 }
 
 status_t MockCasPlugin::closeSession(const CasSessionId &sessionId) {
diff --git a/drm/mediacas/plugins/mock/MockCasPlugin.h b/drm/mediacas/plugins/mock/MockCasPlugin.h
index 91c8855..9632492 100644
--- a/drm/mediacas/plugins/mock/MockCasPlugin.h
+++ b/drm/mediacas/plugins/mock/MockCasPlugin.h
@@ -63,13 +63,7 @@
     virtual status_t setPrivateData(
             const CasData &data) override;
 
-    virtual status_t openSession(
-            uint16_t program_number, CasSessionId *sessionId) override;
-
-    virtual status_t openSession(
-            uint16_t program_number,
-            uint16_t elementary_PID,
-            CasSessionId *sessionId) override;
+    virtual status_t openSession(CasSessionId *sessionId) override;
 
     virtual status_t closeSession(
             const CasSessionId &sessionId) override;
diff --git a/drm/mediacas/plugins/mock/MockSessionLibrary.cpp b/drm/mediacas/plugins/mock/MockSessionLibrary.cpp
index 8679a04..a7ee9a0 100644
--- a/drm/mediacas/plugins/mock/MockSessionLibrary.cpp
+++ b/drm/mediacas/plugins/mock/MockSessionLibrary.cpp
@@ -26,26 +26,6 @@
 Mutex MockSessionLibrary::sSingletonLock;
 MockSessionLibrary* MockSessionLibrary::sSingleton = NULL;
 
-inline bool operator < (
-        const SessionInfo& lhs,
-        const SessionInfo& rhs) {
-    if (lhs.plugin < rhs.plugin) return true;
-    else if (lhs.plugin > rhs.plugin) return false;
-
-    if (lhs.program_number < rhs.program_number) return true;
-    else if (lhs.program_number > rhs.program_number) return false;
-
-    return lhs.elementary_PID < rhs.elementary_PID;
-}
-
-void MockCasSession::setSessionInfo(const SessionInfo &info) {
-    mSessionInfo = info;
-}
-
-const SessionInfo& MockCasSession::getSessionInfo() const {
-    return mSessionInfo;
-}
-
 MockSessionLibrary* MockSessionLibrary::get() {
     Mutex::Autolock lock(sSingletonLock);
 
@@ -60,23 +40,10 @@
 MockSessionLibrary::MockSessionLibrary() : mNextSessionId(1) {}
 
 status_t MockSessionLibrary::addSession(
-        CasPlugin *plugin,
-        uint16_t program_number,
-        uint16_t elementary_PID,
-        CasSessionId *sessionId) {
+        CasPlugin *plugin, CasSessionId *sessionId) {
     Mutex::Autolock lock(mSessionsLock);
 
-    SessionInfo info = {plugin, program_number, elementary_PID};
-    ssize_t index = mSessionInfoToIDMap.indexOfKey(info);
-    if (index >= 0) {
-        ALOGW("Session already exists: program_number=%u, elementary_PID=%u",
-                program_number, elementary_PID);
-        *sessionId = mSessionInfoToIDMap[index];
-        return OK;
-    }
-
-    sp<MockCasSession> session = new MockCasSession();
-    session->setSessionInfo(info);
+    sp<MockCasSession> session = new MockCasSession(plugin);
 
     uint8_t *byteArray = (uint8_t *) &mNextSessionId;
     sessionId->push_back(byteArray[3]);
@@ -85,7 +52,6 @@
     sessionId->push_back(byteArray[0]);
     mNextSessionId++;
 
-    mSessionInfoToIDMap.add(info, *sessionId);
     mIDToSessionMap.add(*sessionId, session);
     return OK;
 }
@@ -110,19 +76,16 @@
     }
 
     sp<MockCasSession> session = mIDToSessionMap.valueAt(index);
-    mSessionInfoToIDMap.removeItem(session->getSessionInfo());
     mIDToSessionMap.removeItemsAt(index);
 }
 
 void MockSessionLibrary::destroyPlugin(CasPlugin *plugin) {
     Mutex::Autolock lock(mSessionsLock);
 
-    for (ssize_t index = mSessionInfoToIDMap.size() - 1; index >= 0; index--) {
-        const SessionInfo &info = mSessionInfoToIDMap.keyAt(index);
-        if (info.plugin == plugin) {
-            const CasSessionId &id = mSessionInfoToIDMap.valueAt(index);
-            mIDToSessionMap.removeItem(id);
-            mSessionInfoToIDMap.removeItemsAt(index);
+    for (ssize_t index = mIDToSessionMap.size() - 1; index >= 0; index--) {
+        sp<MockCasSession> session = mIDToSessionMap.valueAt(index);
+        if (session->getPlugin() == plugin) {
+            mIDToSessionMap.removeItemsAt(index);
         }
     }
 }
diff --git a/drm/mediacas/plugins/mock/MockSessionLibrary.h b/drm/mediacas/plugins/mock/MockSessionLibrary.h
index d28cbdc..0b30f4c 100644
--- a/drm/mediacas/plugins/mock/MockSessionLibrary.h
+++ b/drm/mediacas/plugins/mock/MockSessionLibrary.h
@@ -25,23 +25,17 @@
 
 namespace android {
 
-struct SessionInfo {
-    CasPlugin *plugin;
-    uint16_t program_number;
-    uint16_t elementary_PID;
-};
-
 class MockCasSession : public RefBase {
 public:
-    explicit MockCasSession() {}
+    explicit MockCasSession(CasPlugin *plugin) : mPlugin(plugin) {}
     virtual ~MockCasSession() {}
 
 private:
     friend class MockSessionLibrary;
-    SessionInfo mSessionInfo;
 
-    void setSessionInfo(const SessionInfo &info);
-    const SessionInfo& getSessionInfo() const;
+    CasPlugin* mPlugin;
+
+    CasPlugin* getPlugin() const { return mPlugin; }
 
     DISALLOW_EVIL_CONSTRUCTORS(MockCasSession);
 };
@@ -50,11 +44,7 @@
 public:
     static MockSessionLibrary* get();
 
-    status_t addSession(
-            CasPlugin *plugin,
-            uint16_t program_number,
-            uint16_t elementary_PID,
-            CasSessionId *sessionId);
+    status_t addSession(CasPlugin *plugin, CasSessionId *sessionId);
 
     sp<MockCasSession> findSession(const CasSessionId& sessionId);
 
@@ -69,7 +59,6 @@
     Mutex mSessionsLock;
     uint32_t mNextSessionId;
     KeyedVector<CasSessionId, sp<MockCasSession> > mIDToSessionMap;
-    KeyedVector<SessionInfo, CasSessionId> mSessionInfoToIDMap;
 
     MockSessionLibrary();
     DISALLOW_EVIL_CONSTRUCTORS(MockSessionLibrary);
diff --git a/include/media/CasImpl.h b/include/media/CasImpl.h
index 3c07092..0dd506c 100644
--- a/include/media/CasImpl.h
+++ b/include/media/CasImpl.h
@@ -54,13 +54,7 @@
     virtual Status setPrivateData(
             const CasData& pvtData) override;
 
-    virtual Status openSession(
-            int32_t program_number, CasSessionId* _aidl_return) override;
-
-    virtual Status openSessionForStream(
-            int32_t program_number,
-            int32_t elementary_PID,
-            CasSessionId* _aidl_return) override;
+    virtual Status openSession(CasSessionId* _aidl_return) override;
 
     virtual Status closeSession(const CasSessionId& sessionId) override;
 
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index e8c46e3..621c2ce 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -613,12 +613,21 @@
     uint32_t type;
     const void *data;
     size_t size;
-    if (meta->findData(kKeyCas, &type, &data, &size)) {
+    if (meta->findData(kKeyCASessionID, &type, &data, &size)) {
         sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
-        msg->setBuffer("cas", buffer);
+        if (buffer.get() == NULL || buffer->base() == NULL) {
+            return NO_MEMORY;
+        }
+
+        msg->setBuffer("ca-session-id", buffer);
         memcpy(buffer->data(), data, size);
     }
 
+    int32_t systemId;
+    if (meta->findInt32(kKeyCASystemID, &systemId)) {
+        msg->setInt32("ca-system-id", systemId);
+    }
+
     if (!strncasecmp("video/scrambled", mime, 15)
             || !strncasecmp("audio/scrambled", mime, 15)) {
 
diff --git a/media/libstagefright/include/MetaData.h b/media/libstagefright/include/MetaData.h
index 214f4ff..7afd22d 100644
--- a/media/libstagefright/include/MetaData.h
+++ b/media/libstagefright/include/MetaData.h
@@ -176,7 +176,8 @@
     kKeyCryptoDefaultIVSize = 'cryS',  // int32_t
 
     kKeyPssh              = 'pssh',  // raw data
-    kKeyCas               = ' cas',
+    kKeyCASystemID        = 'caid',  // int32_t
+    kKeyCASessionID       = 'seid',  // raw data
 
     // Please see MediaFormat.KEY_IS_AUTOSELECT.
     kKeyTrackIsAutoselect = 'auto', // bool (int32_t)
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 47caf61..8099edb 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -140,7 +140,8 @@
     unsigned pid() const { return mElementaryPID; }
     void setPID(unsigned pid) { mElementaryPID = pid; }
 
-    void setCasSession(
+    void setCasInfo(
+            int32_t systemId,
             const sp<IDescrambler> &descrambler,
             const std::vector<uint8_t> &sessionId);
 
@@ -682,9 +683,10 @@
         sp<Stream> &stream = mStreams.editValueAt(i);
         sp<IDescrambler> descrambler;
         std::vector<uint8_t> sessionId;
-        if (mParser->mCasManager->getCasSession(
-                mProgramNumber, stream->pid(), &descrambler, &sessionId)) {
-            stream->setCasSession(descrambler, sessionId);
+        int32_t systemId;
+        if (mParser->mCasManager->getCasInfo(mProgramNumber, stream->pid(),
+                &systemId, &descrambler, &sessionId)) {
+            stream->setCasInfo(systemId, descrambler, sessionId);
         }
     }
 }
@@ -767,8 +769,8 @@
             meta->setCString(kKeyMIMEType,
                     isAudio() ? MEDIA_MIMETYPE_AUDIO_SCRAMBLED
                               : MEDIA_MIMETYPE_VIDEO_SCRAMBLED);
-            // for DrmInitData
-            meta->setData(kKeyCas, 0, &CA_system_ID, sizeof(CA_system_ID));
+            // for MediaExtractor.CasInfo
+            meta->setInt32(kKeyCASystemID, CA_system_ID);
             mSource = new AnotherPacketSource(meta);
         }
     }
@@ -1566,14 +1568,14 @@
     return NULL;
 }
 
-void ATSParser::Stream::setCasSession(
-        const sp<IDescrambler> &descrambler,
+void ATSParser::Stream::setCasInfo(
+        int32_t systemId, const sp<IDescrambler> &descrambler,
         const std::vector<uint8_t> &sessionId) {
     if (mSource != NULL && mDescrambler == NULL && descrambler != NULL) {
         signalDiscontinuity(DISCONTINUITY_FORMAT_ONLY, NULL);
         mDescrambler = descrambler;
         if (mQueue->isScrambled()) {
-            mQueue->setCasSession(sessionId);
+            mQueue->setCasInfo(systemId, sessionId);
         }
     }
 }
diff --git a/media/libstagefright/mpeg2ts/CasManager.cpp b/media/libstagefright/mpeg2ts/CasManager.cpp
index 4e34a30..047b1b3 100644
--- a/media/libstagefright/mpeg2ts/CasManager.cpp
+++ b/media/libstagefright/mpeg2ts/CasManager.cpp
@@ -52,8 +52,9 @@
         sp<IDescrambler> mDescrambler;
     };
     status_t initSession(
-             const sp<ICas>& cas, PidToSessionMap &sessionMap,
-             CasSession *session, unsigned programNumber, unsigned elementaryPID);
+            const sp<ICas>& cas,
+            PidToSessionMap &sessionMap,
+            CasSession *session);
     void closeSession(const sp<ICas>& cas, const CasSession &casSession);
 
     unsigned mProgramNumber;
@@ -88,14 +89,14 @@
 status_t ATSParser::CasManager::ProgramCasManager::setMediaCas(
         const sp<ICas> &cas, PidToSessionMap &sessionMap) {
     if (mHasProgramCas) {
-        return initSession(cas, sessionMap, &mProgramCas, mProgramNumber, 0);
+        return initSession(cas, sessionMap, &mProgramCas);
     }
+    // TODO: share session among streams that has identical CA_descriptors.
+    // For now, we open one session for each stream that has CA_descriptor.
     for (size_t index = 0; index < mStreamPidToCasMap.size(); index++) {
-        unsigned elementaryPID = mStreamPidToCasMap.keyAt(index);
-        status_t err;
-        if ((err = initSession(cas, sessionMap,
-                &mStreamPidToCasMap.editValueAt(index),
-                mProgramNumber, elementaryPID)) != OK) {
+        status_t err = initSession(
+                cas, sessionMap, &mStreamPidToCasMap.editValueAt(index));
+        if (err != OK) {
             return err;
         }
     }
@@ -121,8 +122,9 @@
 }
 
 status_t ATSParser::CasManager::ProgramCasManager::initSession(
-         const sp<ICas>& cas, PidToSessionMap &sessionMap,
-         CasSession *session, unsigned programNumber, unsigned elementaryPID) {
+         const sp<ICas>& cas,
+         PidToSessionMap &sessionMap,
+         CasSession *session) {
     sp<IServiceManager> sm = defaultServiceManager();
     sp<IBinder> casServiceBinder = sm->getService(String16("media.cas"));
     sp<IMediaCasService> casService =
@@ -137,13 +139,7 @@
     std::vector<uint8_t> sessionId;
     const CADescriptor &descriptor = session->mCADescriptor;
 
-    Status status;
-    if (elementaryPID == 0) {
-        status = cas->openSession(programNumber, &sessionId);
-    } else {
-        status = cas->openSessionForStream(
-                programNumber, elementaryPID, &sessionId);
-    }
+    Status status = cas->openSession(&sessionId);
     if (!status.isOk()) {
         ALOGE("Failed to open session: exception=%d, error=%d",
                 status.exceptionCode(), status.serviceSpecificErrorCode());
@@ -298,13 +294,15 @@
     return true;
 }
 
-bool ATSParser::CasManager::getCasSession(
+bool ATSParser::CasManager::getCasInfo(
         unsigned programNumber, unsigned elementaryPID,
-        sp<IDescrambler> *descrambler, std::vector<uint8_t> *sessionId) const {
+        int32_t *systemId, sp<IDescrambler> *descrambler,
+        std::vector<uint8_t> *sessionId) const {
     ssize_t index = mProgramCasMap.indexOfKey(programNumber);
     if (index < 0) {
         return false;
     }
+    *systemId = mSystemId;
     return mProgramCasMap[index]->getCasSession(
             elementaryPID, descrambler, sessionId);
 }
diff --git a/media/libstagefright/mpeg2ts/CasManager.h b/media/libstagefright/mpeg2ts/CasManager.h
index a7a3de9..8088dec 100644
--- a/media/libstagefright/mpeg2ts/CasManager.h
+++ b/media/libstagefright/mpeg2ts/CasManager.h
@@ -39,9 +39,9 @@
             unsigned programNumber, unsigned elementaryPID,
             const CADescriptor &descriptor);
 
-    bool getCasSession(
+    bool getCasInfo(
             unsigned programNumber, unsigned elementaryPID,
-            sp<IDescrambler> *descrambler,
+            int32_t *systemId, sp<IDescrambler> *descrambler,
             std::vector<uint8_t> *sessionId) const;
 
     bool isCAPid(unsigned pid);
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index 6bac1db..ae7ec77 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -41,7 +41,8 @@
 ElementaryStreamQueue::ElementaryStreamQueue(Mode mode, uint32_t flags)
     : mMode(mode),
       mFlags(flags),
-      mEOSReached(false) {
+      mEOSReached(false),
+      mCASystemId(0) {
 }
 
 sp<MetaData> ElementaryStreamQueue::getFormat() {
@@ -67,6 +68,16 @@
     mEOSReached = false;
 }
 
+bool ElementaryStreamQueue::isScrambled() const {
+    return (mFlags & kFlag_ScrambledData) != 0;
+}
+
+void ElementaryStreamQueue::setCasInfo(
+        int32_t systemId, const std::vector<uint8_t> &sessionId) {
+    mCASystemId = systemId;
+    mCasSessionId = sessionId;
+}
+
 // Parse AC3 header assuming the current ptr is start position of syncframe,
 // update metadata only applicable, and return the payload size
 static unsigned parseAC3SyncFrame(
@@ -938,8 +949,10 @@
                 mFormat->setInt32(kKeyWidth, 1280);
                 mFormat->setInt32(kKeyHeight, 720);
             }
-            // for DrmInitData
-            mFormat->setData(kKeyCas, 0, mCasSessionId.data(), mCasSessionId.size());
+            // for MediaExtractor.CasInfo
+            mFormat->setInt32(kKeyCASystemID, mCASystemId);
+            mFormat->setData(kKeyCASessionID, 0,
+                    mCasSessionId.data(), mCasSessionId.size());
         }
         return dequeueScrambledAccessUnit();
     }
@@ -1213,8 +1226,10 @@
             mFormat->setInt32(kKeyWidth, 1280);
             mFormat->setInt32(kKeyHeight, 720);
 
-            // for DrmInitData
-            mFormat->setData(kKeyCas, 0, mCasSessionId.data(), mCasSessionId.size());
+            // for MediaExtractor.CasInfo
+            mFormat->setInt32(kKeyCASystemID, mCASystemId);
+            mFormat->setData(kKeyCASessionID, 0,
+                    mCasSessionId.data(), mCasSessionId.size());
         }
         return dequeueScrambledAccessUnit();
     }
diff --git a/media/libstagefright/mpeg2ts/ESQueue.h b/media/libstagefright/mpeg2ts/ESQueue.h
index 6941e3f..11e1af7 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.h
+++ b/media/libstagefright/mpeg2ts/ESQueue.h
@@ -65,13 +65,9 @@
 
     sp<MetaData> getFormat();
 
-    bool isScrambled() {
-        return (mFlags & kFlag_ScrambledData) != 0;
-    }
+    bool isScrambled() const;
 
-    void setCasSession(const std::vector<uint8_t> &sessionId) {
-        mCasSessionId = sessionId;
-    }
+    void setCasInfo(int32_t systemId, const std::vector<uint8_t> &sessionId);
 
 private:
     struct RangeInfo {
@@ -99,6 +95,7 @@
 
     sp<ABuffer> mScrambledBuffer;
     List<ScrambledRangeInfo> mScrambledRangeInfos;
+    int32_t mCASystemId;
     std::vector<uint8_t> mCasSessionId;
 
     sp<MetaData> mFormat;