1 /*
2 * Copyright (C) 2019 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 "android.hardware.cas@1.1-MediaCasService"
19
20 #include <android/hardware/cas/1.1/ICasListener.h>
21 #include <android/hardware/cas/1.2/ICasListener.h>
22 #include <media/cas/CasAPI.h>
23 #include <media/cas/DescramblerAPI.h>
24 #include <utils/Log.h>
25
26 #include "CasImpl.h"
27 #include "DescramblerImpl.h"
28 #include "MediaCasService.h"
29
30 namespace android {
31 namespace hardware {
32 namespace cas {
33 namespace V1_1 {
34 namespace implementation {
35
36 class Wrapper : public V1_1::ICasListener {
37 public:
wrap(sp<V1_0::ICasListener> impl)38 static sp<V1_1::ICasListener> wrap(sp<V1_0::ICasListener> impl) {
39 sp<V1_1::ICasListener> cast = V1_1::ICasListener::castFrom(impl);
40 if (cast == NULL) {
41 cast = new Wrapper(impl);
42 }
43 return cast;
44 }
45
onEvent(int32_t event,int32_t arg,const hidl_vec<uint8_t> & data)46 virtual Return<void> onEvent(int32_t event, int32_t arg,
47 const hidl_vec<uint8_t>& data) override {
48 mImpl->onEvent(event, arg, data);
49 return Void();
50 }
51
onSessionEvent(const hidl_vec<uint8_t> &,int32_t,int32_t,const hidl_vec<uint8_t> &)52 virtual Return<void> onSessionEvent(const hidl_vec<uint8_t>& /* sessionId */,
53 int32_t /* event */, int32_t /* arg */,
54 const hidl_vec<uint8_t>& /*data*/) override {
55 ALOGV("Do nothing on Session Event for cas@1.0 client in cas@1.1");
56 return Void();
57 }
58
59 private:
Wrapper(sp<V1_0::ICasListener> impl)60 Wrapper(sp<V1_0::ICasListener> impl) : mImpl(impl){};
61 sp<V1_0::ICasListener> mImpl;
62 };
63
MediaCasService()64 MediaCasService::MediaCasService()
65 : mCasLoader("createCasFactory"), mDescramblerLoader("createDescramblerFactory") {}
66
~MediaCasService()67 MediaCasService::~MediaCasService() {}
68
enumeratePlugins(enumeratePlugins_cb _hidl_cb)69 Return<void> MediaCasService::enumeratePlugins(enumeratePlugins_cb _hidl_cb) {
70 ALOGV("%s", __FUNCTION__);
71
72 vector<HidlCasPluginDescriptor> results;
73 mCasLoader.enumeratePlugins(&results);
74
75 _hidl_cb(results);
76 return Void();
77 }
78
isSystemIdSupported(int32_t CA_system_id)79 Return<bool> MediaCasService::isSystemIdSupported(int32_t CA_system_id) {
80 ALOGV("isSystemIdSupported: CA_system_id=%d", CA_system_id);
81
82 return mCasLoader.findFactoryForScheme(CA_system_id);
83 }
84
createPlugin(int32_t CA_system_id,const sp<V1_0::ICasListener> & listener)85 Return<sp<V1_0::ICas>> MediaCasService::createPlugin(int32_t CA_system_id,
86 const sp<V1_0::ICasListener>& listener) {
87 ALOGV("%s:Use createPluginExt to create plugin in cas@1.1", __FUNCTION__);
88
89 sp<ICas> result;
90
91 sp<V1_1::ICasListener> listenerV1_1 = Wrapper::wrap(listener);
92
93 result = createPluginExt(CA_system_id, listenerV1_1);
94
95 return result;
96 }
97
createPluginExt(int32_t CA_system_id,const sp<ICasListener> & listener)98 Return<sp<ICas>> MediaCasService::createPluginExt(int32_t CA_system_id,
99 const sp<ICasListener>& listener) {
100 ALOGV("%s: CA_system_id=%d", __FUNCTION__, CA_system_id);
101 if (listener == NULL) ALOGV("%s: Listener is NULL", __FUNCTION__);
102
103 sp<V1_2::ICas> result;
104
105 CasFactory* factory;
106 sp<SharedLibrary> library;
107 if (mCasLoader.findFactoryForScheme(CA_system_id, &library, &factory)) {
108 CasPlugin* plugin = NULL;
109 sp<CasImpl> casImpl = new CasImpl(listener);
110 if (factory->createPlugin(CA_system_id, casImpl.get(), &CasImpl::CallBackExt, &plugin) ==
111 OK &&
112 plugin != NULL) {
113 casImpl->init(library, plugin);
114 result = casImpl;
115
116 sp<V1_2::ICasListener> listenerV1_2 = V1_2::ICasListener::castFrom(listener);
117 if (listenerV1_2 != NULL) {
118 casImpl->setPluginStatusUpdateCallback();
119 }
120 }
121 }
122
123 return result;
124 }
125
isDescramblerSupported(int32_t CA_system_id)126 Return<bool> MediaCasService::isDescramblerSupported(int32_t CA_system_id) {
127 ALOGV("%s: CA_system_id=%d", __FUNCTION__, CA_system_id);
128
129 return mDescramblerLoader.findFactoryForScheme(CA_system_id);
130 }
131
createDescrambler(int32_t CA_system_id)132 Return<sp<IDescramblerBase>> MediaCasService::createDescrambler(int32_t CA_system_id) {
133 ALOGV("%s: CA_system_id=%d", __FUNCTION__, CA_system_id);
134
135 sp<IDescrambler> result;
136
137 DescramblerFactory* factory;
138 sp<SharedLibrary> library;
139 if (mDescramblerLoader.findFactoryForScheme(CA_system_id, &library, &factory)) {
140 DescramblerPlugin* plugin = NULL;
141 if (factory->createPlugin(CA_system_id, &plugin) == OK && plugin != NULL) {
142 result = new DescramblerImpl(library, plugin);
143 }
144 }
145
146 return result;
147 }
148
149 } // namespace implementation
150 } // namespace V1_1
151 } // namespace cas
152 } // namespace hardware
153 } // namespace android
154