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