1 /*
2 * Copyright (c) 2023 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 "session_manager_lite.h"
17 #include <ipc_skeleton.h>
18 #include <iremote_stub.h>
19 #include <iservice_registry.h>
20 #include <system_ability_definition.h>
21
22 #include "session_manager_service_recover_interface.h"
23 #include "scene_session_manager_lite_proxy.h"
24 #include "window_manager_hilog.h"
25
26 namespace OHOS::Rosen {
27 namespace {
28 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SessionManagerLite" };
29 }
30
31 class SessionManagerServiceLiteRecoverListener : public IRemoteStub<ISessionManagerServiceRecoverListener> {
32 public:
33 SessionManagerServiceLiteRecoverListener() = default;
34
35 int32_t OnRemoteRequest(
36 uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) override
37 {
38 if (data.ReadInterfaceToken() != GetDescriptor()) {
39 TLOGE(WmsLogTag::WMS_RECOVER, "InterfaceToken check failed");
40 return ERR_TRANSACTION_FAILED;
41 }
42 auto msgId = static_cast<SessionManagerServiceRecoverMessage>(code);
43 switch (msgId) {
44 case SessionManagerServiceRecoverMessage::TRANS_ID_ON_SESSION_MANAGER_SERVICE_RECOVER: {
45 auto sessionManagerService = data.ReadRemoteObject();
46 // Even if sessionManagerService is null, the recovery process is still required.
47 OnSessionManagerServiceRecover(sessionManagerService);
48 break;
49 }
50 case SessionManagerServiceRecoverMessage::TRANS_ID_ON_WMS_CONNECTION_CHANGED: {
51 int32_t userId = INVALID_USER_ID;
52 int32_t screenId = DEFAULT_SCREEN_ID;
53 bool isConnected = false;
54 if (!data.ReadInt32(userId) || !data.ReadInt32(screenId) || !data.ReadBool(isConnected)) {
55 TLOGE(WmsLogTag::WMS_MULTI_USER, "Read data failed in lite!");
56 return ERR_TRANSACTION_FAILED;
57 }
58 if (isConnected) {
59 // Even if data.ReadRemoteObject() is null, the WMS connection still needs to be notified.
60 OnWMSConnectionChanged(userId, screenId, isConnected, data.ReadRemoteObject());
61 } else {
62 OnWMSConnectionChanged(userId, screenId, isConnected, nullptr);
63 }
64 break;
65 }
66 default:
67 TLOGW(WmsLogTag::WMS_RECOVER, "unknown transaction code %{public}d", code);
68 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
69 }
70 return ERR_NONE;
71 }
72
73 void OnSessionManagerServiceRecover(const sptr<IRemoteObject>& sessionManagerService) override
74 {
75 SessionManagerLite::GetInstance().Clear();
76 SessionManagerLite::GetInstance().ClearSessionManagerProxy();
77
78 auto sms = iface_cast<ISessionManagerService>(sessionManagerService);
79 SessionManagerLite::GetInstance().RecoverSessionManagerService(sms);
80 }
81
82 void OnWMSConnectionChanged(
83 int32_t userId, int32_t screenId, bool isConnected, const sptr<IRemoteObject>& sessionManagerService) override
84 {
85 auto sms = iface_cast<ISessionManagerService>(sessionManagerService);
86 SessionManagerLite::GetInstance().OnWMSConnectionChanged(userId, screenId, isConnected, sms);
87 }
88 };
89
90 class SceneSessionManagerLiteProxyMock : public SceneSessionManagerLiteProxy {
91 public:
SceneSessionManagerLiteProxyMock(const sptr<IRemoteObject>& impl)92 explicit SceneSessionManagerLiteProxyMock(const sptr<IRemoteObject>& impl)
93 : SceneSessionManagerLiteProxy(impl) {}
94 virtual ~SceneSessionManagerLiteProxyMock() = default;
95
96 WSError RegisterSessionListener(const sptr<ISessionListener>& listener, bool isRecover = false) override
97 {
98 TLOGI(WmsLogTag::DEFAULT, "called");
99 auto ret = SceneSessionManagerLiteProxy::RegisterSessionListener(listener);
100 if (ret != WSError::WS_OK) {
101 return ret;
102 }
103 if (isRecover) {
104 TLOGI(WmsLogTag::DEFAULT, "Recover mode, no need to save listener");
105 return WSError::WS_OK;
106 }
107 SessionManagerLite::GetInstance().SaveSessionListener(listener);
108 return WSError::WS_OK;
109 }
110 WSError UnRegisterSessionListener(const sptr<ISessionListener>& listener) override
111 {
112 TLOGI(WmsLogTag::DEFAULT, "called");
113 auto ret = SceneSessionManagerLiteProxy::UnRegisterSessionListener(listener);
114 SessionManagerLite::GetInstance().DeleteSessionListener(listener);
115 return ret;
116 }
117
118 private:
119 static inline BrokerDelegator<SceneSessionManagerLiteProxyMock> delegator_;
120 };
121
122 WM_IMPLEMENT_SINGLE_INSTANCE(SessionManagerLite)
123
~SessionManagerLite()124 SessionManagerLite::~SessionManagerLite()
125 {
126 TLOGI(WmsLogTag::WMS_LIFE, "destroyed");
127 }
128
ClearSessionManagerProxy()129 void SessionManagerLite::ClearSessionManagerProxy()
130 {
131 WLOGFI("enter");
132 std::lock_guard<std::recursive_mutex> lock(mutex_);
133 sessionManagerServiceProxy_ = nullptr;
134 sceneSessionManagerLiteProxy_ = nullptr;
135 screenSessionManagerLiteProxy_ = nullptr;
136 }
137
GetSceneSessionManagerLiteProxy()138 sptr<ISceneSessionManagerLite> SessionManagerLite::GetSceneSessionManagerLiteProxy()
139 {
140 std::lock_guard<std::recursive_mutex> lock(mutex_);
141 InitSessionManagerServiceProxy();
142 InitSceneSessionManagerLiteProxy();
143 return sceneSessionManagerLiteProxy_;
144 }
145
GetScreenSessionManagerLiteProxy()146 sptr<IScreenSessionManagerLite> SessionManagerLite::GetScreenSessionManagerLiteProxy()
147 {
148 std::lock_guard<std::recursive_mutex> lock(mutex_);
149 InitSessionManagerServiceProxy();
150 InitScreenSessionManagerLiteProxy();
151 return screenSessionManagerLiteProxy_;
152 }
153
GetSessionManagerServiceProxy()154 sptr<ISessionManagerService> SessionManagerLite::GetSessionManagerServiceProxy()
155 {
156 std::lock_guard<std::recursive_mutex> lock(mutex_);
157 InitSessionManagerServiceProxy();
158 InitSceneSessionManagerLiteProxy();
159 return sessionManagerServiceProxy_;
160 }
161
SaveSessionListener(const sptr<ISessionListener>& listener)162 void SessionManagerLite::SaveSessionListener(const sptr<ISessionListener>& listener)
163 {
164 if (listener == nullptr) {
165 TLOGW(WmsLogTag::DEFAULT, "listener is nullptr");
166 return;
167 }
168 std::lock_guard<std::recursive_mutex> guard(listenerLock_);
169 auto it = std::find_if(sessionListeners_.begin(), sessionListeners_.end(),
170 [&listener](const sptr<ISessionListener>& item) {
171 return (item && item->AsObject() == listener->AsObject());
172 });
173 if (it != sessionListeners_.end()) {
174 TLOGW(WmsLogTag::DEFAULT, "listener was already added, do not add again");
175 return;
176 }
177 sessionListeners_.emplace_back(listener);
178 }
179
DeleteSessionListener(const sptr<ISessionListener>& listener)180 void SessionManagerLite::DeleteSessionListener(const sptr<ISessionListener>& listener)
181 {
182 TLOGI(WmsLogTag::DEFAULT, "called");
183 std::lock_guard<std::recursive_mutex> guard(listenerLock_);
184 auto it = std::find_if(sessionListeners_.begin(), sessionListeners_.end(),
185 [&listener](const sptr<ISessionListener>& item) {
186 return (item && item->AsObject() == listener->AsObject());
187 });
188 if (it != sessionListeners_.end()) {
189 sessionListeners_.erase(it);
190 }
191 }
192
DeleteAllSessionListeners()193 void SessionManagerLite::DeleteAllSessionListeners()
194 {
195 std::lock_guard<std::recursive_mutex> guard(listenerLock_);
196 sessionListeners_.clear();
197 }
198
RecoverSessionManagerService(const sptr<ISessionManagerService>& sessionManagerService)199 void SessionManagerLite::RecoverSessionManagerService(const sptr<ISessionManagerService>& sessionManagerService)
200 {
201 {
202 std::lock_guard<std::recursive_mutex> lock(mutex_);
203 sessionManagerServiceProxy_ = sessionManagerService;
204 }
205 GetSceneSessionManagerLiteProxy();
206 ReregisterSessionListener();
207 if (userSwitchCallbackFunc_) {
208 TLOGI(WmsLogTag::WMS_RECOVER, "user switch");
209 userSwitchCallbackFunc_();
210 }
211 }
212
ReregisterSessionListener()213 void SessionManagerLite::ReregisterSessionListener()
214 {
215 sptr<ISceneSessionManagerLite> sceneSessionManagerLiteProxy = nullptr;
216 {
217 std::lock_guard<std::recursive_mutex> lock(mutex_);
218 sceneSessionManagerLiteProxy = sceneSessionManagerLiteProxy_;
219 }
220 if (sceneSessionManagerLiteProxy == nullptr) {
221 TLOGE(WmsLogTag::WMS_RECOVER, "sceneSessionManagerLiteProxy is null");
222 return;
223 }
224
225 std::lock_guard<std::recursive_mutex> guard(listenerLock_);
226 TLOGI(WmsLogTag::WMS_RECOVER, "listener count = %{public}" PRIu64,
227 static_cast<int64_t>(sessionListeners_.size()));
228 for (const auto& listener : sessionListeners_) {
229 auto ret = sceneSessionManagerLiteProxy->RegisterSessionListener(listener, true);
230 if (ret != WSError::WS_OK) {
231 TLOGW(WmsLogTag::WMS_RECOVER, "failed, ret = %{public}" PRId32, ret);
232 }
233 }
234 }
235
RegisterUserSwitchListener(const UserSwitchCallbackFunc& callbackFunc)236 void SessionManagerLite::RegisterUserSwitchListener(const UserSwitchCallbackFunc& callbackFunc)
237 {
238 TLOGI(WmsLogTag::WMS_MULTI_USER, "enter");
239 userSwitchCallbackFunc_ = callbackFunc;
240 }
241
OnWMSConnectionChanged( int32_t userId, int32_t screenId, bool isConnected, const sptr<ISessionManagerService>& sessionManagerService)242 void SessionManagerLite::OnWMSConnectionChanged(
243 int32_t userId, int32_t screenId, bool isConnected, const sptr<ISessionManagerService>& sessionManagerService)
244 {
245 bool isCallbackRegistered = false;
246 int32_t lastUserId = INVALID_USER_ID;
247 int32_t lastScreenId = DEFAULT_SCREEN_ID;
248 {
249 // The mutex ensures the timing of the following variable states in multiple threads
250 std::lock_guard<std::mutex> lock(wmsConnectionMutex_);
251 lastUserId = currentWMSUserId_;
252 lastScreenId = currentScreenId_;
253 isCallbackRegistered = wmsConnectionChangedFunc_ != nullptr;
254 if (isConnected) {
255 currentWMSUserId_ = userId;
256 currentScreenId_ = screenId;
257 }
258 // isWMSConnected_ only represents the wms connection status of the active user
259 if (currentWMSUserId_ == userId) {
260 isWMSConnected_ = isConnected;
261 }
262 }
263 TLOGI(WmsLogTag::WMS_MULTI_USER,
264 "Lite: curUserId=%{public}d, oldUserId=%{public}d, screenId=%{public}d, isConnected=%{public}d", userId,
265 lastUserId, screenId, isConnected);
266 if (isConnected && lastUserId > INVALID_USER_ID && lastUserId != userId) {
267 // Notify the user that the old wms has been disconnected.
268 OnWMSConnectionChangedCallback(lastUserId, lastScreenId, false, isCallbackRegistered);
269 OnUserSwitch(sessionManagerService);
270 }
271 // Notify the user that the current wms connection has changed.
272 OnWMSConnectionChangedCallback(userId, screenId, isConnected, isCallbackRegistered);
273 }
274
OnUserSwitch(const sptr<ISessionManagerService>& sessionManagerService)275 void SessionManagerLite::OnUserSwitch(const sptr<ISessionManagerService>& sessionManagerService)
276 {
277 TLOGI(WmsLogTag::WMS_MULTI_USER, "User switched Lite");
278 {
279 Clear();
280 std::lock_guard<std::recursive_mutex> lock(mutex_);
281 sessionManagerServiceProxy_ = sessionManagerService;
282 sceneSessionManagerLiteProxy_ = nullptr;
283 InitSceneSessionManagerLiteProxy();
284 if (!sceneSessionManagerLiteProxy_) {
285 TLOGE(WmsLogTag::WMS_MULTI_USER, "sceneSessionManagerLiteProxy is null");
286 return;
287 }
288 }
289 ReregisterSessionListener();
290 if (userSwitchCallbackFunc_) {
291 TLOGI(WmsLogTag::WMS_MULTI_USER, "User switch Lite callback.");
292 userSwitchCallbackFunc_();
293 }
294 }
295
InitSessionManagerServiceProxy()296 void SessionManagerLite::InitSessionManagerServiceProxy()
297 {
298 if (sessionManagerServiceProxy_) {
299 return;
300 }
301 auto ret = InitMockSMSProxy();
302 if (ret != WMError::WM_OK) {
303 TLOGE(WmsLogTag::DEFAULT, "Init mock session manager service failed in Lite");
304 return;
305 }
306 RegisterSMSRecoverListener();
307 sptr<IRemoteObject> remoteObject = mockSessionManagerServiceProxy_->GetSessionManagerService();
308 if (!remoteObject) {
309 WLOGFE("Remote object is nullptr");
310 return;
311 }
312 sessionManagerServiceProxy_ = iface_cast<ISessionManagerService>(remoteObject);
313 if (!sessionManagerServiceProxy_) {
314 WLOGFE("sessionManagerServiceProxy is nullptr");
315 }
316 }
317
InitScreenSessionManagerLiteProxy()318 void SessionManagerLite::InitScreenSessionManagerLiteProxy()
319 {
320 if (screenSessionManagerLiteProxy_) {
321 return;
322 }
323 if (!mockSessionManagerServiceProxy_) {
324 WLOGFE("mockSessionManagerServiceProxy is nullptr");
325 return;
326 }
327
328 sptr<IRemoteObject> remoteObject = mockSessionManagerServiceProxy_->GetScreenSessionManagerLite();
329 if (!remoteObject) {
330 WLOGFW("Get screen session manager lite proxy failed, null");
331 return;
332 }
333 screenSessionManagerLiteProxy_ = iface_cast<IScreenSessionManagerLite>(remoteObject);
334 if (!screenSessionManagerLiteProxy_) {
335 WLOGFW("Get screen session manager lite proxy failed, iface_cast null");
336 }
337 }
338
InitSceneSessionManagerLiteProxy()339 void SessionManagerLite::InitSceneSessionManagerLiteProxy()
340 {
341 if (sceneSessionManagerLiteProxy_) {
342 return;
343 }
344 if (!sessionManagerServiceProxy_) {
345 WLOGFE("sessionManagerServiceProxy is nullptr");
346 return;
347 }
348
349 sptr<IRemoteObject> remoteObject = sessionManagerServiceProxy_->GetSceneSessionManagerLite();
350 if (!remoteObject) {
351 WLOGFW("Get scene session manager proxy failed, null");
352 return;
353 }
354 sceneSessionManagerLiteProxy_ = iface_cast<ISceneSessionManagerLite>(remoteObject);
355 if (sceneSessionManagerLiteProxy_) {
356 ssmDeath_ = sptr<SSMDeathRecipientLite>::MakeSptr();
357 if (remoteObject->IsProxyObject() && !remoteObject->AddDeathRecipient(ssmDeath_)) {
358 WLOGFE("Failed to add death recipient");
359 return;
360 }
361 } else {
362 WLOGFW("Get scene session manager proxy failed, iface_cast null");
363 }
364 }
365
Clear()366 void SessionManagerLite::Clear()
367 {
368 std::lock_guard<std::recursive_mutex> lock(mutex_);
369 if ((sceneSessionManagerLiteProxy_ != nullptr) && (sceneSessionManagerLiteProxy_->AsObject() != nullptr)) {
370 sceneSessionManagerLiteProxy_->AsObject()->RemoveDeathRecipient(ssmDeath_);
371 }
372 }
373
OnRemoteDied(const wptr<IRemoteObject>& wptrDeath)374 void SSMDeathRecipientLite::OnRemoteDied(const wptr<IRemoteObject>& wptrDeath)
375 {
376 WLOGI("ssm OnRemoteDied");
377 SessionManagerLite::GetInstance().Clear();
378 SessionManagerLite::GetInstance().ClearSessionManagerProxy();
379 }
380
RegisterWMSConnectionChangedListener(const WMSConnectionChangedCallbackFunc& callbackFunc)381 WMError SessionManagerLite::RegisterWMSConnectionChangedListener(const WMSConnectionChangedCallbackFunc& callbackFunc)
382 {
383 TLOGI(WmsLogTag::WMS_MULTI_USER, "Lite in");
384 if (callbackFunc == nullptr) {
385 TLOGE(WmsLogTag::WMS_MULTI_USER, "Lite callbackFunc is null");
386 return WMError::WM_ERROR_NULLPTR;
387 }
388 bool isWMSAlreadyConnected = false;
389 int32_t userId = INVALID_USER_ID;
390 int32_t screenId = DEFAULT_SCREEN_ID;
391 {
392 // The mutex ensures the timing of the following variable states in multiple threads
393 std::lock_guard<std::mutex> lock(wmsConnectionMutex_);
394 wmsConnectionChangedFunc_ = callbackFunc;
395 isWMSAlreadyConnected = isWMSConnected_ && (currentWMSUserId_ > INVALID_USER_ID);
396 userId = currentWMSUserId_;
397 screenId = currentScreenId_;
398 }
399 if (isWMSAlreadyConnected) {
400 TLOGI(WmsLogTag::WMS_MULTI_USER, "Lite WMS already connected, notify immediately");
401 OnWMSConnectionChangedCallback(userId, screenId, true, true);
402 }
403 {
404 std::lock_guard<std::recursive_mutex> lock(mutex_);
405 auto ret = InitMockSMSProxy();
406 if (ret != WMError::WM_OK) {
407 TLOGE(WmsLogTag::WMS_MULTI_USER, "Init mock session manager service failed");
408 return ret;
409 }
410 RegisterSMSRecoverListener();
411 }
412 return WMError::WM_OK;
413 }
414
InitMockSMSProxy()415 WMError SessionManagerLite::InitMockSMSProxy()
416 {
417 sptr<ISystemAbilityManager> systemAbilityManager =
418 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
419 if (!systemAbilityManager) {
420 TLOGE(WmsLogTag::WMS_MULTI_USER, "Failed to get system ability mgr.");
421 return WMError::WM_ERROR_NULLPTR;
422 }
423 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(WINDOW_MANAGER_SERVICE_ID);
424 if (!remoteObject) {
425 TLOGE(WmsLogTag::WMS_MULTI_USER, "Remote object is nullptr");
426 return WMError::WM_ERROR_NULLPTR;
427 }
428 mockSessionManagerServiceProxy_ = iface_cast<IMockSessionManagerInterface>(remoteObject);
429 if (!mockSessionManagerServiceProxy_) {
430 TLOGE(WmsLogTag::WMS_MULTI_USER, "Get mock session manager service proxy failed, nullptr");
431 return WMError::WM_ERROR_NULLPTR;
432 }
433
434 if (GetUserIdByUid(getuid()) != SYSTEM_USERID || isFoundationListenerRegistered_) {
435 return WMError::WM_OK;
436 }
437 if (!foundationDeath_) {
438 foundationDeath_ = sptr<FoundationDeathRecipientLite>::MakeSptr();
439 }
440 if (remoteObject->IsProxyObject() && !remoteObject->AddDeathRecipient(foundationDeath_)) {
441 TLOGE(WmsLogTag::WMS_MULTI_USER, "Failed to add death recipient");
442 return WMError::WM_ERROR_IPC_FAILED;
443 }
444 isFoundationListenerRegistered_ = true;
445 return WMError::WM_OK;
446 }
447
RegisterSMSRecoverListener()448 void SessionManagerLite::RegisterSMSRecoverListener()
449 {
450 if (!recoverListenerRegistered_) {
451 if (!mockSessionManagerServiceProxy_) {
452 TLOGE(WmsLogTag::WMS_RECOVER, "mockSessionManagerServiceProxy is null");
453 return;
454 }
455 recoverListenerRegistered_ = true;
456 TLOGI(WmsLogTag::WMS_RECOVER, "Register recover listener");
457 smsRecoverListener_ = sptr<SessionManagerServiceLiteRecoverListener>::MakeSptr();
458 std::string identity = IPCSkeleton::ResetCallingIdentity();
459 mockSessionManagerServiceProxy_->RegisterSMSLiteRecoverListener(smsRecoverListener_);
460 IPCSkeleton::SetCallingIdentity(identity);
461 }
462 }
463
OnWMSConnectionChangedCallback( int32_t userId, int32_t screenId, bool isConnected, bool isCallbackRegistered)464 void SessionManagerLite::OnWMSConnectionChangedCallback(
465 int32_t userId, int32_t screenId, bool isConnected, bool isCallbackRegistered)
466 {
467 if (isCallbackRegistered) {
468 TLOGI(WmsLogTag::WMS_MULTI_USER,
469 "WMS connection changed with userId=%{public}d, screenId=%{public}d, isConnected=%{public}d", userId,
470 screenId, isConnected);
471 wmsConnectionChangedFunc_(userId, screenId, isConnected);
472 } else {
473 TLOGD(WmsLogTag::WMS_MULTI_USER, "Lite WMS CallbackFunc is null.");
474 }
475 }
476
OnRemoteDied(const wptr<IRemoteObject>& wptrDeath)477 void FoundationDeathRecipientLite::OnRemoteDied(const wptr<IRemoteObject>& wptrDeath)
478 {
479 TLOGI(WmsLogTag::WMS_RECOVER, "Foundation died");
480 SessionManagerLite::GetInstance().OnFoundationDied();
481 }
482
OnFoundationDied()483 void SessionManagerLite::OnFoundationDied()
484 {
485 TLOGI(WmsLogTag::WMS_RECOVER, "enter");
486 {
487 std::lock_guard<std::mutex> lock(wmsConnectionMutex_);
488 isWMSConnected_ = false;
489 }
490 std::lock_guard<std::recursive_mutex> lock(mutex_);
491 isFoundationListenerRegistered_ = false;
492 recoverListenerRegistered_ = false;
493 mockSessionManagerServiceProxy_ = nullptr;
494 sessionManagerServiceProxy_ = nullptr;
495 sceneSessionManagerLiteProxy_ = nullptr;
496 }
497 } // namespace OHOS::Rosen
498