• 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 
91 #ifdef SUPPORT_CODEC
CreateCodecService(std::shared_ptr<ICodecService> & codecClient)92 int32_t AVCodecClient::CreateCodecService(std::shared_ptr<ICodecService> &codecClient)
93 {
94     std::lock_guard<std::mutex> lock(mutex_);
95 
96     sptr<IRemoteObject> object = nullptr;
97     int32_t ret = CreateInstanceAndTryInTimes(IStandardAVCodecService::AVCodecSystemAbility::AVCODEC_CODEC, object);
98     CHECK_AND_RETURN_RET_LOG(object != nullptr, ret, "Create codec proxy object failed.");
99 
100     sptr<IStandardCodecService> codecProxy = iface_cast<IStandardCodecService>(object);
101     CHECK_AND_RETURN_RET_LOG(codecProxy != nullptr, AVCS_ERR_UNSUPPORT, "Codec proxy is nullptr.");
102 
103     ret = CodecClient::Create(codecProxy, codecClient);
104     CHECK_AND_RETURN_RET_LOG(codecClient != nullptr, ret, "Failed to create codec client.");
105 
106     codecClientList_.push_back(codecClient);
107     return AVCS_ERR_OK;
108 }
109 
DestroyCodecService(std::shared_ptr<ICodecService> codecClient)110 int32_t AVCodecClient::DestroyCodecService(std::shared_ptr<ICodecService> codecClient)
111 {
112     std::lock_guard<std::mutex> lock(mutex_);
113     CHECK_AND_RETURN_RET_LOG(codecClient != nullptr, AVCS_ERR_NO_MEMORY, "codec client is nullptr.");
114     codecClientList_.remove(codecClient);
115     return AVCS_ERR_OK;
116 }
117 #endif
118 #ifdef SUPPORT_CODECLIST
CreateCodecListService()119 std::shared_ptr<ICodecListService> AVCodecClient::CreateCodecListService()
120 {
121     std::lock_guard<std::mutex> lock(mutex_);
122 
123     sptr<IRemoteObject> object = nullptr;
124     (void)CreateInstanceAndTryInTimes(IStandardAVCodecService::AVCodecSystemAbility::AVCODEC_CODECLIST, object);
125     CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "Create codeclist proxy object failed.");
126 
127     sptr<IStandardCodecListService> codecListProxy = iface_cast<IStandardCodecListService>(object);
128     CHECK_AND_RETURN_RET_LOG(codecListProxy != nullptr, nullptr, "codeclist proxy is nullptr.");
129 
130     std::shared_ptr<CodecListClient> codecListClient = CodecListClient::Create(codecListProxy);
131     CHECK_AND_RETURN_RET_LOG(codecListClient != nullptr, nullptr, "failed to create codeclist client.");
132 
133     codecListClientList_.push_back(codecListClient);
134     return codecListClient;
135 }
136 
DestroyCodecListService(std::shared_ptr<ICodecListService> codecListClient)137 int32_t AVCodecClient::DestroyCodecListService(std::shared_ptr<ICodecListService> codecListClient)
138 {
139     std::lock_guard<std::mutex> lock(mutex_);
140     CHECK_AND_RETURN_RET_LOG(codecListClient != nullptr, AVCS_ERR_NO_MEMORY, "codeclist client is nullptr.");
141     codecListClientList_.remove(codecListClient);
142     return AVCS_ERR_OK;
143 }
144 #endif
145 
GetAVCodecProxy()146 sptr<IStandardAVCodecService> AVCodecClient::GetAVCodecProxy()
147 {
148     AVCODEC_LOGI("In");
149     sptr<ISystemAbilityManager> samgr = nullptr;
150     CLIENT_COLLIE_LISTEN(samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(),
151         "AVCodecClient GetAVCodecProxy");
152     CHECK_AND_RETURN_RET_LOG(samgr != nullptr, nullptr, "system ability manager is nullptr.");
153 
154     sptr<IRemoteObject> object = nullptr;
155     CLIENT_COLLIE_LISTEN(object = samgr->CheckSystemAbility(OHOS::AV_CODEC_SERVICE_ID),
156                          "AVCodecClient GetAVCodecProxy");
157     if (object == nullptr) {
158         CLIENT_COLLIE_LISTEN(object = samgr->LoadSystemAbility(OHOS::AV_CODEC_SERVICE_ID, 30), // 30: timeout
159                              "AVCodecClient LoadSystemAbility");
160         CHECK_AND_RETURN_RET_LOG(object != nullptr,
161             nullptr, "AVCodec object is nullptr, maybe avcodec service does not exist");
162     }
163 
164     avCodecProxy_ = iface_cast<IStandardAVCodecService>(object);
165     CHECK_AND_RETURN_RET_LOG(avCodecProxy_ != nullptr, nullptr, "AVCodec proxy is nullptr");
166 
167     pid_t pid = 0;
168     deathRecipient_ = new (std::nothrow) AVCodecDeathRecipient(pid);
169     CHECK_AND_RETURN_RET_LOG(deathRecipient_ != nullptr, nullptr, "Failed to create AVCodecDeathRecipient");
170 
171     deathRecipient_->SetNotifyCb(std::bind(&AVCodecClient::AVCodecServerDied, std::placeholders::_1));
172     bool result = object->AddDeathRecipient(deathRecipient_);
173     CHECK_AND_RETURN_RET_LOG(result, nullptr, "Failed to add deathRecipient");
174 
175     listenerStub_ = new (std::nothrow) AVCodecListenerStub();
176     CHECK_AND_RETURN_RET_LOG(listenerStub_ != nullptr, nullptr, "Failed to create AVCodecListenerStub");
177     return avCodecProxy_;
178 }
179 
AVCodecServerDied(pid_t pid)180 void AVCodecClient::AVCodecServerDied(pid_t pid)
181 {
182     std::lock_guard<std::mutex> lock(g_avCodecClientMutex);
183     CHECK_AND_RETURN_LOG(!g_isDestructed, "AVCodecClient is destructed");
184 
185     AVCODEC_LOGE("AVCodec service is died, pid:%{public}d!", pid);
186     g_avCodecClientInstance.DoAVCodecServerDied();
187     FaultEventWrite(FaultType::FAULT_TYPE_CRASH, "AVCodec service is died", "AVCodecClient");
188 }
189 
DoAVCodecServerDied()190 void AVCodecClient::DoAVCodecServerDied()
191 {
192     std::lock_guard<std::mutex> lock(mutex_);
193     if (avCodecProxy_ != nullptr) {
194         (void)avCodecProxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
195         avCodecProxy_ = nullptr;
196     }
197     listenerStub_ = nullptr;
198     deathRecipient_ = nullptr;
199 
200 #ifdef SUPPORT_CODEC
201     for (auto &it : codecClientList_) {
202         auto codecClient = std::static_pointer_cast<CodecClient>(it);
203         if (codecClient != nullptr) {
204             codecClient->AVCodecServerDied();
205         }
206     }
207 #endif
208 #ifdef SUPPORT_CODECLIST
209     for (auto &it : codecListClientList_) {
210         auto codecListClient = std::static_pointer_cast<CodecListClient>(it);
211         if (codecListClient != nullptr) {
212             codecListClient->AVCodecServerDied();
213         }
214     }
215 #endif
216 }
217 } // namespace MediaAVCodec
218 } // namespace OHOS
219