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 <securec.h>
17 #include <unistd.h>
18 #include <unordered_set>
19 #include "system_ability_definition.h"
20 #include "mem_mgr_client.h"
21 #include "mem_mgr_proxy.h"
22 #include "ipc_skeleton.h"
23 #include "iservice_registry.h"
24 #include "drm_dfx_utils.h"
25 #include "drm_log.h"
26 #include "drm_dfx.h"
27 #include "drm_error_code.h"
28 #include "dump_usage.h"
29 #include "hitrace/tracechain.h"
30 #include "iservice_registry.h"
31 #include "mediakeysystem_service.h"
32 #include "mediakeysystemfactory_service.h"
33
34 namespace OHOS {
35 namespace DrmStandard {
36 using namespace OHOS::HiviewDFX;
37 const std::string SPLIT_LINE =
38 "----------------------------------------------------------------------------------------\n";
39
REGISTER_SYSTEM_ABILITY_BY_ID(MediaKeySystemFactoryService,MEDIA_KEY_SYSTEM_SERVICE_ID,true)40 REGISTER_SYSTEM_ABILITY_BY_ID(MediaKeySystemFactoryService, MEDIA_KEY_SYSTEM_SERVICE_ID, true)
41
42
43 void MediaKeySystemFactoryService::OnDrmPluginDied(std::string &name)
44 {
45 DRM_INFO_LOG("OnDrmPluginDied enter.");
46 std::lock_guard<std::recursive_mutex> lock(mutex_);
47 for (auto pidIt = mediaKeySystemForPid_.begin(); pidIt != mediaKeySystemForPid_.end();) {
48 std::set<sptr<MediaKeySystemService>> mediaKeySystemServiceSet = pidIt->second;
49 for (auto keySystem = mediaKeySystemServiceSet.begin(); keySystem != mediaKeySystemServiceSet.end();) {
50 std::string pluginName = (*keySystem)->GetPluginName();
51 if (name == pluginName) {
52 CloseMediaKeySystemService(*keySystem);
53 mediaKeySystemServiceSet.erase(keySystem++);
54 } else {
55 ++keySystem;
56 }
57 }
58 if (mediaKeySystemServiceSet.empty()) {
59 pidIt = mediaKeySystemForPid_.erase(pidIt);
60 } else {
61 pidIt++;
62 }
63 }
64 currentMediaKeySystemNum_.erase(name);
65 }
66
MediaKeySystemFactoryService(int32_t systemAbilityId,bool runOnCreate)67 MediaKeySystemFactoryService::MediaKeySystemFactoryService(int32_t systemAbilityId, bool runOnCreate)
68 : SystemAbility(systemAbilityId, runOnCreate)
69 {
70 DRM_INFO_LOG("MediaKeySystemFactoryService enter.");
71 drmHostManager_ = new (std::nothrow) DrmHostManager(this);
72 if (drmHostManager_ == nullptr) {
73 DRM_ERR_LOG("create drmHostManager_ failed.");
74 return;
75 }
76 }
77
~MediaKeySystemFactoryService()78 MediaKeySystemFactoryService::~MediaKeySystemFactoryService()
79 {
80 DRM_INFO_LOG("~MediaKeySystemFactoryService enter.");
81 }
82
OnStart()83 void MediaKeySystemFactoryService::OnStart()
84 {
85 DRM_INFO_LOG("OnStart enter.");
86 std::lock_guard<std::recursive_mutex> lock(mutex_);
87 if (drmHostManager_ == nullptr || drmHostManager_->Init() != DRM_OK) {
88 DRM_ERR_LOG("OnStart failed to init drm host manager.");
89 }
90 bool res = Publish(this);
91 if (res) {
92 DRM_DEBUG_LOG("MediaKeySystemFactoryService OnStart res=%{public}d", res);
93 }
94 AddSystemAbilityListener(MEMORY_MANAGER_SA_ID);
95 ReportServiceBehaviorEvent("DRM_SERVICE", "start");
96 }
97
OnDump()98 void MediaKeySystemFactoryService::OnDump()
99 {
100 }
101
OnStop()102 void MediaKeySystemFactoryService::OnStop()
103 {
104 DRM_INFO_LOG("OnStop enter.");
105 std::lock_guard<std::recursive_mutex> lock(mutex_);
106
107 if (drmHostManager_) {
108 drmHostManager_->DeInit();
109 drmHostManager_ = nullptr;
110 }
111
112 int pid = getpid();
113 /* 3012 is the saId of drm_service */
114 Memory::MemMgrClient::GetInstance().NotifyProcessStatus(pid, 1, 0, 3012);
115 OHOS::HiviewDFX::DumpUsage dumpUse;
116 ReportServiceBehaviorEvent("DRM_SERVICE", "end");
117 }
118
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)119 void MediaKeySystemFactoryService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
120 {
121 DRM_INFO_LOG("OnAddSystemAbility enter.");
122 if (systemAbilityId == MEMORY_MANAGER_SA_ID) {
123 int32_t pid = getpid();
124 /* 3012 is the said of drm service */
125 Memory::MemMgrClient::GetInstance().NotifyProcessStatus(pid, 1, 1, 3012);
126 }
127 }
128
Dump(int32_t fd,const std::vector<std::u16string> & args)129 int32_t MediaKeySystemFactoryService::Dump(int32_t fd, const std::vector<std::u16string>& args)
130 {
131 DRM_CHECK_AND_RETURN_RET_LOG(fd > 0, OHOS::INVALID_OPERATION, "Failed to check fd.");
132 std::string dumpString;
133
134 auto ret = WriteDumpInfo(fd, dumpString);
135 DRM_CHECK_AND_RETURN_RET_LOG(ret == NO_ERROR,
136 OHOS::INVALID_OPERATION, "Failed to write framework information");
137 return OHOS::NO_ERROR;
138 }
139
DistroyForClientDied(pid_t pid)140 void MediaKeySystemFactoryService::DistroyForClientDied(pid_t pid)
141 {
142 // destroy all system objects for this pid
143 DRM_INFO_LOG("DistroyForClientDied pid: %{public}d.", pid);
144 std::lock_guard<std::recursive_mutex> lock(mutex_);
145 if (mediaKeySystemForPid_.find(pid) == mediaKeySystemForPid_.end()) {
146 return;
147 }
148 for (auto it = mediaKeySystemForPid_[pid].begin(); it != mediaKeySystemForPid_[pid].end();) {
149 if ((*it) != nullptr) {
150 // decrease the total count in drm host manager.
151 sptr<IMediaKeySystem> hdiMediaKeySystem = (*it)->getMediaKeySystem();
152 (*it)->CloseMediaKeySystemServiceByCallback();
153 if (hdiMediaKeySystem != nullptr) {
154 drmHostManager_->ReleaseMediaKeySystem(hdiMediaKeySystem);
155 }
156 if (currentMediaKeySystemNum_.find((*it)->GetPluginName()) != currentMediaKeySystemNum_.end()) {
157 currentMediaKeySystemNum_[(*it)->GetPluginName()]--;
158 }
159 }
160 it = mediaKeySystemForPid_[pid].erase(it);
161 }
162 mediaKeySystemForPid_[pid].clear();
163 mediaKeySystemForPid_.erase(pid);
164 }
165
CreateMediaKeySystem(std::string & name,sptr<IMediaKeySystemService> & mediaKeySystemProxy)166 int32_t MediaKeySystemFactoryService::CreateMediaKeySystem(std::string &name,
167 sptr<IMediaKeySystemService> &mediaKeySystemProxy)
168 {
169 DRM_INFO_LOG("CreateMediaKeySystem enter.");
170 std::lock_guard<std::recursive_mutex> lock(mutex_);
171 sptr<MediaKeySystemService> mediaKeySystemService = nullptr;
172 sptr<IMediaKeySystem> hdiMediaKeySystem = nullptr;
173 if (currentMediaKeySystemNum_[name] >= KEY_SYSTEM_MAX_NUMBER) {
174 DRM_ERR_LOG("The number of MediaKeySystem is greater than 64");
175 return DRM_MAX_SYSTEM_NUM_REACHED;
176 }
177 int32_t ret = drmHostManager_->CreateMediaKeySystem(name, hdiMediaKeySystem);
178 if (hdiMediaKeySystem == nullptr || ret != DRM_OK) {
179 DRM_ERR_LOG("drmHostManager_ return hdiMediaKeySystem nullptr.");
180 ReportFaultEvent(DRM_SERVICE_ERROR, "CreateMediaKeySystem failed", "");
181 return DRM_SERVICE_ERROR;
182 }
183
184 StatisticsInfo statisticsInfo;
185 InitStatisticsInfo(hdiMediaKeySystem, name, statisticsInfo);
186 mediaKeySystemService = new(std::nothrow) MediaKeySystemService(hdiMediaKeySystem, statisticsInfo);
187 if (mediaKeySystemService == nullptr) {
188 DRM_ERR_LOG("CreateMediaKeySystem allocation failed.");
189 ReportFaultEvent(DRM_ALLOC_ERROR, "CreateMediaKeySystem failed", "");
190 return DRM_ALLOC_ERROR;
191 }
192 mediaKeySystemService->SetMediaKeySystemServiceOperatorsCallback(this);
193 (void)mediaKeySystemService->SetBundleName();
194
195 int32_t pid = IPCSkeleton::GetCallingPid();
196 DRM_DEBUG_LOG("CreateMediaKeySystem GetCallingPID: %{public}d.", pid);
197 mediaKeySystemForPid_[pid].insert(mediaKeySystemService);
198 DRM_DEBUG_LOG("0x%{public}06" PRIXPTR " Current mediaKeySystemService",
199 FAKE_POINTER(mediaKeySystemService.GetRefPtr()));
200 mediaKeySystemProxy = mediaKeySystemService;
201 if (currentMediaKeySystemNum_.find(name) != currentMediaKeySystemNum_.end()) {
202 currentMediaKeySystemNum_[name]++;
203 } else {
204 currentMediaKeySystemNum_[name] = 1;
205 }
206 return ret;
207 }
208
CloseMediaKeySystemService(sptr<MediaKeySystemService> mediaKeySystemService)209 int32_t MediaKeySystemFactoryService::CloseMediaKeySystemService(sptr<MediaKeySystemService> mediaKeySystemService)
210 {
211 std::lock_guard<std::recursive_mutex> lock(mutex_);
212 DRM_INFO_LOG("CloseMediaKeySystemService enter.");
213 int32_t currentPid = IPCSkeleton::GetCallingPid();
214 DRM_DEBUG_LOG("MediaKeySystemFactoryService GetCallingPID: %{public}d", currentPid);
215 sptr<IMediaKeySystem> hdiMediaKeySystem = mediaKeySystemService->getMediaKeySystem();
216
217 for (auto &pidSystemsSet : mediaKeySystemForPid_) {
218 if (pidSystemsSet.second.find(mediaKeySystemService) != pidSystemsSet.second.end()) {
219 mediaKeySystemService->CloseMediaKeySystemServiceByCallback();
220 pidSystemsSet.second.erase(mediaKeySystemService);
221 break;
222 }
223 }
224 std::string pluginName = mediaKeySystemService->GetPluginName();
225 if (currentMediaKeySystemNum_.find(pluginName) != currentMediaKeySystemNum_.end() &&
226 currentMediaKeySystemNum_[pluginName] > 0) {
227 currentMediaKeySystemNum_[pluginName]--;
228 }
229 if (hdiMediaKeySystem != NULL) {
230 drmHostManager_->ReleaseMediaKeySystem(hdiMediaKeySystem);
231 }
232 mediaKeySystemService = nullptr;
233 return DRM_OK;
234 }
235
IsMediaKeySystemSupported(std::string & name,bool * isSurpported)236 int32_t MediaKeySystemFactoryService::IsMediaKeySystemSupported(std::string &name, bool *isSurpported)
237 {
238 DRM_INFO_LOG("IsMediaKeySystemSupported one parameters enter.");
239 std::lock_guard<std::recursive_mutex> lock(mutex_);
240 int32_t ret = drmHostManager_->IsMediaKeySystemSupported(name, isSurpported);
241 if (ret != DRM_OK) {
242 DRM_ERR_LOG("IsMediaKeySystemSupported failed.");
243 return ret;
244 }
245 return ret;
246 }
247
IsMediaKeySystemSupported(std::string & name,std::string & mimeType,bool * isSurpported)248 int32_t MediaKeySystemFactoryService::IsMediaKeySystemSupported(std::string &name, std::string &mimeType,
249 bool *isSurpported)
250 {
251 DRM_INFO_LOG("IsMediaKeySystemSupported two parameters enter.");
252 std::lock_guard<std::recursive_mutex> lock(mutex_);
253 int32_t ret = drmHostManager_->IsMediaKeySystemSupported(name, mimeType, isSurpported);
254 if (ret != DRM_OK) {
255 DRM_ERR_LOG("IsMediaKeySystemSupported failed.");
256 return ret;
257 }
258 return ret;
259 }
260
IsMediaKeySystemSupported(std::string & name,std::string & mimeType,int32_t securityLevel,bool * isSurpported)261 int32_t MediaKeySystemFactoryService::IsMediaKeySystemSupported(std::string &name, std::string &mimeType,
262 int32_t securityLevel, bool *isSurpported)
263 {
264 DRM_INFO_LOG("IsMediaKeySystemSupported three parameters enter.");
265 std::lock_guard<std::recursive_mutex> lock(mutex_);
266 int32_t ret = drmHostManager_->IsMediaKeySystemSupported(name, mimeType, securityLevel, isSurpported);
267 if (ret != DRM_OK) {
268 DRM_ERR_LOG("IsMediaKeySystemSupported failed.");
269 return ret;
270 }
271 return ret;
272 }
273
GetMediaKeySystems(std::map<std::string,std::string> & mediaKeySystemNames)274 int32_t MediaKeySystemFactoryService::GetMediaKeySystems(std::map<std::string, std::string> &mediaKeySystemNames)
275 {
276 DRM_INFO_LOG("GetMediaKeySystems enter.");
277 std::lock_guard<std::recursive_mutex> lock(mutex_);
278 int32_t ret = drmHostManager_->GetMediaKeySystems(mediaKeySystemNames);
279 if (ret != DRM_OK) {
280 DRM_ERR_LOG("GetMediaKeySystems failed.");
281 return ret;
282 }
283 return ret;
284 }
285
GetMediaKeySystemUuid(std::string & name,std::string & uuid)286 int32_t MediaKeySystemFactoryService::GetMediaKeySystemUuid(std::string &name, std::string &uuid)
287 {
288 DRM_INFO_LOG("GetMediaKeySystemUuid enter.");
289 std::lock_guard<std::recursive_mutex> lock(mutex_);
290 int32_t ret = drmHostManager_->GetMediaKeySystemUuid(name, uuid);
291 if (ret != DRM_OK) {
292 DRM_ERR_LOG("GetMediaKeySystemUuid failed.");
293 return ret;
294 }
295 return ret;
296 }
297
InitStatisticsInfo(const sptr<IMediaKeySystem> & hdiMediaKeySystem,std::string pluginName,StatisticsInfo & statisticsInfo)298 void MediaKeySystemFactoryService::InitStatisticsInfo(const sptr<IMediaKeySystem> &hdiMediaKeySystem,
299 std::string pluginName, StatisticsInfo &statisticsInfo)
300 {
301 DRM_INFO_LOG("InitStatisticsInfo enter.");
302 std::lock_guard<std::recursive_mutex> lock(mutex_);
303 statisticsInfo.pluginName = pluginName;
304 if (drmHostManager_ != nullptr) {
305 std::map<std::string, std::string> pluginNameUuidMap;
306 drmHostManager_->GetMediaKeySystems(pluginNameUuidMap);
307 if (pluginNameUuidMap.find(pluginName) != pluginNameUuidMap.end()) {
308 statisticsInfo.pluginUuid = pluginNameUuidMap[pluginName];
309 }
310 }
311 statisticsInfo.bundleName = GetClientBundleName(IPCSkeleton::GetCallingUid());
312 if (hdiMediaKeySystem != nullptr) {
313 (void)hdiMediaKeySystem->GetConfigurationString("vendor", statisticsInfo.vendorName);
314 (void)hdiMediaKeySystem->GetConfigurationString("version", statisticsInfo.versionName);
315 }
316 DRM_INFO_LOG("uid: %{public}d, appName: %{public}s.",
317 IPCSkeleton::GetCallingUid(), statisticsInfo.bundleName.c_str());
318 DRM_INFO_LOG("pluginName: %{public}s, pluginUUID: %{public}s",
319 statisticsInfo.pluginName.c_str(), statisticsInfo.pluginUuid.c_str());
320 DRM_INFO_LOG("vendorName: %{public}s, versionName: %{public}s",
321 statisticsInfo.vendorName.c_str(), statisticsInfo.versionName.c_str());
322 }
323
WriteDumpInfo(int32_t fd,std::string & dumpString)324 int32_t MediaKeySystemFactoryService::WriteDumpInfo(int32_t fd, std::string &dumpString)
325 {
326 OHOS::HiviewDFX::DumpUsage dumpUse;
327 std::lock_guard<std::recursive_mutex> lock(mutex_);
328 dumpString += "MediaKeySystem MemoryUsage: " + std::to_string(dumpUse.GetPss(getpid())) + "\n";
329 std::map<std::string, std::string> mediaKeySystemInfo;
330 drmHostManager_->GetMediaKeySystems(mediaKeySystemInfo);
331 for (auto &iter : mediaKeySystemInfo) {
332 dumpString += SPLIT_LINE;
333 std::string tmpStr = "Plugin Name: " + iter.first + "\n" +
334 "Plugin UUID: " + iter.second + "\n" +
335 "Total MediaKeySystem Num: ";
336 int32_t systemNum = 0;
337 if (currentMediaKeySystemNum_.find(iter.first) != currentMediaKeySystemNum_.end()) {
338 systemNum = currentMediaKeySystemNum_[iter.first];
339 }
340 tmpStr += std::to_string(systemNum) + "\n";
341 dumpString += tmpStr;
342 }
343 uint32_t systemNum = 0;
344 for (auto &pidIter : mediaKeySystemForPid_) {
345 dumpString += SPLIT_LINE;
346 systemNum++;
347 dumpString += "#### MediaKeySystem " + std::to_string(systemNum) + " ####\n";
348 dumpString += "PID: " + std::to_string(pidIter.first) + "\n";
349 for (auto &system : pidIter.second) {
350 dumpString += "-------------------------------\n";
351 IMediaKeySystemService::CertificateStatus certStatus = IMediaKeySystemService::CERT_STATUS_UNAVAILABLE;
352 system->GetCertificateStatus(&certStatus);
353 dumpString += "Plugin Name: " + system->GetPluginName() + "\n";
354 dumpString += "Certificate Status: " + std::to_string(certStatus) + "\n";
355 dumpString += system->GetSessionsDumpInfo();
356 }
357 }
358 dumpString += SPLIT_LINE;
359 if (fd != -1) {
360 ssize_t writeLen = write(fd, dumpString.c_str(), dumpString.size());
361 if (writeLen == -1) {
362 DRM_ERR_LOG("Dump write error!");
363 }
364 } else {
365 DRM_INFO_LOG("%{public}s", dumpString.c_str());
366 }
367 return OHOS::NO_ERROR;
368 }
369
370 } // DrmStandard
371 } // OHOS