1 /*
2  * Copyright (c) 2022 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 "update_hdi_client.h"
17 
18 #include <cerrno>
19 #include <dlfcn.h>
20 
21 #include "log/log.h"
22 
23 namespace Updater {
24 constexpr const char *HDI_LIB_NAME = "libupdate_hdi_impl.z.so";
25 
GetInstance()26 UpdateHdiClient &UpdateHdiClient::GetInstance()
27 {
28     static UpdateHdiClient instance;
29     return instance;
30 }
31 
~UpdateHdiClient()32 UpdateHdiClient::~UpdateHdiClient()
33 {
34     CloseLibrary();
35 }
36 
GetLockStatus(bool & status)37 int32_t UpdateHdiClient::GetLockStatus(bool &status)
38 {
39     if (updateInterface_ == nullptr && !Init()) {
40         LOG(ERROR) << "updateInterface_ is null";
41         return -1;
42     }
43     return updateInterface_->GetLockStatus(status);
44 }
45 
Init()46 bool UpdateHdiClient::Init()
47 {
48     if (updateInterface_ != nullptr) {
49         LOG(INFO) << "updateInterface_ has loaded";
50         return true;
51     }
52     return LoadLibrary();
53 }
54 
LoadLibrary()55 bool UpdateHdiClient::LoadLibrary()
56 {
57     constexpr const char *getInstance = "GetInterfaceInstance";
58     if (updateInterface_ != nullptr) {
59         LOG(INFO) << "updateInterface_ has loaded";
60         return true;
61     }
62 
63     handler_ = dlopen(HDI_LIB_NAME, RTLD_LAZY);
64     if (handler_ == nullptr) {
65         LOG(ERROR) << "open " << HDI_LIB_NAME << " fail";
66         return false;
67     }
68 
69     auto getInterface = reinterpret_cast<IUpdateInterface *(*)()>(dlsym(handler_, getInstance));
70     if (getInterface == nullptr) {
71         LOG(ERROR) << "can not find " << getInstance;
72         CloseLibrary();
73         return false;
74     }
75 
76     updateInterface_ = getInterface();
77     if (updateInterface_ == nullptr) {
78         LOG(ERROR) << "updateInterface_ is null";
79         CloseLibrary();
80         return false;
81     }
82     LOG(INFO) << "load " << HDI_LIB_NAME << " success";
83     return true;
84 }
85 
CloseLibrary()86 void UpdateHdiClient::CloseLibrary()
87 {
88     if (handler_ == nullptr) {
89         LOG(INFO) << HDI_LIB_NAME << "is already closed";
90         return;
91     }
92     updateInterface_ = nullptr;
93     dlclose(handler_);
94     handler_ = nullptr;
95     LOG(INFO) << HDI_LIB_NAME << " is closed";
96 }
97 }
98