• 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 "common/include/extension_data_handler.h"
17 
18 #include <sstream>
19 
20 #include <hitrace_meter.h>
21 #include <iremote_proxy.h>
22 #include <message_parcel.h>
23 #include <securec.h>
24 #include <want.h>
25 
26 #include "window_manager_hilog.h"
27 
28 namespace OHOS::Rosen::Extension {
29 
Marshalling(Parcel & parcel) const30 bool DataTransferConfig::Marshalling(Parcel& parcel) const
31 {
32     return parcel.WriteUint8(static_cast<uint8_t>(subSystemId)) && parcel.WriteUint32(customId) &&
33            parcel.WriteBool(needReply) && parcel.WriteBool(needSyncSend);
34 }
35 
Unmarshalling(Parcel & parcel)36 DataTransferConfig* DataTransferConfig::Unmarshalling(Parcel& parcel)
37 {
38     auto config = new DataTransferConfig();
39     uint8_t subSystemIdValue = static_cast<uint8_t>(SubSystemId::INVALID);
40     if (!parcel.ReadUint8(subSystemIdValue) || subSystemIdValue >= static_cast<uint8_t>(SubSystemId::INVALID)) {
41         delete config;
42         return nullptr;
43     }
44     if (!parcel.ReadUint32(config->customId) || !parcel.ReadBool(config->needReply) ||
45         !parcel.ReadBool(config->needSyncSend)) {
46         delete config;
47         return nullptr;
48     }
49     config->subSystemId = static_cast<SubSystemId>(subSystemIdValue);
50     return config;
51 }
52 
ToString() const53 std::string DataTransferConfig::ToString() const
54 {
55     std::string str;
56     constexpr int BUFFER_SIZE = 128;
57     char buffer[BUFFER_SIZE] = { 0 };
58     if (snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1,
59                    "subSystemId: %hhu, customId: %u, needReply: %d, needSyncSend: %d", subSystemId, customId, needReply,
60                    needSyncSend) > 0) {
61         str.append(buffer);
62     }
63     return str;
64 }
65 
RegisterDataConsumer(SubSystemId subSystemId,DataConsumeCallback && callback)66 DataHandlerErr DataHandler::RegisterDataConsumer(SubSystemId subSystemId, DataConsumeCallback&& callback)
67 {
68     std::lock_guard lock(mutex_);
69     if (consumers_.find(subSystemId) != consumers_.end()) {
70         // A consumer already exists for this subSystemId
71         TLOGE(WmsLogTag::WMS_UIEXT, "Consumer already exists for subSystemId: %{public}hhu", subSystemId);
72         return DataHandlerErr::DUPLICATE_REGISTRATION;
73     }
74     consumers_.emplace(subSystemId, std::move(callback));
75     return DataHandlerErr::OK;
76 }
77 
UnregisterDataConsumer(SubSystemId subSystemId)78 void DataHandler::UnregisterDataConsumer(SubSystemId subSystemId)
79 {
80     std::lock_guard lock(mutex_);
81     consumers_.erase(subSystemId);
82     TLOGD(WmsLogTag::WMS_UIEXT, "Unregister consumer for subSystemId: %{public}hhu", subSystemId);
83 }
84 
IsProxyObject() const85 bool DataHandler::IsProxyObject() const
86 {
87     std::lock_guard lock(mutex_);
88     return remoteProxy_ && remoteProxy_->IsProxyObject();
89 }
90 
PrepareSendData(MessageParcel & data,const DataTransferConfig & config,const AAFwk::Want & toSend)91 DataHandlerErr DataHandler::PrepareSendData(MessageParcel& data, const DataTransferConfig& config,
92                                             const AAFwk::Want& toSend)
93 {
94     if (IsProxyObject() && !WriteInterfaceToken(data)) {
95         TLOGE(WmsLogTag::WMS_UIEXT, "write interface token failed, %{public}s", config.ToString().c_str());
96         return DataHandlerErr::WRITE_PARCEL_ERROR;
97     }
98 
99     if (!data.WriteParcelable(&config)) {
100         TLOGE(WmsLogTag::WMS_UIEXT, "write config failed, %{public}s", config.ToString().c_str());
101         return DataHandlerErr::WRITE_PARCEL_ERROR;
102     }
103 
104     if (!data.WriteParcelable(&toSend)) {
105         TLOGE(WmsLogTag::WMS_UIEXT, "write toSend failed, %{public}s", config.ToString().c_str());
106         return DataHandlerErr::WRITE_PARCEL_ERROR;
107     }
108     return DataHandlerErr::OK;
109 }
110 
ParseReply(MessageParcel & replyParcel,AAFwk::Want & reply,const DataTransferConfig & config)111 DataHandlerErr DataHandler::ParseReply(MessageParcel& replyParcel, AAFwk::Want& reply, const DataTransferConfig& config)
112 {
113     if (!config.needReply) {
114         return DataHandlerErr::OK;
115     }
116 
117     uint32_t replyCode = 0;
118     if (!replyParcel.ReadUint32(replyCode)) {
119         TLOGE(WmsLogTag::WMS_UIEXT, "read replyCode failed, %{public}s", config.ToString().c_str());
120         return DataHandlerErr::READ_PARCEL_ERROR;
121     }
122 
123     if (config.needReply) {
124         sptr<AAFwk::Want> response = replyParcel.ReadParcelable<AAFwk::Want>();
125         if (!response) {
126             TLOGE(WmsLogTag::WMS_UIEXT, "read response failed, %{public}s", config.ToString().c_str());
127             return DataHandlerErr::READ_PARCEL_ERROR;
128         }
129         reply = std::move(*response);
130     }
131 
132     return static_cast<DataHandlerErr>(replyCode);
133 }
134 
135 // process data from peer
NotifyDataConsumer(MessageParcel & recieved,MessageParcel & reply)136 void DataHandler::NotifyDataConsumer(MessageParcel& recieved, MessageParcel& reply)
137 {
138     sptr<DataTransferConfig> config = recieved.ReadParcelable<DataTransferConfig>();
139     if (config == nullptr) {
140         TLOGE(WmsLogTag::WMS_UIEXT, "read config failed");
141         reply.WriteUint32(static_cast<uint32_t>(DataHandlerErr::READ_PARCEL_ERROR));
142         return;
143     }
144 
145     sptr<AAFwk::Want> sendWant = recieved.ReadParcelable<AAFwk::Want>();
146     if (sendWant == nullptr) {
147         TLOGE(WmsLogTag::WMS_UIEXT, "read want failed");
148         reply.WriteUint32(static_cast<uint32_t>(DataHandlerErr::READ_PARCEL_ERROR));
149         return;
150     }
151 
152     std::optional<AAFwk::Want> replyWant;
153     bool needReply = (config->needSyncSend && config->needReply);
154     if (needReply) {
155         replyWant = std::make_optional<AAFwk::Want>();
156     }
157 
158     auto ret = NotifyDataConsumer(std::move(*sendWant), replyWant, *config);
159     reply.WriteUint32(static_cast<uint32_t>(ret));
160     if (needReply && replyWant) {
161         reply.WriteParcelable(&(replyWant.value()));
162     }
163 }
164 
SetEventHandler(const std::shared_ptr<AppExecFwk::EventHandler> & eventHandler)165 void DataHandler::SetEventHandler(const std::shared_ptr<AppExecFwk::EventHandler>& eventHandler)
166 {
167     eventHandler_ = eventHandler;
168 }
169 
SetRemoteProxyObject(const sptr<IRemoteObject> & remoteObject)170 void DataHandler::SetRemoteProxyObject(const sptr<IRemoteObject>& remoteObject)
171 {
172     std::lock_guard lock(mutex_);
173     remoteProxy_ = remoteObject;
174 }
175 
SendDataSync(SubSystemId subSystemId,uint32_t customId,const AAFwk::Want & toSend,AAFwk::Want & reply)176 DataHandlerErr DataHandler::SendDataSync(SubSystemId subSystemId, uint32_t customId, const AAFwk::Want& toSend,
177                                          AAFwk::Want& reply)
178 {
179     DataTransferConfig config;
180     config.needSyncSend = true;
181     config.needReply = true;
182     config.subSystemId = subSystemId;
183     config.customId = customId;
184     return SendData(toSend, reply, config);
185 }
186 
SendDataSync(SubSystemId subSystemId,uint32_t customId,const AAFwk::Want & toSend)187 DataHandlerErr DataHandler::SendDataSync(SubSystemId subSystemId, uint32_t customId, const AAFwk::Want& toSend)
188 {
189     DataTransferConfig config;
190     config.needSyncSend = true;
191     config.subSystemId = subSystemId;
192     config.customId = customId;
193     AAFwk::Want reply;
194     return SendData(toSend, reply, config);
195 }
196 
SendDataAsync(SubSystemId subSystemId,uint32_t customId,const AAFwk::Want & toSend)197 DataHandlerErr DataHandler::SendDataAsync(SubSystemId subSystemId, uint32_t customId, const AAFwk::Want& toSend)
198 {
199     DataTransferConfig config;
200     config.subSystemId = subSystemId;
201     config.customId = customId;
202     AAFwk::Want reply;
203     return SendData(toSend, reply, config);
204 }
205 
NotifyDataConsumer(AAFwk::Want && data,std::optional<AAFwk::Want> & reply,const DataTransferConfig & config)206 DataHandlerErr DataHandler::NotifyDataConsumer(AAFwk::Want&& data, std::optional<AAFwk::Want>& reply,
207                                                const DataTransferConfig& config)
208 {
209     DataConsumeCallback callback;
210     {
211         std::lock_guard lock(mutex_);
212         auto it = consumers_.find(config.subSystemId);
213         if (it == consumers_.end()) {
214             TLOGE(WmsLogTag::WMS_UIEXT, "not found, %{public}s", config.ToString().c_str());
215             return DataHandlerErr::NO_CONSUME_CALLBACK;
216         }
217         callback = it->second;
218     }
219 
220     if (!callback) {
221         TLOGE(WmsLogTag::WMS_UIEXT, "not callable, %{public}s", config.ToString().c_str());
222         return DataHandlerErr::INVALID_CALLBACK;
223     }
224 
225     // sync mode
226     if (config.needSyncSend) {
227         auto ret = callback(config.subSystemId, config.customId, std::move(data), reply);
228         TLOGD(WmsLogTag::WMS_UIEXT, "subSystemId: %{public}hhu, customId: %{public}u, ret: %{public}d",
229               config.subSystemId, config.customId, ret);
230         return DataHandlerErr::OK;
231     }
232 
233     // async mode
234     auto task = [input = std::move(data), subSystemId = config.subSystemId, customId = config.customId,
235                  func = std::move(callback)]() mutable {
236         std::optional<AAFwk::Want> reply;
237         auto ret = func(subSystemId, customId, std::move(input), reply);
238         TLOGNI(WmsLogTag::WMS_UIEXT, "subSystemId: %{public}hhu, customId: %{public}u, ret: %{public}d", subSystemId,
239                customId, ret);
240     };
241 
242     std::ostringstream oss;
243     oss << "NotifyDataConsumer_" << static_cast<uint32_t>(config.subSystemId) << "_" << config.customId;
244     PostAsyncTask(std::move(task), oss.str(), 0);
245     return DataHandlerErr::OK;
246 }
247 
PostAsyncTask(Task && task,const std::string & name,int64_t delayTime)248 void DataHandler::PostAsyncTask(Task&& task, const std::string& name, int64_t delayTime)
249 {
250     if (!eventHandler_) {
251         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "uiext:%s", name.c_str());
252         task();
253         return;
254     }
255 
256     if (auto runner = eventHandler_->GetEventRunner(); !runner || runner->IsCurrentRunnerThread()) {
257         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "uiext:%s", name.c_str());
258         task();
259         return;
260     }
261 
262     auto localTask = [task = std::move(task), name] {
263         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "uiext:%s", name.c_str());
264         task();
265     };
266 
267     auto ret = eventHandler_->PostTask(std::move(localTask), "uiext:" + name, delayTime,
268                                        AppExecFwk::EventQueue::Priority::IMMEDIATE);
269     if (!ret) {
270         TLOGE(WmsLogTag::WMS_UIEXT, "Post task failed, name: %{public}s", name.c_str());
271     }
272 }
273 }  // namespace OHOS::Rosen::Extension