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