1 /*
2  * Copyright (c) 2021-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 <mutex>
17 
18 #include <hdf_base.h>
19 #include <hdf_log.h>
20 #include <iproxy_broker.h>
21 #include <iremote_stub.h>
22 #include <iservice_registry.h>
23 #include <object_collector.h>
24 #include <string_ex.h>
25 
26 #include "hdf_device_manager_interface_code.h"
27 #include "iservmgr_hdi.h"
28 
29 #define HDF_LOG_TAG hdi_servmgr_client
30 
31 using OHOS::HDI::HdfDeviceManager::HdfDeviceManagerInterfaceCode;
32 
33 namespace OHOS {
34 namespace HDI {
35 namespace ServiceManager {
36 namespace V1_0 {
37 constexpr int DEVICE_SERVICE_MANAGER_SA_ID = 5100;
38 std::mutex g_remoteMutex;
39 
40 class ServiceManagerProxy : public IProxyBroker<IServiceManager> {
41 public:
ServiceManagerProxy(const sptr<IRemoteObject> & impl)42     explicit ServiceManagerProxy(const sptr<IRemoteObject> &impl) : IProxyBroker<IServiceManager>(impl) {}
~ServiceManagerProxy()43     ~ServiceManagerProxy() {}
44 
45     sptr<IRemoteObject> GetService(const char *serviceName) override;
46     int32_t ListAllService(std::vector<HdiServiceInfo> &serviceInfos) override;
47     int32_t RegisterServiceStatusListener(sptr<IServStatListener> listener, uint16_t deviceClass) override;
48     int32_t UnregisterServiceStatusListener(sptr<IServStatListener> listener) override;
49     int32_t ListServiceByInterfaceDesc(std::vector<std::string> &serviceNames, const char *interfaceDesc) override;
50 
51 private:
52     static inline BrokerDelegator<ServiceManagerProxy> delegator_;
53 };
54 
Get()55 sptr<IServiceManager> IServiceManager::Get()
56 {
57     auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
58     if (saManager == nullptr) {
59         HDF_LOGE("failed to get sa manager");
60         return nullptr;
61     }
62 
63     std::unique_lock<std::mutex> lock(g_remoteMutex);
64     sptr<IRemoteObject> remote = saManager->GetSystemAbility(DEVICE_SERVICE_MANAGER_SA_ID);
65     if (remote != nullptr) {
66         return new ServiceManagerProxy(remote);
67     }
68 
69     HDF_LOGE("failed to get sa hdf service manager");
70     return nullptr;
71 }
72 
RegisterServiceStatusListener(::OHOS::sptr<IServStatListener> listener,uint16_t deviceClass)73 int32_t ServiceManagerProxy::RegisterServiceStatusListener(
74     ::OHOS::sptr<IServStatListener> listener, uint16_t deviceClass)
75 {
76     MessageParcel data;
77     MessageParcel reply;
78     MessageOption option;
79 
80     if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteUint16(deviceClass) ||
81         !data.WriteRemoteObject(listener->AsObject())) {
82         return HDF_FAILURE;
83     }
84 
85     std::unique_lock<std::mutex> lock(g_remoteMutex);
86     if (Remote() == nullptr) {
87         HDF_LOGE("invalid param Remote()");
88         return HDF_ERR_INVALID_PARAM;
89     }
90     int status = Remote()->SendRequest(
91         static_cast<uint32_t>(HdfDeviceManagerInterfaceCode::DEVSVC_MANAGER_REGISTER_SVCLISTENER), data, reply, option);
92     lock.unlock();
93     if (status) {
94         HDF_LOGE("failed to register servstat listener, %{public}d", status);
95     }
96     return status;
97 }
98 
UnregisterServiceStatusListener(::OHOS::sptr<IServStatListener> listener)99 int32_t ServiceManagerProxy::UnregisterServiceStatusListener(::OHOS::sptr<IServStatListener> listener)
100 {
101     MessageParcel data;
102     MessageParcel reply;
103     MessageOption option;
104 
105     if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteRemoteObject(listener->AsObject())) {
106         return HDF_FAILURE;
107     }
108 
109     std::unique_lock<std::mutex> lock(g_remoteMutex);
110     if (Remote() == nullptr) {
111         HDF_LOGE("invalid param Remote()");
112         return HDF_ERR_INVALID_PARAM;
113     }
114     int status = Remote()->SendRequest(
115         static_cast<uint32_t>(HdfDeviceManagerInterfaceCode::DEVSVC_MANAGER_UNREGISTER_SVCLISTENER), data, reply,
116         option);
117     lock.unlock();
118     if (status) {
119         HDF_LOGE("failed to unregister servstat listener, %{public}d", status);
120     }
121     return status;
122 }
123 
GetService(const char * serviceName)124 sptr<IRemoteObject> ServiceManagerProxy::GetService(const char *serviceName)
125 {
126     MessageParcel data;
127     MessageParcel reply;
128     if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteCString(serviceName)) {
129         return nullptr;
130     }
131 
132     MessageOption option;
133     std::unique_lock<std::mutex> lock(g_remoteMutex);
134     if (Remote() == nullptr) {
135         HDF_LOGE("invalid param Remote()");
136         return nullptr;
137     }
138     int status = Remote()->SendRequest(
139         static_cast<uint32_t>(HdfDeviceManagerInterfaceCode::DEVSVC_MANAGER_GET_SERVICE), data, reply, option);
140     lock.unlock();
141     if (status) {
142         HDF_LOGE("get hdi service %{public}s failed, %{public}d", serviceName, status);
143         return nullptr;
144     }
145     HDF_LOGD("get hdi service %{public}s success ", serviceName);
146     return reply.ReadRemoteObject();
147 }
148 
HdfDevMgrDbgFillServiceInfo(std::vector<HdiServiceInfo> & serviceInfos,MessageParcel & reply)149 static void HdfDevMgrDbgFillServiceInfo(std::vector<HdiServiceInfo> &serviceInfos, MessageParcel &reply)
150 {
151     while (true) {
152         HdiServiceInfo info;
153         const char *servName = reply.ReadCString();
154         if (servName == nullptr) {
155             break;
156         }
157         info.serviceName = servName;
158         info.devClass = reply.ReadUint16();
159         info.devId = reply.ReadUint32();
160         serviceInfos.push_back(info);
161     }
162     return;
163 }
164 
ListAllService(std::vector<HdiServiceInfo> & serviceInfos)165 int32_t ServiceManagerProxy::ListAllService(std::vector<HdiServiceInfo> &serviceInfos)
166 {
167     MessageParcel data;
168     MessageParcel reply;
169     if (!data.WriteInterfaceToken(GetDescriptor())) {
170         return HDF_FAILURE;
171     }
172 
173     MessageOption option;
174     std::unique_lock<std::mutex> lock(g_remoteMutex);
175     if (Remote() == nullptr) {
176         HDF_LOGE("invalid param Remote()");
177         return HDF_ERR_INVALID_PARAM;
178     }
179     int status = Remote()->SendRequest(
180         static_cast<uint32_t>(HdfDeviceManagerInterfaceCode::DEVSVC_MANAGER_LIST_ALL_SERVICE), data, reply, option);
181     lock.unlock();
182     if (status != HDF_SUCCESS) {
183         HDF_LOGE("list all service info failed, %{public}d", status);
184         return status;
185     } else {
186         HdfDevMgrDbgFillServiceInfo(serviceInfos, reply);
187     }
188     HDF_LOGD("get all service info success");
189     return status;
190 }
191 
ListServiceByInterfaceDesc(std::vector<std::string> & serviceNames,const char * interfaceDesc)192 int32_t ServiceManagerProxy::ListServiceByInterfaceDesc(
193     std::vector<std::string> &serviceNames, const char *interfaceDesc)
194 {
195     MessageParcel data;
196     MessageParcel reply;
197     if (interfaceDesc == nullptr || strlen(interfaceDesc) == 0) {
198         HDF_LOGE("%{public}s: invalid parameter, interfaceDesc is null or empty", __func__);
199         return HDF_ERR_INVALID_PARAM;
200     }
201     if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteCString(interfaceDesc)) {
202         return HDF_FAILURE;
203     }
204 
205     MessageOption option;
206     std::unique_lock<std::mutex> lock(g_remoteMutex);
207     if (Remote() == nullptr) {
208         HDF_LOGE("invalid param Remote()");
209         return HDF_ERR_INVALID_PARAM;
210     }
211     int status = Remote()->SendRequest(
212         static_cast<uint32_t>(HdfDeviceManagerInterfaceCode::DEVSVC_MANAGER_LIST_SERVICE_BY_INTERFACEDESC), data, reply,
213         option);
214     lock.unlock();
215     if (status != HDF_SUCCESS) {
216         HDF_LOGE("get hdi service collection by %{public}s failed, %{public}d", interfaceDesc, status);
217         return status;
218     }
219 
220     uint32_t serviceNum = 0;
221     if (!reply.ReadUint32(serviceNum)) {
222         HDF_LOGE("failed to read number of service");
223         return HDF_ERR_INVALID_PARAM;
224     }
225 
226     if (serviceNum > serviceNames.max_size()) {
227         HDF_LOGE("invalid len of serviceNames");
228         return HDF_ERR_INVALID_PARAM;
229     }
230 
231     for (uint32_t i = 0; i < serviceNum; i++) {
232         if (reply.GetReadableBytes() == 0) {
233             HDF_LOGE("no enough data to read");
234             return HDF_ERR_INVALID_PARAM;
235         }
236 
237         const char *serviceName = reply.ReadCString();
238         if (serviceName == NULL) {
239             break;
240         }
241         serviceNames.push_back(serviceName);
242     }
243 
244     HDF_LOGD("get hdi service collection by %{public}s successfully", interfaceDesc);
245     return status;
246 }
247 } // namespace V1_0
248 } // namespace ServiceManager
249 } // namespace HDI
250 } // namespace OHOS