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