• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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