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 "update_notify.h"
17
18 #include "cJSON.h"
19 #include "extension_manager_client.h"
20 #include "iservice_registry.h"
21
22 #include "subscribe_info.h"
23 #include "update_log.h"
24
25 namespace OHOS {
26 namespace UpdateEngine {
27 std::mutex UpdateNotify::instanceLock_;
28 sptr<UpdateNotify> UpdateNotify::instance_ = nullptr;
29
UpdateNotify()30 UpdateNotify::UpdateNotify()
31 {
32 ENGINE_LOGD("UpdateNotify");
33 }
34
~UpdateNotify()35 UpdateNotify::~UpdateNotify()
36 {
37 ENGINE_LOGD("~UpdateNotify");
38 }
39
GetInstance()40 sptr<UpdateNotify> UpdateNotify::GetInstance()
41 {
42 if (instance_ == nullptr) {
43 std::lock_guard<std::mutex> autoLock(instanceLock_);
44 if (instance_ == nullptr) {
45 instance_ = new UpdateNotify();
46 }
47 }
48 return instance_;
49 }
50
ConnectAbility(const AAFwk::Want & want,const sptr<AAFwk::AbilityConnectionStub> & connect)51 ErrCode UpdateNotify::ConnectAbility(const AAFwk::Want &want, const sptr<AAFwk::AbilityConnectionStub> &connect)
52 {
53 ErrCode result =
54 AAFwk::ExtensionManagerClient::GetInstance().ConnectServiceExtensionAbility(want, connect, nullptr, -1);
55 ENGINE_LOGI("ConnectAbility result %{public}d", result);
56 return result;
57 }
58
DisconnectAbility(const sptr<AAFwk::AbilityConnectionStub> & connect)59 ErrCode UpdateNotify::DisconnectAbility(const sptr<AAFwk::AbilityConnectionStub> &connect)
60 {
61 ErrCode result =
62 AAFwk::ExtensionManagerClient::GetInstance().DisconnectAbility(connect);
63 ENGINE_LOGI("DisconnectAbility result %{public}d", result);
64 return result;
65 }
66
ConnectToAppService(const std::string & eventInfo,const std::string & subscribeInfo)67 bool UpdateNotify::ConnectToAppService(const std::string &eventInfo, const std::string &subscribeInfo)
68 {
69 if (eventInfo.empty()) {
70 ENGINE_LOGE("ConnectToAppService eventInfo error.");
71 return false;
72 }
73 cJSON *root = cJSON_CreateObject();
74 cJSON_AddItemToObject(root, "EventInfo", cJSON_Parse(eventInfo.c_str()));
75 cJSON_AddItemToObject(root, "SubscribeInfo", cJSON_Parse(subscribeInfo.c_str()));
76
77 char *data = cJSON_PrintUnformatted(root);
78 if (data == nullptr) {
79 cJSON_Delete(root);
80 return false;
81 }
82 std::string message = std::string(data);
83 cJSON_free(data);
84 cJSON_Delete(root);
85 return HandleMessage(message);
86 }
87
HandleMessage(const std::string & message)88 bool UpdateNotify::HandleMessage(const std::string &message)
89 {
90 std::string bundleName = UPDATE_APP_PACKAGE_NAME;
91 std::string abilityName = UPDATE_APP_SERVICE_EXT_ABILITY_NAME;
92 AAFwk::Want want;
93 want.SetElementName(bundleName, abilityName);
94 want.SetParam("Timeout", UPDATE_APP_TIMEOUT);
95 auto connect = sptr<NotifyConnection>::MakeSptr(instance_);
96 int ret = ConnectAbility(want, connect);
97 std::unique_lock<std::mutex> uniqueLock(connectMutex_);
98 conditionVal_.wait_for(uniqueLock, std::chrono::seconds(UPDATE_APP_CONNECT_TIMEOUT));
99 if (ret != OHOS::ERR_OK || remoteObject_ == nullptr) {
100 ENGINE_LOGE("HandleMessage, can not connect to ouc");
101 return false;
102 }
103
104 MessageParcel data;
105 if (!data.WriteString16(Str8ToStr16(message))) {
106 ENGINE_LOGE("HandleMessage, write message failed");
107 return false;
108 }
109
110 MessageParcel reply;
111 MessageOption option(MessageOption::TF_SYNC);
112 int32_t result = remoteObject_->SendRequest(CAST_INT(UpdateAppCode::UPDATE_APP), data, reply, option);
113 if (result != 0) {
114 ENGINE_LOGE("HandleMessage SendRequest, error result %{public}d", result);
115 DisconnectAbility(connect);
116 return false;
117 }
118 return true;
119 }
120
HandleAbilityConnect(const sptr<IRemoteObject> & remoteObject)121 void UpdateNotify::HandleAbilityConnect(const sptr<IRemoteObject> &remoteObject)
122 {
123 remoteObject_ = remoteObject;
124 conditionVal_.notify_one();
125 }
126
NotifyConnection(const sptr<UpdateNotify> & instance)127 NotifyConnection::NotifyConnection(const sptr<UpdateNotify> &instance)
128 {
129 ENGINE_LOGD("NotifyConnection constructor");
130 instance_ = instance;
131 }
132
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int32_t resultCode)133 void NotifyConnection::OnAbilityConnectDone(const AppExecFwk::ElementName &element,
134 const sptr<IRemoteObject> &remoteObject, int32_t resultCode)
135 {
136 ENGINE_LOGI("OnAbilityConnectDone successfully. result %{public}d", resultCode);
137 if (resultCode != ERR_OK) {
138 ENGINE_LOGE("ability connect failed, error code: %{public}d", resultCode);
139 return;
140 }
141 ENGINE_LOGI("ability connect success, ability name %{public}s", element.GetAbilityName().c_str());
142 if (remoteObject == nullptr) {
143 ENGINE_LOGE("get remoteObject failed");
144 return;
145 }
146 if (instance_ == nullptr) {
147 return;
148 }
149 instance_->HandleAbilityConnect(remoteObject);
150 }
151
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)152 void NotifyConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode)
153 {
154 ENGINE_LOGI("OnAbilityDisconnectDone successfully. result %{public}d", resultCode);
155 }
156 } // namespace UpdateEngine
157 } // namespace OHOS