Check SceneHolder validation if we call SetFocusActor 60/314960/1
authorEunki, Hong <eunkiki.hong@samsung.com>
Wed, 24 Jul 2024 01:13:26 +0000 (10:13 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Wed, 24 Jul 2024 01:13:26 +0000 (10:13 +0900)
Since SceneHolder destructor doesn't change child's SceneOn state directly,
It might be possible that SceneHolder is destroyed but Scene is alive.

To avoid this case, let we check the SceneHolder validation one more time.

Change-Id: I16ba69bc5754fe2cec20eea85afc09634064690f
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp

index b3d7f48..b9abe8a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -206,13 +206,16 @@ bool KeyboardFocusManager::SetCurrentFocusActor(Actor actor)
 
 bool KeyboardFocusManager::DoSetCurrentFocusActor(Actor actor)
 {
-  bool success = false;
+  bool                     success = false;
+  Integration::SceneHolder currentWindow;
 
   // Check whether the actor is in the stage and is keyboard focusable.
   if(actor &&
      actor.GetProperty<bool>(Actor::Property::KEYBOARD_FOCUSABLE) &&
      actor.GetProperty<bool>(DevelActor::Property::USER_INTERACTION_ENABLED) &&
-     actor.GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
+     actor.GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE) &&
+     (currentWindow = Integration::SceneHolder::Get(actor))) ///< Note : SceneHolder might not be valid even if actor is connected to scene.
+                                                             ///         (e.g. Adaptor Stopped, SceneHolder removed but Scene is still alive)
   {
     // If the parent's KEYBOARD_FOCUSABLE_CHILDREN is false, it cannot have focus.
     Actor parent = actor.GetParent();
@@ -234,12 +237,11 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor(Actor actor)
       return true;
     }
 
-    Integration::SceneHolder currentWindow = Integration::SceneHolder::Get(actor);
     if(currentWindow.GetRootLayer() != mCurrentFocusedWindow.GetHandle())
     {
       Layer rootLayer       = currentWindow.GetRootLayer();
       mCurrentFocusedWindow = rootLayer;
-      mCurrentWindowId = static_cast<uint32_t>(currentWindow.GetNativeId());
+      mCurrentWindowId      = static_cast<uint32_t>(currentWindow.GetNativeId());
     }
 
     if((mIsFocusIndicatorShown == SHOW) && (mEnableFocusIndicator == ENABLE))
@@ -682,7 +684,7 @@ void KeyboardFocusManager::ClearFocus(Actor actor)
 {
   if(actor)
   {
-    DALI_LOG_RELEASE_INFO("ClearFocus id:(%d)\n",  actor.GetProperty<int32_t>(Dali::Actor::Property::ID));
+    DALI_LOG_RELEASE_INFO("ClearFocus id:(%d)\n", actor.GetProperty<int32_t>(Dali::Actor::Property::ID));
     actor.OffSceneSignal().Disconnect(mSlotDelegate, &KeyboardFocusManager::OnSceneDisconnection);
     // Send notification for the change of focus actor
     if(!mFocusChangedSignal.Empty())
@@ -1113,7 +1115,7 @@ void KeyboardFocusManager::OnWindowFocusChanged(Window window, bool focusIn)
     // Change Current Focused Window
     Layer rootLayer       = window.GetRootLayer();
     mCurrentFocusedWindow = rootLayer;
-    mCurrentWindowId = static_cast<uint32_t>(Integration::SceneHolder::Get(rootLayer).GetNativeId());
+    mCurrentWindowId      = static_cast<uint32_t>(Integration::SceneHolder::Get(rootLayer).GetNativeId());
 
     // Get Current Focused Actor from window
     Actor currentFocusedActor = GetFocusActorFromCurrentWindow();