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