1 /*
2 * Copyright (c) 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 "page_url_checker_ohos.h"
17 #include <string>
18
19 #include "ability_runtime/context/context.h"
20 #include "atomic_service_status_callback.h"
21 #include "errors.h"
22 #include "iremote_broker.h"
23 #include "iremote_object.h"
24 #include "iremote_stub.h"
25 #include "iservice_registry.h"
26 #include "nocopyable.h"
27 #include "system_ability_definition.h"
28 #include "want.h"
29
30 namespace OHOS::Ace {
31 constexpr int32_t SUB_STR_LENGTH = 7;
32 constexpr size_t BUNDLE_START_POS = 8;
33 constexpr int32_t SILENT_INSTALL_SUCCESS = 0;
34
35 /**
36 * @class IAtomicServiceStatusCallback
37 * IAtomicServiceStatusCallback is used to notify caller ability that free install is complete.
38 */
39 class IAtomicServiceStatusCallback : public IRemoteBroker {
40 public:
41 DECLARE_INTERFACE_DESCRIPTOR(u"ohos.IAtomicServiceStatusCallback");
42
43 /**
44 * @brief OnActionEvent.
45 */
46 virtual int32_t OnActionEvent() = 0;
47 /**
48 * @brief OnError.
49 * @param code The code.
50 * @param msg The msg.
51 */
52 virtual int32_t OnError(int32_t code, const std::string& msg) = 0;
53 };
54
55 /**
56 * @class AtomicServiceStatusCallbackStub
57 * AtomicServiceStatusCallbackStub.
58 */
59 class AtomicServiceStatusCallbackStub : public IRemoteStub<IAtomicServiceStatusCallback> {
60 public:
AtomicServiceStatusCallbackStub()61 AtomicServiceStatusCallbackStub()
62 {
63 handleOnActionEventFunc_ = &AtomicServiceStatusCallbackStub::HandleOnActionEvent;
64 handleOnErrorFunc_ = &AtomicServiceStatusCallbackStub::HandleOnError;
65 }
~AtomicServiceStatusCallbackStub()66 ~AtomicServiceStatusCallbackStub() override
67 {
68 handleOnActionEventFunc_ = nullptr;
69 handleOnErrorFunc_ = nullptr;
70 }
71
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)72 int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override
73 {
74 LOGI("AtomicServiceStatusCallbackStub::OnReceived, code = %{public}u, flags= %{public}d.",
75 code, option.GetFlags());
76 std::u16string descriptor = AtomicServiceStatusCallbackStub::GetDescriptor();
77 std::u16string remoteDescriptor = data.ReadInterfaceToken();
78 if (descriptor != remoteDescriptor) {
79 LOGE("%{public}s failed, local descriptor is not equal to remote", __func__);
80 return ERR_INVALID_VALUE;
81 }
82
83 auto resultCode = data.ReadInt32();
84 if (resultCode == SILENT_INSTALL_SUCCESS) {
85 if (handleOnActionEventFunc_ != nullptr) {
86 return (this->*handleOnActionEventFunc_)();
87 }
88 }
89
90 if (resultCode < SILENT_INSTALL_SUCCESS) {
91 if (handleOnErrorFunc_ != nullptr) {
92 return (this->*handleOnErrorFunc_)(data);
93 }
94 }
95
96 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
97 }
98
99 private:
HandleOnActionEvent()100 int32_t HandleOnActionEvent()
101 {
102 return OnActionEvent();
103 }
HandleOnError(MessageParcel & data)104 int32_t HandleOnError(MessageParcel &data)
105 {
106 int32_t code = data.ReadInt32();
107 std::string msg = data.ReadString();
108 return OnError(code, msg);
109 }
110
111 using HandleOnActionEventFunc = int32_t (AtomicServiceStatusCallbackStub::*)();
112 HandleOnActionEventFunc handleOnActionEventFunc_;
113
114 using HandleOnErrorFunc = int32_t (AtomicServiceStatusCallbackStub::*)(MessageParcel &data);
115 HandleOnErrorFunc handleOnErrorFunc_;
116
117 DISALLOW_COPY_AND_MOVE(AtomicServiceStatusCallbackStub);
118 };
119
120 /**
121 * @class AtomicServiceStatusCallback
122 * AtomicServiceStatusCallback.
123 */
124 class AtomicServiceStatusCallback : public AtomicServiceStatusCallbackStub {
125 public:
126 AtomicServiceStatusCallback() = default;
127 ~AtomicServiceStatusCallback() override = default;
128
129 /**
130 * @brief OnActionEvent.
131 */
OnActionEvent()132 int32_t OnActionEvent() override
133 {
134 if (!actionEventHandler_) {
135 LOGE("actionEventHandler_ is null.");
136 return ERR_INVALID_VALUE;
137 }
138 actionEventHandler_();
139 return ERR_OK;
140 }
141 /**
142 * @brief OnError.
143 * @param code The code.
144 * @param msg The msg.
145 */
OnError(int32_t code,const std::string & msg)146 int32_t OnError(int32_t code, const std::string& msg) override
147 {
148 LOGE("OnError code: %{public}d, msg: %{public}s", code, msg.c_str());
149 if (!errorEventHandler_) {
150 LOGE("errorEventHandler_ is null");
151 return ERR_INVALID_VALUE;
152 }
153
154 errorEventHandler_(code, msg);
155 return ERR_OK;
156 }
157
SetActionEventHandler(const std::function<void ()> & listener)158 void SetActionEventHandler(const std::function<void()>& listener)
159 {
160 actionEventHandler_ = listener;
161 }
SetErrorEventHandler(const std::function<void (int32_t,const std::string &)> & listener)162 void SetErrorEventHandler(const std::function<void(int32_t, const std::string&)>& listener)
163 {
164 errorEventHandler_ = listener;
165 }
166
167 private:
168 std::function<void()> actionEventHandler_;
169 std::function<void(int32_t, const std::string&)> errorEventHandler_;
170 };
171
GetBundleManager()172 sptr<AppExecFwk::IBundleMgr> PageUrlCheckerOhos::GetBundleManager()
173 {
174 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
175 if (systemAbilityMgr == nullptr) {
176 LOGE("Failed to get SystemAbilityManager.");
177 return nullptr;
178 }
179
180 auto bundleObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
181 if (bundleObj == nullptr) {
182 LOGE("Failed to get bundle manager service");
183 return nullptr;
184 }
185
186 return iface_cast<AppExecFwk::IBundleMgr>(bundleObj);
187 }
188
LoadPageUrl(const std::string & url,const std::function<void ()> & callback,const std::function<void (int32_t,const std::string &)> & silentInstallErrorCallBack)189 void PageUrlCheckerOhos::LoadPageUrl(const std::string& url, const std::function<void()>& callback,
190 const std::function<void(int32_t, const std::string&)>& silentInstallErrorCallBack)
191 {
192 if (url.substr(0, SUB_STR_LENGTH) != "@bundle") {
193 return;
194 }
195
196 size_t bundleEndPos = url.find('/');
197 std::string bundleName = url.substr(BUNDLE_START_POS, bundleEndPos - BUNDLE_START_POS);
198 size_t moduleStartPos = bundleEndPos + 1;
199 size_t moduleEndPos = url.find('/', moduleStartPos);
200 std::string moduleName = url.substr(moduleStartPos, moduleEndPos - moduleStartPos);
201
202 auto appInfo = context_->GetApplicationInfo();
203 if (appInfo) {
204 std::vector<OHOS::AppExecFwk::ModuleInfo> moduleList = appInfo->moduleInfos;
205 bool isInstalled = false;
206 for (const auto& module : moduleList) {
207 if (module.moduleName == moduleName) {
208 isInstalled = true;
209 }
210 }
211
212 if (!isInstalled) {
213 auto bms = GetBundleManager();
214 CHECK_NULL_VOID(bms);
215 AAFwk::Want want;
216 want.SetBundle(bundleName);
217 want.SetModuleName(moduleName);
218 sptr<AtomicServiceStatusCallback> routerCallback = new AtomicServiceStatusCallback();
219 routerCallback->SetActionEventHandler(callback);
220 routerCallback->SetErrorEventHandler(silentInstallErrorCallBack);
221 if (bms->SilentInstall(want, appInfo->uid, routerCallback)) {
222 LOGI("Begin to silent install");
223 }
224 } else {
225 callback();
226 }
227 }
228 }
229 } // namespace OHOS::Ace