1 /*
2  * Copyright (c) 2023  Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "media_key_system_factory_impl.h"
17 #include "i_mediakeysystem_service.h"
18 #include "drm_error_code.h"
19 #include "napi_param_utils.h"
20 
21 namespace OHOS {
22 namespace DrmStandard {
23 using namespace OHOS::HiviewDFX;
24 
25 sptr<MediaKeySystemFactoryImpl> MediaKeySystemFactoryImpl::mediaKeySystemFactoryImpl_ = nullptr;
26 constexpr int64_t SLEEP_TIME = 1;
27 constexpr int32_t RETRY_TIMES = 3;
28 
MediaKeySystemFactoryImpl()29 MediaKeySystemFactoryImpl::MediaKeySystemFactoryImpl()
30 {
31     DRM_DEBUG_LOG("0x%{public}06" PRIXPTR "MediaKeySystemFactoryImpl Instances create",
32         FAKE_POINTER(this));
33     traceId_ = HiTraceChain::Begin("MediaKeySystemFactory", HITRACE_FLAG_DEFAULT);
34     Init();
35 }
36 
~MediaKeySystemFactoryImpl()37 MediaKeySystemFactoryImpl::~MediaKeySystemFactoryImpl()
38 {
39     DRM_INFO_LOG("~MediaKeySystemFactoryImpl enter.");
40     HiTraceChain::End(traceId_);
41     deathRecipient_ = nullptr;
42 }
43 
GetServiceProxy()44 const sptr<IMediaKeySystemFactoryService> MediaKeySystemFactoryImpl::GetServiceProxy()
45 {
46     std::lock_guard<std::mutex> lock(serviceProxyMutex_);
47     if (privateServiceProxy_ != nullptr) {
48         return privateServiceProxy_;
49     }
50 
51     DRM_INFO_LOG("Connect media key system service.");
52     sptr<IRemoteObject> object = nullptr;
53     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
54     DRM_CHECK_AND_RETURN_RET_LOG(samgr != nullptr, nullptr,
55         "Failed to get System ability manager!");
56     object = samgr->GetSystemAbility(MEDIA_KEY_SYSTEM_SERVICE_ID);
57     DRM_CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr,
58         "the object returned by GetSystemAbility is nullptr!");
59     sptr<IMediaKeySystemFactoryService> tmpProxy = iface_cast<IMediaKeySystemFactoryService>(object);
60     DRM_CHECK_AND_RETURN_RET_LOG(tmpProxy != nullptr, nullptr, "cast the object to privateServiceProxy_ failed!");
61 
62     pid_t pid = 0;
63     sptr<DrmDeathRecipient> deathRecipient = new (std::nothrow) DrmDeathRecipient(pid);
64     DRM_CHECK_AND_RETURN_RET_LOG(deathRecipient != nullptr, nullptr,
65         "failed to new DrmDeathRecipient!");
66     deathRecipient->SetNotifyCb([this] (pid_t pid) {
67         this->MediaKeySystemFactoryServerDied(pid);
68     });
69     bool result = object->AddDeathRecipient(deathRecipient);
70     DRM_CHECK_AND_RETURN_RET_LOG(result, nullptr, "failed to new DrmDeathRecipient!");
71 
72     DRM_INFO_LOG("Ready to create listener object");
73     sptr<DrmListenerStub> tmpListenerStub = new(std::nothrow) DrmListenerStub();
74     DRM_CHECK_AND_RETURN_RET_LOG(tmpListenerStub != nullptr, nullptr, "failed to new DrmListenerStub object");
75 
76     sptr<IRemoteObject> listenerObject = tmpListenerStub->AsObject();
77     DRM_CHECK_AND_RETURN_RET_LOG(listenerObject != nullptr, nullptr, "listener object is nullptr.");
78     int32_t ret = tmpProxy->SetListenerObject(listenerObject);
79     DRM_CHECK_AND_RETURN_RET_LOG(ret == DRM_OK, nullptr, "set listener failed.");
80     privateServiceProxy_ = tmpProxy;
81     deathRecipient_ = deathRecipient;
82     listenerStub_ = tmpListenerStub;
83     return privateServiceProxy_;
84 }
85 
GetInstance()86 sptr<MediaKeySystemFactoryImpl> &MediaKeySystemFactoryImpl::GetInstance()
87 {
88     DRM_INFO_LOG("GetInstance enter.");
89     if (MediaKeySystemFactoryImpl::mediaKeySystemFactoryImpl_ == nullptr) {
90         DRM_DEBUG_LOG("Initializing MediaKeySystemFactoryImpl for first time!");
91         MediaKeySystemFactoryImpl::mediaKeySystemFactoryImpl_ = new (std::nothrow) MediaKeySystemFactoryImpl();
92         if (MediaKeySystemFactoryImpl::mediaKeySystemFactoryImpl_ == nullptr) {
93             DRM_ERR_LOG("GetInstance failed to new MediaKeySystemFactoryImpl");
94         }
95     }
96     return MediaKeySystemFactoryImpl::mediaKeySystemFactoryImpl_;
97 }
98 
Init()99 void MediaKeySystemFactoryImpl::Init()
100 {
101     DRM_INFO_LOG("Init enter.");
102     HiTraceChain::SetId(traceId_);
103 }
104 
MediaKeySystemFactoryServerDied(pid_t pid)105 void MediaKeySystemFactoryImpl::MediaKeySystemFactoryServerDied(pid_t pid)
106 {
107     DRM_ERR_LOG("MediaKeySystemFactoryServerDied has died, pid:%{public}d!", pid);
108     {
109         std::lock_guard<std::mutex> lock(serviceProxyMutex_);
110         if (privateServiceProxy_ != nullptr && privateServiceProxy_->AsObject() != nullptr) {
111             (void)privateServiceProxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
112             privateServiceProxy_ = nullptr;
113         }
114         listenerStub_ = nullptr;
115         deathRecipient_ = nullptr;
116     }
117 
118     int32_t retry = RETRY_TIMES;
119     sptr<IMediaKeySystemFactoryService> serviceProxy = nullptr;
120     while (retry--) {
121         // Sleep and wait for 1 second;
122         sleep(SLEEP_TIME);
123         serviceProxy = GetServiceProxy();
124         if (serviceProxy != nullptr) {
125             DRM_INFO_LOG("Reconnect media key system service success!");
126             break;
127         }
128     }
129 
130     DRM_CHECK_AND_RETURN_LOG(serviceProxy != nullptr, "failed to reconnect service!");
131 }
132 
IsMediaKeySystemSupported(std::string & name)133 bool MediaKeySystemFactoryImpl::IsMediaKeySystemSupported(std::string &name)
134 {
135     DRM_INFO_LOG("IsMediaKeySystemSupported enter.");
136     int32_t ret = DRM_OK;
137     bool isSurpported = false;
138     const sptr<IMediaKeySystemFactoryService> serviceProxy = GetServiceProxy();
139     DRM_CHECK_AND_RETURN_RET_LOG(serviceProxy != nullptr, isSurpported, "service proxy is nullptr!");
140     ret = serviceProxy->IsMediaKeySystemSupported(name, &isSurpported);
141     if (ret != DRM_OK) {
142         DRM_ERR_LOG("IsMediaKeySystemSupported failed, ret: %{public}d", ret);
143     }
144     return isSurpported;
145 }
146 
IsMediaKeySystemSupported(std::string & name,std::string & mimeType)147 bool MediaKeySystemFactoryImpl::IsMediaKeySystemSupported(std::string &name, std::string &mimeType)
148 {
149     DRM_INFO_LOG("IsMediaKeySystemSupported enter.");
150     int32_t ret = DRM_OK;
151     bool isSurpported = false;
152 
153     const sptr<IMediaKeySystemFactoryService> serviceProxy = GetServiceProxy();
154     DRM_CHECK_AND_RETURN_RET_LOG(serviceProxy != nullptr, isSurpported, "service proxy is nullptr!");
155     ret = serviceProxy->IsMediaKeySystemSupported(name, mimeType, &isSurpported);
156     if (ret != DRM_OK) {
157         DRM_ERR_LOG("IsMediaKeySystemSupported failed, ret: %{public}d", ret);
158     }
159     return isSurpported;
160 }
161 
IsMediaKeySystemSupported(std::string & uuid,std::string & mimeType,IMediaKeySessionService::ContentProtectionLevel securityLevel)162 bool MediaKeySystemFactoryImpl::IsMediaKeySystemSupported(std::string &uuid, std::string &mimeType,
163     IMediaKeySessionService::ContentProtectionLevel securityLevel)
164 {
165     DRM_INFO_LOG("IsMediaKeySystemSupported enter.");
166     int32_t ret = DRM_OK;
167     bool isSurpported = false;
168 
169     const sptr<IMediaKeySystemFactoryService> serviceProxy = GetServiceProxy();
170     DRM_CHECK_AND_RETURN_RET_LOG(serviceProxy != nullptr, isSurpported, "service proxy is nullptr!");
171     ret = serviceProxy->IsMediaKeySystemSupported(uuid, mimeType, securityLevel, &isSurpported);
172     if (ret != DRM_OK) {
173         DRM_ERR_LOG("IsMediaKeySystemSupported failed, ret: %{public}d", ret);
174     }
175     return isSurpported;
176 }
177 
GetMediaKeySystems(std::map<std::string,std::string> & keySystemNames)178 int32_t MediaKeySystemFactoryImpl::GetMediaKeySystems(std::map<std::string, std::string> &keySystemNames)
179 {
180     DRM_INFO_LOG("GetMediaKeySystems enter.");
181     int32_t ret = DRM_OK;
182     const sptr<IMediaKeySystemFactoryService> serviceProxy = GetServiceProxy();
183     DRM_CHECK_AND_RETURN_RET_LOG(serviceProxy != nullptr, DRM_SERVICE_ERROR, "service proxy is nullptr!");
184     ret = serviceProxy->GetMediaKeySystems(keySystemNames);
185     if (ret != DRM_OK) {
186         DRM_ERR_LOG("GetMediaKeySystems failed, ret: %{public}d", ret);
187         return ret;
188     }
189     return DRM_OK;
190 }
191 
GetMediaKeySystemUuid(std::string & name,std::string & uuid)192 int32_t MediaKeySystemFactoryImpl::GetMediaKeySystemUuid(std::string &name, std::string &uuid)
193 {
194     DRM_INFO_LOG("GetMediaKeySystemUuid enter.");
195     int32_t ret = DRM_OK;
196     const sptr<IMediaKeySystemFactoryService> serviceProxy = GetServiceProxy();
197     DRM_CHECK_AND_RETURN_RET_LOG(serviceProxy != nullptr, DRM_SERVICE_ERROR, "service proxy is nullptr!");
198     ret = serviceProxy->GetMediaKeySystemUuid(name, uuid);
199     if (ret != DRM_OK) {
200         DRM_ERR_LOG("GetMediaKeySystemUuid failed, ret: %{public}d", ret);
201         return ret;
202     }
203     return DRM_OK;
204 }
205 
CreateMediaKeySystem(std::string & name,sptr<MediaKeySystemImpl> * mediaKeySystemImpl)206 int32_t MediaKeySystemFactoryImpl::CreateMediaKeySystem(std::string &name, sptr<MediaKeySystemImpl> *mediaKeySystemImpl)
207 {
208     DRM_INFO_LOG("CreateMediaKeySystem enter.");
209     sptr<IMediaKeySystemService> mediaKeySystemProxy = nullptr;
210     sptr<MediaKeySystemImpl> localMediaKeySystemImpl = nullptr;
211     int32_t ret = DRM_OK;
212     if (mediaKeySystemImpl == nullptr) {
213         DRM_ERR_LOG("mediaKeySystemImpl is nullptr");
214         return DRM_INVALID_PARAM;
215     }
216 
217     const sptr<IMediaKeySystemFactoryService> serviceProxy = GetServiceProxy();
218     DRM_CHECK_AND_RETURN_RET_LOG(serviceProxy != nullptr, DRM_SERVICE_ERROR, "service proxy is nullptr!");
219     ret = serviceProxy->CreateMediaKeySystem(name, mediaKeySystemProxy);
220     if (ret == DRM_OK) {
221         if (mediaKeySystemProxy != nullptr) {
222             localMediaKeySystemImpl = new (std::nothrow) MediaKeySystemImpl(mediaKeySystemProxy);
223             if (localMediaKeySystemImpl == nullptr) {
224                 DRM_ERR_LOG("Failed to new MediaKeySystemImpl");
225                 return DRM_SERVICE_FATAL_ERROR;
226             }
227         } else {
228             DRM_ERR_LOG("mediaKeySystemProxy is nullptr");
229             return DRM_UNKNOWN_ERROR;
230         }
231     } else if (ret == DRM_MAX_SYSTEM_NUM_REACHED) {
232         DRM_ERR_LOG("The number of MediaKeySystem is greater than 64");
233         return DRM_MAX_SYSTEM_NUM_REACHED;
234     } else {
235         DRM_ERR_LOG("Service faltal error");
236         return DRM_SERVICE_FATAL_ERROR;
237     }
238     *mediaKeySystemImpl = localMediaKeySystemImpl;
239     return DRM_OK;
240 }
241 } // namespace DrmStandard
242 } // namespace OHOS