• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "app_fwk_update_client.h"
17 
18 #include <fcntl.h>
19 #include <string>
20 #include <sys/ioctl.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 
25 #include "app_fwk_update_load_callback.h"
26 #include "if_system_ability_manager.h"
27 #include "ipc_skeleton.h"
28 #include "iservice_registry.h"
29 #include "isystem_ability_load_callback.h"
30 #include "nweb_log.h"
31 #include "system_ability_definition.h"
32 
33 #include "base/web/webview/sa/app_fwk_update_service_proxy.h"
34 #include "base/web/webview/sa/iapp_fwk_update_service.h"
35 
36 namespace OHOS::NWeb {
37 namespace {
38 const int LOAD_SA_TIMEOUT_MS = 4 * 1000;
39 const int FOUNDATION_UID = 5523;
40 const std::set<std::string> ARK_WEB_DEFAULT_BUNDLE_NAME_SET = { "com.ohos.nweb", "com.ohos.arkwebcore" };
41 } // namespace
42 
AppFwkUpdateClient()43 AppFwkUpdateClient::AppFwkUpdateClient()
44 {
45     appFwkUpdateDiedRecipient_ = new (std::nothrow) AppFwkUpdateDiedRecipient();
46     if (appFwkUpdateDiedRecipient_ == nullptr) {
47         WVLOG_I("create fwk update service died recipient failed");
48     }
49 }
50 
GetInstance()51 AppFwkUpdateClient& AppFwkUpdateClient::GetInstance()
52 {
53     static AppFwkUpdateClient singleAppFwkUpdateClient;
54     return singleAppFwkUpdateClient;
55 }
SetFwkUpdate(const sptr<IRemoteObject> & remoteObject)56 void AppFwkUpdateClient::SetFwkUpdate(const sptr<IRemoteObject>& remoteObject)
57 {
58     std::lock_guard<std::mutex> lock(mutex_);
59     fwkUpdateProxy_ = iface_cast<IAppFwkUpdateService>(remoteObject);
60     if (fwkUpdateProxy_) {
61         WVLOG_I("SetFwkUpdate is not null");
62     }
63 }
64 
GetFwkUpdate()65 sptr<IAppFwkUpdateService> AppFwkUpdateClient::GetFwkUpdate()
66 {
67     std::lock_guard<std::mutex> lock(mutex_);
68     return fwkUpdateProxy_;
69 }
70 
GetFwkUpdateProxy()71 sptr<IAppFwkUpdateService> AppFwkUpdateClient::GetFwkUpdateProxy()
72 {
73     auto fwkUpdateProxy = GetFwkUpdate();
74     if (fwkUpdateProxy != nullptr) {
75         return fwkUpdateProxy;
76     }
77     auto sam = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
78     if (sam == nullptr) {
79         WVLOG_E("load fwk service sam is null");
80         return {};
81     }
82 
83     auto remoteObj = sam->CheckSystemAbility(SUBSYS_WEBVIEW_SYS_UPDATE_SERVICE_ID);
84     if (remoteObj != nullptr) {
85         fwkUpdateProxy = iface_cast<IAppFwkUpdateService>(remoteObj);
86         return fwkUpdateProxy;
87     }
88     if (!LoadFwkService()) {
89         WVLOG_I("get fwk update service is null");
90         return nullptr;
91     }
92     fwkUpdateProxy = GetFwkUpdate();
93     if (fwkUpdateProxy == nullptr) {
94         WVLOG_I("get fwk update service proxy is null");
95         return nullptr;
96     }
97     WVLOG_I("load fwk service sa finished");
98     return fwkUpdateProxy;
99 }
100 
NotifyFWKAfterBmsStart()101 void AppFwkUpdateClient::NotifyFWKAfterBmsStart()
102 {
103     WVLOG_I("NotifyFWKAfterBmsStart received message");
104     auto proxy = GetFwkUpdateProxy();
105     if (proxy == nullptr) {
106         WVLOG_E("NotifyFWKAfterBmsStart failed, proxy is null");
107         return;
108     }
109     proxy->NotifyFWKAfterBmsStart();
110 }
111 
VerifyPackageInstall(const std::string & bundleName,const std::string & hapPath)112 int AppFwkUpdateClient::VerifyPackageInstall(const std::string& bundleName, const std::string& hapPath)
113 {
114     WVLOG_I("verify package install callingUid: %{public}d", IPCSkeleton::GetCallingUid());
115     if (IPCSkeleton::GetCallingUid() != FOUNDATION_UID) {
116         return -1;
117     }
118     if (!ARK_WEB_DEFAULT_BUNDLE_NAME_SET.count(bundleName)) {
119         WVLOG_I("bundle name is not nweb.");
120         return 0;
121     }
122 
123     auto proxy = GetFwkUpdateProxy();
124     if (proxy == nullptr) {
125         WVLOG_E("verify package install failed, proxy is null");
126         return -1;
127     }
128     int32_t isSuccess = -1;
129     proxy->VerifyPackageInstall(bundleName, hapPath, isSuccess);
130     WVLOG_I("verify package install result: %{public}d", isSuccess);
131     return isSuccess;
132 }
133 
LoadFwkService()134 bool AppFwkUpdateClient::LoadFwkService()
135 {
136     {
137         std::unique_lock<std::mutex> lock(loadSaMutex_);
138         loadSaFinished_ = false;
139     }
140     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
141     if (systemAbilityMgr == nullptr) {
142         WVLOG_I("failed to get system ability manager");
143         return false;
144     }
145     sptr<AppFwkUpdateLoadCallback> loadCallback = new (std::nothrow) AppFwkUpdateLoadCallback();
146     if (loadCallback == nullptr) {
147         WVLOG_I("failed to create load callback");
148         return false;
149     }
150     auto ret = systemAbilityMgr->LoadSystemAbility(SUBSYS_WEBVIEW_SYS_UPDATE_SERVICE_ID, loadCallback);
151     if (ret != 0) {
152         WVLOG_W("load fwk update service failed.");
153         return false;
154     }
155     {
156         std::unique_lock<std::mutex> lock(loadSaMutex_);
157         auto waitStatus = loadSaCondition_.wait_for(
158             lock, std::chrono::milliseconds(LOAD_SA_TIMEOUT_MS), [this]() { return loadSaFinished_; });
159         if (!waitStatus) {
160             auto remoteObj = systemAbilityMgr->CheckSystemAbility(SUBSYS_WEBVIEW_SYS_UPDATE_SERVICE_ID);
161             if (remoteObj != nullptr) {
162                 SetFwkUpdate(remoteObj);
163                 return true;
164             }
165             WVLOG_I("load fwk service timeout.");
166             return false;
167         }
168         WVLOG_I("load fwk service success.");
169         return true;
170     }
171 }
172 
OnLoadSystemAbilitySuccess(const sptr<IRemoteObject> & remoteObject)173 void AppFwkUpdateClient::OnLoadSystemAbilitySuccess(const sptr<IRemoteObject>& remoteObject)
174 {
175     WVLOG_I("on load systemAbility success");
176     if (appFwkUpdateDiedRecipient_ == nullptr) {
177         WVLOG_E("register fwk update service died recipient failed");
178         return;
179     }
180     if (!remoteObject->AddDeathRecipient(appFwkUpdateDiedRecipient_)) {
181         WVLOG_E("add fwk update service died recipient failed");
182         return;
183     }
184     SetFwkUpdate(remoteObject);
185     std::unique_lock<std::mutex> lock(loadSaMutex_);
186     loadSaFinished_ = true;
187     loadSaCondition_.notify_one();
188 }
189 
OnLoadSystemAbilityFail()190 void AppFwkUpdateClient::OnLoadSystemAbilityFail()
191 {
192     SetFwkUpdate(nullptr);
193     std::unique_lock<std::mutex> lock(loadSaMutex_);
194     loadSaFinished_ = true;
195     loadSaCondition_.notify_one();
196 }
197 
OnRemoteDied(const wptr<IRemoteObject> & remoteObject)198 void AppFwkUpdateClient::AppFwkUpdateDiedRecipient::OnRemoteDied(const wptr<IRemoteObject>& remoteObject)
199 {
200     if (remoteObject == nullptr) {
201         WVLOG_E("remote object of fwk update service died recipient is nullptr");
202         return;
203     }
204     AppFwkUpdateClient::GetInstance().AppFwkUpdateOnRemoteDied(remoteObject);
205 }
206 
AppFwkUpdateOnRemoteDied(const wptr<IRemoteObject> & remoteObject)207 void AppFwkUpdateClient::AppFwkUpdateOnRemoteDied(const wptr<IRemoteObject>& remoteObject)
208 {
209     WVLOG_I("remote object of fwk update service died recipient is died");
210     auto fwkUpdateProxy = GetFwkUpdate();
211     if (fwkUpdateProxy == nullptr) {
212         WVLOG_E("app fwk update proxy is nullptr");
213         return;
214     }
215     sptr<IRemoteObject> remotePromote = remoteObject.promote();
216     if (remotePromote == nullptr) {
217         WVLOG_E("remote object of fwk update service promote fail");
218         return;
219     }
220     if (fwkUpdateProxy->AsObject() != remotePromote) {
221         WVLOG_E("app fwk update died recipient not find remote object");
222         return;
223     }
224     remotePromote->RemoveDeathRecipient(appFwkUpdateDiedRecipient_);
225     SetFwkUpdate(nullptr);
226 }
227 } // namespace OHOS::NWeb
228