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