Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 34 additions & 20 deletions src/Tizen.Applications.UIGadget/Tizen.Applications/UIGadgetInfo.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
Expand Down Expand Up @@ -222,31 +222,45 @@ private static void SetResourceType(UIGadgetInfo info, IntPtr handle)

internal static UIGadgetInfo CreateUIGadgetInfo(string packageId)
{
Interop.PackageManagerInfo.ErrorCode errorCode = Interop.PackageManagerInfo.PackageInfoGet(packageId, out IntPtr handle);
if (errorCode != Interop.PackageManagerInfo.ErrorCode.None)
IntPtr handle = IntPtr.Zero;
try
{
Log.Error("Failed to get package info. error = " + errorCode);
return null;
}
Interop.PackageManagerInfo.ErrorCode errorCode = Interop.PackageManagerInfo.PackageInfoGet(packageId, out handle);
if (errorCode != Interop.PackageManagerInfo.ErrorCode.None)
{
Log.Error("Failed to get package info. packageId: " + packageId + ", error = " + errorCode);
return null;
}

UIGadgetInfo info = new UIGadgetInfo(packageId);
UIGadgetInfo info = new UIGadgetInfo(packageId);

SetResourceType(info, handle);
SetResourceVersion(info, handle);
SetMetadata(info, handle);
SetResourceType(info, handle);
SetResourceVersion(info, handle);
SetMetadata(info, handle);

errorCode = Interop.PackageManagerInfo.PackageInfoDestroy(handle);
if (errorCode != Interop.PackageManagerInfo.ErrorCode.None)
SetExecutableFile(info);
SetResourceFile(info);
SetResourceClassName(info);
SetResourcePath(info);
SetUIGadgetResourcePath(info);
return info;
}
catch (Exception e)
{
Log.Warn("Failed to destroy package info. error = " + errorCode);
Log.Error("Exception occurred while creating UIGadgetInfo. packageId: " + packageId + ", exception: " + e);
return null;
}
finally
{
if (handle != IntPtr.Zero)
{
Interop.PackageManagerInfo.ErrorCode errorCode = Interop.PackageManagerInfo.PackageInfoDestroy(handle);
if (errorCode != Interop.PackageManagerInfo.ErrorCode.None)
{
Log.Warn("Failed to destroy package info. error = " + errorCode);
}
}
}

SetExecutableFile(info);
SetResourceFile(info);
SetResourceClassName(info);
SetResourcePath(info);
SetUIGadgetResourcePath(info);
return info;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
Expand Down Expand Up @@ -39,43 +39,53 @@ public static class UIGadgetManager

static UIGadgetManager()
{
var ptr = Interop.Libc.GetEnvironmentVariable("GADGET_PKGIDS");
if (ptr != IntPtr.Zero)
try
{
var packages = Marshal.PtrToStringAnsi(ptr);
if (!string.IsNullOrWhiteSpace(packages))
var ptr = Interop.Libc.GetEnvironmentVariable("GADGET_PKGIDS");
if (ptr != IntPtr.Zero)
{
foreach (var pkg in packages.Split(':'))
var packages = Marshal.PtrToStringAnsi(ptr);
if (!string.IsNullOrWhiteSpace(packages))
{
var info = UIGadgetInfo.CreateUIGadgetInfo(pkg);
if (info != null)
foreach (var pkg in packages.Split(':'))
{
try
{
_gadgetInfos.TryAdd(info.ResourceType, info);
}
catch (Exception e) when (e is ArgumentNullException || e is OverflowException)
var info = UIGadgetInfo.CreateUIGadgetInfo(pkg);
if (info != null)
{
Log.Error("Exception occurs. " + e.Message);
try
{
_gadgetInfos.TryAdd(info.ResourceType, info);
}
catch (Exception e) when (e is ArgumentNullException || e is OverflowException)
{
Log.Error("Exception occurs while adding gadget info. packageId: " + pkg + ", " + e.Message);
}
Comment on lines +59 to +62

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The exception filter here is quite restrictive. To ensure the robustness intended by this pull request and prevent TypeInitializationException, it is safer to catch all exceptions during gadget info registration, consistent with the implementation in NUIGadgetManager.cs. Additionally, logging the full exception object e instead of just e.Message provides the stack trace, which is essential for debugging.

                                catch (Exception e)
                                {
                                    Log.Error("Exception occurs while adding gadget info. packageId: " + pkg + ", " + e);
                                }

}
}
}
}
else
{
Log.Warn("Failed to get environment variable");
}

var app = CoreApplication.Current as CoreApplication;
if (app != null)
{
app.AppControlReceived += (s, e) => HandleAppControl(e);
app.LowMemory += (s, e) => HandleLowMemoryEvent(e);
app.LowBattery += (s, e) => HandleLowBatteryEvent(e);
app.LocaleChanged += (s, e) => HandleLocaleChangedEvent(e);
app.RegionFormatChanged += (s, e) => HandleRegionFormatChangedEvent(e);
app.DeviceOrientationChanged += (s, e) => HandleDeviceOrientationChangedEvent(e);
}
Comment on lines +72 to +81

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If CoreApplication.Current is null or cannot be cast to CoreApplication, the manager will silently skip registering critical system event handlers (AppControl, LowMemory, etc.). This could lead to difficult-to-debug issues where the application fails to respond to system events. It is recommended to log an error if app is null to aid in troubleshooting.

                var app = CoreApplication.Current as CoreApplication;
                if (app != null)
                {
                    app.AppControlReceived += (s, e) => HandleAppControl(e);
                    app.LowMemory += (s, e) => HandleLowMemoryEvent(e);
                    app.LowBattery += (s, e) => HandleLowBatteryEvent(e);
                    app.LocaleChanged += (s, e) => HandleLocaleChangedEvent(e);
                    app.RegionFormatChanged += (s, e) => HandleRegionFormatChangedEvent(e);
                    app.DeviceOrientationChanged += (s, e) => HandleDeviceOrientationChangedEvent(e);
                }
                else
                {
                    Log.Error("Failed to get CoreApplication instance. Event handlers will not be registered.");
                }


UIGadgetLifecycleEventBroker.LifecycleChanged += OnUIGadgetLifecycleChanged;
}
else
catch (Exception e)
{
Log.Warn("Failed to get environment variable");
Log.Error("Exception occurs in UIGadgetManager static constructor. " + e);
}

var app = (CoreApplication)CoreApplication.Current;
app.AppControlReceived += (s, e) => HandleAppControl(e);
app.LowMemory += (s, e) => HandleLowMemoryEvent(e);
app.LowBattery += (s, e) => HandleLowBatteryEvent(e);
app.LocaleChanged += (s, e) => HandleLocaleChangedEvent(e);
app.RegionFormatChanged += (s, e) => HandleRegionFormatChangedEvent(e);
app.DeviceOrientationChanged += (s, e) => HandleDeviceOrientationChangedEvent(e);

UIGadgetLifecycleEventBroker.LifecycleChanged += OnUIGadgetLifecycleChanged;
}

