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