Skip to content

Commit 842af48

Browse files
Hyeon-Ukhjhun
andauthored
[Tizen.Applications.UIGadget] Remove idler from lifecycle of UIGadget (#7280)
* Remove idler from lifecycle change of UIGadget Signed-off-by: Hyeon-Uk <rlagusdnr120@gmail.com> * Add UIGadgetLifecycleEventManager class To handle UIGadget's lifecycle synchronously Signed-off-by: Hyeon-Uk <rlagusdnr120@gmail.com> * Add ConcurrentQueue on ProcessLifecycleEvent To handle Lifecycle change event synchonously Signed-off-by: Hyeon-Uk <rlagusdnr120@gmail.com> * Use an idler depending on whether it is main thread or not Signed-off-by: Hyeon-Uk <rlagusdnr120@gmail.com> * Replace state parameter with Action parameter in LifecycleEvent Signed-off-by: Hyeon-Uk <rlagusdnr120@gmail.com> * Remove unnecessary variable Signed-off-by: Hyeon-Uk <rlagusdnr120@gmail.com> --------- Signed-off-by: Hyeon-Uk <rlagusdnr120@gmail.com> Co-authored-by: hjhun <36876573+hjhun@users.noreply.github.com>
1 parent db58651 commit 842af48

File tree

4 files changed

+127
-32
lines changed

4 files changed

+127
-32
lines changed

src/Tizen.Applications.UIGadget/Tizen.Applications/UIGadget.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -342,15 +342,18 @@ public void SendMessage(Bundle message)
342342
/// <since_tizen> 13 </since_tizen>
343343
public void Finish()
344344
{
345-
if (State == UIGadgetLifecycleState.Resumed)
345+
UIGadgetLifecycleManager.DispatchLifecycleEvent(this, () =>
346346
{
347-
OnPause();
348-
}
349-
350-
if (State == UIGadgetLifecycleState.PreCreated || State == UIGadgetLifecycleState.Created || State == UIGadgetLifecycleState.Paused)
351-
{
352-
OnDestroy();
353-
}
347+
if (State == UIGadgetLifecycleState.Resumed)
348+
{
349+
OnPause();
350+
}
351+
352+
if (State == UIGadgetLifecycleState.PreCreated || State == UIGadgetLifecycleState.Created || State == UIGadgetLifecycleState.Paused)
353+
{
354+
OnDestroy();
355+
}
356+
});
354357
}
355358

356359
void IUIGadget.OnAppControlReceived(AppControlReceivedEventArgs args) => OnAppControlReceived(args);

src/Tizen.Applications.UIGadget/Tizen.Applications/UIGadgetLifecycleEventBroker.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,15 @@ public static void NotifyLifecycleChanged(IUIGadget gadget)
4848
throw new ArgumentNullException(nameof(gadget));
4949
}
5050

51-
var args = new UIGadgetLifecycleChangedEventArgs
51+
CoreApplication.Post(() =>
5252
{
53-
State = gadget.State,
54-
UIGadget = gadget,
55-
};
56-
LifecycleChanged?.Invoke(null, args);
53+
var args = new UIGadgetLifecycleChangedEventArgs
54+
{
55+
State = gadget.State,
56+
UIGadget = gadget,
57+
};
58+
LifecycleChanged?.Invoke(null, args);
59+
});
5760
}
5861
}
5962
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the License);
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an AS IS BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
using System;
18+
using System.Collections.Concurrent;
19+
using System.Threading;
20+
21+
namespace Tizen.Applications
22+
{
23+
internal static class UIGadgetLifecycleManager
24+
{
25+
private static ConcurrentQueue<LifecycleEvent> _lifecycleEvents = new ConcurrentQueue<LifecycleEvent>();
26+
private static readonly Thread _mainThread = Thread.CurrentThread;
27+
private static bool _processing = false;
28+
29+
internal static void DispatchLifecycleEvent(IUIGadget gadget, Action action)
30+
{
31+
if (gadget == null)
32+
{
33+
throw new ArgumentNullException(nameof(gadget));
34+
}
35+
36+
Log.Info("ResourceType=" + gadget.UIGadgetInfo.ResourceType + ", State=" + gadget.State);
37+
_lifecycleEvents.Enqueue(new LifecycleEvent(gadget, action));
38+
39+
if (_mainThread.Equals(Thread.CurrentThread))
40+
{
41+
ProcessLifecycleEvent();
42+
}
43+
else
44+
{
45+
Log.Warn("The caller is not main thread.");
46+
CoreApplication.Post(() =>
47+
{
48+
ProcessLifecycleEvent();
49+
});
50+
}
51+
52+
}
53+
54+
private static void ProcessLifecycleEvent()
55+
{
56+
if (_processing)
57+
{
58+
Log.Info("Already processing");
59+
return;
60+
}
61+
62+
_processing = true;
63+
while (!_lifecycleEvents.IsEmpty)
64+
{
65+
if (!_lifecycleEvents.TryDequeue(out LifecycleEvent lifecycleEvent))
66+
{
67+
return;
68+
}
69+
70+
var action = lifecycleEvent.Action;
71+
action?.Invoke();
72+
}
73+
_processing = false;
74+
}
75+
76+
internal class LifecycleEvent
77+
{
78+
internal LifecycleEvent(IUIGadget gadget, Action action)
79+
{
80+
UIGadget = gadget;
81+
Action = action;
82+
}
83+
84+
internal IUIGadget UIGadget { get; set; }
85+
86+
internal Action Action { get; set; }
87+
}
88+
}
89+
}

