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