• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright (C) 2017 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "CasImpl"
19 
20 #include <android/media/ICasListener.h>
21 #include <media/cas/CasAPI.h>
22 #include <media/CasImpl.h>
23 #include <media/SharedLibrary.h>
24 #include <utils/Log.h>
25 
26 namespace android {
27 
getBinderStatus(status_t err)28 static Status getBinderStatus(status_t err) {
29     if (err == OK) {
30         return Status::ok();
31     }
32     if (err == BAD_VALUE) {
33         return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
34     }
35     if (err == INVALID_OPERATION) {
36         return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
37     }
38     return Status::fromServiceSpecificError(err);
39 }
40 
sessionIdToString(const CasSessionId & sessionId)41 static String8 sessionIdToString(const CasSessionId &sessionId) {
42     String8 result;
43     for (size_t i = 0; i < sessionId.size(); i++) {
44         result.appendFormat("%02x ", sessionId[i]);
45     }
46     if (result.isEmpty()) {
47         result.append("(null)");
48     }
49     return result;
50 }
51 
52 struct CasImpl::PluginHolder : public RefBase {
53 public:
PluginHolderandroid::CasImpl::PluginHolder54     explicit PluginHolder(CasPlugin *plugin) : mPlugin(plugin) {}
~PluginHolderandroid::CasImpl::PluginHolder55     ~PluginHolder() { if (mPlugin != NULL) delete mPlugin; }
getandroid::CasImpl::PluginHolder56     CasPlugin* get() { return mPlugin; }
57 
58 private:
59     CasPlugin *mPlugin;
60     DISALLOW_EVIL_CONSTRUCTORS(PluginHolder);
61 };
62 
CasImpl(const sp<ICasListener> & listener)63 CasImpl::CasImpl(const sp<ICasListener> &listener)
64     : mPluginHolder(NULL), mListener(listener) {
65     ALOGV("CTOR");
66 }
67 
~CasImpl()68 CasImpl::~CasImpl() {
69     ALOGV("DTOR");
70     release();
71 }
72 
73 //static
OnEvent(void * appData,int32_t event,int32_t arg,uint8_t * data,size_t size)74 void CasImpl::OnEvent(
75         void *appData,
76         int32_t event,
77         int32_t arg,
78         uint8_t *data,
79         size_t size) {
80     if (appData == NULL) {
81         ALOGE("Invalid appData!");
82         return;
83     }
84     CasImpl *casImpl = static_cast<CasImpl *>(appData);
85     casImpl->onEvent(event, arg, data, size);
86 }
87 
init(const sp<SharedLibrary> & library,CasPlugin * plugin)88 void CasImpl::init(const sp<SharedLibrary>& library, CasPlugin *plugin) {
89     mLibrary = library;
90     mPluginHolder = new PluginHolder(plugin);
91 }
92 
onEvent(int32_t event,int32_t arg,uint8_t * data,size_t size)93 void CasImpl::onEvent(
94         int32_t event, int32_t arg, uint8_t *data, size_t size) {
95     if (mListener == NULL) {
96         return;
97     }
98 
99     std::unique_ptr<CasData> eventData;
100     if (data != NULL && size > 0) {
101         eventData.reset(new CasData(data, data + size));
102     }
103 
104     mListener->onEvent(event, arg, eventData);
105 }
106 
setPrivateData(const CasData & pvtData)107 Status CasImpl::setPrivateData(const CasData& pvtData) {
108     ALOGV("setPrivateData");
109     sp<PluginHolder> holder = mPluginHolder;
110     if (holder == NULL) {
111         return getBinderStatus(INVALID_OPERATION);
112     }
113     return getBinderStatus(holder->get()->setPrivateData(pvtData));
114 }
115 
openSession(CasSessionId * sessionId)116 Status CasImpl::openSession(CasSessionId* sessionId) {
117     ALOGV("openSession");
118     sp<PluginHolder> holder = mPluginHolder;
119     if (holder == NULL) {
120         return getBinderStatus(INVALID_OPERATION);
121     }
122     status_t err = holder->get()->openSession(sessionId);
123 
124     ALOGV("openSession: session opened, sessionId=%s",
125             sessionIdToString(*sessionId).string());
126 
127     return getBinderStatus(err);
128 }
129 
setSessionPrivateData(const CasSessionId & sessionId,const CasData & pvtData)130 Status CasImpl::setSessionPrivateData(
131         const CasSessionId &sessionId, const CasData& pvtData) {
132     ALOGV("setSessionPrivateData: sessionId=%s",
133             sessionIdToString(sessionId).string());
134     sp<PluginHolder> holder = mPluginHolder;
135     if (holder == NULL) {
136         return getBinderStatus(INVALID_OPERATION);
137     }
138     return getBinderStatus(holder->get()->setSessionPrivateData(sessionId, pvtData));
139 }
140 
closeSession(const CasSessionId & sessionId)141 Status CasImpl::closeSession(const CasSessionId &sessionId) {
142     ALOGV("closeSession: sessionId=%s",
143             sessionIdToString(sessionId).string());
144     sp<PluginHolder> holder = mPluginHolder;
145     if (holder == NULL) {
146         return getBinderStatus(INVALID_OPERATION);
147     }
148     return getBinderStatus(holder->get()->closeSession(sessionId));
149 }
150 
processEcm(const CasSessionId & sessionId,const ParcelableCasData & ecm)151 Status CasImpl::processEcm(const CasSessionId &sessionId, const ParcelableCasData& ecm) {
152     ALOGV("processEcm: sessionId=%s",
153             sessionIdToString(sessionId).string());
154     sp<PluginHolder> holder = mPluginHolder;
155     if (holder == NULL) {
156         return getBinderStatus(INVALID_OPERATION);
157     }
158 
159     return getBinderStatus(holder->get()->processEcm(sessionId, ecm));
160 }
161 
processEmm(const ParcelableCasData & emm)162 Status CasImpl::processEmm(const ParcelableCasData& emm) {
163     ALOGV("processEmm");
164     sp<PluginHolder> holder = mPluginHolder;
165     if (holder == NULL) {
166         return getBinderStatus(INVALID_OPERATION);
167     }
168 
169     return getBinderStatus(holder->get()->processEmm(emm));
170 }
171 
sendEvent(int32_t event,int32_t arg,const::std::unique_ptr<CasData> & eventData)172 Status CasImpl::sendEvent(
173         int32_t event, int32_t arg, const ::std::unique_ptr<CasData> &eventData) {
174     ALOGV("sendEvent");
175     sp<PluginHolder> holder = mPluginHolder;
176     if (holder == NULL) {
177         return getBinderStatus(INVALID_OPERATION);
178     }
179 
180     status_t err;
181     if (eventData == nullptr) {
182         err = holder->get()->sendEvent(event, arg, CasData());
183     } else {
184         err = holder->get()->sendEvent(event, arg, *eventData);
185     }
186     return getBinderStatus(err);
187 }
188 
provision(const String16 & provisionString)189 Status CasImpl::provision(const String16& provisionString) {
190     ALOGV("provision: provisionString=%s", String8(provisionString).string());
191     sp<PluginHolder> holder = mPluginHolder;
192     if (holder == NULL) {
193         return getBinderStatus(INVALID_OPERATION);
194     }
195 
196     return getBinderStatus(holder->get()->provision(String8(provisionString)));
197 }
198 
refreshEntitlements(int32_t refreshType,const::std::unique_ptr<CasData> & refreshData)199 Status CasImpl::refreshEntitlements(
200         int32_t refreshType, const ::std::unique_ptr<CasData> &refreshData) {
201     ALOGV("refreshEntitlements");
202     sp<PluginHolder> holder = mPluginHolder;
203     if (holder == NULL) {
204         return getBinderStatus(INVALID_OPERATION);
205     }
206 
207     status_t err;
208     if (refreshData == nullptr) {
209         err = holder->get()->refreshEntitlements(refreshType, CasData());
210     } else {
211         err = holder->get()->refreshEntitlements(refreshType, *refreshData);
212     }
213     return getBinderStatus(err);
214 }
215 
release()216 Status CasImpl::release() {
217     ALOGV("release: plugin=%p",
218             mPluginHolder == NULL ? mPluginHolder->get() : NULL);
219     mPluginHolder.clear();
220     return Status::ok();
221 }
222 
223 } // namespace android
224 
225