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 "avcodec_server.h"
17 #include <sys/time.h>
18 #include "avcodec_errors.h"
19 #include "avcodec_log.h"
20 #include "avcodec_sysevent.h"
21 #include "avcodec_trace.h"
22 #include "iservice_registry.h"
23 #include "system_ability_definition.h"
24 
25 namespace {
26 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_FRAMEWORK, "AVCodecServer"};
27 constexpr uint32_t SERVER_MAX_IPC_THREAD_NUM = 64;
28 } // namespace
29 
30 namespace OHOS {
31 namespace MediaAVCodec {
REGISTER_SYSTEM_ABILITY_BY_ID(AVCodecServer,AV_CODEC_SERVICE_ID,true)32 REGISTER_SYSTEM_ABILITY_BY_ID(AVCodecServer, AV_CODEC_SERVICE_ID, true)
33 AVCodecServer::AVCodecServer(int32_t systemAbilityId, bool runOnCreate) : SystemAbility(systemAbilityId, runOnCreate)
34 {
35     AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
36 }
37 
~AVCodecServer()38 AVCodecServer::~AVCodecServer()
39 {
40     AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
41 }
42 
OnDump()43 void AVCodecServer::OnDump()
44 {
45     AVCODEC_LOGD("AVCodecServer OnDump");
46 }
47 
OnStart()48 void AVCodecServer::OnStart()
49 {
50     AVCODEC_LOGD("AVCodecServer OnStart");
51     struct timeval start = {};
52     struct timeval end = {};
53     (void)gettimeofday(&start, nullptr);
54     bool res = Publish(this);
55     if (res) {
56         AVCODEC_LOGD("AVCodecServer OnStart res=%{public}d", res);
57     }
58     (void)gettimeofday(&end, nullptr);
59     uint32_t useTime = static_cast<uint32_t>((end.tv_sec - start.tv_sec) * 1000000 + end.tv_usec - start.tv_usec);
60     IPCSkeleton::SetMaxWorkThreadNum(SERVER_MAX_IPC_THREAD_NUM);
61     AddSystemAbilityListener(MEMORY_MANAGER_SA_ID);
62     ServiceStartEventWrite(useTime, "AV_CODEC service");
63 }
64 
OnStop()65 void AVCodecServer::OnStop()
66 {
67     AVCODEC_LOGD("AVCodecServer OnStop");
68     AVCodecServerManager::GetInstance().NotifyProcessStatus(0);
69 }
70 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)71 void AVCodecServer::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
72 {
73     AVCODEC_LOGI("AVCodecServer OnAddSystemAbility, systemAbilityId:%{public}d, deviceId:%s", systemAbilityId,
74                  deviceId.c_str());
75     if (systemAbilityId == MEMORY_MANAGER_SA_ID) {
76         AVCodecServerManager::GetInstance().SetMemMgrStatus(true);
77         AVCodecServerManager::GetInstance().NotifyProcessStatus(1);
78     }
79 }
80 
SwitchSystemId(IStandardAVCodecService::AVCodecSystemAbility subSystemId)81 std::optional<AVCodecServerManager::StubType> AVCodecServer::SwitchSystemId(
82     IStandardAVCodecService::AVCodecSystemAbility subSystemId)
83 {
84     switch (subSystemId) {
85 #ifdef SUPPORT_CODECLIST
86         case AVCodecSystemAbility::AVCODEC_CODECLIST: {
87             return AVCodecServerManager::CODECLIST;
88         }
89 #endif
90 #ifdef SUPPORT_CODEC
91         case AVCodecSystemAbility::AVCODEC_CODEC: {
92             return AVCodecServerManager::CODEC;
93         }
94 #endif
95         default: {
96             AVCODEC_LOGE("subSystemId is invalid");
97             return std::nullopt;
98         }
99     }
100 }
101 
GetSubSystemAbility(IStandardAVCodecService::AVCodecSystemAbility subSystemId,const sptr<IRemoteObject> & listener,sptr<IRemoteObject> & stubObject)102 int32_t AVCodecServer::GetSubSystemAbility(IStandardAVCodecService::AVCodecSystemAbility subSystemId,
103                                            const sptr<IRemoteObject> &listener, sptr<IRemoteObject> &stubObject)
104 {
105     std::optional<AVCodecServerManager::StubType> stubType = SwitchSystemId(subSystemId);
106     CHECK_AND_RETURN_RET_LOG(stubType != std::nullopt, AVCS_ERR_INVALID_OPERATION, "Get sub system type failed");
107 
108     int32_t ret = AVCodecServerManager::GetInstance().CreateStubObject(stubType.value(), stubObject);
109     CHECK_AND_RETURN_RET_LOG(stubObject != nullptr, ret, "Create sub system failed, err: %{public}d", ret);
110 
111     ret = AVCodecServiceStub::SetDeathListener(listener);
112     if (ret != AVCS_ERR_OK) {
113         AVCodecServerManager::GetInstance().DestroyStubObject(*stubType, stubObject);
114         stubObject = nullptr;
115         AVCODEC_LOGE("SetDeathListener failed");
116         return AVCS_ERR_IPC_SET_DEATH_LISTENER_FAILED;
117     }
118 
119     return AVCS_ERR_OK;
120 }
121 
Dump(int32_t fd,const std::vector<std::u16string> & args)122 int32_t AVCodecServer::Dump(int32_t fd, const std::vector<std::u16string> &args)
123 {
124     if (fd <= 0) {
125         AVCODEC_LOGW("Failed to check fd");
126         return OHOS::INVALID_OPERATION;
127     }
128     if (AVCodecServerManager::GetInstance().Dump(fd, args) != OHOS::NO_ERROR) {
129         AVCODEC_LOGW("Failed to call AVCodecServerManager::Dump");
130         return OHOS::INVALID_OPERATION;
131     }
132 
133     return OHOS::NO_ERROR;
134 }
135 } // namespace MediaAVCodec
136 } // namespace OHOS
137