1 /*
2 * Copyright (c) 2025 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 #include "migration_manager_adapter_impl.h"
16
17 #include <cmath>
18
19 #include "ability_manager_client.h"
20 #include "nweb_log.h"
21
22 using namespace OHOS::NWeb;
23
24 namespace OHOS::NWeb {
25 static const uint32_t CMD_CODE = 1;
26 static sptr<OHOS::IRemoteObject> remoteObject_ = nullptr;
27 static const std::string REPLY_CODE = "code";
28 static const std::string REPLY_ERROR_LIST = "errorList";
29 static const std::string REPLY_SUCCESS_COUNT = "successCount";
30 static const std::string REPLY_INDEX = "index";
31 std::atomic<bool> MigrationManagerAdapterImpl::isConnectSystemUI_(false);
32
OnMigrationReply(int32_t errorCode,int32_t succussCount,const std::vector<int32_t> & errorIndex,const std::vector<int32_t> & codeList)33 void MigrationManagerAdapterImpl::MigrationListenerAdapterImpl::OnMigrationReply(int32_t errorCode,
34 int32_t succussCount, const std::vector<int32_t>& errorIndex, const std::vector<int32_t>& codeList)
35 {
36 if (listener_) {
37 WVLOG_I("on migration replay will be invoked");
38 listener_->OnMigrationReply(errorCode, succussCount, errorIndex, codeList);
39 }
40 }
41
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)42 void MigrationManagerAdapterImpl::MigrationListenerAdapterImpl::OnAbilityConnectDone(
43 const AppExecFwk::ElementName& element, const sptr<IRemoteObject>& remoteObject, int resultCode)
44 {
45 WVLOG_I("send migration request begin");
46 if (!remoteObject) {
47 return;
48 }
49
50 remoteObject_ = remoteObject;
51
52 MessageParcel data;
53 MessageParcel reply;
54 MessageOption option;
55 isConnectSystemUI_.store(true);
56
57 data.WriteInterfaceToken(Str8ToStr16(token_));
58 data.WriteString16(Str8ToStr16(jsonData_));
59 int32_t ret = remoteObject_->SendRequest(CMD_CODE, data, reply, option);
60 if (ret != ERR_OK) {
61 WVLOG_W("send request failed: %{public}d", ret);
62 return;
63 }
64 std::string replyData = Str16ToStr8(reply.ReadString16());
65 WVLOG_I("send migration request reply res: %{public}s", replyData.c_str());
66
67 int errorCode = 0;
68 int successCount = 0;
69 std::vector<int> errorIndexList;
70 std::vector<int> codeList;
71 nlohmann::json jsonObj = nlohmann::json::parse(replyData, nullptr, false);
72 if (jsonObj.is_discarded()) {
73 WVLOG_W("parse reply json data failed.");
74 return;
75 }
76 if (jsonObj.contains(REPLY_CODE) && jsonObj[REPLY_CODE].is_number_integer()) {
77 errorCode = jsonObj[REPLY_CODE];
78 }
79 if (jsonObj.contains(REPLY_ERROR_LIST)) {
80 auto errorList = jsonObj[REPLY_ERROR_LIST];
81 for (size_t i = 0; i < errorList.size(); ++i) {
82 if (errorList[i].contains(REPLY_CODE) && errorList[i].contains(REPLY_INDEX)) {
83 int errorCode = errorList[i][REPLY_CODE];
84 int errorIndex = errorList[i][REPLY_INDEX];
85 codeList.push_back(errorCode);
86 errorIndexList.push_back(errorIndex);
87 }
88 }
89 }
90 if (jsonObj.contains(REPLY_SUCCESS_COUNT) && jsonObj[REPLY_SUCCESS_COUNT].is_number_integer()) {
91 successCount = jsonObj[REPLY_SUCCESS_COUNT];
92 }
93 OnMigrationReply(errorCode, successCount, errorIndexList, codeList);
94 WVLOG_I("send migration request finish, successCount: %{public}d", successCount);
95 }
96
SetJsonData(const std::string & jsonData)97 void MigrationManagerAdapterImpl::MigrationListenerAdapterImpl::SetJsonData(const std::string& jsonData)
98 {
99 WVLOG_D("set json data invoke");
100 jsonData_ = jsonData;
101 }
102
SetInterfaceToken(const std::string & token)103 void MigrationManagerAdapterImpl::MigrationListenerAdapterImpl::SetInterfaceToken(const std::string& token)
104 {
105 WVLOG_I("SetInterfaceToken invoke");
106 token_ = token;
107 }
108
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)109 void MigrationManagerAdapterImpl::MigrationListenerAdapterImpl::OnAbilityDisconnectDone(
110 const AppExecFwk::ElementName& element, int resultCode)
111 {
112 WVLOG_I("onAbilityDisconnectDone, resultCode is %{public}d", resultCode);
113 std::vector<int32_t> vec(0);
114 OnMigrationReply(0, 0, vec, vec);
115 isConnectSystemUI_.store(false);
116 }
117
SetMigrationParam(const std::string & bundleName,const std::string & abilityName,const std::string & token)118 void MigrationManagerAdapterImpl::SetMigrationParam(
119 const std::string& bundleName, const std::string& abilityName, const std::string& token)
120 {
121 WVLOG_I("setMigrationParam start.");
122 bundleName_ = bundleName;
123 abilityName_ = abilityName;
124 if (callback_) {
125 callback_->SetInterfaceToken(token);
126 }
127 }
128
SendMigrationRequest(std::shared_ptr<std::string> jsonData)129 bool MigrationManagerAdapterImpl::SendMigrationRequest(std::shared_ptr<std::string> jsonData)
130 {
131 WVLOG_I("send migration reqeust start.");
132 if (callback_) {
133 callback_->SetJsonData(*jsonData);
134 }
135 if (isConnectSystemUI_.load() && callback_ != nullptr) {
136 AppExecFwk::ElementName element;
137 callback_->OnAbilityConnectDone(element, remoteObject_, AppExecFwk::Constants::INVALID_USERID);
138 WVLOG_I("connectExtension has been invoked once.");
139 return true;
140 }
141
142 AAFwk::Want want;
143 want.SetElementName(bundleName_, abilityName_);
144 auto abilityManager = AAFwk::AbilityManagerClient::GetInstance();
145 if (abilityManager == nullptr) {
146 WVLOG_W("ability Manager Client is nullptr");
147 return false;
148 }
149 auto ret = abilityManager->ConnectAbility(want, callback_, AppExecFwk::Constants::INVALID_USERID);
150 if (ret != ERR_OK) {
151 WVLOG_E("connectExtensionAbility failed.");
152 return false;
153 }
154 WVLOG_I("connectExtensionAbility end.");
155 return true;
156 }
157
RegisterMigrationListener(std::shared_ptr<MigrationListenerAdapter> listener)158 uint32_t MigrationManagerAdapterImpl::RegisterMigrationListener(std::shared_ptr<MigrationListenerAdapter> listener)
159 {
160 if (!listener) {
161 WVLOG_E("registerMigrationListener make failed");
162 }
163 WVLOG_I("connectExtensionAbility RegisterMigrationListener.");
164 callback_ = new (std::nothrow) MigrationListenerAdapterImpl(listener);
165 if (!callback_) {
166 WVLOG_E("make_shared failed");
167 return -1;
168 }
169 return 0;
170 }
171
172 } // namespace OHOS::NWeb
173