Skip to content

Fix uigadget api13#7655

Open
upple wants to merge 2 commits into
Samsung:API13from
upple:fix-uigadget-api13
Open

Fix uigadget api13#7655
upple wants to merge 2 commits into
Samsung:API13from
upple:fix-uigadget-api13

Conversation

@upple

@upple upple commented May 20, 2026

Copy link
Copy Markdown
Collaborator

Description of Change

  • Wrap UIGadgetInfo.CreateUIGadgetInfo with try/catch and log packageId on exception
  • Add try/catch in UIGadgetManager static constructor to prevent TypeInitializationException
  • Add try/catch in foreach loop to continue loading other packages on failure
  • Add try/catch in UIGadgetManager.Refresh() with packageId in error logs
  • Add try/catch in NUIGadgetManager static constructor, LoadGadgetInfos, and Refresh

API Changes

  • ACR: N/A

upple added 2 commits May 20, 2026 15:19
- Wrap UIGadgetInfo.CreateUIGadgetInfo with try/catch and log packageId on exception
- Add try/catch in UIGadgetManager static constructor to prevent TypeInitializationException
- Add try/catch in foreach loop to continue loading other packages on failure
- Add try/catch in UIGadgetManager.Refresh() with packageId in error logs
- Add try/catch in NUIGadgetManager static constructor, LoadGadgetInfos, and Refresh

Signed-off-by: Changgyu Choi <changyu.choi@samsung.com>
- Use 'as' cast instead of direct cast for CoreApplication.Current with null check
- Remove redundant outer try/catch in foreach loops (CreateUIGadgetInfo already handles exceptions internally)
- Move PackageInfoDestroy to finally block for proper native handle cleanup
- Remove redundant null check after 'new NUIGadgetInfo' operator

Co-Authored-By: Cline SR
Signed-off-by: Changgyu Choi <changyu.choi@samsung.com>
@upple upple requested review from hjhun and pjh9216 as code owners May 20, 2026 06:25
@github-actions github-actions Bot added the API13 Platform : Tizen 10.0 / TFM: net8.0-tizen10.0 label May 20, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request improves the robustness and error handling of the UIGadget and NUIGadget managers by wrapping initialization and refresh logic in try-catch blocks and ensuring proper resource cleanup. Feedback focuses on further strengthening these improvements by validating essential properties like ResourceType to prevent downstream null references, broadening exception handling to ensure all packages are processed even if one fails, and adding diagnostic logs for missing application contexts.

Comment on lines +237 to +246
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;

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 SetResourceType fails to retrieve the resource type, it logs an error but the method continues. This results in an UIGadgetInfo object with a null ResourceType. Since ResourceType is used as a key in the _gadgetInfos dictionary in UIGadgetManager, this will cause an ArgumentNullException later. It is better to validate that essential properties like ResourceType are successfully set before returning the object.

                SetResourceType(info, handle);
                if (string.IsNullOrEmpty(info.ResourceType))
                {
                    return null;
                }

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

                SetExecutableFile(info);
                SetResourceFile(info);
                SetResourceClassName(info);
                SetResourcePath(info);
                SetUIGadgetResourcePath(info);
                return info;

Comment on lines +59 to +62
catch (Exception e) when (e is ArgumentNullException || e is OverflowException)
{
Log.Error("Exception occurs while adding gadget info. packageId: " + pkg + ", " + e.Message);
}

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 when (e is ArgumentNullException || e is OverflowException) is quite restrictive. If any other unexpected exception occurs during the processing of a single package, it will propagate out and cause the entire static constructor to fail (caught by the outer block, but stopping the loop). It is safer to catch all exceptions within the loop to ensure that one problematic package doesn't prevent others from being loaded. Additionally, logging the full exception object e instead of just e.Message provides much better diagnostic information, such as stack traces.

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

Comment on lines +73 to +81
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);
}

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

When CoreApplication.Current is null or not a CoreApplication, the lifecycle events are silently skipped. This could lead to difficult-to-debug issues where the manager appears to be initialized but doesn't respond to system events. Adding a warning log in an else block would improve maintainability and aid in troubleshooting.

                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.Warn("CoreApplication.Current is null or not a CoreApplication. Lifecycle events will not be handled.");
                }

Comment on lines 668 to 671
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);
}

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

Similar to the static constructor, catching only specific exceptions here might cause the Refresh operation to abort prematurely if an unexpected error occurs for one package. Catching the base Exception and logging the full exception object e is recommended for better robustness and consistency with the changes in NUIGadgetManager.

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

@JoonghyunCho

Copy link
Copy Markdown
Member

🤖 [AI Review]

Reviewed — no findings.

Scope checked:

  • UIGadgetInfo.CreateUIGadgetInfo: PackageInfoDestroy moved into a finally — the native package handle is now released on every path including exceptions (fixes the prior leak), and the resource setters still run while the handle is valid.
  • Static-constructor hardening: (CoreApplication)CoreApplication.Current hard cast → as CoreApplication + null guard avoids InvalidCastException/TypeInitializationException; lifecycle event wiring remains unconditional.
  • NUIGadgetManager.LoadGadgetInfos: removal of the dead if (gadgetInfo != null) after new NUIGadgetInfo(...) is safe (a constructor cannot return null) and per-item failures are now isolated in the inner catch.
  • Public API surface: no signature changes; only Refresh() body changed and it retains its <since_tizen> 13 documentation — no missing-doc surface across the 3 files (all internal/private/static-ctor or body-only).

No 🔴 critical issues, no 🟡 suggestions to flag.


Automated review — final merge decision rests with human reviewers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

API13 Platform : Tizen 10.0 / TFM: net8.0-tizen10.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants