1 /*
2 * Copyright (c) 2021-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 <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
25 #include "iservmgr_hdi.h"
26
27 #define HDF_LOG_TAG hdi_servmgr_client
28
29 namespace OHOS {
30 namespace HDI {
31 namespace ServiceManager {
32 namespace V1_0 {
33 constexpr int DEVICE_SERVICE_MANAGER_SA_ID = 5100;
34 constexpr int DEVSVC_MANAGER_GET_SERVICE = 3;
35 constexpr int DEVSVC_MANAGER_REGISTER_SVCLISTENER = 4;
36 constexpr int DEVSVC_MANAGER_UNREGISTER_SVCLISTENER = 5;
37 constexpr int DEVSVC_MANAGER_LIST_ALL_SERVICE = 6;
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
50 private:
51 static inline BrokerDelegator<ServiceManagerProxy> delegator_;
52 };
53
Get()54 sptr<IServiceManager> IServiceManager::Get()
55 {
56 auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
57 if (saManager == nullptr) {
58 HDF_LOGE("failed to get sa manager");
59 return nullptr;
60 }
61
62 std::unique_lock<std::mutex> lock(g_remoteMutex);
63 sptr<IRemoteObject> remote = saManager->GetSystemAbility(DEVICE_SERVICE_MANAGER_SA_ID);
64 if (remote != nullptr) {
65 return new ServiceManagerProxy(remote);
66 }
67
68 HDF_LOGE("failed to get sa hdf service manager");
69 return nullptr;
70 }
71
RegisterServiceStatusListener(::OHOS::sptr<IServStatListener> listener,uint16_t deviceClass)72 int32_t ServiceManagerProxy::RegisterServiceStatusListener(
73 ::OHOS::sptr<IServStatListener> listener, uint16_t deviceClass)
74 {
75 MessageParcel data;
76 MessageParcel reply;
77 MessageOption option;
78
79 if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteUint16(deviceClass) ||
80 !data.WriteRemoteObject(listener->AsObject())) {
81 return HDF_FAILURE;
82 }
83
84 std::unique_lock<std::mutex> lock(g_remoteMutex);
85 int status = Remote()->SendRequest(DEVSVC_MANAGER_REGISTER_SVCLISTENER, data, reply, option);
86 lock.unlock();
87 if (status) {
88 HDF_LOGE("failed to register servstat listener, %{public}d", status);
89 }
90 return status;
91 }
92
UnregisterServiceStatusListener(::OHOS::sptr<IServStatListener> listener)93 int32_t ServiceManagerProxy::UnregisterServiceStatusListener(::OHOS::sptr<IServStatListener> listener)
94 {
95 MessageParcel data;
96 MessageParcel reply;
97 MessageOption option;
98
99 if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteRemoteObject(listener->AsObject())) {
100 return HDF_FAILURE;
101 }
102
103 std::unique_lock<std::mutex> lock(g_remoteMutex);
104 int status = Remote()->SendRequest(DEVSVC_MANAGER_UNREGISTER_SVCLISTENER, data, reply, option);
105 lock.unlock();
106 if (status) {
107 HDF_LOGE("failed to unregister servstat listener, %{public}d", status);
108 }
109 return status;
110 }
111
GetService(const char * serviceName)112 sptr<IRemoteObject> ServiceManagerProxy::GetService(const char *serviceName)
113 {
114 MessageParcel data;
115 MessageParcel reply;
116 if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteCString(serviceName)) {
117 return nullptr;
118 }
119
120 MessageOption option;
121 std::unique_lock<std::mutex> lock(g_remoteMutex);
122 int status = Remote()->SendRequest(DEVSVC_MANAGER_GET_SERVICE, data, reply, option);
123 lock.unlock();
124 if (status) {
125 HDF_LOGE("get hdi service %{public}s failed, %{public}d", serviceName, status);
126 return nullptr;
127 }
128 HDF_LOGD("get hdi service %{public}s success ", serviceName);
129 return reply.ReadRemoteObject();
130 }
131
HdfDevMgrDbgFillServiceInfo(std::vector<HdiServiceInfo> & serviceInfos,MessageParcel & reply)132 static void HdfDevMgrDbgFillServiceInfo(std::vector<HdiServiceInfo> &serviceInfos, MessageParcel &reply)
133 {
134 while (true) {
135 HdiServiceInfo info;
136 const char *servName = reply.ReadCString();
137 if (servName == nullptr) {
138 break;
139 }
140 info.serviceName = servName;
141 info.devClass = reply.ReadUint16();
142 info.devId = reply.ReadUint32();
143 serviceInfos.push_back(info);
144 }
145 return;
146 }
147
ListAllService(std::vector<HdiServiceInfo> & serviceInfos)148 int32_t ServiceManagerProxy::ListAllService(std::vector<HdiServiceInfo> &serviceInfos)
149 {
150 MessageParcel data;
151 MessageParcel reply;
152 if (!data.WriteInterfaceToken(GetDescriptor())) {
153 return HDF_FAILURE;
154 }
155
156 MessageOption option;
157 std::unique_lock<std::mutex> lock(g_remoteMutex);
158 int status = Remote()->SendRequest(DEVSVC_MANAGER_LIST_ALL_SERVICE, data, reply, option);
159 lock.unlock();
160 if (status != HDF_SUCCESS) {
161 HDF_LOGE("list all service info failed, %{public}d", status);
162 return status;
163 } else {
164 HdfDevMgrDbgFillServiceInfo(serviceInfos, reply);
165 }
166 HDF_LOGD("get all service info success");
167 return status;
168 }
169 } // namespace V1_0
170 } // namespace ServiceManager
171 } // namespace HDI
172 } // namespace OHOS