feat: Configurable widgets for Android#396
Conversation
|
To view this pull requests documentation preview, visit the following URL: docs.page/abausg/home_widget~396 Documentation is deployed and generated using docs.page. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds Android widget-configuration support: two new Dart APIs to detect configure-time launches and finish configuration, platform handlers on Android and iOS plugins, updated (duplicated) documentation, and tests and an example integration exercising the configure pathway. Changes
Sequence Diagram(s)sequenceDiagram
participant App as Flutter App
participant Plugin as Android Plugin
participant Activity as Android Activity
participant System as Android Home Launcher
Note over System,Activity: Launcher starts Activity for widget configuration
System->>Activity: start (action=APPWIDGET_CONFIGURE, EXTRA_APPWIDGET_ID)
Activity->>Plugin: activity attached / intent available
App->>Plugin: invokeMethod("initiallyLaunchedFromHomeWidgetConfigure")
Plugin->>Activity: read intent.action and EXTRA_APPWIDGET_ID
Plugin-->>App: return widgetId (string) or null
App->>Plugin: invokeMethod("finishHomeWidgetConfigure")
Plugin->>Activity: setResult(RESULT_OK, EXTRA_APPWIDGET_ID) and finish()
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In
`@packages/home_widget/android/src/main/kotlin/es/antonborri/home_widget/HomeWidgetPlugin.kt`:
- Around line 139-147: The handler for
"initiallyLaunchedFromHomeWidgetConfigure" in HomeWidgetPlugin returns "-1" when
the EXTRA_APPWIDGET_ID is missing because it converts the int directly to
string; change the logic to read the int via activity?.intent?.getIntExtra(...),
check if it equals AppWidgetManager.INVALID_APPWIDGET_ID and call
result.success(null) in that case, otherwise call result.success(id.toString())
so Dart receives null for invalid/missing widget IDs.
🧹 Nitpick comments (1)
docs/features/configurable-widgets.mdx (1)
440-462: Add documentation aboutandroid:exportedattribute and configure activity return requirements.The current snippet omits two critical implementation details. On Android 12+, the configure activity must declare
android:exported="true"(otherwise the app cannot be installed). Additionally, the configure activity must returnRESULT_OKwithEXTRA_APPWIDGET_IDfor the widget to actually be added; without this, the widget won't appear even if configuration completes successfully.📌 Suggested doc addition
<intent-filter> <action android:name="android.intent.action.APPWIDGET_CONFIGURE"/> </intent-filter> +> **Note:** On Android 12+ the configure activity must include `android:exported="true"`. +> The activity must also return `RESULT_OK` with an Intent containing `EXTRA_APPWIDGET_ID` +> set to the widget ID received from the launch intent; without this, the widget won't be added.
|
Thanks for this! Can you maybe add some more links to official Android Documentation to home_widget's docs? Will try to find some time to review this proper by end of week |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #396 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 3 3
Lines 163 167 +4
=========================================
+ Hits 163 167 +4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@ABausG I've added a link to the Android docs page on this feature. I also made a minor change to the code based on the CodeRabbit suggestion in this thread. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In
`@packages/home_widget/android/src/main/kotlin/es/antonborri/home_widget/HomeWidgetPlugin.kt`:
- Around line 151-160: The finishHomeWidgetConfigure branch should validate the
AppWidget ID and default the activity result to RESULT_CANCELED early; read the
ID from activity!!.intent?.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID), if the ID is INVALID_APPWIDGET_ID then
call activity!!.setResult(Activity.RESULT_CANCELED) (or leave the default) and
finish, otherwise set activity!!.setResult(Activity.RESULT_OK,
Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId)) and finish;
update the finishHomeWidgetConfigure flow to perform this check before returning
result.success(null).
|
@ABausG just checking in on this PR. If you need any more info, let me know! |
|
Hi sorry. Super busy both with work and a new (really big, really awesome) home_widget feature! To understand the full flow better would you be able to add the android implementation and the suggested usage of these new apis to the configurable_widget? This would help me (but I guess also all users of this) to directly see how they can use it to add configuration to their widgets! |
|
Hey @ABausG, unfortunately I'm swamped and I don't know if or when I would get to that since it looks like that project doesn't have an Android widget implementation at all yet. However, I'd be happy to answer questions and/or expand on the documentation if that would be helpful in understanding how to use this feature. We've implemented it in our own app and it seems to work pretty well. |
ABausG
left a comment
There was a problem hiding this comment.
Thank you so much for this!
I added this to the example app and it works quite nice.
Apart from the comments regarding the documentation: Could you find some time to add the following integration tests:
- iOS integration test: add tests that ensures the two new calls are a no-op on iOS and don't produce a crash
- Add an Android Integration Test to validate that calling
finishHomeWidgetConfiguredoes not produce an error when not started from an activity
As a note: I'll add the example as a follow PR before releasing this feature. I'll probably also then adjust the documentation and advocate for using a separate Activity for the configuration. Just as a heads up.
Once Again: Thank you so much for the contribution and sorry that it took me so long to properly get back to you
|
@jonmarkhall can you give me access to push to your branch? I have the tests and iOS fix ready and just waiting for permission to push to your branch! |
|
@ABausG you should now have write access to our home_widget fork. Sorry, I completely missed your earlier comment about tests etc. Thank you for your work on this! |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/home_widget/example/integration_test/ios_test.dart (1)
145-145: Rename the group to match iOS intent.
Android Configurable Widgetsinsideios_test.dartis a bit misleading; consider naming it as iOS no-op compatibility for Android-only APIs.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/home_widget/example/integration_test/ios_test.dart` at line 145, Rename the test group label to reflect iOS intent: locate the group call currently written as group('Android Configurable Widgets', () { in ios_test.dart and change the string to something like 'iOS no-op compatibility for Android-only APIs' (or similar) so the group name accurately describes iOS behavior while leaving the group function and its tests unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/home_widget/example/integration_test/ios_test.dart`:
- Around line 145-171: Replace the incorrect use of returnsNormally on async
closures with proper Future matchers so the tests await actual completion: for
each call to HomeWidget.isRequestPinWidgetSupported(),
HomeWidget.requestPinWidget(...),
HomeWidget.initiallyLaunchedFromHomeWidgetConfigure(), and
HomeWidget.finishHomeWidgetConfigure() use either completes (to assert
successful completion) or completion(<matcher>) if you need to assert the
returned value (e.g., completion(isFalse) or completion(isNull)); keep the
initial HomeWidget.setAppGroupId(...) as-is. Also add complementary Android-side
integration tests in
packages/home_widget/example/integration_test/android_test.dart that exercise
the configure flow (launch intent, widget ID handling, and calling
finishHomeWidgetConfigure()).
---
Nitpick comments:
In `@packages/home_widget/example/integration_test/ios_test.dart`:
- Line 145: Rename the test group label to reflect iOS intent: locate the group
call currently written as group('Android Configurable Widgets', () { in
ios_test.dart and change the string to something like 'iOS no-op compatibility
for Android-only APIs' (or similar) so the group name accurately describes iOS
behavior while leaving the group function and its tests unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: bc01ebae-b0b8-46f5-95de-3de837fab694
📒 Files selected for processing (3)
packages/home_widget/example/integration_test/ios_test.dartpackages/home_widget/ios/home_widget/Sources/home_widget/HomeWidgetPlugin.swiftpackages/home_widget/lib/src/home_widget.dart
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/home_widget/lib/src/home_widget.dart
Description
Android supports "reconfigurable" widgets via a Settings item in the widget menu (opened via long-press on the widget), and also on initial widget creation. This PR adds a method,
initiallyLaunchedFromHomeWidgetConfigure(), which can be used to detect if the app was launched from a widget configuration requests, and returns the corresponding widget ID if so. This can then be handled in the app to load a widget settings UI.Checklist
exampleor documentation.Breaking Change?
Related Issues
N/A