• 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 "avcodec_client.h"
17 #include <thread>
18 #include "avcodec_xcollie.h"
19 #include "ipc_skeleton.h"
20 #include "iservice_registry.h"
21 #include "system_ability_definition.h"
22 #include "avcodec_trace.h"
23 #include "avcodec_sysevent.h"
24 
25 #ifdef SUPPORT_CODEC
26 #include "i_standard_codec_service.h"
27 #endif
28 #ifdef SUPPORT_CODECLIST
29 #include "i_standard_codeclist_service.h"
30 #endif
31 
32 #include "avcodec_errors.h"
33 #include "avcodec_log.h"
34 
35 namespace {
36 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_FRAMEWORK, "AVCodecClient"};
37 }
38 
39 namespace OHOS {
40 namespace MediaAVCodec {
41 static bool g_isDestructed = false;
42 static std::mutex g_avCodecClientMutex;
43 static AVCodecClient g_avCodecClientInstance;
GetInstance()44 IAVCodecService &AVCodecServiceFactory::GetInstance()
45 {
46     return g_avCodecClientInstance;
47 }
48 
AVCodecClient()49 AVCodecClient::AVCodecClient() noexcept
50 {
51     AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
52 }
53 
~AVCodecClient()54 AVCodecClient::~AVCodecClient()
55 {
56     std::lock_guard<std::mutex> lock(g_avCodecClientMutex);
57     g_isDestructed = true;
58     AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
59 }
60 
IsAlived()61 bool AVCodecClient::IsAlived()
62 {
63     if (avCodecProxy_ == nullptr) {
64         avCodecProxy_ = GetAVCodecProxy();
65     }
66 
67     return avCodecProxy_ != nullptr;
68 }
69 
CreateInstanceAndTryInTimes(IStandardAVCodecService::AVCodecSystemAbility subSystemId,sptr<IRemoteObject> & object,uint32_t tryTimes)70 int32_t AVCodecClient::CreateInstanceAndTryInTimes(IStandardAVCodecService::AVCodecSystemAbility subSystemId,
71                                                    sptr<IRemoteObject> &object,
72                                                    uint32_t tryTimes)
73 {
74     int32_t ret = AVCS_ERR_OK;
75     do {
76         if (!IsAlived()) {
77             std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
78             continue;
79         }
80 
81         ret = avCodecProxy_->GetSubSystemAbility(subSystemId, listenerStub_->AsObject(), object);
82         if (object != nullptr) {
83             break;
84         }
85         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
86         continue;
87     } while (--tryTimes);
88     return ret;
89 }
90 
SuspendFreeze(const std::vector<pid_t> & pidList)91 int32_t AVCodecClient::SuspendFreeze(const std::vector<pid_t> &pidList)
92 {
93     std::lock_guard<std::mutex> lock(mutex_);
94     auto avCodecProxy = GetTemporaryAVCodecProxy();
95     CHECK_AND_RETURN_RET_LOG(avCodecProxy != nullptr, AVCS_ERR_SERVICE_DIED, "AVCodec proxy does not exist");
96     return avCodecProxy->SuspendFreeze(pidList);
97 }
98 
SuspendActive(const std::vector<pid_t> & pidList)99 int32_t AVCodecClient::SuspendActive(const std::vector<pid_t> &pidList)
100 {
101     std::lock_guard<std::mutex> lock(mutex_);
102     auto avCodecProxy = GetTemporaryAVCodecProxy();
103     CHECK_AND_RETURN_RET_LOG(avCodecProxy != nullptr, AVCS_ERR_SERVICE_DIED, "AVCodec proxy does not exist");
104     return avCodecProxy->SuspendActive(pidList);
105 }
106 
SuspendActiveAll()107 int32_t AVCodecClient::SuspendActiveAll()
108 {
109     std::lock_guard<std::mutex> lock(mutex_);
110     auto avCodecProxy = GetTemporaryAVCodecProxy();
111     CHECK_AND_RETURN_RET_LOG(avCodecProxy != nullptr, AVCS_ERR_SERVICE_DIED, "AVCodec proxy does not exist");
112     return avCodecProxy->SuspendActiveAll();
113 }
114 
115 #ifdef SUPPORT_CODEC
CreateCodecService(std::shared_ptr<ICodecService> & codecClient)116 int32_t AVCodecClient::CreateCodecService(std::shared_ptr<ICodecService> &codecClient)
117 {
118     std::lock_guard<std::mutex> lock(mutex_);
119 
120     sptr<IRemoteObject> object = nullptr;
121     int32_t ret = CreateInstanceAndTryInTimes(IStandardAVCodecService::AVCodecSystemAbility::AVCODEC_CODEC, object);
122     CHECK_AND_RETURN_RET_LOG(object != nullptr, ret, "Create codec proxy object failed.");
123 
124     sptr<IStandardCodecService> codecProxy = iface_cast<IStandardCodecService>(object);
125     CHECK_AND_RETURN_RET_LOG(codecProxy != nullptr, AVCS_ERR_UNSUPPORT, "Codec proxy is nullptr.");
126 
127     ret = CodecClient::Create(codecProxy, codecClient);
128     CHECK_AND_RETURN_RET_LOG(codecClient != nullptr, ret, "Failed to create codec client.");
129 
130     codecClientList_.push_back(codecClient);
131     return AVCS_ERR_OK;
132 }
133 
DestroyCodecService(std::shared_ptr<ICodecService> codecClient)134 int32_t AVCodecClient::DestroyCodecService(std::shared_ptr<ICodecService> codecClient)
135 {
136     std::lock_guard<std::mutex> lock(mutex_);
137     CHECK_AND_RETURN_RET_LOG(codecClient != nullptr, AVCS_ERR_NO_MEMORY, "codec client is nullptr.");
138     codecClientList_.remove(codecClient);
139     return AVCS_ERR_OK;
140 }
141 #endif
142 #ifdef SUPPORT_CODECLIST
CreateCodecListService()143 std::shared_ptr<ICodecListService> AVCodecClient::CreateCodecListService()
144 {
145     std::lock_guard<std::mutex> lock(mutex_);
146 
147     sptr<IRemoteObject> object = nullptr;
148     (void)CreateInstanceAndTryInTimes(IStandardAVCodecService::AVCodecSystemAbility::AVCODEC_CODECLIST, object);
149     CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "Create codeclist proxy object failed.");
150 
151     sptr<IStandardCodecListService> codecListProxy = iface_cast<IStandardCodecListService>(object);
152     CHECK_AND_RETURN_RET_LOG(codecListProxy != nullptr, nullptr, "codeclist proxy is nullptr.");
153 
154     std::shared_ptr<CodecListClient> codecListClient = CodecListClient::Create(codecListProxy);
155     CHECK_AND_RETURN_RET_LOG(codecListClient != nullptr, nullptr, "failed to create codeclist client.");
156 
157     codecListClientList_.push_back(codecListClient);
158     return codecListClient;
159 }
160 
DestroyCodecListService(std::shared_ptr<ICodecListService> codecListClient)161 int32_t AVCodecClient::DestroyCodecListService(std::shared_ptr<ICodecListService> codecListClient)
162 {
163     std::lock_guard<std::mutex> lock(mutex_);
164     CHECK_AND_RETURN_RET_LOG(codecListClient != nullptr, AVCS_ERR_NO_MEMORY, "codeclist client is nullptr.");
165     codecListClientList_.remove(codecListClient);
166     return AVCS_ERR_OK;
167 }
168 #endif
169 
GetAVCodecProxy()170 sptr<IStandardAVCodecService> AVCodecClient::GetAVCodecProxy()
171 {
172     AVCODEC_LOGI("In");
173     sptr<ISystemAbilityManager> samgr = nullptr;
174     CLIENT_COLLIE_LISTEN(samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(),
175         "AVCodecClient GetAVCodecProxy");
176     CHECK_AND_RETURN_RET_LOG(samgr != nullptr, nullptr, "system ability manager is nullptr.");
177 
178     sptr<IRemoteObject> object = nullptr;
179     CLIENT_COLLIE_LISTEN(object = samgr->CheckSystemAbility(OHOS::AV_CODEC_SERVICE_ID),
180                          "AVCodecClient GetAVCodecProxy");
181     if (object == nullptr) {
182         CLIENT_COLLIE_LISTEN(object = samgr->LoadSystemAbility(OHOS::AV_CODEC_SERVICE_ID, 30), // 30: timeout
183                              "AVCodecClient LoadSystemAbility");
184         CHECK_AND_RETURN_RET_LOG(object != nullptr,
185             nullptr, "AVCodec object is nullptr, maybe avcodec service does not exist");
186     }
187 
188     avCodecProxy_ = iface_cast<IStandardAVCodecService>(object);
189     CHECK_AND_RETURN_RET_LOG(avCodecProxy_ != nullptr, nullptr, "AVCodec proxy is nullptr");
190 
191     pid_t pid = 0;
192     deathRecipient_ = new (std::nothrow) AVCodecDeathRecipient(pid);
193     CHECK_AND_RETURN_RET_LOG(deathRecipient_ != nullptr, nullptr, "Failed to create AVCodecDeathRecipient");
194 
195     deathRecipient_->SetNotifyCb(std::bind(&AVCodecClient::AVCodecServerDied, std::placeholders::_1));
196     bool result = object->AddDeathRecipient(deathRecipient_);
197     CHECK_AND_RETURN_RET_LOG(result, nullptr, "Failed to add deathRecipient");
198 
199     listenerStub_ = new (std::nothrow) AVCodecListenerStub();
200     CHECK_AND_RETURN_RET_LOG(listenerStub_ != nullptr, nullptr, "Failed to create AVCodecListenerStub");
201     return avCodecProxy_;
202 }
203 
GetTemporaryAVCodecProxy()204 sptr<IStandardAVCodecService> AVCodecClient::GetTemporaryAVCodecProxy()
205 {
206     AVCODEC_LOGD("In");
207     sptr<ISystemAbilityManager> samgr = nullptr;
208     CLIENT_COLLIE_LISTEN(samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(),
209                          "AVCodecClient GetTemporaryAVCodecProxy");
210     CHECK_AND_RETURN_RET_LOG(samgr != nullptr, nullptr, "system ability manager is nullptr.");
211 
212     sptr<IRemoteObject> object = nullptr;
213     CLIENT_COLLIE_LISTEN(object = samgr->CheckSystemAbility(OHOS::AV_CODEC_SERVICE_ID),
214                          "AVCodec object is nullptr, maybe avcodec service does not exist");
215 
216     sptr<IStandardAVCodecService> avCodecProxy = iface_cast<IStandardAVCodecService>(object);
217     CHECK_AND_RETURN_RET_LOG(avCodecProxy != nullptr, nullptr, "AVCodec proxy is nullptr");
218 
219     return avCodecProxy;
220 }
221 
AVCodecServerDied(pid_t pid)222 void AVCodecClient::AVCodecServerDied(pid_t pid)
223 {
224     std::lock_guard<std::mutex> lock(g_avCodecClientMutex);
225     CHECK_AND_RETURN_LOG(!g_isDestructed, "AVCodecClient is destructed");
226 
227     AVCODEC_LOGE("AVCodec service is died, pid:%{public}d!", pid);
228     g_avCodecClientInstance.DoAVCodecServerDied();
229     FaultEventWrite(FaultType::FAULT_TYPE_CRASH, "AVCodec service is died", "AVCodecClient");
230 }
231 
DoAVCodecServerDied()232 void AVCodecClient::DoAVCodecServerDied()
233 {
234     std::lock_guard<std::mutex> lock(mutex_);
235     if (avCodecProxy_ != nullptr) {
236         (void)avCodecProxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
237         avCodecProxy_ = nullptr;
238     }
239     listenerStub_ = nullptr;
240     deathRecipient_ = nullptr;
241 
242 #ifdef SUPPORT_CODEC
243     for (auto &it : codecClientList_) {
244         auto codecClient = std::static_pointer_cast<CodecClient>(it);
245         if (codecClient != nullptr) {
246             codecClient->AVCodecServerDied();
247         }
248     }
249 #endif
250 #ifdef SUPPORT_CODECLIST
251     for (auto &it : codecListClientList_) {
252         auto codecListClient = std::static_pointer_cast<CodecListClient>(it);
253         if (codecListClient != nullptr) {
254             codecListClient->AVCodecServerDied();
255         }
256     }
257 #endif
258 }
259 } // namespace MediaAVCodec
260 } // namespace OHOS
261