src/Tizen.Applications.UIGadget/Tizen.Applications/UIGadgetManager.cs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -324,11 +324,13 @@ public static void PreCreate(IUIGadget gadget)
324324
throw new ArgumentNullException(nameof(gadget));
325325
}
326326

327-
Log.Warn("ResourceType: " + gadget.UIGadgetInfo.ResourceType + ", State: " + gadget.State);
328-
if (gadget.State == UIGadgetLifecycleState.Initialized)
327+
UIGadgetLifecycleManager.DispatchLifecycleEvent(gadget, () =>
329328
{
330-
gadget.OnPreCreate();
331-
}
329+
if (gadget.State == UIGadgetLifecycleState.Initialized)
330+
{
331+
gadget.OnPreCreate();
332+
}
333+
});
332334
}
333335

334336
/// <summary>
@@ -351,17 +353,18 @@ public static void Create(IUIGadget gadget)
351353
return;
352354
}
353355

354-
Log.Warn("ResourceType: " + gadget.UIGadgetInfo.ResourceType + ", State: " + gadget.State);
355-
if (gadget.State == UIGadgetLifecycleState.PreCreated)
356+
UIGadgetLifecycleManager.DispatchLifecycleEvent(gadget, () =>
356357
{
357-
gadget.MainView = gadget.OnCreate();
358-
if (gadget.MainView == null)
358+
if (gadget.State == UIGadgetLifecycleState.PreCreated)
359359
{
360-
throw new InvalidOperationException("The View MUST be created");
360+
gadget.MainView = gadget.OnCreate();
361+
if (gadget.MainView == null)
362+
{
363+
throw new InvalidOperationException("The View MUST be created");
364+
}
365+
_gadgets.TryAdd(gadget, 0);
361366
}
362-
363-
_gadgets.TryAdd(gadget, 0);
364-
}
367+
});
365368
}
366369

367370
/// <summary>
@@ -383,9 +386,8 @@ public static void Remove(IUIGadget gadget)
383386
}
384387

385388
_gadgets.TryRemove(gadget, out _);
386-
CoreApplication.Post(() =>
389+
UIGadgetLifecycleManager.DispatchLifecycleEvent(gadget, () =>
387390
{
388-
Log.Warn("ResourceType: " + gadget.UIGadgetInfo.ResourceType + ", State: " + gadget.State);
389391
gadget.Finish();
390392
});
391393
}
@@ -428,11 +430,10 @@ public static void Resume(IUIGadget gadget)
428430
return;
429431
}
430432

431-
CoreApplication.Post(() =>
433+
UIGadgetLifecycleManager.DispatchLifecycleEvent(gadget, () =>
432434
{
433-
Log.Warn("ResourceType: " + gadget.UIGadgetInfo.ResourceType + ", State: " + gadget.State);
434435
if (gadget.State == UIGadgetLifecycleState.Created || gadget.State == UIGadgetLifecycleState.Paused)
435-
{
436+
{
436437
gadget.OnResume();
437438
}
438439
});
@@ -459,9 +460,8 @@ public static void Pause(IUIGadget gadget)
459460
return;
460461
}
461462

462-
CoreApplication.Post(() =>
463+
UIGadgetLifecycleManager.DispatchLifecycleEvent(gadget, () =>
463464
{
464-
Log.Warn("ResourceType: " + gadget.UIGadgetInfo.ResourceType + ", State: " + gadget.State);
465465
if (gadget.State == UIGadgetLifecycleState.Resumed)
466466
{
467467
gadget.OnPause();

0 commit comments

Comments
 (0)