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 "window_extension_proxy.h"
25 #include "window_extension_client_stub_impl.h"
26 #include "window_manager_hilog.h"
27 #include "wm_common.h"
28 #include "wm_common_inner.h"
29
30 namespace OHOS {
31 namespace Rosen {
32 namespace {
33 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowExtensionConnection"};
34 }
35
36 class WindowExtensionConnection::Impl : public AAFwk::AbilityConnectionStub {
37 public:
38 Impl() = default;
39 ~Impl() = default;
40 void OnAbilityConnectDone(const AppExecFwk::ElementName& element,
41 const sptr<IRemoteObject>& remoteObject, int resultCode) override;
42 void OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int resultCode) override;
43
44 int ConnectExtension(const AppExecFwk::ElementName& element, const Rect& rect,
45 uint32_t uid, uint32_t windowId, const sptr<IWindowExtensionCallback>& callback);
46 void DisconnectExtension();
47 void Show() const;
48 void Hide() const;
49 void SetBounds(const Rect& rect) const;
50 void RequestFocus() const;
51 private:
52 class WindowExtensionClientRecipient
53 final : public IRemoteObject::DeathRecipient {
54 public:
55 explicit WindowExtensionClientRecipient(sptr<IWindowExtensionCallback> callback);
56 ~WindowExtensionClientRecipient() = default;
57 void OnRemoteDied(const wptr<IRemoteObject>& remote);
58 private:
59 sptr<IWindowExtensionCallback> callback_;
60 };
61
62 sptr<IWindowExtensionCallback> componentCallback_;
63 sptr<IWindowExtension> proxy_;
64 sptr<WindowExtensionClientRecipient> deathRecipient_;
65 };
66
WindowExtensionConnection()67 WindowExtensionConnection::WindowExtensionConnection()
68 : pImpl_(new Impl())
69 {
70 }
71
~WindowExtensionConnection()72 WindowExtensionConnection::~WindowExtensionConnection()
73 {
74 DisconnectExtension();
75 WLOGI("disconnect");
76 }
77
WindowExtensionClientRecipient(sptr<IWindowExtensionCallback> callback)78 WindowExtensionConnection::Impl::WindowExtensionClientRecipient::WindowExtensionClientRecipient(
79 sptr<IWindowExtensionCallback> callback)
80 : callback_(callback)
81 {
82 }
83
OnRemoteDied(const wptr<IRemoteObject> & wptrDeath)84 void WindowExtensionConnection::Impl::WindowExtensionClientRecipient::OnRemoteDied(const wptr<IRemoteObject>& wptrDeath)
85 {
86 if (wptrDeath == nullptr) {
87 WLOGFE("wptrDeath is null");
88 return;
89 }
90
91 sptr<IRemoteObject> object = wptrDeath.promote();
92 if (!object) {
93 WLOGFE("object is null");
94 return;
95 }
96
97 if (callback_ != nullptr) {
98 WLOGFI("on extension disconnected");
99 callback_->OnExtensionDisconnected();
100 }
101 WLOGFI("Remote died");
102 }
103
ConnectExtension(const AppExecFwk::ElementName & element,const Rect & rect,uint32_t uid,uint32_t windowId,const sptr<IWindowExtensionCallback> & callback)104 int WindowExtensionConnection::Impl::ConnectExtension(const AppExecFwk::ElementName& element,
105 const Rect& rect, uint32_t uid, uint32_t windowId, const sptr<IWindowExtensionCallback>& callback)
106 {
107 AAFwk::Want want;
108 want.SetElement(element);
109 StartAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::CONNECT_EXTENSION),
110 "WindowExtension %s-%s", element.GetBundleName().c_str(), element.GetAbilityName().c_str());
111 want.SetParam(RECT_FORM_KEY_POS_X, rect.posX_);
112 want.SetParam(RECT_FORM_KEY_POS_Y, rect.posY_);
113 want.SetParam(RECT_FORM_KEY_WIDTH, static_cast<int>(rect.width_));
114 want.SetParam(RECT_FORM_KEY_HEIGHT, static_cast<int>(rect.height_));
115 want.SetParam(WINDOW_ID, static_cast<int>(windowId));
116 // 100 default userId
117 auto ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, this, nullptr, uid);
118 if (ret == ERR_OK) {
119 componentCallback_ = callback;
120 }
121 WLOGFI("Connection extension end ret = %{public}d windowId = %{public}u", ret, windowId);
122 return ret;
123 }
124
Show() const125 void WindowExtensionConnection::Impl::Show() const
126 {
127 if (proxy_ != nullptr) {
128 proxy_->Show();
129 WLOGFI("show window");
130 }
131 }
132
Hide() const133 void WindowExtensionConnection::Impl::Hide() const
134 {
135 if (proxy_ != nullptr) {
136 proxy_->Hide();
137 WLOGFI("hide window");
138 }
139 }
140
RequestFocus() const141 void WindowExtensionConnection::Impl::RequestFocus() const
142 {
143 if (proxy_ != nullptr) {
144 proxy_->RequestFocus();
145 }
146 }
147
SetBounds(const Rect & rect) const148 void WindowExtensionConnection::Impl::SetBounds(const Rect& rect) const
149 {
150 if (proxy_ != nullptr) {
151 proxy_->SetBounds(rect);
152 }
153 }
154
DisconnectExtension()155 void WindowExtensionConnection::Impl::DisconnectExtension()
156 {
157 if (AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(this) != ERR_OK) {
158 WLOGFE("ConnectAbility failed!");
159 return;
160 }
161 }
162
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)163 void WindowExtensionConnection::Impl::OnAbilityConnectDone(const AppExecFwk::ElementName& element,
164 const sptr<IRemoteObject>& remoteObject, int resultCode)
165 {
166 if (!remoteObject) {
167 WLOGFE("remote object is null");
168 return;
169 }
170 if (!proxy_) {
171 proxy_ = new(std::nothrow) WindowExtensionProxy(remoteObject);
172 if (!proxy_) {
173 WLOGFE("get proxy failed");
174 return;
175 }
176 }
177 if (!deathRecipient_) {
178 deathRecipient_ = new(std::nothrow) WindowExtensionClientRecipient(componentCallback_);
179 if (!deathRecipient_) {
180 WLOGFE("get death recipient failed");
181 return;
182 }
183 }
184 if (!proxy_->AsObject() || !proxy_->AsObject()->AddDeathRecipient(deathRecipient_)) {
185 WLOGFE("Failed to add death recipient");
186 }
187 sptr<IWindowExtensionClient> clientToken(new WindowExtensionClientStubImpl(componentCallback_));
188 if (clientToken != nullptr) {
189 proxy_->GetExtensionWindow(clientToken);
190 WLOGFI("GetExtensionWindow");
191 }
192 WLOGFI("call end");
193 FinishAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::CONNECT_EXTENSION),
194 "WindowExtension %s-%s", element.GetBundleName().c_str(), element.GetAbilityName().c_str());
195 }
196
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)197 void WindowExtensionConnection::Impl::OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int resultCode)
198 {
199 if (componentCallback_ != nullptr) {
200 componentCallback_->OnExtensionDisconnected();
201 }
202 WLOGFI("end");
203 }
204
ConnectExtension(const AppExecFwk::ElementName & element,const Rect & rect,uint32_t uid,uint32_t windowId,const sptr<IWindowExtensionCallback> & callback) const205 int WindowExtensionConnection::ConnectExtension(const AppExecFwk::ElementName& element,
206 const Rect& rect, uint32_t uid, uint32_t windowId, const sptr<IWindowExtensionCallback>& callback) const
207 {
208 return pImpl_->ConnectExtension(element, rect, uid, windowId, callback);
209 }
210
Show() const211 void WindowExtensionConnection::Show() const
212 {
213 pImpl_->Show();
214 }
215
Hide() const216 void WindowExtensionConnection::Hide() const
217 {
218 pImpl_->Hide();
219 }
220
RequestFocus() const221 void WindowExtensionConnection::RequestFocus() const
222 {
223 pImpl_->RequestFocus();
224 }
225
SetBounds(const Rect & rect) const226 void WindowExtensionConnection::SetBounds(const Rect& rect) const
227 {
228 pImpl_->SetBounds(rect);
229 }
230
DisconnectExtension() const231 void WindowExtensionConnection::DisconnectExtension() const
232 {
233 pImpl_->DisconnectExtension();
234 }
235 } // namespace Rosen
236 } // namespace OHOS
237