/// <summary>
Expand Down Expand Up @@ -657,7 +667,7 @@ public static void Refresh()
}
catch (Exception e) when (e is ArgumentNullException || e is OverflowException)
{
Log.Error("Exception occurs. " + e.Message);
Log.Error("Exception occurs while adding gadget info. packageId: " + pkg + ", " + e.Message);
}
Comment on lines 668 to 671

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For consistency and improved robustness, consider catching all exceptions here instead of using a specific filter. Logging the full exception object e is also preferred as it includes the stack trace for better diagnostics.

                        catch (Exception e)
                        {
                            Log.Error("Exception occurs while adding gadget info. packageId: " + pkg + ", " + e);
                        }

}
}
Expand Down
48 changes: 33 additions & 15 deletions src/Tizen.NUI.Gadget/Tizen.NUI/NUIGadgetManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
Expand Down Expand Up @@ -36,26 +36,37 @@ public static class NUIGadgetManager

static NUIGadgetManager()
{
LoadGadgetInfos();
UIGadgetLifecycleEventBroker.LifecycleChanged += OnUIGadgetLifecycleChanged;
try
{
LoadGadgetInfos();
UIGadgetLifecycleEventBroker.LifecycleChanged += OnUIGadgetLifecycleChanged;
}
catch (Exception e)
{
Log.Error("Exception occurs in NUIGadgetManager static constructor. " + e);
}
}

private static void LoadGadgetInfos()
{
foreach (var info in UIGadgetManager.GetUIGadgetInfos())
try
{
try
foreach (var info in UIGadgetManager.GetUIGadgetInfos())
{
var gadgetInfo = new NUIGadgetInfo(info);
if (gadgetInfo != null)
try
{
var gadgetInfo = new NUIGadgetInfo(info);
_gadgetInfos.TryAdd(gadgetInfo.ResourceType, gadgetInfo);
}
catch (Exception e)
{
Log.Error("Exception occurs while creating NUIGadgetInfo. packageId: " + info.PackageId + ", " + e);
}
}
catch (Exception e) when (e is ArgumentNullException || e is OverflowException)
{
Log.Error("Exception occurs. " + e.Message);
}
}
catch (Exception e)
{
Log.Error("Exception occurs in LoadGadgetInfos. " + e);
}
}

Expand Down Expand Up @@ -561,10 +572,17 @@ public static void SendMessage(Bundle message)
/// <since_tizen> 13 </since_tizen>
public static void Refresh()
{
UIGadgetManager.Refresh();
_gadgetInfos.Clear();
LoadGadgetInfos();
Log.Info("# of Gadget after refresh (" + _gadgetInfos.Count + ")");
try
{
UIGadgetManager.Refresh();
_gadgetInfos.Clear();
LoadGadgetInfos();
Log.Info("# of Gadget after refresh (" + _gadgetInfos.Count + ")");
}
catch (Exception e)
{
Log.Error("Exception occurs in NUIGadgetManager.Refresh. " + e);
}
}
}
}
Loading