Widget Fix V5 - Process Isolation and Listener Management
Problem Analysis
The widget was working initially but stopped updating after some time due to several critical issues:
Root Causes
Process Isolation Issue
- Widget forms run in separate processes (
apppool) from the main app
- Static
globalListenerSetup flag prevented proper listener registration in new processes
- Each widget click creates a new form process, but listeners weren't being set up correctly
Listener Management Problems
- Main app showed
listeners=0 while form process showed listeners=1
- No duplicate listener prevention in PlayerControlService
- AvSessionWidgetListener wasn't properly handling cross-process data synchronization
Data Synchronization Issues
- Form processes weren't requesting current state on startup
- No retry mechanism for failed widget updates
- Missing process identification for debugging
Key Fixes Applied
1. Fixed Static Listener Setup
File: entry/src/main/ets/entryformability/EntryFormAbility.ets
// Changed from static to instance variable
private globalListenerSetup: boolean = false; // Was: private static globalListenerSetup
// This ensures each process instance can set up its own listeners
2. Enhanced AvSessionWidgetListener
File: entry/src/main/ets/common/widget/AvSessionWidgetListener.ets
- Added process identification for better debugging
- Added delayed callback to give main app time to broadcast state
- Enhanced logging with process ID
3. Improved PlayerControlService
File: entry/src/main/ets/common/widget/PlayerControlService.ets
- Added duplicate listener prevention
- Added automatic state request on initialization
- Enhanced CommonEvent handling with better error recovery
4. Added Widget Update Retry Mechanism
File: entry/src/main/ets/entryformability/EntryFormAbility.ets
- Split widget update into individual widget updates with retry logic
- Added exponential backoff for failed updates
- Enhanced logging for better debugging
Technical Details
Process Flow
- User clicks widget → New form process starts
- EntryFormAbility.onAddForm() called
- initializeServices() sets up listeners (now works correctly)
- setupGlobalStateListener() registers with AvSessionWidgetListener
- PlayerControlService requests current state from main app
- Main app broadcasts state via CommonEvent
- Form process receives and updates widget UI
Key Improvements
- Process-aware singleton: Each process gets its own listener setup
- State synchronization: Form processes actively request current state
- Retry mechanism: Failed widget updates are retried with backoff
- Better debugging: Process IDs and enhanced logging
Expected Behavior After Fix
- Initial Load: Widget shows current playing state immediately
- User Interaction: Button clicks work and trigger proper state updates
- State Changes: All widgets update when playback state changes
- Process Resilience: New widget processes properly sync with main app
- Error Recovery: Failed updates are retried automatically
Testing Recommendations
Basic Functionality
- Add widget to desktop
- Verify it shows current playing state
- Test play/pause, next/previous buttons
Process Isolation
- Add multiple widgets
- Click widgets after some time of inactivity
- Verify all widgets update correctly
State Synchronization
- Change playback state in main app
- Verify all widgets reflect the change
- Test with app in background
Error Recovery
- Monitor logs for retry attempts
- Verify widgets eventually update even after initial failures
Log Monitoring
Key log patterns to watch for:
[process_xxx] Updating widget data - Process-specific updates
State listener registered, total listeners: X - Listener count tracking
Current state requested from main app - State synchronization
Widget updated successfully - Successful updates
update failed, retry count: X - Retry attempts
This fix addresses the core process isolation issues that were preventing widgets from updating after initial creation.