• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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