1 /*
2  * Copyright (c) 2024 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 "hardware/imagecodec/image_codec_list.h"
17 #include "hardware/imagecodec/image_codec_log.h"
18 #include "iremote_object.h"
19 #include "iproxy_broker.h"
20 #include "syspara/parameters.h" // base/startup/init/interfaces/innerkits/include/
21 
22 namespace OHOS::ImagePlugin {
23 using namespace std;
24 using namespace HdiCodecNamespace;
25 
26 static mutex g_heifCodecMtx;
27 static sptr<ICodecComponentManager> g_compMgrForHeif;
28 
29 class CodecHeifDeathRecipient : public IRemoteObject::DeathRecipient {
30 public:
OnRemoteDied(const wptr<IRemoteObject> & object)31     void OnRemoteDied(const wptr<IRemoteObject> &object) override
32     {
33         LOGW("codec_component_manager_service died");
34         std::lock_guard<std::mutex> lk(g_heifCodecMtx);
35         g_compMgrForHeif = nullptr;
36     }
37 };
38 
IsPassthrough()39 static bool IsPassthrough()
40 {
41     static bool usePassthrough = OHOS::system::GetBoolParameter("image.codec.usePassthrough", false);
42     LOGI("%{public}s mode", usePassthrough ? "passthrough" : "ipc");
43     return usePassthrough;
44 }
45 
GetManager()46 sptr<ICodecComponentManager> GetManager()
47 {
48     lock_guard<mutex> lk(g_heifCodecMtx);
49     if (g_compMgrForHeif) {
50         return g_compMgrForHeif;
51     }
52     LOGI("need to get ICodecComponentManager");
53     bool isPassthrough = IsPassthrough();
54     g_compMgrForHeif = ICodecComponentManager::Get(isPassthrough);
55     if (g_compMgrForHeif == nullptr || isPassthrough) {
56         return g_compMgrForHeif;
57     }
58     bool isDeathRecipientAdded = false;
59     const sptr<OHOS::IRemoteObject> &remote = OHOS::HDI::hdi_objcast<ICodecComponentManager>(g_compMgrForHeif);
60     if (remote) {
61         sptr<CodecHeifDeathRecipient> deathCallBack(new CodecHeifDeathRecipient());
62         isDeathRecipientAdded = remote->AddDeathRecipient(deathCallBack);
63     }
64     if (!isDeathRecipientAdded) {
65         LOGE("failed to add deathRecipient for ICodecComponentManager!");
66     }
67     return g_compMgrForHeif;
68 }
69 
GetCapList()70 vector<CodecCompCapability> GetCapList()
71 {
72     sptr<ICodecComponentManager> mnger = GetManager();
73     if (mnger == nullptr) {
74         LOGE("failed to create codec component manager");
75         return {};
76     }
77     int32_t compCnt = 0;
78     int32_t ret = mnger->GetComponentNum(compCnt);
79     if (ret != HDF_SUCCESS || compCnt <= 0) {
80         LOGE("failed to query component number, ret=%{public}d", ret);
81         return {};
82     }
83     std::vector<CodecCompCapability> capList(compCnt);
84     ret = mnger->GetComponentCapabilityList(capList, compCnt);
85     if (ret != HDF_SUCCESS) {
86         LOGE("failed to query component capability list, ret=%{public}d", ret);
87         return {};
88     }
89     if (capList.empty()) {
90         LOGE("GetComponentCapabilityList return empty");
91     } else {
92         LOGD("GetComponentCapabilityList return %{public}zu components", capList.size());
93     }
94     return capList;
95 }
96 } // namespace OHOS::ImagePlugin