1 /*
2 * Copyright (c) 2022 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 "window_extension_connection.h"
17
18 #include <ability_connect_callback_stub.h>
19 #include <ability_manager_client.h>
20 #include <element_name.h>
21 #include <hitrace_meter.h>
22 #include <iremote_object.h>
23
24 #include "session_info.h"
25 #include "session/host/include/extension_session.h"
26 #include "window_extension_proxy.h"
27 #include "window_extension_client_stub_impl.h"
28 #include "window_manager_hilog.h"
29 #include "wm_common.h"
30 #include "wm_common_inner.h"
31
32 namespace OHOS {
33 namespace Rosen {
34 namespace {
35 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowExtensionConnection"};
36 }
37
38 class WindowExtensionConnection::Impl : public AAFwk::AbilityConnectionStub {
39 public:
40 Impl() = default;
41 ~Impl() = default;
42 void OnAbilityConnectDone(const AppExecFwk::ElementName& element,
43 const sptr<IRemoteObject>& remoteObject, int resultCode) override;
44 void OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int resultCode) override;
45
46 int ConnectExtension(const AppExecFwk::ElementName& element, const Rect& rect,
47 uint32_t uid, uint32_t windowId, const sptr<IWindowExtensionCallback>& callback);
48 int ConnectExtension(const AppExecFwk::ElementName& element, const Rect& rect,
49 uint32_t uid, uint32_t windowId, const sptr<IWindowExtensionCallback>& callback,
50 const sptr<ExtensionSession>& extensionSession);
51 void DisconnectExtension();
52 void Show() const;
53 void Hide() const;
54 void SetBounds(const Rect& rect) const;
55 void RequestFocus() const;
56 private:
57 class WindowExtensionClientRecipient
58 final : public IRemoteObject::DeathRecipient {
59 public:
60 explicit WindowExtensionClientRecipient(sptr<IWindowExtensionCallback> callback);
61 ~WindowExtensionClientRecipient() = default;
62 void OnRemoteDied(const wptr<IRemoteObject>& remote);
63 private:
64 sptr<IWindowExtensionCallback> callback_;
65 };
66
67 sptr<AAFwk::SessionInfo> SetAbilitySessionInfo(const sptr<ExtensionSession>& extSession);
68
69 sptr<IWindowExtensionCallback> componentCallback_;
70 sptr<IWindowExtension> proxy_;
71 sptr<WindowExtensionClientRecipient> deathRecipient_;
72 };
73
WindowExtensionConnection()74 WindowExtensionConnection::WindowExtensionConnection()
75 : pImpl_(new Impl())
76 {
77 }
78
~WindowExtensionConnection()79 WindowExtensionConnection::~WindowExtensionConnection()
80 {
81 DisconnectExtension();
82 WLOGI("disconnect");
83 }
84
WindowExtensionClientRecipient(sptr<IWindowExtensionCallback> callback)85 WindowExtensionConnection::Impl::WindowExtensionClientRecipient::WindowExtensionClientRecipient(
86 sptr<IWindowExtensionCallback> callback)
87 : callback_(callback)
88 {
89 }
90
OnRemoteDied(const wptr<IRemoteObject> & wptrDeath)91 void WindowExtensionConnection::Impl::WindowExtensionClientRecipient::OnRemoteDied(const wptr<IRemoteObject>& wptrDeath)
92 {
93 if (wptrDeath == nullptr) {
94 WLOGFE("wptrDeath is null");
95 return;
96 }
97
98 sptr<IRemoteObject> object = wptrDeath.promote();
99 if (!object) {
100 WLOGFE("object is null");
101 return;
102 }
103
104 if (callback_ != nullptr) {
105 WLOGI("on extension disconnected");
106 callback_->OnExtensionDisconnected();
107 }
108 WLOGI("Remote died");
109 }
110
ConnectExtension(const AppExecFwk::ElementName & element,const Rect & rect,uint32_t uid,uint32_t windowId,const sptr<IWindowExtensionCallback> & callback)111 int WindowExtensionConnection::Impl::ConnectExtension(const AppExecFwk::ElementName& element,
112 const Rect& rect, uint32_t uid, uint32_t windowId, const sptr<IWindowExtensionCallback>& callback)
113 {
114 AAFwk::Want want;
115 want.SetElement(element);
116 StartAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::CONNECT_EXTENSION),
117 "WindowExtension %s-%s", element.GetBundleName().c_str(), element.GetAbilityName().c_str());
118 want.SetParam(RECT_FORM_KEY_POS_X, rect.posX_);
119 want.SetParam(RECT_FORM_KEY_POS_Y, rect.posY_);
120 want.SetParam(RECT_FORM_KEY_WIDTH, static_cast<int>(rect.width_));
121 want.SetParam(RECT_FORM_KEY_HEIGHT, static_cast<int>(rect.height_));
122 want.SetParam(WINDOW_ID, static_cast<int>(windowId));
123 componentCallback_ = callback;
124 auto ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, this, nullptr);
125 WLOGI("Connection extension end ret = %{public}d windowId = %{public}u uid = %{public}u", ret, windowId, uid);
126 return ret;
127 }
128
ConnectExtension(const AppExecFwk::ElementName & element,const Rect & rect,uint32_t uid,uint32_t windowId,const sptr<IWindowExtensionCallback> & callback,const sptr<ExtensionSession> & extensionSession)129 int WindowExtensionConnection::Impl::ConnectExtension(const AppExecFwk::ElementName& element,
130 const Rect& rect, uint32_t uid, uint32_t windowId, const sptr<IWindowExtensionCallback>& callback,
131 const sptr<ExtensionSession>& extensionSession)
132 {
133 AAFwk::Want want;
134 want.SetElement(element);
135 StartAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::CONNECT_EXTENSION),
136 "WindowExtension %s-%s", element.GetBundleName().c_str(), element.GetAbilityName().c_str());
137 want.SetParam(RECT_FORM_KEY_POS_X, rect.posX_);
138 want.SetParam(RECT_FORM_KEY_POS_Y, rect.posY_);
139 want.SetParam(RECT_FORM_KEY_WIDTH, static_cast<int>(rect.width_));
140 want.SetParam(RECT_FORM_KEY_HEIGHT, static_cast<int>(rect.height_));
141 want.SetParam(WINDOW_ID, static_cast<int>(windowId));
142 componentCallback_ = callback;
143 auto extSessionInfo = SetAbilitySessionInfo(extensionSession);
144 auto ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectUIExtensionAbility(want, this, extSessionInfo, uid);
145 WLOGI("Connection ui extension end ret = %{public}d windowId = %{public}u uid = %{public}u", ret, windowId, uid);
146 return ret;
147 }
148
SetAbilitySessionInfo(const sptr<ExtensionSession> & extSession)149 sptr<AAFwk::SessionInfo> WindowExtensionConnection::Impl::SetAbilitySessionInfo(
150 const sptr<ExtensionSession>& extSession)
151 {
152 sptr<AAFwk::SessionInfo> abilitySessionInfo = new (std::nothrow) AAFwk::SessionInfo();
153 if (!abilitySessionInfo) {
154 WLOGFE("abilitySessionInfo is nullptr");
155 return nullptr;
156 }
157 auto sessionInfo = extSession->GetSessionInfo();
158 abilitySessionInfo->sessionToken = extSession->AsObject();
159 abilitySessionInfo->callerToken = sessionInfo.callerToken_;
160 abilitySessionInfo->persistentId = extSession->GetPersistentId();
161 return abilitySessionInfo;
162 }
163
Show() const164 void WindowExtensionConnection::Impl::Show() const
165 {
166 if (proxy_ != nullptr) {
167 proxy_->Show();
168 WLOGI("show window");
169 }
170 }
171
Hide() const172 void WindowExtensionConnection::Impl::Hide() const
173 {
174 if (proxy_ != nullptr) {
175 proxy_->Hide();
176 WLOGI("hide window");
177 }
178 }
179
RequestFocus() const180 void WindowExtensionConnection::Impl::RequestFocus() const
181 {
182 if (proxy_ != nullptr) {
183 proxy_->RequestFocus();
184 }
185 }
186
SetBounds(const Rect & rect) const187 void WindowExtensionConnection::Impl::SetBounds(const Rect& rect) const
188 {
189 if (proxy_ != nullptr) {
190 proxy_->SetBounds(rect);
191 }
192 }
193
DisconnectExtension()194 void WindowExtensionConnection::Impl::DisconnectExtension()
195 {
196 if (AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(this) != ERR_OK) {
197 WLOGFE("ConnectAbility failed!");
198 return;
199 }
200 }
201
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)202 void WindowExtensionConnection::Impl::OnAbilityConnectDone(const AppExecFwk::ElementName& element,
203 const sptr<IRemoteObject>& remoteObject, int resultCode)
204 {
205 if (!remoteObject) {
206 WLOGFE("remote object is null");
207 return;
208 }
209 if (!proxy_) {
210 proxy_ = new(std::nothrow) WindowExtensionProxy(remoteObject);
211 if (!proxy_) {
212 WLOGFE("get proxy failed");
213 return;
214 }
215 }
216 if (!deathRecipient_) {
217 deathRecipient_ = new(std::nothrow) WindowExtensionClientRecipient(componentCallback_);
218 if (!deathRecipient_) {
219 WLOGFE("get death recipient failed");
220 return;
221 }
222 }
223 if (!proxy_->AsObject() || !proxy_->AsObject()->AddDeathRecipient(deathRecipient_)) {
224 WLOGFE("Failed to add death recipient");
225 }
226 sptr<IWindowExtensionClient> clientToken(new WindowExtensionClientStubImpl(componentCallback_));
227 if (clientToken != nullptr) {
228 proxy_->GetExtensionWindow(clientToken);
229 WLOGI("GetExtensionWindow");
230 }
231 WLOGI("call end");
232 FinishAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::CONNECT_EXTENSION),
233 "WindowExtension %s-%s", element.GetBundleName().c_str(), element.GetAbilityName().c_str());
234 }
235
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)236 void WindowExtensionConnection::Impl::OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int resultCode)
237 {
238 if (componentCallback_ != nullptr) {
239 componentCallback_->OnExtensionDisconnected();
240 }
241 WLOGI("end");
242 }
243
ConnectExtension(const AppExecFwk::ElementName & element,const Rect & rect,uint32_t uid,uint32_t windowId,const sptr<IWindowExtensionCallback> & callback) const244 int WindowExtensionConnection::ConnectExtension(const AppExecFwk::ElementName& element,
245 const Rect& rect, uint32_t uid, uint32_t windowId, const sptr<IWindowExtensionCallback>& callback) const
246 {
247 return pImpl_->ConnectExtension(element, rect, uid, windowId, callback);
248 }
249
ConnectExtension(const AppExecFwk::ElementName & element,const Rect & rect,uint32_t uid,uint32_t windowId,const sptr<IWindowExtensionCallback> & callback,const sptr<ExtensionSession> & extensionSession) const250 int WindowExtensionConnection::ConnectExtension(const AppExecFwk::ElementName& element,
251 const Rect& rect, uint32_t uid, uint32_t windowId, const sptr<IWindowExtensionCallback>& callback,
252 const sptr<ExtensionSession>& extensionSession) const
253 {
254 return pImpl_->ConnectExtension(element, rect, uid, windowId, callback, extensionSession);
255 }
256
Show() const257 void WindowExtensionConnection::Show() const
258 {
259 pImpl_->Show();
260 }
261
Hide() const262 void WindowExtensionConnection::Hide() const
263 {
264 pImpl_->Hide();
265 }
266
RequestFocus() const267 void WindowExtensionConnection::RequestFocus() const
268 {
269 pImpl_->RequestFocus();
270 }
271
SetBounds(const Rect & rect) const272 void WindowExtensionConnection::SetBounds(const Rect& rect) const
273 {
274 pImpl_->SetBounds(rect);
275 }
276
DisconnectExtension() const277 void WindowExtensionConnection::DisconnectExtension() const
278 {
279 pImpl_->DisconnectExtension();
280 }
281 } // namespace Rosen
282 } // namespace OHOS
283