• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     auto abilitySessionInfo = sptr<AAFwk::SessionInfo>::MakeSptr();
153     abilitySessionInfo->sessionToken = extSession->AsObject();
154     abilitySessionInfo->callerToken = extSession->GetSessionInfo().callerToken_;
155     abilitySessionInfo->persistentId = extSession->GetPersistentId();
156     return abilitySessionInfo;
157 }
158 
Show() const159 void WindowExtensionConnection::Impl::Show() const
160 {
161     if (proxy_ != nullptr) {
162         proxy_->Show();
163         WLOGI("show window");
164     }
165 }
166 
Hide() const167 void WindowExtensionConnection::Impl::Hide() const
168 {
169     if (proxy_ != nullptr) {
170         proxy_->Hide();
171         WLOGI("hide window");
172     }
173 }
174 
RequestFocus() const175 void WindowExtensionConnection::Impl::RequestFocus() const
176 {
177     if (proxy_ != nullptr) {
178         proxy_->RequestFocus();
179     }
180 }
181 
SetBounds(const Rect & rect) const182 void WindowExtensionConnection::Impl::SetBounds(const Rect& rect) const
183 {
184     if (proxy_ != nullptr) {
185         proxy_->SetBounds(rect);
186     }
187 }
188 
DisconnectExtension()189 void WindowExtensionConnection::Impl::DisconnectExtension()
190 {
191     if (AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(this) != ERR_OK) {
192         WLOGFE("ConnectAbility failed!");
193         return;
194     }
195 }
196 
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)197 void WindowExtensionConnection::Impl::OnAbilityConnectDone(const AppExecFwk::ElementName& element,
198                                                            const sptr<IRemoteObject>& remoteObject, int resultCode)
199 {
200     if (!remoteObject) {
201         WLOGFE("remote object is null");
202         return;
203     }
204     if (!proxy_) {
205         proxy_ = new(std::nothrow) WindowExtensionProxy(remoteObject);
206         if (!proxy_) {
207             WLOGFE("get proxy failed");
208             return;
209         }
210     }
211     if (!deathRecipient_) {
212         deathRecipient_ = new(std::nothrow) WindowExtensionClientRecipient(componentCallback_);
213         if (!deathRecipient_) {
214             WLOGFE("get death recipient failed");
215             return;
216         }
217     }
218     if (!proxy_->AsObject() || !proxy_->AsObject()->AddDeathRecipient(deathRecipient_)) {
219         WLOGFE("Failed to add death recipient");
220     }
221     sptr<IWindowExtensionClient> clientToken(new WindowExtensionClientStubImpl(componentCallback_));
222     if (clientToken != nullptr) {
223         proxy_->GetExtensionWindow(clientToken);
224         WLOGI("GetExtensionWindow");
225     }
226     WLOGI("call end");
227     FinishAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::CONNECT_EXTENSION),
228         "WindowExtension %s-%s", element.GetBundleName().c_str(), element.GetAbilityName().c_str());
229 }
230 
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)231 void WindowExtensionConnection::Impl::OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int resultCode)
232 {
233     if (componentCallback_ != nullptr) {
234         componentCallback_->OnExtensionDisconnected();
235     }
236     WLOGI("end");
237 }
238 
ConnectExtension(const AppExecFwk::ElementName & element,const Rect & rect,uint32_t uid,uint32_t windowId,const sptr<IWindowExtensionCallback> & callback) const239 int WindowExtensionConnection::ConnectExtension(const AppExecFwk::ElementName& element,
240     const Rect& rect, uint32_t uid, uint32_t windowId, const sptr<IWindowExtensionCallback>& callback) const
241 {
242     return pImpl_->ConnectExtension(element, rect, uid, windowId, callback);
243 }
244 
ConnectExtension(const AppExecFwk::ElementName & element,const Rect & rect,uint32_t uid,uint32_t windowId,const sptr<IWindowExtensionCallback> & callback,const sptr<ExtensionSession> & extensionSession) const245 int WindowExtensionConnection::ConnectExtension(const AppExecFwk::ElementName& element,
246     const Rect& rect, uint32_t uid, uint32_t windowId, const sptr<IWindowExtensionCallback>& callback,
247     const sptr<ExtensionSession>& extensionSession) const
248 {
249     return pImpl_->ConnectExtension(element, rect, uid, windowId, callback, extensionSession);
250 }
251 
Show() const252 void WindowExtensionConnection::Show() const
253 {
254     pImpl_->Show();
255 }
256 
Hide() const257 void WindowExtensionConnection::Hide() const
258 {
259     pImpl_->Hide();
260 }
261 
RequestFocus() const262 void WindowExtensionConnection::RequestFocus() const
263 {
264     pImpl_->RequestFocus();
265 }
266 
SetBounds(const Rect & rect) const267 void WindowExtensionConnection::SetBounds(const Rect& rect) const
268 {
269     pImpl_->SetBounds(rect);
270 }
271 
DisconnectExtension() const272 void WindowExtensionConnection::DisconnectExtension() const
273 {
274     pImpl_->DisconnectExtension();
275 }
276 } // namespace Rosen
277 } // namespace OHOS
278