Merge "MediaCas: add plugin APIs"
diff --git a/include/media/cas/CasAPI.h b/include/media/cas/CasAPI.h
new file mode 100644
index 0000000..0e88019
--- /dev/null
+++ b/include/media/cas/CasAPI.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef CAS_API_H_
+#define CAS_API_H_
+
+#include <vector>
+#include <utils/String8.h>
+
+//  Loadable CasPlugin shared libraries should define the entry points
+//  as shown below:
+//
+//  extern "C" {
+//      extern android::CasFactory *createCasFactory();
+//      extern android::DescramblerFactory *createDescramblerFactory();
+//  }
+
+namespace android {
+
+struct CasPlugin;
+
+struct CasPluginDescriptor {
+    int32_t CA_system_id;
+    String8 name;
+};
+
+typedef std::vector<uint8_t> CasData;
+typedef std::vector<uint8_t> CasSessionId;
+typedef std::vector<uint8_t> CasEmm;
+typedef std::vector<uint8_t> CasEcm;
+typedef void (*CasPluginCallback)(
+        void *appData,
+        int32_t event,
+        int32_t arg,
+        uint8_t *data,
+        size_t size);
+
+struct CasFactory {
+    CasFactory() {}
+    virtual ~CasFactory() {}
+
+    // Determine if the plugin can handle the CA scheme identified by CA_system_id.
+    virtual bool isSystemIdSupported(
+            int32_t CA_system_id) const = 0;
+
+    // Get a list of the CA schemes supported by the plugin.
+    virtual status_t queryPlugins(
+            std::vector<CasPluginDescriptor> *descriptors) const = 0;
+
+    // Construct a new instance of a CasPlugin given a CA_system_id
+    virtual status_t createPlugin(
+            int32_t CA_system_id,
+            uint64_t appData,
+            CasPluginCallback callback,
+            CasPlugin **plugin) = 0;
+
+private:
+    CasFactory(const CasFactory &);
+    CasFactory &operator=(const CasFactory &); /* NOLINT */
+};
+
+struct CasPlugin {
+    CasPlugin() {}
+    virtual ~CasPlugin() {}
+
+    // Provide the CA private data from a CA_descriptor in the conditional
+    // access table to a CasPlugin.
+    virtual status_t setPrivateData(
+            const CasData &privateData) = 0;
+
+    // Open a session for descrambling a program. The session will receive the
+    // ECM stream corresponding to the CA_PID for the program.
+    virtual status_t openSession(
+            uint16_t program_number,
+            CasSessionId *sessionId) = 0;
+
+    // Open a session for descrambling an elementary stream inside a program.
+    // The session will receive the ECM stream corresponding to the CA_PID for
+    // the stream.
+    virtual status_t openSession(
+            uint16_t program_number,
+            uint16_t elementary_PID,
+            CasSessionId *sessionId) = 0;
+
+    // Close a previously opened session.
+    virtual status_t closeSession(
+            const CasSessionId &sessionId) = 0;
+
+    // Provide the CA private data from a CA_descriptor in the program map
+    // table to a CasPlugin.
+    virtual status_t setSessionPrivateData(
+            const CasSessionId &sessionId,
+            const CasData &privateData) = 0;
+
+    // Process an ECM from the ECM stream for this session’s elementary stream.
+    virtual status_t processEcm(
+            const CasSessionId &sessionId,
+            const CasEcm &ecm) = 0;
+
+    // Process an in-band EMM from the EMM stream.
+    virtual status_t processEmm(
+            const CasEmm &emm) = 0;
+
+    // Deliver an event to the CasPlugin. The format of the event is specific
+    // to the CA scheme and is opaque to the framework.
+    virtual status_t sendEvent(
+            int32_t event,
+            int32_t arg,
+            const CasData &eventData) = 0;
+
+    // Native implementation of the MediaCas Java API provision method.
+    virtual status_t provision(
+            const String8 &provisionString) = 0;
+
+    // Native implementation of the MediaCas Java API refreshEntitlements method
+    virtual status_t refreshEntitlements(
+            int32_t refreshType,
+            const CasData &refreshData) = 0;
+
+private:
+    CasPlugin(const CasPlugin &);
+    CasPlugin &operator=(const CasPlugin &); /* NOLINT */
+};
+
+extern "C" {
+    extern android::CasFactory *createCasFactory();
+}
+
+} // namespace android
+
+#endif // CAS_API_H_
diff --git a/include/media/cas/DescramblerAPI.h b/include/media/cas/DescramblerAPI.h
new file mode 100644
index 0000000..0a51952
--- /dev/null
+++ b/include/media/cas/DescramblerAPI.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef DESCRAMBLER_API_H_
+#define DESCRAMBLER_API_H_
+
+#include <media/stagefright/MediaErrors.h>
+#include <media/cas/CasAPI.h>
+
+namespace android {
+
+struct AString;
+struct DescramblerPlugin;
+
+struct DescramblerFactory {
+    DescramblerFactory() {}
+    virtual ~DescramblerFactory() {}
+
+    // Determine if the plugin can handle the CA scheme identified by CA_system_id.
+    virtual bool isSystemIdSupported(
+            int32_t CA_system_id) const = 0;
+
+    // Construct a new instance of a DescramblerPlugin given a CA_system_id
+    virtual status_t createPlugin(
+            int32_t CA_system_id, DescramblerPlugin **plugin) = 0;
+
+private:
+    DescramblerFactory(const DescramblerFactory &);
+    DescramblerFactory &operator=(const DescramblerFactory &);
+};
+
+struct DescramblerPlugin {
+    enum ScramblingControl {
+        kScrambling_Unscrambled = 0,
+        kScrambling_Reserved    = 1,
+        kScrambling_EvenKey     = 2,
+        kScrambling_OddKey      = 3,
+    };
+
+    struct SubSample {
+        uint32_t mNumBytesOfClearData;
+        uint32_t mNumBytesOfEncryptedData;
+    };
+
+    DescramblerPlugin() {}
+    virtual ~DescramblerPlugin() {}
+
+    // If this method returns false, a non-secure decoder will be used to
+    // decode the data after decryption. The decrypt API below will have
+    // to support insecure decryption of the data (secure = false) for
+    // media data of the given mime type.
+    virtual bool requiresSecureDecoderComponent(const char *mime) const = 0;
+
+    // A MediaCas session may be associated with a MediaCrypto session.  The
+    // associated MediaCas session is used to load decryption keys
+    // into the crypto/cas plugin.  The keys are then referenced by key-id
+    // in the 'key' parameter to the decrypt() method.
+    // Should return NO_ERROR on success, ERROR_DRM_SESSION_NOT_OPENED if
+    // the session is not opened and a code from MediaErrors.h otherwise.
+    virtual status_t setMediaCasSession(const CasSessionId& sessionId) = 0;
+
+    // If the error returned falls into the range
+    // ERROR_DRM_VENDOR_MIN..ERROR_DRM_VENDOR_MAX, errorDetailMsg should be
+    // filled in with an appropriate string.
+    // At the java level these special errors will then trigger a
+    // MediaCodec.CryptoException that gives clients access to both
+    // the error code and the errorDetailMsg.
+    // Returns a non-negative result to indicate the number of bytes written
+    // to the dstPtr, or a negative result to indicate an error.
+    virtual ssize_t descramble(
+            bool secure,
+            ScramblingControl scramblingControl,
+            size_t numSubSamples,
+            const SubSample *subSamples,
+            const void *srcPtr,
+            int32_t srcOffset,
+            void *dstPtr,
+            int32_t dstOffset,
+            AString *errorDetailMsg) = 0;
+
+private:
+    DescramblerPlugin(const DescramblerPlugin &);
+    DescramblerPlugin &operator=(const DescramblerPlugin &);
+};
+
+}  // namespace android
+
+extern "C" {
+    extern android::DescramblerFactory *createDescramblerFactory();
+}
+
+#endif  // DESCRAMBLER_API_H_