1 /*
2 * Copyright (c) 2021 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 "iservice_registry.h"
17
18 #include <unistd.h>
19
20 #include "errors.h"
21 #include "hilog/log.h"
22 #include "ipc_skeleton.h"
23 #include "ipc_types.h"
24 #include "iremote_broker.h"
25 #include "iremote_object.h"
26 #include "iremote_proxy.h"
27 #include "message_option.h"
28 #include "message_parcel.h"
29 #include "refbase.h"
30 #include "sam_log.h"
31 #include "string_ex.h"
32
33 namespace OHOS {
34 using namespace OHOS::HiviewDFX;
35
36 namespace {
37 constexpr int32_t MASK = 0x100;
38 constexpr int32_t INTERFACE_TOKEN = 0;
39 constexpr int64_t SLEEP_TIME = 1;
40 constexpr int32_t RETRY_TIMES = 10;
41 }
42
43 class ServiceRegistryProxy : public IRemoteProxy <IServiceRegistry> {
44 public:
ServiceRegistryProxy(const sptr<IRemoteObject> & object)45 explicit ServiceRegistryProxy(const sptr<IRemoteObject>& object)
46 : IRemoteProxy<IServiceRegistry>(object)
47 {
48 }
49
50 ~ServiceRegistryProxy() = default;
51
GetService(const std::u16string & name)52 virtual sptr<IRemoteObject> GetService(const std::u16string& name)
53 {
54 sptr<IRemoteObject> service = CheckService(name);
55 if (service != nullptr) {
56 return service;
57 }
58 int32_t retry = RETRY_TIMES;
59 HILOGI("Waiting for service %{public}s...", Str16ToStr8(name).data());
60 while (retry--) {
61 // Sleep and wait for 1 second;
62 sleep(SLEEP_TIME);
63 service = CheckService(name);
64 if (service != nullptr) {
65 HILOGI("%{public}s:found service %{public}s", __func__, Str16ToStr8(name).data());
66 return service;
67 }
68 }
69 HILOGE("Service %{public}s didn't start. Returning nullptr", Str16ToStr8(name).data());
70 return nullptr;
71 }
72
CheckService(const std::u16string & name)73 virtual sptr<IRemoteObject> CheckService(const std::u16string& name)
74 {
75 HILOGI("%{public}s called", __func__);
76 MessageParcel data;
77 if (!data.WriteInt32(MASK)) {
78 HILOGE("%{public}s write MASK failed!", __func__);
79 return nullptr;
80 }
81 if (!data.WriteInt32(INTERFACE_TOKEN)) {
82 HILOGE("%{public}s write INTERFACE_TOKEN failed!", __func__);
83 return nullptr;
84 }
85 if (!data.WriteString16(IServiceRegistry::GetDescriptor())) {
86 HILOGE("%{public}s write Descriptor failed!", __func__);
87 return nullptr;
88 }
89 if (!data.WriteString16(name.data())) {
90 HILOGE("%{public}s write name failed!", __func__);
91 return nullptr;
92 }
93 sptr<IRemoteObject> remote = Remote();
94 if (remote == nullptr) {
95 HILOGE("ServiceRegistryProxy::CheckService remote is nullptr !");
96 return nullptr;
97 }
98 MessageOption option;
99 MessageParcel reply;
100 int32_t err = remote->SendRequest(CHECK_SERVICE_TRANSACTION, data, reply, option);
101 HILOGI("%{public}s available parcel size:%zd", __func__, reply.GetReadableBytes());
102 return (err == ERR_NONE) ? reply.ReadRemoteObject() : nullptr;
103 }
104
AddService(const std::u16string & name,const sptr<IRemoteObject> & service,bool allowIsolated,int32_t dumpsysPriority)105 virtual int32_t AddService(const std::u16string& name,
106 const sptr<IRemoteObject>& service, bool allowIsolated, int32_t dumpsysPriority)
107 {
108 HILOGD("%{public}s called", __func__);
109 MessageParcel data;
110 if (!data.WriteInt32(MASK)) {
111 HILOGE("%{public}s write MASK failed!", __func__);
112 return ERR_FLATTEN_OBJECT;
113 }
114 if (!data.WriteInt32(INTERFACE_TOKEN)) {
115 HILOGE("%{public}s write INTERFACE_TOKEN failed!", __func__);
116 return ERR_FLATTEN_OBJECT;
117 }
118 if (!data.WriteString16(IServiceRegistry::GetDescriptor())) {
119 HILOGE("%{public}s write Descriptor failed!", __func__);
120 return ERR_FLATTEN_OBJECT;
121 }
122 if (!data.WriteString16(name.data())) {
123 HILOGE("%{public}s write name failed!", __func__);
124 return ERR_FLATTEN_OBJECT;
125 }
126 if (!data.WriteRemoteObject(service)) {
127 HILOGE("%{public}s write RemoteObject failed!", __func__);
128 return ERR_FLATTEN_OBJECT;
129 }
130 if (!data.WriteInt32((allowIsolated ? 1 : 0))) {
131 HILOGE("%{public}s write allowIsolated failed!", __func__);
132 return ERR_FLATTEN_OBJECT;
133 }
134 if (!data.WriteInt32(dumpsysPriority)) {
135 HILOGE("%{public}s write dumpsysPriority failed!", __func__);
136 return ERR_FLATTEN_OBJECT;
137 }
138 sptr<IRemoteObject> remote = Remote();
139 if (remote == nullptr) {
140 HILOGE("ServiceRegistryProxy::AddService remote is nullptr !");
141 return ERR_INVALID_OPERATION;
142 }
143 MessageOption option;
144 MessageParcel reply;
145 int32_t err = remote->SendRequest(ADD_SERVICE_TRANSACTION, data, reply, option);
146
147 HILOGI("%{public}s:add service %{public}s %{public}s, return %d",
148 __func__, Str16ToStr8(name).data(), err ? "fail" : "succ", err);
149
150 return err;
151 }
152 private:
153 static constexpr HiLogLabel LABEL = { LOG_CORE, 0xD001800, "ServiceRegistry" };
154 };
155
156 std::mutex ServiceRegistry::serviceRegistryLock_;
157 static inline BrokerDelegator<ServiceRegistryProxy> delegator_;
158
GetInstance()159 sptr<IServiceRegistry> ServiceRegistry::GetInstance()
160 {
161 static sptr<IServiceRegistry> registryInstance;
162 std::lock_guard<std::mutex> lock(serviceRegistryLock_);
163 if (registryInstance == nullptr) {
164 sptr<IRemoteObject> registryObject = IPCSkeleton::GetContextObject();
165 if (registryObject == nullptr) {
166 return nullptr;
167 }
168 registryInstance = iface_cast<IServiceRegistry>(registryObject);
169 }
170 return registryInstance;
171 }
172
GetInstance()173 SystemAbilityManagerClient& SystemAbilityManagerClient::GetInstance()
174 {
175 static auto instance = new SystemAbilityManagerClient();
176 return *instance;
177 }
178
GetSystemAbilityManager()179 sptr<ISystemAbilityManager> SystemAbilityManagerClient::GetSystemAbilityManager()
180 {
181 std::lock_guard<std::mutex> lock(systemAbilityManagerLock_);
182 if (systemAbilityManager_ != nullptr) {
183 return systemAbilityManager_;
184 }
185 sptr<IRemoteObject> registryObject = IPCSkeleton::GetContextObject();
186 if (registryObject == nullptr) {
187 KHILOGD("samgrClient regObject=null,callPid:%{public}d", IPCSkeleton::GetCallingPid());
188 return nullptr;
189 }
190 systemAbilityManager_ = iface_cast<ISystemAbilityManager>(registryObject);
191 if (systemAbilityManager_ == nullptr) {
192 KHILOGD("samgrClient is null,callPid:%{public}d", IPCSkeleton::GetCallingPid());
193 }
194 return systemAbilityManager_;
195 }
196
DestroySystemAbilityManagerObject()197 void SystemAbilityManagerClient::DestroySystemAbilityManagerObject()
198 {
199 HILOGD("%{public}s called", __func__);
200 std::lock_guard<std::mutex> lock(systemAbilityManagerLock_);
201 systemAbilityManager_.clear();
202 }
203 } // namespace OHOS
204