• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "ClearKeyCryptoPlugin"
19 #include <utils/Log.h>
20 
21 #include <media/stagefright/MediaErrors.h>
22 #include <utils/StrongPointer.h>
23 
24 #include "DrmPlugin.h"
25 
26 #include "Session.h"
27 
28 namespace {
29 const android::String8 kStreaming("Streaming");
30 const android::String8 kOffline("Offline");
31 const android::String8 kTrue("True");
32 
33 const android::String8 kQueryKeyLicenseType("LicenseType");
34     // Value: "Streaming" or "Offline"
35 const android::String8 kQueryKeyPlayAllowed("PlayAllowed");
36     // Value: "True" or "False"
37 const android::String8 kQueryKeyRenewAllowed("RenewAllowed");
38     // Value: "True" or "False"
39 };
40 
41 namespace clearkeydrm {
42 
43 using android::sp;
44 
DrmPlugin(SessionLibrary * sessionLibrary)45 DrmPlugin::DrmPlugin(SessionLibrary* sessionLibrary)
46         : mSessionLibrary(sessionLibrary) {
47     mPlayPolicy.clear();
48 }
49 
openSession(Vector<uint8_t> & sessionId)50 status_t DrmPlugin::openSession(Vector<uint8_t>& sessionId) {
51     sp<Session> session = mSessionLibrary->createSession();
52     sessionId = session->sessionId();
53     return android::OK;
54 }
55 
closeSession(const Vector<uint8_t> & sessionId)56 status_t DrmPlugin::closeSession(const Vector<uint8_t>& sessionId) {
57     sp<Session> session = mSessionLibrary->findSession(sessionId);
58     if (sessionId.size() == 0) {
59         return android::BAD_VALUE;
60     }
61     if (session.get()) {
62         mSessionLibrary->destroySession(session);
63         return android::OK;
64     }
65     return android::ERROR_DRM_SESSION_NOT_OPENED;
66 }
67 
getKeyRequest(const Vector<uint8_t> & scope,const Vector<uint8_t> & initData,const String8 & mimeType,KeyType keyType,const KeyedVector<String8,String8> & optionalParameters,Vector<uint8_t> & request,String8 & defaultUrl,DrmPlugin::KeyRequestType * keyRequestType)68 status_t DrmPlugin::getKeyRequest(
69         const Vector<uint8_t>& scope,
70         const Vector<uint8_t>& initData,
71         const String8& mimeType,
72         KeyType keyType,
73         const KeyedVector<String8, String8>& optionalParameters,
74         Vector<uint8_t>& request,
75         String8& defaultUrl,
76         DrmPlugin::KeyRequestType *keyRequestType) {
77     UNUSED(optionalParameters);
78     if (scope.size() == 0) {
79         return android::BAD_VALUE;
80     }
81 
82     if (keyType != kKeyType_Streaming) {
83         return android::ERROR_DRM_CANNOT_HANDLE;
84     }
85 
86     *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
87     defaultUrl.clear();
88     sp<Session> session = mSessionLibrary->findSession(scope);
89     if (!session.get()) {
90         return android::ERROR_DRM_SESSION_NOT_OPENED;
91     }
92 
93     return session->getKeyRequest(initData, mimeType, &request);
94 }
95 
setPlayPolicy()96 void DrmPlugin::setPlayPolicy() {
97     mPlayPolicy.clear();
98     mPlayPolicy.add(kQueryKeyLicenseType, kStreaming);
99     mPlayPolicy.add(kQueryKeyPlayAllowed, kTrue);
100     mPlayPolicy.add(kQueryKeyRenewAllowed, kTrue);
101 }
102 
provideKeyResponse(const Vector<uint8_t> & scope,const Vector<uint8_t> & response,Vector<uint8_t> & keySetId)103 status_t DrmPlugin::provideKeyResponse(
104         const Vector<uint8_t>& scope,
105         const Vector<uint8_t>& response,
106         Vector<uint8_t>& keySetId) {
107     if (scope.size() == 0 || response.size() == 0) {
108         return android::BAD_VALUE;
109     }
110     sp<Session> session = mSessionLibrary->findSession(scope);
111     if (!session.get()) {
112         return android::ERROR_DRM_SESSION_NOT_OPENED;
113     }
114 
115     setPlayPolicy();
116     status_t res = session->provideKeyResponse(response);
117     if (res == android::OK) {
118         // This is for testing AMediaDrm_setOnEventListener only.
119         sendEvent(kDrmPluginEventVendorDefined, 0, &scope, NULL);
120         keySetId.clear();
121     }
122     return res;
123 }
124 
getPropertyString(const String8 & name,String8 & value) const125 status_t DrmPlugin::getPropertyString(
126         const String8& name, String8& value) const {
127     if (name == "vendor") {
128         value = "Google";
129     } else if (name == "version") {
130         value = "1.0";
131     } else if (name == "description") {
132         value = "ClearKey CDM";
133     } else if (name == "algorithms") {
134         value = "";
135     } else if (name == "listenerTestSupport") {
136         value = "true";
137     } else {
138         ALOGE("App requested unknown string property %s", name.string());
139         return android::ERROR_DRM_CANNOT_HANDLE;
140     }
141     return android::OK;
142 }
143 
queryKeyStatus(const Vector<uint8_t> & sessionId,KeyedVector<String8,String8> & infoMap) const144 status_t DrmPlugin::queryKeyStatus(
145         const Vector<uint8_t>& sessionId,
146         KeyedVector<String8, String8>& infoMap) const {
147 
148     if (sessionId.size() == 0) {
149         return android::BAD_VALUE;
150     }
151 
152     infoMap.clear();
153     for (size_t i = 0; i < mPlayPolicy.size(); ++i) {
154         infoMap.add(mPlayPolicy.keyAt(i), mPlayPolicy.valueAt(i));
155     }
156     return android::OK;
157 }
158 }  // namespace clearkeydrm
159