• 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 <thread>
17 #include "media_key_system_impl.h"
18 #include "imedia_key_system_service.h"
19 #include "drm_error_code.h"
20 #include "drm_trace.h"
21 #include "napi_param_utils.h"
22 
23 namespace OHOS {
24 namespace DrmStandard {
MediaKeySystemImpl(sptr<IMediaKeySystemService> & mediaKeysystem)25 MediaKeySystemImpl::MediaKeySystemImpl(sptr<IMediaKeySystemService> &mediaKeysystem) : serviceProxy_(mediaKeysystem)
26 {
27     DRM_DEBUG_LOG(
28         "MediaKeySystemImpl:0x %{public}06" PRIXPTR "MediaKeySystemImpl Instances create", FAKE_POINTER(this));
29 
30     sptr<IRemoteObject> object = serviceProxy_->AsObject();
31     pid_t pid = 0;
32     deathRecipient_ = new (std::nothrow) DrmDeathRecipient(pid);
33     DRM_CHECK_AND_RETURN_LOG(deathRecipient_ != nullptr, "failed to new DrmDeathRecipient.");
34 
35     deathRecipient_->SetNotifyCb([this](pid_t pid) { this->MediaKeySystemServerDied(pid); });
36     bool result = object->AddDeathRecipient(deathRecipient_);
37     if (!result) {
38         DRM_ERR_LOG("failed to add deathRecipient");
39         return;
40     }
41 }
42 
~MediaKeySystemImpl()43 MediaKeySystemImpl::~MediaKeySystemImpl()
44 {
45     Release();
46     std::lock_guard<std::recursive_mutex> lock(mutex_);
47     serviceProxy_ = nullptr;
48 }
49 
MediaKeySystemServerDied(pid_t pid)50 void MediaKeySystemImpl::MediaKeySystemServerDied(pid_t pid)
51 {
52     DRM_ERR_LOG("MediaKeySystem server has died, pid:%{public}d!", pid);
53     std::lock_guard<std::recursive_mutex> lock(mutex_);
54     if (serviceProxy_ != nullptr && serviceProxy_->AsObject() != nullptr) {
55         (void)serviceProxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
56         serviceProxy_ = nullptr;
57         deathRecipient_ = nullptr;
58     }
59 }
60 
Release()61 int32_t MediaKeySystemImpl::Release()
62 {
63     DRM_INFO_LOG("Release enter.");
64     if (serviceCallback_ != nullptr) {
65         serviceCallback_->Release();
66         serviceCallback_ = nullptr;
67     }
68     std::lock_guard<std::recursive_mutex> lock(mutex_);
69     int32_t ret = DRM_INNER_ERR_UNKNOWN;
70     if (serviceProxy_ != nullptr) {
71         sptr<IRemoteObject> object = serviceProxy_->AsObject();
72         if (object != nullptr && deathRecipient_ != nullptr) {
73             object->RemoveDeathRecipient(deathRecipient_);
74             deathRecipient_ = nullptr;
75         }
76         ret = serviceProxy_->Release();
77         if (ret != DRM_INNER_ERR_OK) {
78             DRM_ERR_LOG("Failed to Release keySystem!, errCode:%{public}d", ret);
79             return ret;
80         }
81         serviceProxy_ = nullptr;
82     } else {
83         DRM_ERR_LOG("serviceProxy_ is nullptr");
84         return ret;
85     }
86     return DRM_INNER_ERR_OK;
87 }
88 
GenerateKeySystemRequest(std::vector<uint8_t> & request,std::string & defaultUrl)89 int32_t MediaKeySystemImpl::GenerateKeySystemRequest(std::vector<uint8_t> &request, std::string &defaultUrl)
90 {
91     DrmTrace trace("MediaKeySystemImpl::GenerateKeySystemRequest");
92     DRM_INFO_LOG("GenerateKeySystemRequest enter.");
93     std::lock_guard<std::recursive_mutex> lock(mutex_);
94     int32_t ret = DRM_INNER_ERR_OK;
95 
96     if (serviceProxy_ == nullptr) {
97         DRM_ERR_LOG("GenerateKeySystemRequest serviceProxy_ is null");
98         return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
99     }
100     ret = serviceProxy_->GenerateKeySystemRequest(request, defaultUrl);
101     if (ret != DRM_INNER_ERR_OK) {
102         DRM_ERR_LOG("GenerateKeySystemRequest failed, ret: %{public}d", ret);
103         return DRM_INNER_ERR_BASE;
104     }
105     return DRM_INNER_ERR_OK;
106 }
107 
ProcessKeySystemResponse(const std::vector<uint8_t> & response)108 int32_t MediaKeySystemImpl::ProcessKeySystemResponse(const std::vector<uint8_t> &response)
109 {
110     DrmTrace trace("MediaKeySystemImpl::ProcessKeySystemResponse");
111     DRM_INFO_LOG("ProcessKeySystemResponse enter.");
112     std::lock_guard<std::recursive_mutex> lock(mutex_);
113     int32_t ret = DRM_INNER_ERR_OK;
114 
115     if (serviceProxy_ == nullptr) {
116         DRM_ERR_LOG("ProcessKeySystemResponse serviceProxy_ is null");
117         return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
118     }
119     ret = serviceProxy_->ProcessKeySystemResponse(response);
120     if (ret != DRM_INNER_ERR_OK) {
121         DRM_ERR_LOG("ProcessKeySystemResponse failed, ret: %{public}d", ret);
122         return DRM_INNER_ERR_BASE;
123     }
124     return DRM_INNER_ERR_OK;
125 }
126 
SetConfigurationString(std::string & configName,std::string & value)127 int32_t MediaKeySystemImpl::SetConfigurationString(std::string &configName, std::string &value)
128 {
129     DRM_INFO_LOG("SetConfiguration enter, configName:%{public}s, value:%{public}s.", configName.c_str(), value.c_str());
130     std::lock_guard<std::recursive_mutex> lock(mutex_);
131     int32_t ret = DRM_INNER_ERR_OK;
132 
133     if (serviceProxy_ == nullptr) {
134         DRM_ERR_LOG("SetConfiguration serviceProxy_ is null");
135         return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
136     }
137     ret = serviceProxy_->SetConfigurationString(configName, value);
138     if (ret != DRM_INNER_ERR_OK) {
139         DRM_ERR_LOG("SetConfiguration failed, ret: %{public}d", ret);
140         return DRM_INNER_ERR_BASE;
141     }
142     return DRM_INNER_ERR_OK;
143 }
144 
GetConfigurationString(std::string & configName,std::string & value)145 int32_t MediaKeySystemImpl::GetConfigurationString(std::string &configName, std::string &value)
146 {
147     DRM_INFO_LOG("GetConfiguration enter, configName:%{public}s.", configName.c_str());
148     std::lock_guard<std::recursive_mutex> lock(mutex_);
149     int32_t ret = DRM_INNER_ERR_OK;
150 
151     if (serviceProxy_ == nullptr) {
152         DRM_ERR_LOG("GetConfiguration serviceProxy_ is null");
153         return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
154     }
155     ret = serviceProxy_->GetConfigurationString(configName, value);
156     if (ret != DRM_INNER_ERR_OK) {
157         DRM_ERR_LOG("GetConfiguration failed, ret: %{public}d", ret);
158         return DRM_INNER_ERR_BASE;
159     }
160     return DRM_INNER_ERR_OK;
161 }
162 
SetConfigurationByteArray(std::string & configName,std::vector<uint8_t> & value)163 int32_t MediaKeySystemImpl::SetConfigurationByteArray(std::string &configName, std::vector<uint8_t> &value)
164 {
165     DRM_INFO_LOG("SetConfiguration enter, configName:%{public}s.", configName.c_str());
166     std::lock_guard<std::recursive_mutex> lock(mutex_);
167     int32_t ret = DRM_INNER_ERR_OK;
168 
169     if (serviceProxy_ == nullptr) {
170         DRM_ERR_LOG("SetConfiguration serviceProxy_ is null");
171         return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
172     }
173     ret = serviceProxy_->SetConfigurationByteArray(configName, value);
174     if (ret != DRM_INNER_ERR_OK) {
175         DRM_ERR_LOG("SetConfiguration failed, ret: %{public}d", ret);
176         return DRM_INNER_ERR_BASE;
177     }
178     return DRM_INNER_ERR_OK;
179 }
180 
GetConfigurationByteArray(std::string & configName,std::vector<uint8_t> & value)181 int32_t MediaKeySystemImpl::GetConfigurationByteArray(std::string &configName, std::vector<uint8_t> &value)
182 {
183     DRM_INFO_LOG("GetConfiguration enter, configName:%{public}s.", configName.c_str());
184     std::lock_guard<std::recursive_mutex> lock(mutex_);
185     int32_t ret = DRM_INNER_ERR_OK;
186 
187     if (serviceProxy_ == nullptr) {
188         DRM_ERR_LOG("GetConfiguration serviceProxy_ is null");
189         return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
190     }
191     ret = serviceProxy_->GetConfigurationByteArray(configName, value);
192     if (ret != DRM_INNER_ERR_OK) {
193         DRM_ERR_LOG("GetConfiguration failed, ret: %{public}d", ret);
194         return DRM_INNER_ERR_BASE;
195     }
196 
197     return DRM_INNER_ERR_OK;
198 }
199 
CreateMediaKeySession(ContentProtectionLevel securityLevel,sptr<MediaKeySessionImpl> * keySessionImpl)200 int32_t MediaKeySystemImpl::CreateMediaKeySession(
201     ContentProtectionLevel securityLevel, sptr<MediaKeySessionImpl> *keySessionImpl)
202 {
203     DrmTrace trace("MediaKeySystemImpl::CreateMediaKeySession");
204     DRM_INFO_LOG("CreateMediaKeySession enter.");
205     std::lock_guard<std::recursive_mutex> lock(mutex_);
206     sptr<IMediaKeySessionService> keySessionProxy = nullptr;
207     sptr<MediaKeySessionImpl> localMediaKeySessionImpl = nullptr;
208     int32_t ret = DRM_INNER_ERR_OK;
209     if (serviceProxy_ == nullptr) {
210         DRM_ERR_LOG("serviceProxy_ == nullptr");
211         return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
212     }
213 
214     ret = serviceProxy_->CreateMediaKeySession(securityLevel, keySessionProxy);
215     if (ret == DRM_INNER_ERR_OK) {
216         if (keySessionProxy != nullptr) {
217             localMediaKeySessionImpl = new (std::nothrow) MediaKeySessionImpl(keySessionProxy);
218             if (localMediaKeySessionImpl == nullptr) {
219                 DRM_ERR_LOG("Failed to new MediaKeySessionImpl");
220                 return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
221             }
222         } else {
223             DRM_ERR_LOG("Service faltal error");
224             return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
225         }
226     } else {
227         if (ret == DRM_INNER_ERR_MAX_SESSION_NUM_REACHED) {
228             DRM_ERR_LOG("The number of MediaKeySession is greater than 64");
229             return DRM_INNER_ERR_MAX_SESSION_NUM_REACHED;
230         }
231         DRM_ERR_LOG("Failed to get session object from mediakeysystem service!, %{public}d", ret);
232         return ret;
233     }
234     *keySessionImpl = localMediaKeySessionImpl;
235     return DRM_INNER_ERR_OK;
236 }
237 
GetStatistics(std::vector<MetircKeyValue> & metrics)238 int32_t MediaKeySystemImpl::GetStatistics(std::vector<MetircKeyValue> &metrics)
239 {
240     DRM_INFO_LOG("GetStatistics enter.");
241     std::lock_guard<std::recursive_mutex> lock(mutex_);
242     int32_t ret = DRM_INNER_ERR_OK;
243 
244     if (serviceProxy_ == nullptr) {
245         DRM_ERR_LOG("GetStatistics serviceProxy_ is null");
246         return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
247     }
248     ret = serviceProxy_->GetStatistics(metrics);
249     if (ret != DRM_INNER_ERR_OK) {
250         DRM_ERR_LOG("GetStatistics failed, ret: %{public}d", ret);
251         return DRM_INNER_ERR_BASE;
252     }
253     return DRM_INNER_ERR_OK;
254 }
255 
GetMaxContentProtectionLevel(ContentProtectionLevel * securityLevel)256 int32_t MediaKeySystemImpl::GetMaxContentProtectionLevel(ContentProtectionLevel *securityLevel)
257 {
258     DRM_INFO_LOG("GetMaxContentProtectionLevel enter.");
259     std::lock_guard<std::recursive_mutex> lock(mutex_);
260     int32_t ret = DRM_INNER_ERR_OK;
261     ContentProtectionLevel protectionLevel;
262 
263     if (serviceProxy_ == nullptr) {
264         DRM_ERR_LOG("GetMaxContentProtectionLevel serviceProxy_ is null");
265         return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
266     }
267     ret = serviceProxy_->GetMaxContentProtectionLevel(protectionLevel);
268     *securityLevel = protectionLevel;
269     if (ret != DRM_INNER_ERR_OK) {
270         DRM_ERR_LOG("GetMaxContentProtectionLevel failed, ret: %{public}d", ret);
271         return DRM_INNER_ERR_BASE;
272     }
273     return DRM_INNER_ERR_OK;
274 }
275 
GetOfflineMediaKeyIds(std::vector<std::vector<uint8_t>> & licenseIds)276 int32_t MediaKeySystemImpl::GetOfflineMediaKeyIds(std::vector<std::vector<uint8_t>> &licenseIds)
277 {
278     DRM_INFO_LOG("GetOfflineMediaKeyIds enter.");
279     std::lock_guard<std::recursive_mutex> lock(mutex_);
280     int32_t ret = DRM_INNER_ERR_OK;
281 
282     if (serviceProxy_ == nullptr) {
283         DRM_ERR_LOG("GetOfflineMediaKeyIds serviceProxy_ is null");
284         return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
285     }
286     ret = serviceProxy_->GetOfflineMediaKeyIds(licenseIds);
287     if (ret != DRM_INNER_ERR_OK) {
288         DRM_ERR_LOG("GetOfflineMediaKeyIds failed, ret: %{public}d", ret);
289         return DRM_INNER_ERR_BASE;
290     }
291     return DRM_INNER_ERR_OK;
292 }
293 
GetOfflineMediaKeyStatus(std::vector<uint8_t> & licenseId,OfflineMediaKeyStatus & status)294 int32_t MediaKeySystemImpl::GetOfflineMediaKeyStatus(std::vector<uint8_t> &licenseId, OfflineMediaKeyStatus &status)
295 {
296     DRM_INFO_LOG("GetOfflineMediaKeyStatus enter.");
297     std::lock_guard<std::recursive_mutex> lock(mutex_);
298     int32_t ret = DRM_INNER_ERR_OK;
299 
300     if (serviceProxy_ == nullptr) {
301         DRM_ERR_LOG("GetOfflineMediaKeyStatus serviceProxy_ is null");
302         return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
303     }
304     ret = serviceProxy_->GetOfflineMediaKeyStatus(licenseId, status);
305     if (ret != DRM_INNER_ERR_OK) {
306         DRM_ERR_LOG("GetOfflineMediaKeyStatus failed, ret: %{public}d", ret);
307         return DRM_INNER_ERR_BASE;
308     }
309     return DRM_INNER_ERR_OK;
310 }
311 
ClearOfflineMediaKeys(std::vector<uint8_t> & licenseId)312 int32_t MediaKeySystemImpl::ClearOfflineMediaKeys(std::vector<uint8_t> &licenseId)
313 {
314     DRM_INFO_LOG("ClearOfflineMediaKeys enter.");
315     std::lock_guard<std::recursive_mutex> lock(mutex_);
316     int32_t ret = DRM_INNER_ERR_OK;
317     if (serviceProxy_ == nullptr) {
318         DRM_ERR_LOG("ClearOfflineMediaKeys serviceProxy_ is null");
319         return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
320     }
321     ret = serviceProxy_->ClearOfflineMediaKeys(licenseId);
322     if (ret != DRM_INNER_ERR_OK) {
323         DRM_ERR_LOG("ClearOfflineMediaKeys failed, ret: %{public}d", ret);
324         return DRM_INNER_ERR_BASE;
325     }
326     return DRM_INNER_ERR_OK;
327 }
328 
GetCertificateStatus(CertificateStatus * certStatus)329 int32_t MediaKeySystemImpl::GetCertificateStatus(CertificateStatus *certStatus)
330 {
331     DRM_INFO_LOG("GetCertificateStatus enter.");
332     std::lock_guard<std::recursive_mutex> lock(mutex_);
333     int32_t ret = DRM_INNER_ERR_OK;
334     CertificateStatus certificateStatus;
335 
336     if (serviceProxy_ == nullptr) {
337         DRM_ERR_LOG("GetCertificateStatus serviceProxy_ is null");
338         return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
339     }
340     ret = serviceProxy_->GetCertificateStatus(certificateStatus);
341     *certStatus = certificateStatus;
342     if (ret != DRM_INNER_ERR_OK) {
343         DRM_ERR_LOG("GetCertificateStatus failed, ret: %{public}d", ret);
344         return DRM_INNER_ERR_BASE;
345     }
346     return DRM_INNER_ERR_OK;
347 }
348 
SetCallback(const sptr<MediaKeySystemImplCallback> & callback)349 int32_t MediaKeySystemImpl::SetCallback(const sptr<MediaKeySystemImplCallback> &callback)
350 {
351     DRM_DEBUG_LOG("0x%{public}06" PRIXPTR " SetCallback in", FAKE_POINTER(this));
352     DRM_CHECK_AND_RETURN_RET_LOG(callback != nullptr, DRM_INNER_ERR_INVALID_VAL, "callback is nullptr");
353     std::lock_guard<std::recursive_mutex> lock(mutex_);
354     mediaKeySystemApplicationCallback_ = callback;
355 
356     int32_t ret = DRM_INNER_ERR_BASE;
357     serviceCallback_ = new (std::nothrow) MediaKeySystemCallback(this);
358     if (serviceCallback_ == nullptr) {
359         DRM_ERR_LOG("MediaKeySystemCallback alloc failed.");
360         return ret;
361     }
362     serviceCallback_->Init();
363     if (serviceProxy_ == nullptr) {
364         DRM_ERR_LOG("SetCallback serviceProxy_ is null");
365         return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
366     }
367     ret = serviceProxy_->SetCallback(serviceCallback_);
368     if (ret != DRM_INNER_ERR_OK) {
369         DRM_ERR_LOG("SetCallback failed, ret: %{public}d", ret);
370         return DRM_INNER_ERR_BASE;
371     }
372     return ret;
373 }
374 
GetApplicationCallback()375 sptr<MediaKeySystemImplCallback> MediaKeySystemImpl::GetApplicationCallback()
376 {
377     DRM_INFO_LOG("GetApplicationCallback");
378     return mediaKeySystemApplicationCallback_;
379 }
380 
~MediaKeySystemCallback()381 MediaKeySystemCallback::~MediaKeySystemCallback()
382 {
383     DRM_INFO_LOG("~MediaKeySystemCallback");
384     Release();
385 }
386 
Init()387 void MediaKeySystemCallback::Init()
388 {
389     DRM_INFO_LOG("MediaKeySystemCallback::Init");
390     serviceThreadRunning = true;
391     eventQueueThread = std::thread([this] { this->ProcessEventMessage(); });
392     DRM_INFO_LOG("MediaKeySystemCallback::Init exit");
393 }
394 
Release()395 void MediaKeySystemCallback::Release()
396 {
397     DRM_INFO_LOG("Release Enter");
398     serviceThreadRunning = false;
399     {
400         std::unique_lock<std::mutex> queueMutexLock(queueMutex);
401         cv.notify_all();
402     }
403     if (eventQueueThread.joinable()) {
404         DRM_INFO_LOG("MediaKeySystemCallback join");
405         eventQueueThread.join();
406     }
407     std::lock_guard<std::recursive_mutex> lock(mutex_);
408     systemImpl_ = nullptr;
409 }
410 
InitEventMap()411 void MediaKeySystemCallback::InitEventMap()
412 {
413     DRM_INFO_LOG("MediaKeySystemCallback InitEventMap");
414     std::lock_guard<std::recursive_mutex> lock(mutex_);
415     eventMap_[static_cast<int32_t>(DrmEventType::DRM_EVENT_PROVISION_REQUIRED)] =
416         MediaKeySystemEvent::EVENT_STR_PROVISION_REQUIRED;
417 }
418 
GetEventName(DrmEventType event)419 std::string MediaKeySystemCallback::GetEventName(DrmEventType event)
420 {
421     DRM_INFO_LOG("MediaKeySystemCallback GetEventName");
422     std::string eventName = "";
423     std::lock_guard<std::recursive_mutex> lock(mutex_);
424     int32_t eventType = static_cast<int32_t>(event);
425     if (eventMap_.find(eventType) == eventMap_.end()) {
426         return eventName;
427     }
428     return eventMap_[eventType];
429 }
430 
SendEvent(DrmEventType event,int32_t extra,const std::vector<uint8_t> & data)431 int32_t MediaKeySystemCallback::SendEvent(DrmEventType event, int32_t extra, const std::vector<uint8_t> &data)
432 {
433     DRM_INFO_LOG("SendEvent enter");
434     std::unique_lock<std::mutex> queueMutexLock(queueMutex);
435     MediaKeySystemEventMessage message(event, extra, data);
436     eventQueue.push(message);
437     cv.notify_all();
438     return DRM_INNER_ERR_OK;
439 }
440 
SendEventHandler(DrmEventType event,int32_t extra,const std::vector<uint8_t> & data)441 int32_t MediaKeySystemCallback::SendEventHandler(DrmEventType event, int32_t extra, const std::vector<uint8_t> &data)
442 {
443     DRM_INFO_LOG("SendEventHandler enter");
444     std::string eventName = GetEventName(event);
445     std::lock_guard<std::recursive_mutex> lock(mutex_);
446     if (systemImpl_ != nullptr && eventName.length() != 0) {
447         sptr<MediaKeySystemImplCallback> applicationCallback = systemImpl_->GetApplicationCallback();
448         if (applicationCallback != nullptr) {
449             applicationCallback->SendEvent(eventName, extra, data);
450             return DRM_INNER_ERR_OK;
451         }
452     }
453     DRM_DEBUG_LOG("SendEventHandler failed");
454     return DRM_INNER_ERR_BASE;
455 }
456 
ProcessEventMessage()457 void MediaKeySystemCallback::ProcessEventMessage()
458 {
459     DRM_INFO_LOG("ProcessEventMessage msg enter");
460     while (serviceThreadRunning) {
461         std::unique_lock<std::mutex> queueMutexLock(queueMutex);
462         cv.wait_for(queueMutexLock, std::chrono::milliseconds(100L));  // 100ms
463         std::queue<MediaKeySystemEventMessage> localQueue;
464         localQueue.swap(eventQueue);
465         queueMutexLock.unlock();
466         while (!localQueue.empty()) {
467             auto e = localQueue.front();
468             localQueue.pop();
469             SendEventHandler(e.event, e.extra, e.data);
470         }
471     }
472     DRM_INFO_LOG("ProcessEventMessage msg exit");
473 }
474 }  // namespace DrmStandard
475 }  // namespace OHOS
476