• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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