chendeben 1 год назад
Родитель
Сommit
207075abd9

+ 115 - 117
entry/src/main/ets/common/service/DataPersistenceService.ets

@@ -43,7 +43,6 @@ export interface PlayerStateData {
   isPaused: boolean;
   currentIndex: number;
   playMode: PlayMode;
-  isFavorite: boolean;
   volume: number;
   speed: number;
   timestamp: number;
@@ -114,7 +113,7 @@ export class DataPersistenceService implements IDataPersistenceService {
   private static readonly COMPLETION_THRESHOLD = 5000;
 
   private constructor() {
-    
+
   }
 
   public static getInstance(): DataPersistenceService {
@@ -126,26 +125,26 @@ export class DataPersistenceService implements IDataPersistenceService {
 
   async initialize(context: common.UIAbilityContext): Promise<void> {
     if (this.isInitialized && this.context) {
-      
-      
+
+
       return;
     }
 
     try {
       // 验证context是否有效
       if (!context) {
-        
+
         throw new Error('Context is null');
       }
 
       this.context = context;
       this.isInitialized = true;
 
-      
-      
+
+
     } catch (error) {
-      
-      
+
+
       throw new Error;
     }
   }
@@ -154,22 +153,22 @@ export class DataPersistenceService implements IDataPersistenceService {
    * 重新初始化context(用于context失效后的恢复)
    */
   async reinitialize(context: common.UIAbilityContext): Promise<void> {
-    
-    
+
+
     try {
       if (!context) {
-        
+
         throw new Error('Context is null');
       }
 
       this.context = context;
       this.isInitialized = true;
 
-      
-      
+
+
     } catch (error) {
-      
-      
+
+
       throw new Error;
     }
   }
@@ -215,8 +214,8 @@ export class DataPersistenceService implements IDataPersistenceService {
         try {
           PreferencesUtil.putSync(key, JSON.stringify(progressData));
         } catch (error) {
-          
-          
+
+
           // 即使PreferencesUtil失败,AppStorage已保存,不抛出异常
         }
       }
@@ -226,9 +225,9 @@ export class DataPersistenceService implements IDataPersistenceService {
         await this.addToCompletedSongs(songId);
       }
 
-      
+
     } catch (error) {
-      
+
       throw new Error;
     }
   }
@@ -264,34 +263,34 @@ export class DataPersistenceService implements IDataPersistenceService {
                 AppStorage.setOrCreate(key, progressData);
                 break; // 成功,跳出循环
               } catch (parseError) {
-                
+
                 return null;
               }
             } else {
               break; // 没有数据
             }
           } catch (preferencesError) {
-            
-            
+
+
             if (preferencesError.toString().includes('context is invalid') && retryCount < maxRetries - 1) {
               await new Promise<void>(resolve => setTimeout(resolve, 50));
             } else {
               break;
             }
-            
+
             retryCount++;
           }
         }
       }
 
       if (progressData) {
-        
+
         return progressData;
       }
 
       return null;
     } catch (error) {
-      
+
       return null;
     }
   }
@@ -314,9 +313,9 @@ export class DataPersistenceService implements IDataPersistenceService {
       // 从AppStorage删除
       AppStorage.delete(key);
 
-      
+
     } catch (error) {
-      
+
       throw new Error;
     }
   }
@@ -339,12 +338,12 @@ export class DataPersistenceService implements IDataPersistenceService {
       }
 
       // 清空已完成列表
-       PreferencesUtil.deleteSync(DataPersistenceService.KEYS.COMPLETED_SONGS);
+      PreferencesUtil.deleteSync(DataPersistenceService.KEYS.COMPLETED_SONGS);
       AppStorage.delete(DataPersistenceService.KEYS.COMPLETED_SONGS);
 
-      
+
     } catch (error) {
-      
+
       throw new Error;
     }
   }
@@ -361,7 +360,7 @@ export class DataPersistenceService implements IDataPersistenceService {
         AppStorage.setOrCreate(DataPersistenceService.KEYS.COMPLETED_SONGS, completedSongs);
       }
     } catch (error) {
-      
+
     }
   }
 
@@ -381,14 +380,14 @@ export class DataPersistenceService implements IDataPersistenceService {
           completedSongs = parsedData;
           AppStorage.setOrCreate(DataPersistenceService.KEYS.COMPLETED_SONGS, completedSongs);
         } catch (parseError) {
-          
+
           completedSongs = [];
         }
       }
 
       return completedSongs || [];
     } catch (error) {
-      
+
       return [];
     }
   }
@@ -400,7 +399,7 @@ export class DataPersistenceService implements IDataPersistenceService {
   async savePlaylist(playlist: VideoItem[], currentIndex: number, playMode: PlayMode): Promise<void> {
     try {
       if (!this.isInitialized) {
-        
+
         throw new Error('DataPersistenceService not initialized');
       }
 
@@ -413,7 +412,7 @@ export class DataPersistenceService implements IDataPersistenceService {
 
       // 首先保存到AppStorage(确保内存中有数据)
       AppStorage.setOrCreate(DataPersistenceService.KEYS.PLAYLIST, playlistData);
-      
+
 
       // 如果context有效,尝试保存到PreferencesUtil
       if (this.context) {
@@ -423,37 +422,37 @@ export class DataPersistenceService implements IDataPersistenceService {
 
         while (retryCount < maxRetries) {
           try {
-             PreferencesUtil.putSync(DataPersistenceService.KEYS.PLAYLIST, JSON.stringify(playlistData));
-            
+            PreferencesUtil.putSync(DataPersistenceService.KEYS.PLAYLIST, JSON.stringify(playlistData));
+
             break; // 成功,跳出循环
           } catch (error) {
             lastError = error;
-            
-            
+
+
             if (error.toString().includes('context is invalid')) {
-              
+
               await new Promise<void>(resolve => setTimeout(resolve, 100 * (retryCount + 1)));
             } else {
               // 其他错误,不重试
               break;
             }
-            
+
             retryCount++;
           }
         }
 
         if (retryCount >= maxRetries && lastError) {
-          
-          
+
+
         }
       } else {
-        
+
       }
 
-      
+
     } catch (error) {
-      
-      
+
+
       throw new Error;
     }
   }
@@ -464,7 +463,7 @@ export class DataPersistenceService implements IDataPersistenceService {
   async loadPlaylist(): Promise<PlaylistData | null> {
     try {
       if (!this.isInitialized) {
-        
+
         throw new Error('DataPersistenceService not initialized');
       }
 
@@ -475,12 +474,12 @@ export class DataPersistenceService implements IDataPersistenceService {
       if (!playlistData) {
         // 检查context是否有效
         if (!this.context) {
-          
+
           return null;
         }
 
         // 从PreferencesUtil获取,增加重试机制
-        
+
 
         const maxRetries = 3;
         let retryCount = 0;
@@ -489,19 +488,19 @@ export class DataPersistenceService implements IDataPersistenceService {
         while (retryCount < maxRetries) {
           try {
             const playlistStr = PreferencesUtil.getStringSync(DataPersistenceService.KEYS.PLAYLIST, '');
-            
+
 
             if (playlistStr) {
               try {
                 const parsedData = JSON.parse(playlistStr) as PlaylistData;
                 playlistData = parsedData;
-                
+
                 // 同步到AppStorage
                 AppStorage.setOrCreate(DataPersistenceService.KEYS.PLAYLIST, playlistData);
                 break; // 成功,跳出循环
               } catch (parseError) {
-                
-                
+
+
                 return null;
               }
             } else {
@@ -510,36 +509,36 @@ export class DataPersistenceService implements IDataPersistenceService {
             }
           } catch (preferencesError) {
             lastError = preferencesError;
-            
-            
+
+
             // 如果是context无效错误,增加等待时间
             if (preferencesError.toString().includes('context is invalid')) {
-              
+
               await new Promise<void>(resolve => setTimeout(resolve, 100 * (retryCount + 1)));
             } else {
               // 其他错误,不重试
               break;
             }
-            
+
             retryCount++;
           }
         }
 
         // 如果所有重试都失败了
         if (retryCount >= maxRetries && lastError) {
-          
+
           return null;
         }
       }
 
       if (playlistData) {
-        
+
         return playlistData;
       }
-      
+
       return null;
     } catch (error) {
-      
+
       return null;
     }
   }
@@ -552,7 +551,7 @@ export class DataPersistenceService implements IDataPersistenceService {
   async savePlayerState(state: PlayerState): Promise<void> {
     try {
       if (!this.isInitialized) {
-        
+
         throw new Error('DataPersistenceService not initialized');
       }
 
@@ -561,7 +560,6 @@ export class DataPersistenceService implements IDataPersistenceService {
         isPaused: state.isPaused,
         currentIndex: state.currentIndex,
         playMode: state.playMode,
-        isFavorite: state.isFavorite,
         volume: state.volume,
         speed: state.speed,
         timestamp: Date.now()
@@ -582,32 +580,32 @@ export class DataPersistenceService implements IDataPersistenceService {
             break; // 成功,跳出循环
           } catch (error) {
             lastError = error;
-            
-            
+
+
             if (error.toString().includes('context is invalid')) {
-              
+
               await new Promise<void>(resolve => setTimeout(resolve, 100 * (retryCount + 1)));
             } else {
               // 其他错误,不重试
               break;
             }
-            
+
             retryCount++;
           }
         }
 
         if (retryCount >= maxRetries && lastError) {
-          
-          
+
+
         }
       } else {
-        
+
       }
 
-      
+
     } catch (error) {
-      
-      
+
+
       throw new Error;
     }
   }
@@ -618,11 +616,11 @@ export class DataPersistenceService implements IDataPersistenceService {
   async loadPlayerState(): Promise<PlayerStateData | null> {
     try {
       if (!this.isInitialized) {
-        
+
         throw new Error('DataPersistenceService not initialized');
       }
 
-      
+
 
       // 优先从AppStorage获取
       let stateData = AppStorage.get<PlayerStateData>(DataPersistenceService.KEYS.PLAYER_STATE);
@@ -630,12 +628,12 @@ export class DataPersistenceService implements IDataPersistenceService {
       if (!stateData) {
         // 检查context是否有效
         if (!this.context) {
-          
+
           return null;
         }
 
         // 从PreferencesUtil获取,增加重试机制
-        
+
 
         const maxRetries = 3;
         let retryCount = 0;
@@ -644,19 +642,19 @@ export class DataPersistenceService implements IDataPersistenceService {
         while (retryCount < maxRetries) {
           try {
             const stateStr = PreferencesUtil.getStringSync(DataPersistenceService.KEYS.PLAYER_STATE, '');
-            
+
 
             if (stateStr) {
               try {
                 const parsedData = JSON.parse(stateStr) as PlayerStateData;
                 stateData = parsedData;
-                
+
                 // 同步到AppStorage
                 AppStorage.setOrCreate(DataPersistenceService.KEYS.PLAYER_STATE, stateData);
                 break; // 成功,跳出循环
               } catch (parseError) {
-                
-                
+
+
                 return null;
               }
             } else {
@@ -665,24 +663,24 @@ export class DataPersistenceService implements IDataPersistenceService {
             }
           } catch (preferencesError) {
             lastError = preferencesError;
-            
-            
+
+
             // 如果是context无效错误,增加等待时间
             if (preferencesError.toString().includes('context is invalid')) {
-              
+
               await new Promise<void>(resolve => setTimeout(resolve, 100 * (retryCount + 1)));
             } else {
               // 其他错误,不重试
               break;
             }
-            
+
             retryCount++;
           }
         }
 
         // 如果所有重试都失败了
         if (retryCount >= maxRetries && lastError) {
-          
+
           return null;
         }
       }
@@ -692,11 +690,11 @@ export class DataPersistenceService implements IDataPersistenceService {
         return stateData;
       }
 
-      
+
       return null;
     } catch (error) {
-      
-      
+
+
       return null;
     }
   }
@@ -723,9 +721,9 @@ export class DataPersistenceService implements IDataPersistenceService {
       // 清除所有播放进度
       await this.clearCompletedProgress();
 
-      
+
     } catch (error) {
-      
+
       throw new Error;
     }
   }
@@ -752,9 +750,9 @@ export class DataPersistenceService implements IDataPersistenceService {
         AppStorage.setOrCreate(DataPersistenceService.KEYS.PLAYER_STATE, stateData);
       }
 
-      
+
     } catch (error) {
-      
+
     }
   }
 
@@ -777,7 +775,7 @@ export class DataPersistenceService implements IDataPersistenceService {
       };
       return stats;
     } catch (error) {
-      
+
       const errorStats: DataStats = {
         playlistSize: 0,
         progressRecords: 0,
@@ -806,7 +804,7 @@ export class PlaylistSyncService {
 
   private constructor() {
     this.dataPersistence = DataPersistenceService.getInstance();
-    
+
   }
 
   public static getInstance(): PlaylistSyncService {
@@ -827,9 +825,9 @@ export class PlaylistSyncService {
         this.startAutoSync();
       }
 
-      
+
     } catch (error) {
-      
+
       throw new Error;
     }
   }
@@ -849,9 +847,9 @@ export class PlaylistSyncService {
       // 通知监听器
       this.notifyPlaylistSynced(playlist, currentIndex, playMode);
 
-      
+
     } catch (error) {
-      
+
       throw new Error;
     }
   }
@@ -866,12 +864,12 @@ export class PlaylistSyncService {
       if (playlistData) {
         // 通知监听器
         this.notifyPlaylistLoaded(playlistData);
-        
+
       }
 
       return playlistData;
     } catch (error) {
-      
+
       return null;
     }
   }
@@ -900,12 +898,12 @@ export class PlaylistSyncService {
 
       if (storedData.timestamp > localTimestamp) {
         // 存储的数据更新,使用存储的数据
-        
+
         return storedData;
       } else {
         // 本地数据更新,同步到存储
         await this.syncPlaylistToStorage(localPlaylist, localIndex, localPlayMode);
-        
+
         return {
           songs: localPlaylist,
           currentIndex: localIndex,
@@ -914,7 +912,7 @@ export class PlaylistSyncService {
         };
       }
     } catch (error) {
-      
+
       // 出错时返回本地数据
       return {
         songs: localPlaylist,
@@ -937,11 +935,11 @@ export class PlaylistSyncService {
       try {
         await this.performAutoSync();
       } catch (error) {
-        
+
       }
     }, PlaylistSyncService.SYNC_INTERVAL);
 
-    
+
   }
 
   /**
@@ -951,7 +949,7 @@ export class PlaylistSyncService {
     if (this.syncTimer !== -1) {
       clearInterval(this.syncTimer);
       this.syncTimer = -1;
-      
+
     }
   }
 
@@ -966,7 +964,7 @@ export class PlaylistSyncService {
       // 通知监听器执行同步检查
       this.notifyAutoSyncPerformed();
     } catch (error) {
-      
+
     }
   }
 
@@ -982,7 +980,7 @@ export class PlaylistSyncService {
       this.stopAutoSync();
     }
 
-    
+
   }
 
   /**
@@ -990,7 +988,7 @@ export class PlaylistSyncService {
    */
   addSyncListener(listener: PlaylistSyncListener): void {
     this.syncListeners.add(listener);
-    
+
   }
 
   /**
@@ -998,7 +996,7 @@ export class PlaylistSyncService {
    */
   removeSyncListener(listener: PlaylistSyncListener): void {
     this.syncListeners.delete(listener);
-    
+
   }
 
   /**
@@ -1009,7 +1007,7 @@ export class PlaylistSyncService {
       try {
         listener.onPlaylistSynced?.(playlist, currentIndex, playMode);
       } catch (error) {
-        
+
       }
     });
   }
@@ -1022,7 +1020,7 @@ export class PlaylistSyncService {
       try {
         listener.onPlaylistLoaded?.(playlistData);
       } catch (error) {
-        
+
       }
     });
   }
@@ -1035,7 +1033,7 @@ export class PlaylistSyncService {
       try {
         listener.onAutoSyncPerformed?.();
       } catch (error) {
-        
+
       }
     });
   }
@@ -1058,7 +1056,7 @@ export class PlaylistSyncService {
   release(): void {
     this.stopAutoSync();
     this.syncListeners.clear();
-    
+
   }
 }
 

+ 26 - 29
entry/src/main/ets/common/service/PlayerStateModel.ets

@@ -25,7 +25,6 @@ export interface PlayerState {
   playMode: PlayMode;
   volume: number;
   speed: number;
-  isFavorite: boolean; // 是否收藏
   // 播放列表相关状态
   hasNext?: boolean;
   hasPrevious?: boolean;
@@ -64,7 +63,7 @@ export class PlayerError extends Error {
   code: number;
   recoverable: boolean;
   retryCount: number;
-  
+
   constructor(type: PlayerErrorType, message: string, code: number = 0) {
     super(message);
     this.type = type;
@@ -72,7 +71,7 @@ export class PlayerError extends Error {
     this.recoverable = this.isRecoverable(type);
     this.retryCount = 0;
   }
-  
+
   private isRecoverable(type: PlayerErrorType): boolean {
     return type !== PlayerErrorType.FILE_NOT_FOUND;
   }
@@ -84,7 +83,7 @@ export class PlayerError extends Error {
 export class PlayerStateModel {
   private state: PlayerState;
   private listeners: Set<PlayerStateListener> = new Set();
-  
+
   constructor() {
     this.state = {
       isPlaying: false,
@@ -99,8 +98,7 @@ export class PlayerStateModel {
       hasNext: false,
       hasPrevious: false,
       totalCount: 0,
-      currentSong: undefined,
-      isFavorite: false
+      currentSong: undefined
     };
   }
 
@@ -121,8 +119,7 @@ export class PlayerStateModel {
       hasNext: this.state.hasNext,
       hasPrevious: this.state.hasPrevious,
       totalCount: this.state.totalCount,
-      currentSong: this.state.currentSong,
-      isFavorite: this.state.isFavorite
+      currentSong: this.state.currentSong
     };
   }
 
@@ -132,14 +129,14 @@ export class PlayerStateModel {
   updatePlayingState(isPlaying: boolean): void {
     const wasPlaying = this.state.isPlaying;
     const wasPaused = this.state.isPaused;
-    
+
     if (this.state.isPlaying !== isPlaying) {
       this.state.isPlaying = isPlaying;
       this.state.isPaused = !isPlaying;
       this.state.isLoading = false;
-      
+
       LogUtils.getInstance().LOGI(`PlayerStateModel: Playing state updated from ${wasPlaying} to ${isPlaying}, paused from ${wasPaused} to ${!isPlaying}`);
-      
+
       this.notifyStateChanged();
     }
   }
@@ -161,11 +158,11 @@ export class PlayerStateModel {
   updateProgress(currentPosition: number, duration: number): void {
     const positionChanged = this.state.currentPosition !== currentPosition;
     const durationChanged = this.state.duration !== duration;
-    
+
     if (positionChanged || durationChanged) {
       this.state.currentPosition = currentPosition;
       this.state.duration = duration;
-      
+
       if (positionChanged || durationChanged) {
         this.notifyProgressChanged();
       }
@@ -182,8 +179,8 @@ export class PlayerStateModel {
       LogUtils.getInstance().LOGI(`PlayerStateModel: Current index updated to ${index}`);
     }
   }  /**
-  
- * 更新播放模式
+
+   * 更新播放模式
    */
   updatePlayMode(mode: PlayMode): void {
     if (this.state.playMode !== mode) {
@@ -220,22 +217,22 @@ export class PlayerStateModel {
    */
   updatePlaylistState(hasNext: boolean, hasPrevious: boolean, totalCount: number): void {
     let changed = false;
-    
+
     if (this.state.hasNext !== hasNext) {
       this.state.hasNext = hasNext;
       changed = true;
     }
-    
+
     if (this.state.hasPrevious !== hasPrevious) {
       this.state.hasPrevious = hasPrevious;
       changed = true;
     }
-    
+
     if (this.state.totalCount !== totalCount) {
       this.state.totalCount = totalCount;
       changed = true;
     }
-    
+
     if (changed) {
       this.notifyStateChanged();
       LogUtils.getInstance().LOGI(`PlayerStateModel: Playlist state updated - hasNext=${hasNext}, hasPrevious=${hasPrevious}, totalCount=${totalCount}`);
@@ -261,34 +258,34 @@ export class PlayerStateModel {
    */
   validate(): boolean {
     const state = this.state;
-    
+
     // 基本状态验证
     if (state.isPlaying && state.isPaused) {
       LogUtils.getInstance().LOGI('PlayerStateModel: Invalid state - cannot be playing and paused simultaneously');
       return false;
     }
-    
+
     // 进度验证
     if (state.currentPosition < 0 || (state.duration > 0 && state.currentPosition > state.duration)) {
       LogUtils.getInstance().LOGI('PlayerStateModel: Invalid progress - position out of range');
       return false;
     }
-    
+
     // 音量验证
     if (state.volume < 0 || state.volume > 1) {
       LogUtils.getInstance().LOGI('PlayerStateModel: Invalid volume - must be between 0 and 1');
       return false;
     }
-    
+
     // 速度验证
     if (state.speed <= 0) {
       LogUtils.getInstance().LOGI('PlayerStateModel: Invalid speed - must be positive');
       return false;
     }
-    
+
     return true;
-  } 
- /**
+  }
+  /**
    * 转换为卡片数据格式
    */
   toWidgetData(currentSong?: VideoItem): WidgetData {
@@ -297,7 +294,7 @@ export class PlayerStateModel {
       isPaused: this.state.isPaused,
       isLoading: this.state.isLoading
     };
-    
+
     const songInfo: SongInfo = currentSong ? {
       id: currentSong.id || '',
       title: currentSong.name || '未知歌曲',
@@ -308,7 +305,7 @@ export class PlayerStateModel {
     } : {
       id: '',
       title: '未知歌曲',
-      artist: '未知艺术家', 
+      artist: '未知艺术家',
       album: '未知专辑',
       coverImagePath: '',
       duration: 0
@@ -396,7 +393,7 @@ export class PlayerStateModel {
       currentTimeText: this.formatTime(Math.floor(this.state.currentPosition / 1000)),
       totalTimeText: this.formatTime(Math.floor(this.state.duration / 1000))
     };
-    
+
     this.listeners.forEach(listener => {
       try {
         listener.onProgressChanged(progress);

+ 0 - 644
entry/src/main/ets/common/service/StateSyncService.ets

@@ -1,644 +0,0 @@
-import commonEventManager from '@ohos.commonEventManager';
-import { hilog } from '@kit.PerformanceAnalysisKit';
-import { common } from '@kit.AbilityKit';
-import { VideoItem } from '../../viewmodel/VideoItem';
-import { PlayerState, PlayMode } from './PlayerStateModel';
-import { PlayProgress, WidgetData } from '../widget/WidgetTypes';
-import { 
-  PLAYER_STATE_CHANGED_EVENT,
-  PLAYER_SONG_CHANGED_EVENT,
-  PLAYER_PROGRESS_CHANGED_EVENT,
-  WIDGET_CONTROL_EVENT,
-  WIDGET_REQUEST_STATE_EVENT
-} from '../widget/WidgetEventConstants';
-
-const TAG = 'StateSyncService';
-
-/**
- * 状态同步服务接口
- */
-export interface IStateSyncService {
-  broadcastState(state: PlayerState): Promise<void>;
-  broadcastSongChange(song: VideoItem): Promise<void>;
-  broadcastProgress(progress: PlayProgress): Promise<void>;
-  subscribeToStateChanges(callback: StateChangeCallback): void;
-  unsubscribeFromStateChanges(callback: StateChangeCallback): void;
-  subscribeToWidgetControl(callback: WidgetControlCallback): void;
-  unsubscribeFromWidgetControl(callback: WidgetControlCallback): void;
-  initialize(context: common.UIAbilityContext): Promise<void>;
-  release(): void;
-}
-
-/**
- * 状态变化回调接口
- */
-export interface StateChangeCallback {
-  onStateChanged?(state: PlayerState): void;
-  onSongChanged?(song: VideoItem): void;
-  onProgressChanged?(progress: PlayProgress): void;
-}
-
-/**
- * 卡片控制命令回调接口
- */
-export interface WidgetControlCallback {
-  onPlayPause?(): Promise<void>;
-  onNextSong?(): Promise<void>;
-  onPreviousSong?(): Promise<void>;
-  onSeekTo?(position: number): Promise<void>;
-  onStateRequest?(): Promise<void>;
-}
-
-/**
- * 卡片控制事件数据
- */
-interface WidgetControlEventData {
-  command: string;
-  params?: Record<string, Object>;
-  timestamp: number;
-  source: string;
-}
-
-/**
- * 播放状态数据接口
- */
-interface PlayStateBroadcast {
-  isPlaying: boolean;
-  isPaused: boolean;
-  isLoading: boolean;
-  currentPosition: number;
-  duration: number;
-}
-
-/**
- * 当前歌曲数据接口
- */
-interface CurrentSongBroadcast {
-  id: string;
-  title: string;
-  artist: string;
-  album: string;
-  filePath: string;
-  duration: number;
-}
-
-/**
- * 进度数据接口
- */
-interface ProgressBroadcast {
-  currentPosition: number;
-  duration: number;
-  percentage: number;
-  currentTimeText: string;
-  totalTimeText: string;
-}
-
-/**
- * 播放列表数据接口
- */
-interface PlaylistBroadcast {
-  hasNext: boolean;
-  hasPrevious: boolean;
-  currentIndex: number;
-  totalCount: number;
-}
-
-/**
- * 播放器状态广播数据
- */
-interface PlayerStateBroadcastData {
-  playState: PlayStateBroadcast;
-  currentSong: CurrentSongBroadcast;
-  progress: ProgressBroadcast;
-  playlist: PlaylistBroadcast;
-}
-
-/**
- * 歌曲变化广播数据
- */
-interface SongChangeBroadcastData {
-  currentSong: CurrentSongBroadcast;
-  playlist: PlaylistBroadcast;
-}
-
-/**
- * 进度更新广播数据
- */
-interface ProgressBroadcastData {
-  currentPosition: number;
-  duration: number;
-  percentage: number;
-  currentTimeText: string;
-  totalTimeText: string;
-}
-
-/**
- * 状态同步服务实现
- * 负责在不同组件和进程间同步播放状态
- */
-export class StateSyncService implements IStateSyncService {
-  private static instance: StateSyncService | null = null;
-  private context: common.UIAbilityContext | null = null;
-  private stateChangeCallbacks: StateChangeCallback[] = [];
-  private widgetControlCallbacks: WidgetControlCallback[] = [];
-  private isInitialized: boolean = false;
-  private lastStateBroadcastTime: number = 0;
-  private lastProgressBroadcastTime: number = 0;
-  private readonly STATE_BROADCAST_THROTTLE: number = 500; // 状态广播节流间隔(毫秒)
-  private readonly PROGRESS_BROADCAST_THROTTLE: number = 1000; // 进度广播节流间隔(毫秒)
-  private readonly COMMAND_EXECUTION_TIMEOUT: number = 5000; // 命令执行超时时间(毫秒)
-
-  private constructor() {}
-
-  public static getInstance(): StateSyncService {
-    if (!StateSyncService.instance) {
-      StateSyncService.instance = new StateSyncService();
-    }
-    return StateSyncService.instance;
-  }
-
-  /**
-   * 初始化状态同步服务
-   */
-  async initialize(context: common.UIAbilityContext): Promise<void> {
-    if (this.isInitialized) {
-      hilog.info(0x0000, TAG, 'StateSyncService already initialized');
-      return;
-    }
-
-    try {
-      this.context = context;
-
-      // 注册状态请求事件监听器
-      await this.registerStateRequestListener();
-      
-      // 注册卡片控制事件监听器
-      await this.registerWidgetControlListener();
-      
-      this.isInitialized = true;
-      hilog.info(0x0000, TAG, 'StateSyncService initialized successfully');
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to initialize StateSyncService: ${error}`);
-      throw new Error(`Failed to initialize StateSyncService: ${error}`);
-    }
-  }
-
-  /**
-   * 广播播放状态变化
-   */
-  async broadcastState(state: PlayerState): Promise<void> {
-    try {
-      // 节流控制,避免过于频繁的广播
-      const now = Date.now();
-      if (now - this.lastStateBroadcastTime < this.STATE_BROADCAST_THROTTLE) {
-        return;
-      }
-      this.lastStateBroadcastTime = now;
-
-      const playStateBroadcast: PlayStateBroadcast = {
-        isPlaying: state.isPlaying,
-        isPaused: state.isPaused,
-        isLoading: state.isLoading,
-        currentPosition: state.currentPosition,
-        duration: state.duration
-      };
-
-      const currentSongBroadcast: CurrentSongBroadcast = {
-        id: state.currentSong?.id || '',
-        title: state.currentSong?.name || '暂无播放',
-        artist: state.currentSong?.artist || '未知艺术家',
-        album: state.currentSong?.album || '未知专辑',
-        filePath: state.currentSong?.filePath || '',
-        duration: state.currentSong?.duration ? parseInt(state.currentSong.duration) : 0
-      };
-
-      const progressBroadcast: ProgressBroadcast = {
-        currentPosition: state.currentPosition,
-        duration: state.duration,
-        percentage: this.calculatePercentage(state.currentPosition, state.duration),
-        currentTimeText: this.formatTime(Math.floor(state.currentPosition / 1000)),
-        totalTimeText: this.formatTime(Math.floor(state.duration / 1000))
-      };
-
-      const broadcastData: PlayerStateBroadcastData = {
-        playState: playStateBroadcast,
-        currentSong: currentSongBroadcast,
-        progress: progressBroadcast,
-        playlist: {
-          hasNext: state.hasNext || false,
-          hasPrevious: state.hasPrevious || false,
-          currentIndex: state.currentIndex,
-          totalCount: state.totalCount || 0
-        } as PlaylistBroadcast
-      };
-
-      const publishInfo: commonEventManager.CommonEventPublishData = {
-        data: JSON.stringify(broadcastData)
-      };
-
-      await commonEventManager.publish(PLAYER_STATE_CHANGED_EVENT, publishInfo, (err) => {
-        if (err) {
-          hilog.error(0x0000, TAG, `Failed to broadcast state: ${err}`);
-        } else {
-          hilog.info(0x0000, TAG, `State broadcasted: isPlaying=${state.isPlaying}, song=${state.currentSong?.name || 'none'}`);
-        }
-      });
-
-      // 通知本地监听器
-      this.notifyLocalStateListeners(state);
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to broadcast state: ${error}`);
-    }
-  }
-
-  /**
-   * 广播歌曲切换事件
-   */
-  async broadcastSongChange(song: VideoItem): Promise<void> {
-    try {
-      const currentSongBroadcast: CurrentSongBroadcast = {
-        id: song.id || '',
-        title: song.name || '暂无播放',
-        artist: song.artist || '未知艺术家',
-        album: song.album || '未知专辑',
-        filePath: song.filePath || '',
-        duration: song.duration ? parseInt(song.duration) : 0
-      };
-
-      const playlistBroadcast: PlaylistBroadcast = {
-        hasNext: false, // 这些值需要从播放列表服务获取
-        hasPrevious: false,
-        currentIndex: 0,
-        totalCount: 0
-      };
-
-      const broadcastData: SongChangeBroadcastData = {
-        currentSong: currentSongBroadcast,
-        playlist: playlistBroadcast
-      };
-
-      const publishInfo: commonEventManager.CommonEventPublishData = {
-        data: JSON.stringify(broadcastData)
-      };
-
-      commonEventManager.publish(PLAYER_SONG_CHANGED_EVENT, publishInfo, (err) => {
-        if (err) {
-          hilog.error(0x0000, TAG, `Failed to broadcast song change: ${err}`);
-        } else {
-          hilog.info(0x0000, TAG, `Song change broadcasted: ${song.name} by ${song.artist || '未知艺术家'}`);
-        }
-      });
-
-      // 通知本地监听器
-      this.notifyLocalSongChangeListeners(song);
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to broadcast song change: ${error}`);
-    }
-  }
-
-  /**
-   * 广播播放进度更新
-   */
-  async broadcastProgress(progress: PlayProgress): Promise<void> {
-    try {
-      // 节流控制,避免过于频繁的进度广播
-      const now = Date.now();
-      if (now - this.lastProgressBroadcastTime < this.PROGRESS_BROADCAST_THROTTLE) {
-        return;
-      }
-      this.lastProgressBroadcastTime = now;
-
-      const broadcastData: ProgressBroadcastData = {
-        currentPosition: progress.currentPosition,
-        duration: progress.duration,
-        percentage: this.calculatePercentage(progress.currentPosition, progress.duration),
-        currentTimeText: this.formatTime(Math.floor(progress.currentPosition / 1000)),
-        totalTimeText: this.formatTime(Math.floor(progress.duration / 1000))
-      };
-
-      const publishInfo: commonEventManager.CommonEventPublishData = {
-        data: JSON.stringify(broadcastData)
-      };
-
-      commonEventManager.publish(PLAYER_PROGRESS_CHANGED_EVENT, publishInfo, (err) => {
-        if (err) {
-          hilog.error(0x0000, TAG, `Failed to broadcast progress: ${err}`);
-        } else {
-          hilog.info(0x0000, TAG, `Progress broadcasted: ${broadcastData.percentage.toFixed(1)}% (${broadcastData.currentTimeText}/${broadcastData.totalTimeText})`);
-        }
-      });
-
-      // 通知本地监听器
-      this.notifyLocalProgressListeners(progress);
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to broadcast progress: ${error}`);
-    }
-  }
-
-  /**
-   * 订阅状态变化
-   */
-  subscribeToStateChanges(callback: StateChangeCallback): void {
-    if (this.stateChangeCallbacks.indexOf(callback) === -1) {
-      this.stateChangeCallbacks.push(callback);
-      hilog.info(0x0000, TAG, `State change callback registered, total: ${this.stateChangeCallbacks.length}`);
-    }
-  }
-
-  /**
-   * 取消订阅状态变化
-   */
-  unsubscribeFromStateChanges(callback: StateChangeCallback): void {
-    const index = this.stateChangeCallbacks.indexOf(callback);
-    if (index !== -1) {
-      this.stateChangeCallbacks.splice(index, 1);
-      hilog.info(0x0000, TAG, `State change callback unregistered, remaining: ${this.stateChangeCallbacks.length}`);
-    }
-  }
-
-  /**
-   * 订阅卡片控制事件
-   */
-  subscribeToWidgetControl(callback: WidgetControlCallback): void {
-    if (this.widgetControlCallbacks.indexOf(callback) === -1) {
-      this.widgetControlCallbacks.push(callback);
-      hilog.info(0x0000, TAG, `Widget control callback registered, total: ${this.widgetControlCallbacks.length}`);
-    }
-  }
-
-  /**
-   * 取消订阅卡片控制事件
-   */
-  unsubscribeFromWidgetControl(callback: WidgetControlCallback): void {
-    const index = this.widgetControlCallbacks.indexOf(callback);
-    if (index !== -1) {
-      this.widgetControlCallbacks.splice(index, 1);
-      hilog.info(0x0000, TAG, `Widget control callback unregistered, remaining: ${this.widgetControlCallbacks.length}`);
-    }
-  }
-
-  /**
-   * 释放资源
-   */
-  release(): void {
-    try {
-      this.stateChangeCallbacks = [];
-      this.widgetControlCallbacks = [];
-      this.isInitialized = false;
-      hilog.info(0x0000, TAG, 'StateSyncService released');
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to release StateSyncService: ${error}`);
-    }
-  }
-
-  // ==================== 私有辅助方法 ====================
-
-  /**
-   * 注册状态请求事件监听器
-   */
-  private async registerStateRequestListener(): Promise<void> {
-    try {
-      const subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
-        events: [WIDGET_REQUEST_STATE_EVENT]
-      };
-
-      const subscriber = await commonEventManager.createSubscriber(subscribeInfo);
-      
-      await commonEventManager.subscribe(subscriber, (err, data: commonEventManager.CommonEventData) => {
-        if (!err) {
-          hilog.info(0x0000, TAG, `Received state request from widget: ${data.event}`);
-          this.handleStateRequest(data);
-        } else {
-          hilog.error(0x0000, TAG, `State request listener error: ${JSON.stringify(err)}`);
-        }
-      });
-
-      hilog.info(0x0000, TAG, 'State request listener registered successfully');
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to register state request listener: ${error}`);
-    }
-  }
-
-  /**
-   * 注册卡片控制事件监听器
-   */
-  private async registerWidgetControlListener(): Promise<void> {
-    try {
-      const subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
-        events: [WIDGET_CONTROL_EVENT]
-      };
-
-      const subscriber = await commonEventManager.createSubscriber(subscribeInfo);
-      
-      commonEventManager.subscribe(subscriber, (err, data: commonEventManager.CommonEventData) => {
-        if (!err) {
-          hilog.info(0x0000, TAG, `Received widget control command: ${data.event}`);
-          this.handleWidgetControlCommand(data);
-        } else {
-          hilog.error(0x0000, TAG, `Widget control listener error: ${JSON.stringify(err)}`);
-        }
-      });
-
-      hilog.info(0x0000, TAG, 'Widget control listener registered successfully');
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to register widget control listener: ${error}`);
-    }
-  }
-
-  /**
-   * 处理状态请求
-   */
-  private handleStateRequest(eventData: commonEventManager.CommonEventData): void {
-    try {
-      const requestData: Record<string, string> = JSON.parse(eventData.data || '{}');
-      const source: string = requestData.source || 'unknown';
-      
-      hilog.info(0x0000, TAG, `Handling state request from: ${source}`);
-      
-      // 通知控制回调处理状态请求
-      this.notifyWidgetControlCallbacks('onStateRequest');
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to handle state request: ${error}`);
-    }
-  }
-
-  /**
-   * 处理卡片控制命令
-   */
-  private async handleWidgetControlCommand(eventData: commonEventManager.CommonEventData): Promise<void> {
-    try {
-      const controlData: WidgetControlEventData = JSON.parse(eventData.data || '{}');
-      const command = controlData.command;
-      const params = controlData.params;
-      const source = controlData.source;
-      const timestamp = controlData.timestamp;
-      
-      hilog.info(0x0000, TAG, `Processing widget control command: ${command} from ${source}`);
-      
-      // 验证命令时效性(防止过期命令执行)
-      const now = Date.now();
-      if (now - timestamp > this.COMMAND_EXECUTION_TIMEOUT) {
-        hilog.warn(0x0000, TAG, `Command ${command} expired, ignoring (age: ${now - timestamp}ms)`);
-        return;
-      }
-      
-      // 验证命令来源
-      if (!this.isValidCommandSource(source)) {
-        hilog.warn(0x0000, TAG, `Invalid command source: ${source}, ignoring command ${command}`);
-        return;
-      }
-      
-      // 执行命令
-      await this.executeWidgetCommand(command, params);
-      
-      hilog.info(0x0000, TAG, `Widget control command ${command} executed successfully`);
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to handle widget control command: ${error}`);
-    }
-  }
-
-  /**
-   * 通知本地状态监听器
-   */
-  private notifyLocalStateListeners(state: PlayerState): void {
-    this.stateChangeCallbacks.forEach(callback => {
-      try {
-        if (callback.onStateChanged) {
-          callback.onStateChanged(state);
-        }
-      } catch (error) {
-        hilog.error(0x0000, TAG, `Error in state change callback: ${error}`);
-      }
-    });
-  }
-
-  /**
-   * 通知本地歌曲变化监听器
-   */
-  private notifyLocalSongChangeListeners(song: VideoItem): void {
-    this.stateChangeCallbacks.forEach(callback => {
-      try {
-        if (callback.onSongChanged) {
-          callback.onSongChanged(song);
-        }
-      } catch (error) {
-        hilog.error(0x0000, TAG, `Error in song change callback: ${error}`);
-      }
-    });
-  }
-
-  /**
-   * 通知本地进度监听器
-   */
-  private notifyLocalProgressListeners(progress: PlayProgress): void {
-    this.stateChangeCallbacks.forEach(callback => {
-      try {
-        if (callback.onProgressChanged) {
-          callback.onProgressChanged(progress);
-        }
-      } catch (error) {
-        hilog.error(0x0000, TAG, `Error in progress change callback: ${error}`);
-      }
-    });
-  }
-
-  /**
-   * 执行卡片控制命令
-   */
-  private async executeWidgetCommand(command: string, params?: Record<string, Object>): Promise<void> {
-    try {
-      switch (command) {
-        case 'PLAY_PAUSE':
-          await this.notifyWidgetControlCallbacks('onPlayPause');
-          break;
-        case 'NEXT_SONG':
-          await this.notifyWidgetControlCallbacks('onNextSong');
-          break;
-        case 'PREV_SONG':
-          await this.notifyWidgetControlCallbacks('onPreviousSong');
-          break;
-        case 'SEEK_TO':
-          const position = params?.position as number || 0;
-          await this.notifyWidgetControlCallbacks('onSeekTo', position);
-          break;
-        default:
-          hilog.warn(0x0000, TAG, `Unknown widget command: ${command}`);
-      }
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to execute widget command ${command}: ${error}`);
-      throw new Error(`Failed to execute widget command ${command}: ${error}`);
-    }
-  }
-
-  /**
-   * 验证命令来源是否有效
-   */
-  private isValidCommandSource(source: string): boolean {
-    const validSources = ['widget', 'form', 'card', 'desktop_widget'];
-    return validSources.includes(source);
-  }
-
-  /**
-   * 通知卡片控制回调
-   */
-  private async notifyWidgetControlCallbacks(method: string, ...args: Object[]): Promise<void> {
-    const promises: Promise<void>[] = [];
-    
-    this.widgetControlCallbacks.forEach(callback => {
-      try {
-        let promise: Promise<void> | undefined;
-        
-        switch (method) {
-          case 'onPlayPause':
-            promise = callback.onPlayPause?.();
-            break;
-          case 'onNextSong':
-            promise = callback.onNextSong?.();
-            break;
-          case 'onPreviousSong':
-            promise = callback.onPreviousSong?.();
-            break;
-          case 'onSeekTo':
-            promise = callback.onSeekTo?.(args[0] as number);
-            break;
-          case 'onStateRequest':
-            promise = callback.onStateRequest?.();
-            break;
-        }
-        
-        if (promise) {
-          promises.push(promise);
-        }
-      } catch (error) {
-        hilog.error(0x0000, TAG, `Error in widget control callback ${method}: ${error}`);
-      }
-    });
-    
-    // 等待所有回调执行完成
-    if (promises.length > 0) {
-      try {
-        await Promise.all(promises);
-        hilog.info(0x0000, TAG, `All widget control callbacks for ${method} completed`);
-      } catch (error) {
-        hilog.error(0x0000, TAG, `Some widget control callbacks for ${method} failed: ${error}`);
-      }
-    }
-  }
-
-  /**
-   * 计算播放进度百分比
-   */
-  private calculatePercentage(current: number, total: number): number {
-    if (total <= 0) return 0;
-    return Math.min(100, Math.max(0, (current / total) * 100));
-  }
-
-  /**
-   * 格式化时间显示
-   */
-  private formatTime(seconds: number): string {
-    const mins = Math.floor(seconds / 60);
-    const secs = Math.floor(seconds % 60);
-    return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
-  }
-}

+ 37 - 201
entry/src/main/ets/common/service/UnifiedPlayerService.ets

@@ -8,13 +8,10 @@ import { common } from '@kit.AbilityKit';
 import { PreferencesUtil, StrUtil } from '@pura/harmony-utils';
 import { DataPersistenceService, PlaylistSyncService, PlaylistSyncListener, IDataPersistenceService, PlaylistData,
   PlayerStateData } from './DataPersistenceService';
-import { StateSyncService, IStateSyncService, StateChangeCallback, WidgetControlCallback } from './StateSyncService';
 import { ErrorRecoveryStrategy, IErrorRecoveryStrategy, ErrorContext, ErrorRecoveryAction } from './ErrorRecoveryStrategy';
-import { EnhancedFormUpdateService, UpdateStats } from '../widget/EnhancedFormUpdateService';
 import { AvSessionController } from '../../controller/AvSessionController';
 import { avSession } from '@kit.AVSessionKit';
 import json from '@ohos.util.json';
-import { Utility } from '../util/Utility';
 import MediaTable from '../util/MediaTable';
 
 /**
@@ -246,27 +243,20 @@ export interface IPlayerService {
    * 强制刷新收藏状态(用于收藏/取消收藏操作后)
    */
   refreshFavoriteStatus(): Promise<void>;
-
-  /**
-   * 切换收藏状态
-   */
-  toggleFavorite(): Promise<void>;
 }
 
 /**
  * 统一播放器服务实现
  * 整合PlayerManager、PlayerStateModel和PlaylistModel
  */
-export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListener, StateChangeCallback, WidgetControlCallback, PlayerStateCallback {
+export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListener, PlayerStateCallback {
   private static instance: UnifiedPlayerService | null = null;
   private playerManager: IPlayerManager;
   private stateModel: PlayerStateModel;
   private playlistModel: PlaylistModel;
   private dataPersistence: IDataPersistenceService;
   private playlistSync: PlaylistSyncService;
-  private stateSync: IStateSyncService;
   private errorRecovery: IErrorRecoveryStrategy;
-  private widgetUpdateService: EnhancedFormUpdateService;
   private avSessionController: AvSessionController | null = null;
   private context: common.UIAbilityContext | null = null;
   private progressTimer: number = -1;
@@ -278,7 +268,7 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
   private lastAvSessionUpdate: number = 0;
   private lastAvMetadataUpdate: number = 0; // 新增:上次元数据更新时间
   private avSessionUpdateTimer: number = -1; // 新增:系统播控更新防抖定时器
-  private avMetadataUpdateTimer: number = -1; // 新增:元数据更新防抖定时器 
+  private avMetadataUpdateTimer: number = -1; // 新增:元数据更新防抖定时器
   private lastUpdateTime: number=0;
   private favList: VideoItem[]=[];
   private table: MediaTable | undefined = undefined;
@@ -292,9 +282,7 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
     this.playlistModel = new PlaylistModel();
     this.dataPersistence = DataPersistenceService.getInstance();
     this.playlistSync = PlaylistSyncService.getInstance();
-    this.stateSync = StateSyncService.getInstance();
     this.errorRecovery = ErrorRecoveryStrategy.getInstance();
-    this.widgetUpdateService = EnhancedFormUpdateService.getInstance();
 
     LogUtils.getInstance().LOGI('UnifiedPlayerService: Instance created');
   }
@@ -317,7 +305,6 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
 
       // 快速初始化核心组件
       this.playerManager.setStateCallback(this);
-      this.widgetUpdateService.setAppContext(context);
 
       // 初始化PlaylistModel的MediaTable
       this.playlistModel.initializeMediaTable(context);
@@ -328,21 +315,16 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
 
       // 设置同步监听器
       this.playlistSync.addSyncListener(this);
-      this.stateSync.subscribeToStateChanges(this);
-      this.stateSync.subscribeToWidgetControl(this);
 
       // 设置状态模型监听器,自动广播状态变化
-      class StateListenerImpl implements PlayerStateListener {
-        private stateSync: IStateSyncService;
+      class StateListenerImpl {
         private unifiedService: UnifiedPlayerService;
 
-        constructor(stateSync: IStateSyncService, unifiedService: UnifiedPlayerService) {
-          this.stateSync = stateSync;
+        constructor(unifiedService: UnifiedPlayerService) {
           this.unifiedService = unifiedService;
         }
 
         onStateChanged(state: PlayerState): void {
-          this.stateSync.broadcastState(state);
 
           // 使用防抖机制更新系统播控,避免频繁更新
           this.unifiedService.updateSessionPlayState();
@@ -350,7 +332,6 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
           this.unifiedService.updateWidgetsForStateChange();
         }
         onSongChanged(song: VideoItem): void {
-          this.stateSync.broadcastSongChange(song);
 
           // 使用防抖机制更新系统播控元数据,避免频繁更新
           this.unifiedService.updateAvSessionMetadata(song);
@@ -358,17 +339,11 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
           // 歌曲变化时更新卡片
           this.unifiedService.updateWidgetsForSongChange(song);
         }
-        onProgressChanged(progress: PlayProgress): void {
-          this.stateSync.broadcastProgress(progress);
-          // 进度变化时更新卡片(防抖处理)
-          this.unifiedService.updateWidgetsForProgressChange(progress);
-        }
+
         onError(error: PlayerError): void {
           LogUtils.getInstance().LOGI(`Player error: ${error.message}`);
         }
       }
-      const stateListener = new StateListenerImpl(this.stateSync, this);
-      this.stateModel.addStateListener(stateListener);
 
       this.setupProgressTimer();
       this.isInitialized = true;
@@ -396,7 +371,6 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
           this.playerManager.initialize(context),
           this.dataPersistence.initialize(context),
           this.playlistSync.initialize(context),
-          this.stateSync.initialize(context)
         ];
 
         await Promise.all(initPromises);
@@ -412,7 +386,7 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
           this.restorePersistedState(),
           this.initializeFavoriteList()
         ];
-        
+
         await Promise.all(initPromises2);
 
         console.log("Heanup2 UnifiedPlayerService: 异步组件初始化完成");
@@ -680,16 +654,16 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
     try {
       this.savePlaybackPosition();
       this.playerManager.stopPlayback();
-      
+
       // 重要:停止时应该清除所有播放状态,不是暂停状态
       this.stateModel.updatePlayingState( false);
       // this.stateModel.state.isPaused = false; // 停止不是暂停
       this.stateModel.updateProgress(0, 0);
       this.stopProgressTimer();
-      
+
       // 通知状态变化
       this.stateModel.notifySongChanged(this.getCurrentSong() as VideoItem);
-      
+
       // 更新卡片显示停止状态
       await this.updateWidgetsForPlayStateChange();
 
@@ -819,7 +793,7 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
     try {
       // 设置手动歌曲切换标志,防止自动播放干扰
       this.isManualSongChange = true;
-      
+
       const success = this.playlistModel.playSongAtIndex(index);
       if (!success) {
         this.isManualSongChange = false;
@@ -905,21 +879,21 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
   /**
    * 获取当前歌曲的收藏状态
    */
-  public  getCurrentSongFavoriteState(): boolean {
+  private getCurrentSongFavoriteState(): boolean {
     try {
       let currentSong = this.playlistModel.getCurrentSong();
       if (!currentSong) {
         LogUtils.getInstance().LOGI(`UnifiedPlayerService: 当前歌曲为空`);
         return false;
       }
-      
+
       let favList = this.getFav();
       if (!favList || favList.length === 0) {
         // 如果收藏列表为空,可能还在加载中,先返回false
         // 但不记录为错误,因为这是正常的初始化状态
         return false;
       }
-      
+
       // 检查当前歌曲是否在收藏列表中
       for (let i = 0; i < favList.length; i++) {
         if (favList[i].filePath === currentSong.filePath && favList[i].isFav === 1) {
@@ -961,12 +935,12 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
         this.getTable().queryByisFav(1, (result: VideoItem[]) => {
           this.favList = result;
           LogUtils.getInstance().LOGI(`UnifiedPlayerService: Favorite list updated with ${this.favList.length} items`);
-          
+
           // 更新收藏列表后,立即更新AVSession状态以反映正确的收藏状态
           setTimeout(() => {
             this.updateSessionPlayState();
           }, 100);
-          
+
           resolve();
         });
       });
@@ -988,31 +962,6 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
       LogUtils.getInstance().LOGI(`UnifiedPlayerService: Failed to refresh favorite status: ${error}`);
     }
   }
-
-  public async toggleFavorite(): Promise<void> {
-    try {
-      const currentSong = this.getCurrentSong();
-      if (!currentSong) {
-        LogUtils.getInstance().LOGI('UnifiedPlayerService: No current song to toggle favorite');
-        return;
-      }
-
-      const isFavorite = this.getCurrentSongFavoriteState();
-      const newFavState = isFavorite ? 0 : 1;
-
-       this.getTable().updateIsFavByFilePath(currentSong.filePath, newFavState, () => {
-          this.refreshFavoriteStatus();
-      });
-
-
-      // 广播状态更新
-      this.broadcastCurrentState();
-
-      LogUtils.getInstance().LOGI(`UnifiedPlayerService: Toggled favorite for ${currentSong.name} to ${newFavState}`);
-    } catch (error) {
-      LogUtils.getInstance().LOGI(`UnifiedPlayerService: Failed to toggle favorite: ${error}`);
-    }
-  }
   private getTable(): MediaTable {
     if (this.table) {
       return this.table;
@@ -1160,19 +1109,10 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
         errors.push('DataPersistence service not available');
       }
 
-      // 检查同步服务
-      if (!this.stateSync) {
-        errors.push('StateSync service not available');
-      }
-
       if (!this.playlistSync) {
         errors.push('PlaylistSync service not available');
       }
 
-      // 检查卡片更新服务
-      if (!this.widgetUpdateService) {
-        warnings.push('WidgetUpdate service not available');
-      }
 
       // 检查错误恢复策略
       if (!this.errorRecovery) {
@@ -1404,9 +1344,6 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
       // 清理同步监听器
       this.playlistSync.removeSyncListener(this);
       this.playlistSync.release();
-      this.stateSync.unsubscribeFromStateChanges(this);
-      this.stateSync.unsubscribeFromWidgetControl(this);
-      this.stateSync.release();
 
       this.playerManager.release();
       this.playlistModel.clear();
@@ -2241,22 +2178,12 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
     }
   }
 
-  // ==================== 状态同步服务访问方法 ====================
-
-  /**
-   * 获取状态同步服务实例
-   */
-  getStateSyncService(): IStateSyncService {
-    return this.stateSync;
-  }
-
   /**
    * 手动广播当前状态(用于响应卡片的状态请求)
    */
   async broadcastCurrentState(): Promise<void> {
     try {
-      const currentState = this.getCurrentState();
-      await this.stateSync.broadcastState(currentState);
+      this.updateAllForms();
       LogUtils.getInstance().LOGI('UnifiedPlayerService: Current state broadcasted manually');
     } catch (error) {
       LogUtils.getInstance().LOGI(`UnifiedPlayerService broadcastCurrentState error: ${error}`);
@@ -2291,7 +2218,7 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
   async handleAudioInterrupt(event: InterruptEvent): Promise<void> {
     try {
       LogUtils.getInstance().LOGI(`onecold 与其他应用音频冲突 被截断点event: ${JSON.stringify(event)}`);
-      
+
       // 首先保存当前播放位置
       await this.savePlaybackPosition();
 
@@ -2347,7 +2274,7 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
       // 在随机播放模式下,确保当前歌曲在播放历史中
       if (playMode === PlayMode.RANDOM) {
         await this.playlistModel.ensureCurrentSongInHistory();
-        
+
         // 输出播放历史调试信息
         const debugInfo = this.playlistModel.getPlayHistoryDebugInfo();
         LogUtils.getInstance().LOGI(`UnifiedPlayerService: Random mode play history - ${debugInfo}`);
@@ -2454,7 +2381,7 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
         LogUtils.getInstance().LOGI('UnifiedPlayerService: Manual song change in progress, skipping auto-play');
         return;
       }
-      
+
       // 防抖检查:避免快速连续的自动播放调用
       const currentTime = Date.now();
       if (currentTime - this.lastAutoPlayTime < this.autoPlayDebounceMs) {
@@ -2471,7 +2398,7 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
 
       const currentState = this.stateModel.getState();
       const playMode = currentState.playMode;
-      
+
       LogUtils.getInstance().LOGI(`UnifiedPlayerService: Handling auto-play, mode: ${playMode}`);
 
       switch (playMode) {
@@ -2484,23 +2411,23 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
             LogUtils.getInstance().LOGI('UnifiedPlayerService: No next song available in sequence mode');
           }
           break;
-          
+
         case PlayMode.SINGLE_REPEAT: // 1: 单曲循环
           LogUtils.getInstance().LOGI('UnifiedPlayerService: Repeating current song');
           // 重新播放当前歌曲
           await this.startPlayOrResumePlay();
           break;
-          
+
         case PlayMode.NORMAL: // 2: 正常播放,播完停止
           LogUtils.getInstance().LOGI('UnifiedPlayerService: Normal mode - stopping after completion');
           // 不做任何操作,保持停止状态
           break;
-          
+
         case PlayMode.RANDOM: // 3: 随机播放
           LogUtils.getInstance().LOGI('UnifiedPlayerService: Auto-playing random next song');
           await this.playRandomNext();
           break;
-          
+
         default:
           LogUtils.getInstance().LOGI(`UnifiedPlayerService: Unknown play mode: ${playMode}`);
           break;
@@ -2527,7 +2454,7 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
 
       const currentIndex = this.playlistModel.getCurrentIndex();
       let randomIndex: number;
-      
+
       // 确保随机选择的不是当前歌曲
       do {
         randomIndex = Math.floor(Math.random() * playlist.length);
@@ -2580,107 +2507,41 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
 
   // ========== 卡片更新相关方法 ==========
 
-  /**
-   * 创建当前的卡片数据
-   */
-  private createWidgetData(): WidgetData {
-    const currentState = this.stateModel.getState();
-    const currentSong = this.playlistModel.getCurrentSong();
-    const currentIndex = this.playlistModel.getCurrentIndex();
-    const totalCount = this.playlistModel.getTotalCount();
-    const playMode = currentState.playMode;
-
-    return {
-      playState: {
-        isPlaying: currentState.isPlaying,
-        isPaused: currentState.isPaused,
-        isLoading: currentState.isLoading
-      },
-      currentSong: {
-        id: currentSong?.id || '',
-        title: currentSong?.name || '暂无播放',
-        artist: currentSong?.artist || '未知艺术家',
-        album: currentSong?.album || '未知专辑',
-        coverImagePath: currentSong?.pixelMapPath || '',
-        duration: this.parseDuration(currentSong?.duration || '0')
-      },
-      progress: {
-        currentPosition: currentState.currentPosition,
-        duration: currentState.duration,
-        percentage: currentState.duration > 0 ? (currentState.currentPosition / currentState.duration) * 100 : 0,
-        currentTimeText: this.formatTime(currentState.currentPosition),
-        totalTimeText: this.formatTime(currentState.duration)
-      },
-      playlist: {
-        hasNext: this.playlistModel.hasNext(playMode),
-        hasPrevious: this.playlistModel.hasPreviousSync(playMode),
-        currentIndex: currentIndex,
-        totalCount: totalCount
-      },
-      config: {
-        size: WidgetSize.MEDIUM, // 默认尺寸,实际会根据卡片尺寸适配
-        theme: WidgetTheme.AUTO,
-        showProgress: true,
-        showCover: true
-      }
-    };
-  }
 
   /**
    * 播放状态变化时更新卡片
    */
   private async updateWidgetsForPlayStateChange(): Promise<void> {
     try {
-      const widgetData = this.createWidgetData();
-      await this.widgetUpdateService.updateAllForms(widgetData);
+       this.updateAllForms();
       LogUtils.getInstance().LOGI(`UnifiedPlayerService: Widgets updated for play state change`);
     } catch (error) {
       LogUtils.getInstance().LOGI(`UnifiedPlayerService: Failed to update widgets for play state change: ${error}`);
     }
   }
 
+  updateAllForms() {
+    let formData=this.getCurrentSong();
+    let songState=this.getCurrentState();
+    throw new Error('Method not implemented.');
+  }
+
   /**
    * 歌曲变化时更新卡片
    */
   private async updateWidgetsForSongChange(song: VideoItem, forceUpdate: boolean = false): Promise<void> {
-    try {
-      const widgetData = this.createWidgetData();
 
-      if (forceUpdate) {
-        // 强制更新(忽略防抖),用于重要事件如歌曲切换
-        await this.widgetUpdateService.forceUpdateAllForms(widgetData);
-        LogUtils.getInstance().LOGI(`UnifiedPlayerService: Widgets force updated for song change: ${song.name}`);
-      } else {
-        await this.widgetUpdateService.updateAllForms(widgetData);
-        LogUtils.getInstance().LOGI(`UnifiedPlayerService: Widgets updated for song change: ${song.name}`);
-      }
-    } catch (error) {
-      LogUtils.getInstance().LOGI(`UnifiedPlayerService: Failed to update widgets for song change: ${error}`);
-    }
-  }
+      this.updateAllForms();
 
-  /**
-   * 进度变化时更新卡片(防抖处理)
-   */
-  private async updateWidgetsForProgressChange(progress: PlayProgress): Promise<void> {
-    try {
-      // 进度更新很频繁,让防抖机制发挥作用
-      const widgetData = this.createWidgetData();
-      await this.widgetUpdateService.updateAllForms(widgetData);
-      // 不记录日志,避免过多输出
-    } catch (error) {
-      // 进度更新失败不影响播放,只记录错误
-      LogUtils.getInstance().LOGI(`UnifiedPlayerService: Failed to update widgets for progress change: ${error}`);
-    }
   }
 
+
   /**
    * 状态变化时更新卡片
    */
   public async updateWidgetsForStateChange(): Promise<void> {
     try {
-      const widgetData = this.createWidgetData();
-      await this.widgetUpdateService.updateAllForms(widgetData);
+      this.updateAllForms();
       LogUtils.getInstance().LOGI(`UnifiedPlayerService: Widgets updated for state change`);
     } catch (error) {
       LogUtils.getInstance().LOGI(`UnifiedPlayerService: Failed to update widgets for state change: ${error}`);
@@ -2692,8 +2553,7 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
    */
   private async updateWidgetsForPlaylistChange(): Promise<void> {
     try {
-      const widgetData = this.createWidgetData();
-      await this.widgetUpdateService.updateAllForms(widgetData);
+      this.updateAllForms();
       LogUtils.getInstance().LOGI(`UnifiedPlayerService: Widgets updated for playlist change`);
     } catch (error) {
       LogUtils.getInstance().LOGI(`UnifiedPlayerService: Failed to update widgets for playlist change: ${error}`);
@@ -2705,37 +2565,13 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
    */
   public async initializeWidgetDisplay(): Promise<void> {
     try {
-      const widgetData = this.createWidgetData();
-      await this.widgetUpdateService.forceUpdateAllForms(widgetData);
+      this.updateAllForms();
       LogUtils.getInstance().LOGI('UnifiedPlayerService: Widget display initialized');
     } catch (error) {
       LogUtils.getInstance().LOGI(`UnifiedPlayerService: Failed to initialize widget display: ${error}`);
     }
   }
 
-  /**
-   * 获取卡片更新统计信息
-   */
-  public getWidgetUpdateStats(): UpdateStats {
-    return this.widgetUpdateService.getUpdateStats();
-  }
-
-  /**
-   * 重置卡片更新统计
-   */
-  public resetWidgetUpdateStats(): void {
-    this.widgetUpdateService.resetStats();
-  }
-
-  /**
-   * 格式化时间为 MM:SS 格式
-   */
-  private formatTime(timeInMs: number): string {
-    const totalSeconds = Math.floor(timeInMs / 1000);
-    const minutes = Math.floor(totalSeconds / 60);
-    const seconds = totalSeconds % 60;
-    return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
-  }
 
   /**
    * 解析时长字符串为毫秒数

+ 0 - 430
entry/src/main/ets/common/widget/AvSessionWidgetListener.ets

@@ -1,430 +0,0 @@
-import { hilog } from '@kit.PerformanceAnalysisKit';
-import { WidgetData } from './WidgetTypes';
-import { WidgetTypeHelpers } from './WidgetTypeHelpers';
-
-const TAG = 'Heanup AvSessionWidgetListener';
-
-/**
- * 同步状态信息接口
- */
-interface SyncStatusInfo {
-  processId: string;
-  listenerCount: number;
-  lastUpdateTime: number;
-  isProgressAnimating: boolean;
-  hasProgressTimer: boolean;
-}
-
-/**
- * AvSession卡片监听器
- * 负责监听媒体会话状态变化并同步到卡片
- * 增强版本:支持实时状态同步和平滑进度更新
- * 支持跨进程数据同步
- */
-export class AvSessionWidgetListener {
-  private static instance: AvSessionWidgetListener | null = null;
-  private stateListeners: Array<(data: WidgetData) => void> = [];
-  private isInitialized: boolean = false;
-  private lastWidgetData: WidgetData | null = null;
-  private processId: string = '';
-  
-  // 实时同步相关
-  private progressUpdateTimer: number = -1;
-  private lastProgressUpdate: number = 0;
-  private readonly PROGRESS_UPDATE_INTERVAL = 1000; // 1秒更新一次进度
-  private readonly STATE_SYNC_DEBOUNCE = 100; // 状态同步防抖延迟
-  private lastStateSyncTime: number = 0;
-  
-  // 平滑动画相关
-  private isProgressAnimating: boolean = false;
-  private animationStartTime: number = 0;
-  private animationStartProgress: number = 0;
-  private animationTargetProgress: number = 0;
-  private animationDuration: number = 1000; // 1秒动画时长
-
-  private constructor() {
-    // 生成进程唯一标识
-    this.processId = `process_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
-    hilog.info(0x0000, TAG, `AvSessionWidgetListener created for process: ${this.processId}`);
-    this.initializeAvSessionManager();
-  }
-
-  public static getInstance(): AvSessionWidgetListener {
-    if (!AvSessionWidgetListener.instance) {
-      AvSessionWidgetListener.instance = new AvSessionWidgetListener();
-    }
-    return AvSessionWidgetListener.instance;
-  }
-
-  /**
-   * 初始化AvSession管理器
-   */
-  private async initializeAvSessionManager(): Promise<void> {
-    try {
-      this.isInitialized = true;
-      hilog.info(0x0000, TAG, 'AvSession manager initialized (simplified version)');
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to initialize AvSession manager: ${error}`);
-    }
-  }
-
-  /**
-   * 注册状态监听器
-   */
-  public addStateListener(callback: (data: WidgetData) => void): void {
-    // 检查是否已经注册过相同的监听器,避免重复注册
-    if (this.stateListeners.indexOf(callback) === -1) {
-      this.stateListeners.push(callback);
-      hilog.info(0x0000, TAG, `State listener registered, total listeners: ${this.stateListeners.length}`);
-    } else {
-      hilog.warn(0x0000, TAG, 'State listener already registered, skipping');
-      return;
-    }
-    
-    // 延迟回调,给主应用时间广播当前状态
-    setTimeout(() => {
-      // 如果有缓存的数据,立即返回
-      if (this.lastWidgetData) {
-        hilog.info(0x0000, TAG, `Sending cached data to new listener: isPlaying=${this.lastWidgetData.playState.isPlaying}, title=${this.lastWidgetData.currentSong.title}`);
-        callback(this.lastWidgetData);
-      } else {
-        // 否则返回默认数据
-        const defaultData = this.getDefaultWidgetData();
-        hilog.info(0x0000, TAG, `Sending default data to new listener: isPlaying=${defaultData.playState.isPlaying}, title=${defaultData.currentSong.title}`);
-        callback(defaultData);
-      }
-    }, 500); // 延迟500ms,给主应用时间广播状态
-  }
-
-  /**
-   * 获取当前监听器数量(调试用)
-   */
-  public getListenerCount(): number {
-    return this.stateListeners.length;
-  }
-
-  /**
-   * 更新卡片数据(由主应用调用)- 增强版本
-   */
-  public updateWidgetData(data: WidgetData): void {
-    const now = Date.now();
-    
-    // 防抖处理,避免过于频繁的更新
-    if (now - this.lastStateSyncTime < this.STATE_SYNC_DEBOUNCE) {
-      return;
-    }
-    this.lastStateSyncTime = now;
-    
-    // 检查数据是否真的发生了变化,避免无意义的更新
-    if (this.lastWidgetData && this.isDataEqual(this.lastWidgetData, data)) {
-      // 即使数据相同,也要更新进度(如果正在播放)
-      if (data.playState.isPlaying && !this.isProgressAnimating) {
-        this.updateProgressOnly(data);
-      }
-      return;
-    }
-    
-    // 检查是否需要启动平滑进度动画
-    const shouldAnimateProgress = this.shouldStartProgressAnimation(data);
-    
-    this.lastWidgetData = data;
-    
-    // 添加调用栈信息以便调试
-    const callerInfo = new Error().stack?.split('\n')[2]?.trim() || 'Unknown caller';
-    hilog.info(0x0000, TAG, `[${this.processId}] Updating widget data: isPlaying=${data.playState.isPlaying}, title=${data.currentSong.title}, progress=${data.progress.percentage.toFixed(1)}%, listeners=${this.stateListeners.length}, caller: ${callerInfo}`);
-    
-    // 启动或停止进度更新定时器
-    this.manageProgressTimer(data.playState.isPlaying);
-    
-    // 如果需要平滑进度动画,启动动画
-    if (shouldAnimateProgress) {
-      this.startProgressAnimation(data);
-    }
-    
-    // 通知所有监听器
-    this.notifyStateListeners(data);
-    
-    hilog.info(0x0000, TAG, `[${this.processId}] Widget data updated and broadcasted to ${this.stateListeners.length} listeners`);
-  }
-
-  /**
-   * 仅更新进度信息
-   */
-  private updateProgressOnly(data: WidgetData): void {
-    if (!this.lastWidgetData) {
-      return;
-    }
-    
-    // 创建更新后的数据,只修改进度部分
-    const updatedData: WidgetData = {
-      playState: this.lastWidgetData.playState,
-      currentSong: this.lastWidgetData.currentSong,
-      progress: {
-        currentPosition: data.progress.currentPosition,
-        duration: data.progress.duration,
-        percentage: data.progress.percentage,
-        currentTimeText: data.progress.currentTimeText,
-        totalTimeText: data.progress.totalTimeText
-      },
-      playlist: this.lastWidgetData.playlist,
-      config: this.lastWidgetData.config,
-      castingInfo: this.lastWidgetData.castingInfo
-    };
-    
-    this.lastWidgetData = updatedData;
-    this.notifyStateListeners(updatedData);
-  }
-
-  /**
-   * 判断是否应该启动进度动画
-   */
-  private shouldStartProgressAnimation(newData: WidgetData): boolean {
-    if (!this.lastWidgetData || !newData.playState.isPlaying) {
-      return false;
-    }
-    
-    // 如果进度变化较大(超过2%),启动平滑动画
-    const progressDiff = Math.abs(newData.progress.percentage - this.lastWidgetData.progress.percentage);
-    return progressDiff > 2.0 && progressDiff < 50.0; // 避免在拖拽时启动动画
-  }
-
-  /**
-   * 启动进度平滑动画
-   */
-  private startProgressAnimation(targetData: WidgetData): void {
-    if (!this.lastWidgetData) {
-      return;
-    }
-    
-    this.isProgressAnimating = true;
-    this.animationStartTime = Date.now();
-    this.animationStartProgress = this.lastWidgetData.progress.percentage;
-    this.animationTargetProgress = targetData.progress.percentage;
-    
-    hilog.info(0x0000, TAG, `Starting progress animation: ${this.animationStartProgress.toFixed(1)}% -> ${this.animationTargetProgress.toFixed(1)}%`);
-    
-    // 启动动画定时器
-    const animationTimer = setInterval(() => {
-      const elapsed = Date.now() - this.animationStartTime;
-      const progress = Math.min(elapsed / this.animationDuration, 1.0);
-      
-      // 使用缓动函数计算当前进度
-      const easedProgress = this.easeInOutQuad(progress);
-      const currentProgress = this.animationStartProgress + 
-        (this.animationTargetProgress - this.animationStartProgress) * easedProgress;
-      
-      // 更新进度数据
-      if (this.lastWidgetData) {
-        const animatedData: WidgetData = {
-          playState: this.lastWidgetData.playState,
-          currentSong: this.lastWidgetData.currentSong,
-          progress: {
-            currentPosition: targetData.progress.currentPosition,
-            duration: targetData.progress.duration,
-            percentage: currentProgress,
-            currentTimeText: targetData.progress.currentTimeText,
-            totalTimeText: targetData.progress.totalTimeText
-          },
-          playlist: this.lastWidgetData.playlist,
-          config: this.lastWidgetData.config,
-          castingInfo: this.lastWidgetData.castingInfo
-        };
-        
-        this.notifyStateListeners(animatedData);
-      }
-      
-      // 动画完成
-      if (progress >= 1.0) {
-        clearInterval(animationTimer);
-        this.isProgressAnimating = false;
-        hilog.info(0x0000, TAG, `Progress animation completed at ${currentProgress.toFixed(1)}%`);
-      }
-    }, 50); // 20fps动画
-  }
-
-  /**
-   * 缓动函数:二次缓入缓出
-   */
-  private easeInOutQuad(t: number): number {
-    return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
-  }
-
-  /**
-   * 管理进度更新定时器
-   */
-  private manageProgressTimer(isPlaying: boolean): void {
-    if (isPlaying && this.progressUpdateTimer === -1) {
-      // 启动进度更新定时器
-      this.progressUpdateTimer = setInterval(() => {
-        this.updateRealtimeProgress();
-      }, this.PROGRESS_UPDATE_INTERVAL);
-      
-      hilog.info(0x0000, TAG, 'Progress update timer started');
-    } else if (!isPlaying && this.progressUpdateTimer !== -1) {
-      // 停止进度更新定时器
-      clearInterval(this.progressUpdateTimer);
-      this.progressUpdateTimer = -1;
-      
-      hilog.info(0x0000, TAG, 'Progress update timer stopped');
-    }
-  }
-
-  /**
-   * 实时更新进度(基于时间推算)
-   */
-  private updateRealtimeProgress(): void {
-    if (!this.lastWidgetData || !this.lastWidgetData.playState.isPlaying || this.isProgressAnimating) {
-      return;
-    }
-    
-    const now = Date.now();
-    const timeSinceLastUpdate = now - this.lastProgressUpdate;
-    
-    if (timeSinceLastUpdate < this.PROGRESS_UPDATE_INTERVAL) {
-      return;
-    }
-    
-    // 基于时间推算当前进度
-    const estimatedProgress = this.lastWidgetData.progress.currentPosition + timeSinceLastUpdate;
-    const estimatedPercentage = this.calculatePercentage(estimatedProgress, this.lastWidgetData.progress.duration);
-    
-    // 创建更新后的数据
-    const updatedData: WidgetData = {
-      playState: this.lastWidgetData.playState,
-      currentSong: this.lastWidgetData.currentSong,
-      progress: {
-        currentPosition: estimatedProgress,
-        duration: this.lastWidgetData.progress.duration,
-        percentage: estimatedPercentage,
-        currentTimeText: this.formatTime(Math.floor(estimatedProgress / 1000)),
-        totalTimeText: this.lastWidgetData.progress.totalTimeText
-      },
-      playlist: this.lastWidgetData.playlist,
-      config: this.lastWidgetData.config,
-      castingInfo: this.lastWidgetData.castingInfo
-    };
-    
-    this.lastWidgetData = updatedData;
-    this.lastProgressUpdate = now;
-    
-    // 通知监听器(仅进度更新,不记录详细日志)
-    this.notifyStateListeners(updatedData, false);
-  }
-
-  /**
-   * 通知状态监听器
-   */
-  private notifyStateListeners(data: WidgetData, logDetails: boolean = true): void {
-    this.stateListeners.forEach((listener: (data: WidgetData) => void, index: number) => {
-      try {
-        if (logDetails) {
-          hilog.info(0x0000, TAG, `[${this.processId}] Notifying listener ${index}`);
-        }
-        listener(data);
-      } catch (error) {
-        hilog.error(0x0000, TAG, `[${this.processId}] Error in state listener ${index}: ${error}`);
-      }
-    });
-  }
-
-  /**
-   * 检查两个WidgetData是否相等(简化版本,只检查关键字段)
-   */
-  private isDataEqual(data1: WidgetData, data2: WidgetData): boolean {
-    return data1.playState.isPlaying === data2.playState.isPlaying &&
-           data1.currentSong.title === data2.currentSong.title &&
-           data1.currentSong.id === data2.currentSong.id &&
-           data1.playlist.hasNext === data2.playlist.hasNext &&
-           data1.playlist.hasPrevious === data2.playlist.hasPrevious &&
-           Math.abs(data1.progress.percentage - data2.progress.percentage) < 0.1; // 进度变化小于0.1%时忽略
-  }
-
-  /**
-   * 移除状态监听器
-   */
-  public removeStateListener(callback: (data: WidgetData) => void): void {
-    const index = this.stateListeners.indexOf(callback);
-    if (index > -1) {
-      this.stateListeners.splice(index, 1);
-    }
-    hilog.info(0x0000, TAG, 'State listener removed');
-  }
-
-  /**
-   * 获取当前卡片数据
-   */
-  public getCurrentWidgetData(): WidgetData {
-    if (this.lastWidgetData) {
-      hilog.info(0x0000, TAG, `Returning cached widget data: hasNext=${this.lastWidgetData.playlist.hasNext}, hasPrevious=${this.lastWidgetData.playlist.hasPrevious}, currentIndex=${this.lastWidgetData.playlist.currentIndex}, totalCount=${this.lastWidgetData.playlist.totalCount}`);
-      return this.lastWidgetData;
-    }
-    
-    const defaultData = this.getDefaultWidgetData();
-    hilog.info(0x0000, TAG, `Returning default widget data: hasNext=${defaultData.playlist.hasNext}, hasPrevious=${defaultData.playlist.hasPrevious}`);
-    return defaultData;
-  }
-
-  /**
-   * 销毁监听器
-   */
-  public destroy(): void {
-    // 清理定时器
-    if (this.progressUpdateTimer !== -1) {
-      clearInterval(this.progressUpdateTimer);
-      this.progressUpdateTimer = -1;
-    }
-    
-    this.stateListeners = [];
-    this.lastWidgetData = null;
-    this.isProgressAnimating = false;
-    
-    hilog.info(0x0000, TAG, 'AvSession widget listener destroyed');
-  }
-
-  /**
-   * 计算播放进度百分比
-   */
-  private calculatePercentage(current: number, total: number): number {
-    if (total <= 0) return 0;
-    return Math.min(100, Math.max(0, (current / total) * 100));
-  }
-
-  /**
-   * 格式化时间显示
-   */
-  private formatTime(seconds: number): string {
-    const mins = Math.floor(seconds / 60);
-    const secs = Math.floor(seconds % 60);
-    return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
-  }
-
-  /**
-   * 强制同步状态(用于调试和故障恢复)
-   */
-  public forceSyncState(data: WidgetData): void {
-    hilog.info(0x0000, TAG, `[${this.processId}] Force syncing widget state`);
-    this.lastWidgetData = data;
-    this.lastStateSyncTime = 0; // 重置防抖时间
-    this.updateWidgetData(data);
-  }
-
-  /**
-   * 获取同步状态信息(用于调试)
-   */
-  public getSyncStatus(): SyncStatusInfo {
-    return {
-      processId: this.processId,
-      listenerCount: this.stateListeners.length,
-      lastUpdateTime: this.lastStateSyncTime,
-      isProgressAnimating: this.isProgressAnimating,
-      hasProgressTimer: this.progressUpdateTimer !== -1
-    };
-  }
-
-  /**
-   * 获取默认卡片数据
-   */
-  private getDefaultWidgetData(): WidgetData {
-    return WidgetTypeHelpers.createDefaultWidgetData();
-  }
-}

+ 0 - 1233
entry/src/main/ets/common/widget/EnhancedFormUpdateService.ets

@@ -1,1233 +0,0 @@
-import { hilog } from '@kit.PerformanceAnalysisKit';
-import { formProvider, formBindingData } from '@kit.FormKit';
-import { preferences } from '@kit.ArkData';
-import { Context } from '@kit.AbilityKit';
-import { WidgetData, FormattedWidgetData, WidgetSize, ImageFileInfo } from './WidgetTypes';
-import { FormLayoutManager } from './FormLayoutManager';
-import { PreferencesUtil } from '../utils/PreferencesUtil';
-import { GlobalWidgetManager } from './GlobalWidgetManager';
-import { fileIo } from '@kit.CoreFileKit';
-import { http } from '@kit.NetworkKit';
-
-const TAG = 'EnhancedFormUpdateService';
-
-/**
- * 表单状态数据接口
- */
-interface FormStateData extends Record<string, string | number | boolean | Uint8Array> {
-  size: string;
-  lastUpdate: number;
-  lastSongId: string;
-  updateCount: number;
-  lastImageUrl: string;
-}
-
-/**
- * 更新结果接口
- */
-interface UpdateResult {
-  formId: string;
-  success: boolean;
-  error?: Error;
-  updateTime: number;
-  retryCount: number;
-}
-
-/**
- * 批量更新统计
- */
-interface BatchUpdateStats {
-  total: number;
-  success: number;
-  failed: number;
-  duration: number;
-  averageUpdateTime: number;
-}
-
-/**
- * 网络图片缓存项
- */
-interface ImageCacheItem {
-  fileName: string;
-  downloadTime: number;
-  expiry: number;
-  fileSize: number;
-}
-
-/**
- * 图片下载结果接口
- */
-interface ImageDownloadResult {
-  fileName: string;
-  fd?: number;
-}
-
-/**
- * 包含图片文件描述符的卡片数据接口
- */
-interface FormattedWidgetDataWithImages extends FormattedWidgetData {
-  formImages?: Record<string, number>;
-}
-
-/**
- * 处理后的本地图片信息接口
- */
-interface ProcessedImageInfo {
-  fileName: string;
-  memoryUri: string;
-  fd: number;
-  sourceHash?: string;  // 添加源文件哈希用于缓存标识
-}
-
-/**
- * 更新统计接口
- */
-export interface UpdateStats {
-  totalUpdates: number;
-  successfulUpdates: number;
-  failedUpdates: number;
-  averageUpdateTime: number;
-  lastBatchStats?: BatchUpdateStats;
-}
-
-/**
- * 增强版卡片更新服务
- * 在原有DirectFormUpdateService基础上添加了以下功能:
- * 1. 智能重试机制
- * 2. 网络图片缓存
- * 3. 批量更新统计
- * 4. 性能监控
- * 5. 错误恢复
- */
-export class EnhancedFormUpdateService {
-  private static instance: EnhancedFormUpdateService | null = null;
-  private layoutManager: FormLayoutManager = FormLayoutManager.getInstance();
-  private preferencesUtil: PreferencesUtil = PreferencesUtil.getInstance();
-  private globalWidgetManager: GlobalWidgetManager = GlobalWidgetManager.getInstance();
-  private appContext: Context | null = null;
-
-  // 防抖和节流
-  private lastUpdateTime: number = 0;
-  private updateDebounceDelay: number = 100; // 100ms防抖延迟
-  private isUpdating: boolean = false;
-
-  // 重试配置
-  private readonly maxRetryCount: number = 3;
-  private readonly retryDelays: number[] = [500, 1000, 2000]; // 递增重试延迟
-
-  // 网络图片缓存
-  private imageCache: Map<string, ImageCacheItem> = new Map();
-  private downloadingImages: Map<string, Promise<ImageDownloadResult | null>> = new Map();
-  private readonly imageCacheExpiry: number = 24 * 60 * 60 * 1000; // 24小时
-  private readonly maxCacheSize: number = 50; // 最多缓存50张图片
-
-  // 本地图片处理缓存
-  private localImageCache: Map<string, ProcessedImageInfo> = new Map();
-  private processingLocalImages: Map<string, Promise<ProcessedImageInfo | null>> = new Map();
-  private readonly localImageCacheExpiry: number = 30 * 60 * 1000; // 30分钟
-  private lastLocalCacheCleanup: number = 0;
-
-  // 性能统计
-  private updateStats: UpdateStats = {
-    totalUpdates: 0,
-    successfulUpdates: 0,
-    failedUpdates: 0,
-    averageUpdateTime: 0
-  };
-
-  private constructor() {}
-
-  public static getInstance(): EnhancedFormUpdateService {
-    if (!EnhancedFormUpdateService.instance) {
-      EnhancedFormUpdateService.instance = new EnhancedFormUpdateService();
-    }
-    return EnhancedFormUpdateService.instance;
-  }
-
-  /**
-   * 设置应用上下文
-   */
-  public setAppContext(context: Context): void {
-    this.appContext = context;
-
-    this.initializeImageCache();
-  }
-
-  /**
-   * 主要的更新所有卡片方法 - 参考原DirectFormUpdateService.updateAllForms()
-   */
-  public async updateAllForms(data: WidgetData): Promise<BatchUpdateStats> {
-    const batchStartTime = Date.now();
-    console.log("Heanup updateAllForms data:"+JSON.stringify(data))
-
-    // 预处理图片路径 - 转换本地文件URI为可用格式
-    const processedData = await this.preprocessImageData(data);
-
-    try {
-      if (!this.appContext) {
-        hilog.error(0x0000, TAG, '❌ App context not set, cannot update forms');
-        throw new Error('App context not set');
-      }
-
-      // 防抖检查
-      const now = Date.now();
-      if (now - this.lastUpdateTime < this.updateDebounceDelay) {
-
-        return this.createEmptyStats();
-      }
-
-      // 防止并发更新
-      if (this.isUpdating) {
-
-        return this.createEmptyStats();
-      }
-
-      this.isUpdating = true;
-      this.lastUpdateTime = now;
-
-
-
-      // 获取所有持久化的 Form ID(使用原有方法)
-      const prefs = await this.preferencesUtil.getPreferences(this.appContext);
-      const formIds = await this.preferencesUtil.getFormIds(prefs);
-
-      if (formIds.length === 0) {
-
-        return this.createEmptyStats();
-      }
-
-
-
-      // 验证活跃卡片与持久化卡片的一致性
-      await this.validateActiveWidgets(formIds, prefs);
-
-      // 预先验证卡片ID的有效性,移除无效的ID
-      const validFormIds = await this.preValidateFormIds(formIds, prefs);
-
-      if (validFormIds.length === 0) {
-        hilog.warn(0x0000, TAG, '📋 No valid form IDs found after validation');
-        return this.createEmptyStats();
-      }
-
-      hilog.info(0x0000, TAG, `📋 Valid forms: ${validFormIds.length}/${formIds.length}`);
-
-      // 并行更新所有卡片
-      const updatePromises = validFormIds.map((formId, index) => {
-
-
-        return this.updateSingleFormWithRetry(formId, processedData, prefs);
-      });
-
-
-
-      // 等待所有更新完成
-      const results = await Promise.allSettled(updatePromises);
-
-      // 处理结果并生成统计信息
-      const batchStats = this.processBatchResults(validFormIds, results, batchStartTime);
-
-      // 清理无效的 Form ID
-      if (batchStats.failed > 0) {
-        await this.cleanupInvalidForms(prefs, validFormIds, results);
-      }
-
-      return batchStats;
-
-    } catch (error) {
-      hilog.error(0x0000, TAG, `❌ Failed to update forms: ${error}`);
-      throw new Error(`Failed to update forms: ${error}`);
-    } finally {
-      this.isUpdating = false;
-    }
-  }
-
-  /**
-   * 带重试机制的单个卡片更新
-   */
-  private async updateSingleFormWithRetry(formId: string, data: WidgetData, prefs: preferences.Preferences): Promise<UpdateResult> {
-    const startTime = Date.now();
-    let lastError: Error | null = null;
-
-    for (let attempt = 0; attempt <= this.maxRetryCount; attempt++) {
-      try {
-        // if (attempt > 0) {
-        //   const delay = this.retryDelays[Math.min(attempt - 1, this.retryDelays.length - 1)];
-        //
-        //   await this.sleep(delay);
-        // }
-
-        await this.updateSingleForm(formId, data, prefs);
-
-        const updateTime = Date.now() - startTime;
-
-
-        return {
-          formId,
-          success: true,
-          updateTime,
-          retryCount: attempt
-        };
-
-      } catch (error) {
-        lastError = error as Error;
-        const errorStr :string= error.toString();
-
-        // 如果是无效卡片ID错误,立即停止重试并清理
-        if (errorStr.includes('form not exist') ||
-        errorStr.includes('16501001') ||
-        errorStr.includes('The ID of the form to be operated does not exist')) {
-          hilog.warn(0x0000, TAG, `🗑️ [${formId}] Invalid form ID detected, cleaning up immediately`);
-
-          // 立即清理无效ID
-          try {
-            await this.preferencesUtil.removeFormId(prefs, formId);
-            this.globalWidgetManager.unregisterWidget(formId);
-            hilog.info(0x0000, TAG, `🗑️ [${formId}] Cleaned up invalid form ID`);
-          } catch (cleanupError) {
-            hilog.error(0x0000, TAG, `❌ [${formId}] Failed to cleanup invalid form ID: ${cleanupError}`);
-          }
-
-          // 立即返回失败结果,不再重试
-          const updateTime = Date.now() - startTime;
-          return {
-            formId,
-            success: false,
-            error: lastError,
-            updateTime,
-            retryCount: attempt
-          };
-        }
-
-
-      }
-    }
-
-    const updateTime = Date.now() - startTime;
-    hilog.error(0x0000, TAG, `❌ [${formId}] All ${this.maxRetryCount + 1} attempts failed (${updateTime}ms total)`);
-
-    return {
-      formId,
-      success: false,
-      error: lastError || new Error('Unknown error'),
-      updateTime,
-      retryCount: this.maxRetryCount
-    };
-  }
-
-  /**
-   * 更新单个卡片(增强版,参考原有方法)
-   */
-  private async updateSingleForm(formId: string, data: WidgetData, prefs: preferences.Preferences): Promise<void> {
-    try {
-
-
-      // 获取卡片的当前状态
-      const formState = await this.preferencesUtil.getFormState(prefs, formId);
-      const widgetSizeStr = (formState?.size as string) || 'medium';
-      const widgetSize: WidgetSize = widgetSizeStr as WidgetSize;
-
-
-
-      // 适配数据到卡片尺寸
-      const adaptedData = this.layoutManager.adaptDataForSize(data, widgetSize);
-
-      // 处理网络图片(传递原始数据以便设置文件描述符)
-      await this.handleNetworkImage(adaptedData, data);
-
-      // 转换为 FormattedWidgetData
-      const formattedData: FormattedWidgetData = {
-        isPlaying: adaptedData.isPlaying,
-        isPaused: adaptedData.isPaused,
-        isLoading: adaptedData.isLoading,
-        songTitle: adaptedData.songTitle,
-        songArtist: adaptedData.songArtist,
-        songAlbum: adaptedData.songAlbum,
-        coverImage: adaptedData.coverImage,
-        currentTime: adaptedData.currentTime,
-        totalTime: adaptedData.totalTime,
-        progressPercentage: adaptedData.progressPercentage,
-        hasNext: adaptedData.hasNext,
-        hasPrevious: adaptedData.hasPrevious,
-        showProgress: adaptedData.showProgress,
-        showCover: adaptedData.showCover,
-        widgetSize: adaptedData.widgetSize,
-        timestamp: Date.now(),
-        imgName: adaptedData.imgName || '',
-        isFavorite: adaptedData.isFavorite,
-      };
-
-
-
-      // 处理图片文件描述符(如果有本地图片)
-      let formData: formBindingData.FormBindingData;
-      if (data.imageFileInfo && formattedData.imgName) {
-        // 创建包含文件描述符的数据
-        const dataWithImages: FormattedWidgetDataWithImages = {
-          isPlaying: formattedData.isPlaying,
-          isPaused: formattedData.isPaused,
-          isLoading: formattedData.isLoading,
-          songTitle: formattedData.songTitle,
-          songArtist: formattedData.songArtist,
-          songAlbum: formattedData.songAlbum,
-          coverImage: formattedData.coverImage,
-          currentTime: formattedData.currentTime,
-          totalTime: formattedData.totalTime,
-          progressPercentage: formattedData.progressPercentage,
-          hasNext: formattedData.hasNext,
-          hasPrevious: formattedData.hasPrevious,
-          showProgress: formattedData.showProgress,
-          showCover: formattedData.showCover,
-          widgetSize: formattedData.widgetSize,
-          timestamp: formattedData.timestamp,
-          imgName: formattedData.imgName,
-          formImages: {} as Record<string, number>,
-          isFavorite: formattedData.isFavorite
-        };
-
-        // 设置图片文件描述符
-        // 根据官方文档:imgName 必须和 formImages 中的 key 相同
-        if (dataWithImages.formImages && data.imageFileInfo.fileName) {
-          dataWithImages.formImages[data.imageFileInfo.fileName] = data.imageFileInfo.fd;
-          // 确保 imgName 与 formImages 的 key 一致
-          dataWithImages.imgName = data.imageFileInfo.fileName;
-        }
-
-        formData = formBindingData.createFormBindingData(dataWithImages);
-        hilog.info(0x0000, TAG, `📷 [${formId}] Created form data with image fd: ${data.imageFileInfo.fd} for ${data.imageFileInfo.fileName}`);
-      } else {
-        formData = formBindingData.createFormBindingData(formattedData);
-      }
-
-      // 更新卡片
-      await formProvider.updateForm(formId, formData);
-      
-      // 注意:不手动关闭文件描述符,让系统自动管理
-      // 手动关闭可能导致EBADF错误,因为卡片系统可能还在使用文件描述符
-      if (data.imageFileInfo && data.imageFileInfo.fd !== undefined && data.imageFileInfo.fd > 0) {
-        hilog.info(0x0000, TAG, `📷 [${formId}] Form updated with file descriptor: ${data.imageFileInfo.fd} for ${data.imageFileInfo.fileName}`);
-        // 将fd标记为已使用,但不关闭,让系统自动回收
-        data.imageFileInfo.fd = -1;
-      }
-
-
-
-      // 保存增强状态信息
-      await this.saveEnhancedFormState(prefs, formId, widgetSizeStr, data);
-
-    } catch (error) {
-      hilog.error(0x0000, TAG, `❌ [${formId}] Failed to update form: ${error}`);
-      throw new Error(`Failed to update form ${formId}: ${error}`);
-    }
-  }
-
-  /**
-   * 预处理图片数据 - 转换本地文件URI为卡片可用格式
-   */
-  private async preprocessImageData(data: WidgetData): Promise<WidgetData> {
-    try {
-      // 修改点1: 显式声明processedData的类型为WidgetData
-      let processedData: WidgetData = data;
-      const coverImagePath = data.currentSong.coverImagePath;
-
-      if (!coverImagePath || coverImagePath.trim() === '') {
-        hilog.info(0x0000, TAG, '📷 No cover image path, skipping preprocessing');
-        return data;
-      }
-
-      hilog.info(0x0000, TAG, `📷 Processing cover image: ${coverImagePath}`);
-
-      // 处理本地文件URI
-      if (this.isLocalFileUri(coverImagePath)) {
-        hilog.info(0x0000, TAG, `📷 Detected local file URI: ${coverImagePath}`);
-
-        const processedImageInfo = await this.processLocalImageFile(coverImagePath);
-
-        if (processedImageInfo) {
-          // 创建新的数据对象,包含处理后的图片信息
-          processedData.currentSong.coverImagePath = processedImageInfo.memoryUri;
-          processedData.imageFileInfo = processedImageInfo as ImageFileInfo;
-
-          hilog.info(0x0000, TAG, `📷 Local image processed successfully: ${processedImageInfo.fileName} -> ${processedImageInfo.memoryUri}`);
-          return processedData;
-        } else {
-          hilog.warn(0x0000, TAG, `📷 Failed to process local image, using original data`);
-          return data;
-        }
-      }
-      // 处理网络图片
-      else if (this.isNetworkUrl(coverImagePath)) {
-        hilog.info(0x0000, TAG, `📷 Detected network image: ${coverImagePath}`);
-        // 网络图片在 handleNetworkImage 中处理
-        return data;
-      }
-      // 其他情况
-      else {
-        hilog.info(0x0000, TAG, `📷 Using image path as-is: ${coverImagePath}`);
-        return data;
-      }
-
-    } catch (error) {
-      hilog.error(0x0000, TAG, `❌ Error preprocessing image data: ${error}`);
-      return data; // 出错时返回原始数据
-    }
-  }
-
-  /**
-   * 处理本地图片文件
-   */
-  private async processLocalImageFile(fileUri: string): Promise<ProcessedImageInfo | null> {
-    try {
-      hilog.info(0x0000, TAG, `📷 Processing local image file: ${fileUri}`);
-
-      // 生成缓存键(基于URI和时间戳)
-      const cacheKey = this.generateLocalImageCacheKey(fileUri);
-
-      // 检查本地图片缓存
-      const cachedInfo = this.localImageCache.get(cacheKey);
-      if (cachedInfo) {
-        // 验证缓存的文件是否还存在
-        const tempFilePath = `${this.appContext!.getApplicationContext().tempDir}/${cachedInfo.fileName}`;
-        if (fileIo.accessSync(tempFilePath)) {
-          hilog.info(0x0000, TAG, `📷 Using cached local image: ${cachedInfo.fileName}`);
-          return cachedInfo;
-        } else {
-          // 缓存文件不存在,移除缓存项
-          this.localImageCache.delete(cacheKey);
-          hilog.warn(0x0000, TAG, `📷 Cached file not found, will reprocess: ${cachedInfo.fileName}`);
-        }
-      }
-
-      // 检查是否正在处理中
-      if (this.processingLocalImages.has(cacheKey)) {
-        hilog.info(0x0000, TAG, `📷 Image already being processed, waiting: ${fileUri}`);
-        return await this.processingLocalImages.get(cacheKey)!;
-      }
-
-      // 创建处理Promise
-      const processingPromise = this.performLocalImageProcessing(fileUri, cacheKey);
-      this.processingLocalImages.set(cacheKey, processingPromise);
-
-      try {
-        const result = await processingPromise;
-        return result;
-      } finally {
-        this.processingLocalImages.delete(cacheKey);
-      }
-
-    } catch (error) {
-      hilog.error(0x0000, TAG, `❌ Failed to process local image: ${error}`);
-      return null;
-    }
-  }
-
-  /**
-   * 生成本地图片缓存键
-   */
-  private generateLocalImageCacheKey(fileUri: string): string {
-    // 从URI中提取文件名或路径的关键部分作为缓存键
-    const pathParts = fileUri.split('/');
-    const fileName = pathParts[pathParts.length - 1];
-    // 使用文件名作为缓存键(因为日志显示相同的文件被重复处理)
-    return `local_${fileName}`;
-  }
-
-  /**
-   * 执行本地图片处理
-   */
-  private async performLocalImageProcessing(fileUri: string, cacheKey: string): Promise<ProcessedImageInfo | null> {
-    try {
-      // 清理过期缓存
-      this.cleanupLocalImageCache();
-
-      // 转换 file:// URI 为实际文件路径
-      // file://com.xgplayer.ttmusic.hm/data/storage/el2/base/haps/entry/files/xxx.jpg
-      // 转换为 /data/storage/el2/base/haps/entry/files/xxx.jpg
-      let realPath = fileUri.replace('file://', '');
-
-      // 如果路径包含应用包名,需要移除它并构建正确的绝对路径
-      if (realPath.startsWith('com.xgplayer.ttmusic.hm/')) {
-        // 移除包名前缀,获取相对路径
-        const relativePath = realPath.replace('com.xgplayer.ttmusic.hm/', '');
-        // 使用应用上下文获取正确的文件路径
-        realPath = `${this.appContext!.filesDir}/${relativePath.split('/').pop()}`;
-        hilog.info(0x0000, TAG, `📷 Converted path with package name: ${fileUri} -> ${realPath}`);
-      } else if (!realPath.startsWith('/')) {
-        // 如果不是绝对路径,添加根路径
-        realPath = `/${realPath}`;
-      }
-
-      hilog.info(0x0000, TAG, `📷 Final resolved path: ${realPath}`);
-
-      // 检查源文件是否存在
-      if (!fileIo.accessSync(realPath)) {
-        hilog.error(0x0000, TAG, `📷 Source image file does not exist: ${realPath}`);
-
-        // 尝试备用路径查找
-        const fileName = realPath.split('/').pop();
-        const alternativePaths = [
-          `${this.appContext!.filesDir}/${fileName}`,
-          `${this.appContext!.cacheDir}/${fileName}`,
-          `${this.appContext!.tempDir}/${fileName}`
-        ];
-
-        let foundPath: string | null = null;
-        for (const altPath of alternativePaths) {
-          if (fileIo.accessSync(altPath)) {
-            foundPath = altPath;
-            hilog.info(0x0000, TAG, `📷 Found file at alternative path: ${altPath}`);
-            break;
-          }
-        }
-
-        if (!foundPath) {
-          hilog.error(0x0000, TAG, `📷 File not found in any location: ${fileName}`);
-          return null;
-        }
-
-        realPath = foundPath;
-      }
-
-      // 生成目标文件名(确保每次都不同,符合官方文档要求)
-      const fileExtension = this.getFileExtension(realPath) || 'jpg';
-      const fileName = `widget_local_${Date.now()}_${Math.random().toString(36).substr(2, 9)}.${fileExtension}`;
-
-      // 使用 FormExtensionAbility 的 tempDir(官方文档要求)
-      const formTempDir = this.appContext!.getApplicationContext().tempDir;
-      const tempFilePath = `${formTempDir}/${fileName}`;
-
-      hilog.info(0x0000, TAG, `📷 Using tempDir: ${formTempDir}`);
-
-      // 复制文件到临时目录
-      fileIo.copyFileSync(realPath, tempFilePath);
-
-      // 获取文件描述符
-      const file = fileIo.openSync(tempFilePath, fileIo.OpenMode.READ_ONLY);
-      const fd = file.fd;
-
-      const memoryUri = `memory://${fileName}`;
-
-      hilog.info(0x0000, TAG, `📷 Local image copied successfully: ${realPath} -> ${tempFilePath}, fd: ${fd}`);
-
-      const result: ProcessedImageInfo = {
-        fileName,
-        memoryUri,
-        fd,
-        sourceHash: cacheKey
-      };
-
-      // 添加到缓存
-      this.localImageCache.set(cacheKey, result);
-      hilog.info(0x0000, TAG, `📷 Added to local image cache: ${cacheKey}`);
-
-      return result;
-
-    } catch (error) {
-      hilog.error(0x0000, TAG, `❌ Failed to process local image: ${error}`);
-      return null;
-    }
-  }
-
-  /**
-   * 检查是否为本地文件URI
-   */
-  private isLocalFileUri(url: string): boolean {
-    return url.startsWith('file://');
-  }
-
-  /**
-   * 清理本地图片缓存
-   */
-  private cleanupLocalImageCache(): void {
-    const now = Date.now();
-
-    // 每5分钟清理一次
-    if (now - this.lastLocalCacheCleanup < 5 * 60 * 1000) {
-      return;
-    }
-
-    this.lastLocalCacheCleanup = now;
-
-    // 清理过期的缓存项
-    const keysToDelete: string[] = [];
-    const tempDir = this.appContext!.getApplicationContext().tempDir;
-
-    this.localImageCache.forEach((info, key) => {
-      const tempFilePath = `${tempDir}/${info.fileName}`;
-
-      // 检查文件是否存在
-      if (!fileIo.accessSync(tempFilePath)) {
-        keysToDelete.push(key);
-        hilog.info(0x0000, TAG, `📷 Removing cache entry for missing file: ${info.fileName}`);
-      }
-    });
-
-    // 如果缓存过大,删除最旧的项
-    if (this.localImageCache.size > 20) {
-      const sortedEntries = Array.from(this.localImageCache.entries())
-        .sort((a, b) => {
-          // 根据文件名中的时间戳排序
-          const timeA = parseInt(a[1].fileName.split('_')[2] || '0');
-          const timeB = parseInt(b[1].fileName.split('_')[2] || '0');
-          return timeA - timeB;
-        });
-
-      const entriesToDelete = sortedEntries.slice(0, this.localImageCache.size - 15);
-      entriesToDelete.forEach((entry) => {
-        const key = entry[0];
-        const info = entry[1];
-        keysToDelete.push(key);
-        // 尝试删除临时文件
-        try {
-          const filePath = `${tempDir}/${info.fileName}`;
-          if (fileIo.accessSync(filePath)) {
-            // 不要关闭可能已经无效的文件描述符,直接删除文件
-            fileIo.unlinkSync(filePath);
-            hilog.info(0x0000, TAG, `📷 Deleted old cached file: ${info.fileName}`);
-          }
-        } catch (error) {
-          hilog.warn(0x0000, TAG, `📷 Failed to delete cached file: ${info.fileName}`);
-        }
-      });
-    }
-
-    // 删除缓存项
-    keysToDelete.forEach(key => {
-      this.localImageCache.delete(key);
-    });
-
-    if (keysToDelete.length > 0) {
-      hilog.info(0x0000, TAG, `📷 Cleaned up ${keysToDelete.length} local image cache entries`);
-    }
-  }
-
-  /**
-   * 获取文件扩展名
-   */
-  private getFileExtension(filePath: string): string | null {
-    const lastDotIndex = filePath.lastIndexOf('.');
-    if (lastDotIndex === -1 || lastDotIndex === filePath.length - 1) {
-      return null;
-    }
-    return filePath.substring(lastDotIndex + 1).toLowerCase();
-  }
-
-  /**
-   * 处理网络图片(缓存 + 下载)
-   */
-  private async handleNetworkImage(adaptedData: FormattedWidgetData, originalData: WidgetData): Promise<void> {
-    if (!adaptedData.coverImage) {
-      return;
-    }
-
-    try {
-      // 如果已经是 memory:// 格式(本地图片已处理),验证缓存是否有效
-      if (adaptedData.coverImage.startsWith('memory://')) {
-        const fileName = adaptedData.coverImage.replace('memory://', '');
-        const tempFilePath = `${this.appContext!.getApplicationContext().tempDir}/${fileName}`;
-
-        // 验证文件是否存在
-        if (fileIo.accessSync(tempFilePath)) {
-          hilog.info(0x0000, TAG, `📷 Using existing memory URI: ${adaptedData.coverImage}`);
-          adaptedData.imgName = fileName;
-          return;
-        } else {
-          hilog.warn(0x0000, TAG, `📷 Memory URI file not found, will reprocess: ${fileName}`);
-          // 清除无效的memory URI,继续处理
-          adaptedData.coverImage = '';
-        }
-      }
-
-      // 处理网络图片
-      if (!this.isNetworkUrl(adaptedData.coverImage)) {
-        return;
-      }
-
-      const imageUrl = adaptedData.coverImage;
-
-
-      // 检查缓存
-      const cachedItem = this.imageCache.get(imageUrl);
-      if (cachedItem && cachedItem.expiry > Date.now()) {
-
-        // 尝试打开缓存的文件获取文件描述符
-        try {
-          const cachedFilePath = `${this.appContext!.getApplicationContext().tempDir}/${cachedItem.fileName}`;
-          const fileForWidget = fileIo.openSync(cachedFilePath, fileIo.OpenMode.READ_ONLY);
-          const fd = fileForWidget.fd;
-
-          adaptedData.coverImage = `memory://${cachedItem.fileName}`;
-          adaptedData.imgName = cachedItem.fileName;
-
-          // 设置文件描述符信息到原始数据
-          originalData.imageFileInfo = {
-            fileName: cachedItem.fileName,
-            memoryUri: `memory://${cachedItem.fileName}`,
-            fd: fd
-          };
-
-          hilog.info(0x0000, TAG, `📷 Using cached image with fd: ${fd}, fileName: ${cachedItem.fileName}`);
-          // 注意:不要在这里关闭文件,文件描述符需要传递给卡片
-          return;
-        } catch (fdError) {
-          hilog.warn(0x0000, TAG, `📷 Failed to open cached file for fd: ${fdError}, will redownload`);
-          // 如果无法打开文件,继续下载新的
-        }
-      }
-
-      // 下载图片
-      const downloadResult = await this.downloadAndCacheImage(imageUrl);
-      if (downloadResult) {
-        adaptedData.coverImage = `memory://${downloadResult.fileName}`;
-        adaptedData.imgName = downloadResult.fileName;
-
-        // 设置文件描述符信息到原始数据(memory协议需要)
-        if (downloadResult.fd !== undefined) {
-          originalData.imageFileInfo = {
-            fileName: downloadResult.fileName,
-            memoryUri: `memory://${downloadResult.fileName}`,
-            fd: downloadResult.fd
-          };
-          hilog.info(0x0000, TAG, `📷 Network image downloaded with fd: ${downloadResult.fd}, fileName: ${downloadResult.fileName}`);
-        }
-
-      } else {
-        // 下载失败,清除图片
-        adaptedData.coverImage = '';
-        adaptedData.imgName = '';
-
-      }
-
-    } catch (error) {
-      hilog.error(0x0000, TAG, `❌ Error processing network image: ${error}`);
-      adaptedData.coverImage = '';
-      adaptedData.imgName = '';
-    }
-  }
-
-  /**
-   * 下载并缓存网络图片
-   */
-  private async downloadAndCacheImage(imageUrl: string): Promise<ImageDownloadResult | null> {
-    // 检查是否正在下载
-    if (this.downloadingImages.has(imageUrl)) {
-
-      return await this.downloadingImages.get(imageUrl)!;
-    }
-
-    // 创建下载Promise
-    const downloadPromise = this.performImageDownload(imageUrl);
-    this.downloadingImages.set(imageUrl, downloadPromise);
-
-    try {
-      const result = await downloadPromise;
-      return result;
-    } finally {
-      this.downloadingImages.delete(imageUrl);
-    }
-  }
-
-  /**
-   * 执行图片下载
-   */
-  private async performImageDownload(imageUrl: string): Promise<ImageDownloadResult | null> {
-    try {
-
-
-      const httpRequest = http.createHttp();
-      const response = await httpRequest.request(imageUrl, {
-        method: http.RequestMethod.GET,
-        connectTimeout: 10000,
-        readTimeout: 10000
-      });
-
-      if (response.responseCode !== 200) {
-        throw new Error(`HTTP ${response.responseCode}`);
-      }
-
-      // 生成文件名
-      const fileName = `widget_cover_${Date.now()}_${Math.random().toString(36).substr(2, 9)}.jpg`;
-
-      // 保存到临时目录(卡片要求使用tempDir)
-      const filePath = `${this.appContext!.getApplicationContext().tempDir}/${fileName}`;
-      
-      // 修改点2: 显式声明buffer的类型为ArrayBuffer
-      const buffer: ArrayBuffer = response.result as ArrayBuffer;
-      
-      // 根据官方文档:先创建文件并写入数据
-      const tempFile = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
-      try {
-        // 使用 write 方法写入数据
-        const writeLen = await fileIo.write(tempFile.fd, buffer);
-        hilog.info(0x0000, TAG, `📷 Write data to file succeed and size is: ${writeLen}`);
-      } catch (writeError) {
-        hilog.error(0x0000, TAG, `❌ Write data to file failed: ${writeError}`);
-        fileIo.closeSync(tempFile);
-        httpRequest.destroy();
-        return null;
-      } finally {
-        // 关闭临时文件句柄
-        fileIo.closeSync(tempFile);
-      }
-
-      // 添加到缓存
-      const cacheItem: ImageCacheItem = {
-        fileName,
-        downloadTime: Date.now(),
-        expiry: Date.now() + this.imageCacheExpiry,
-        fileSize: buffer.byteLength
-      };
-
-      this.imageCache.set(imageUrl, cacheItem);
-      this.cleanupImageCache();
-
-      // 根据官方文档:重新打开文件获取文件描述符用于卡片显示
-      try {
-        const fileForWidget = fileIo.openSync(filePath, fileIo.OpenMode.READ_ONLY);
-        const fd = fileForWidget.fd;
-
-        hilog.info(0x0000, TAG, `📷 Image downloaded and opened for widget: ${fileName}, fd: ${fd}`);
-
-        // 注意:根据官方文档,不要在这里关闭文件,文件描述符需要传递给卡片
-        // fileIo.closeSync(fileForWidget); // 等待卡片更新完成后再关闭
-
-        httpRequest.destroy();
-        const result: ImageDownloadResult = { fileName: fileName, fd: fd };
-        return result;
-      } catch (fdError) {
-        hilog.error(0x0000, TAG, `❌ Failed to open file for widget fd: ${fdError}`);
-        httpRequest.destroy();
-        const result: ImageDownloadResult = { fileName: fileName };
-        return result; // 返回不包含fd的结果
-      }
-
-    } catch (error) {
-      hilog.error(0x0000, TAG, `❌ Failed to download image: ${error}`);
-      return null;
-    }
-  }
-
-  /**
-   * 清理图片缓存
-   */
-  private cleanupImageCache(): void {
-    if (this.imageCache.size <= this.maxCacheSize) {
-      return;
-    }
-
-    // 按下载时间排序,删除最旧的
-    const sortedItems = Array.from(this.imageCache.entries())
-      .sort((a, b) => a[1].downloadTime - b[1].downloadTime);
-
-    const itemsToDelete = sortedItems.slice(0, this.imageCache.size - this.maxCacheSize);
-
-    for (let i = 0; i < itemsToDelete.length; i++) {
-      try {
-        const entry = itemsToDelete[i];
-        const url = entry[0];
-        const item = entry[1];
-        const filePath = `${this.appContext!.cacheDir}/${item.fileName}`;
-        if (fileIo.accessSync(filePath)) {
-          fileIo.unlinkSync(filePath);
-        }
-        this.imageCache.delete(url);
-
-      } catch (error) {
-
-      }
-    }
-  }
-
-  /**
-   * 初始化图片缓存
-   */
-  private initializeImageCache(): void {
-    // 清理过期的缓存文件
-    try {
-      const cacheDir = this.appContext!.cacheDir;
-      const files = fileIo.listFileSync(cacheDir);
-
-      for (const file of files) {
-        if (file.startsWith('widget_cover_')) {
-          const filePath = `${cacheDir}/${file}`;
-          const stat = fileIo.statSync(filePath);
-
-          // 删除超过24小时的文件
-          if (Date.now() - stat.mtime > this.imageCacheExpiry) {
-            fileIo.unlinkSync(filePath);
-
-          }
-        }
-      }
-    } catch (error) {
-
-    }
-  }
-
-  /**
-   * 预先验证卡片ID的有效性
-   */
-  private async preValidateFormIds(formIds: string[], prefs: preferences.Preferences): Promise<string[]> {
-    const validFormIds: string[] = [];
-    const invalidFormIds: string[] = [];
-
-    hilog.info(0x0000, TAG, `🔍 Pre-validating ${formIds.length} form IDs...`);
-
-    for (const formId of formIds) {
-      try {
-        // 尝试使用一个简单的测试数据来验证卡片ID
-        const testData = formBindingData.createFormBindingData({
-          test: 'validation'
-        });
-
-        // 尝试更新卡片,如果失败说明卡片ID无效
-        await formProvider.updateForm(formId, testData);
-        validFormIds.push(formId);
-        hilog.debug(0x0000, TAG, `✅ [${formId}] Valid form ID`);
-
-      } catch (error) {
-        const errorStr :string= error.toString();
-        if (errorStr.includes('form not exist') ||
-        errorStr.includes('16501001') ||
-        errorStr.includes('The ID of the form to be operated does not exist')) {
-          hilog.warn(0x0000, TAG, `❌ [${formId}] Invalid form ID detected during validation`);
-          invalidFormIds.push(formId);
-        } else {
-          // 其他错误,可能是临时性的,保留该ID
-          hilog.warn(0x0000, TAG, `⚠️ [${formId}] Validation error (keeping): ${error}`);
-          validFormIds.push(formId);
-        }
-      }
-    }
-
-    // 清理无效的卡片ID
-    if (invalidFormIds.length > 0) {
-      hilog.info(0x0000, TAG, `🗑️ Cleaning up ${invalidFormIds.length} invalid form IDs`);
-      for (const invalidFormId of invalidFormIds) {
-        try {
-          await this.preferencesUtil.removeFormId(prefs, invalidFormId);
-          this.globalWidgetManager.unregisterWidget(invalidFormId);
-          hilog.info(0x0000, TAG, `🗑️ [${invalidFormId}] Cleaned up invalid form ID`);
-        } catch (cleanupError) {
-          hilog.error(0x0000, TAG, `❌ [${invalidFormId}] Failed to cleanup: ${cleanupError}`);
-        }
-      }
-    }
-
-    hilog.info(0x0000, TAG, `🔍 Validation complete: ${validFormIds.length} valid, ${invalidFormIds.length} invalid`);
-    return validFormIds;
-  }
-
-  /**
-   * 验证活跃卡片与持久化卡片的一致性
-   */
-  private async validateActiveWidgets(formIds: string[], prefs: preferences.Preferences): Promise<void> {
-    const activeWidgets = this.globalWidgetManager.getActiveWidgets();
-    const activeFormIds = Array.from(activeWidgets.keys());
-
-
-
-    // 检查持久化但不活跃的卡片
-    const persistentOnlyIds = formIds.filter(id => !activeWidgets.has(id));
-    if (persistentOnlyIds.length > 0) {
-
-    }
-
-    // 检查活跃但未持久化的卡片
-    const activeOnlyIds = activeFormIds.filter(id => !formIds.includes(id));
-    if (activeOnlyIds.length > 0) {
-
-
-      // 将活跃的卡片添加到持久化存储
-      for (const formId of activeOnlyIds) {
-        await this.preferencesUtil.addFormId(prefs, formId);
-
-      }
-    }
-  }
-
-  /**
-   * 保存增强的表单状态
-   */
-  private async saveEnhancedFormState(prefs: preferences.Preferences, formId: string, widgetSize: string, data: WidgetData): Promise<void> {
-    try {
-      const existingState = await this.preferencesUtil.getFormState(prefs, formId) as FormStateData | null;
-      const updateCount = (existingState?.updateCount as number || 0) + 1;
-
-      const stateData: FormStateData = {
-        size: widgetSize,
-        lastUpdate: Date.now(),
-        lastSongId: data.currentSong.id,
-        updateCount: updateCount,
-        lastImageUrl: data.currentSong.coverImagePath || ''
-      };
-
-      await this.preferencesUtil.saveFormState(prefs, formId, stateData);
-
-    } catch (error) {
-
-    }
-  }
-
-  /**
-   * 处理批量更新结果
-   */
-  private processBatchResults(formIds: string[], results: PromiseSettledResult<UpdateResult>[], startTime: number): BatchUpdateStats {
-    const duration = Date.now() - startTime;
-    let successCount = 0;
-    let failedCount = 0;
-    let totalUpdateTime = 0;
-
-    results.forEach((result, index) => {
-      const formId = formIds[index];
-
-      if (result.status === 'fulfilled') {
-        const updateResult = result.value;
-        if (updateResult.success) {
-          successCount++;
-          totalUpdateTime += updateResult.updateTime;
-
-        } else {
-          failedCount++;
-          hilog.error(0x0000, TAG, `❌ Form ${index + 1}/${formIds.length} (${formId}) failed: ${updateResult.error?.message}`);
-        }
-      } else {
-        failedCount++;
-        hilog.error(0x0000, TAG, `❌ Form ${index + 1}/${formIds.length} (${formId}) promise rejected: ${result.reason}`);
-      }
-    });
-
-    const averageUpdateTime = successCount > 0 ? totalUpdateTime / successCount : 0;
-
-    return {
-      total: formIds.length,
-      success: successCount,
-      failed: failedCount,
-      duration,
-      averageUpdateTime
-    };
-  }
-
-  /**
-   * 清理无效的 Form ID(参考原有方法)
-   */
-  private async cleanupInvalidForms(prefs: preferences.Preferences, formIds: string[], results: PromiseSettledResult<UpdateResult>[]): Promise<void> {
-    try {
-      const invalidFormIds: string[] = [];
-
-      results.forEach((result: PromiseSettledResult<UpdateResult>, index: number) => {
-        if (result.status === 'fulfilled' && !result.value.success) {
-          const error = result.value.error!;
-          const errorStr = error.toString();
-          const formId = formIds[index];
-
-
-
-          if (errorStr.includes('form not exist') ||
-          errorStr.includes('16501001') ||
-          errorStr.includes('FormProvider') ||
-          errorStr.includes('invalid form')) {
-
-            invalidFormIds.push(formId);
-          }
-        }
-      });
-
-      if (invalidFormIds.length > 0) {
-
-
-        for (const invalidFormId of invalidFormIds) {
-          await this.preferencesUtil.removeFormId(prefs, invalidFormId);
-          this.globalWidgetManager.unregisterWidget(invalidFormId);
-
-        }
-
-
-      }
-    } catch (error) {
-      hilog.error(0x0000, TAG, `❌ Failed to cleanup invalid forms: ${error}`);
-    }
-  }
-
-  /**
-   * 获取更新统计信息
-   */
-  public getUpdateStats(): UpdateStats {
-    const stats: UpdateStats = {
-      totalUpdates: this.updateStats.totalUpdates,
-      successfulUpdates: this.updateStats.successfulUpdates,
-      failedUpdates: this.updateStats.failedUpdates,
-      averageUpdateTime: this.updateStats.averageUpdateTime,
-      lastBatchStats: this.updateStats.lastBatchStats
-    };
-    return stats;
-  }
-
-  /**
-   * 重置统计信息
-   */
-  public resetStats(): void {
-    this.updateStats = {
-      totalUpdates: 0,
-      successfulUpdates: 0,
-      failedUpdates: 0,
-      averageUpdateTime: 0
-    };
-
-  }
-
-  /**
-   * 清理所有缓存
-   */
-  public clearAllCaches(): void {
-    // 清理本地图片缓存
-    this.localImageCache.forEach((info) => {
-      try {
-        const tempFilePath = `${this.appContext!.getApplicationContext().tempDir}/${info.fileName}`;
-        if (fileIo.accessSync(tempFilePath)) {
-          // 不要关闭可能已经无效的文件描述符,直接删除文件
-          fileIo.unlinkSync(tempFilePath);
-        }
-      } catch (error) {
-        hilog.warn(0x0000, TAG, `Failed to clean cached file: ${info.fileName}`);
-      }
-    });
-    this.localImageCache.clear();
-    this.processingLocalImages.clear();
-
-    // 清理网络图片缓存
-    this.imageCache.clear();
-    this.downloadingImages.clear();
-
-    hilog.info(0x0000, TAG, '🧹 All caches cleared');
-  }
-
-  /**
-   * 强制刷新所有卡片(忽略防抖)
-   */
-  public async forceUpdateAllForms(data: WidgetData): Promise<BatchUpdateStats> {
-    this.lastUpdateTime = 0; // 重置防抖时间
-    return await this.updateAllForms(data);
-  }
-
-  /**
-   * 工具方法
-   */
-  private isNetworkUrl(url: string): boolean {
-    return url.startsWith('http://') || url.startsWith('https://');
-  }
-
-  private sleep(ms: number): Promise<void> {
-    return new Promise(resolve => setTimeout(resolve, ms));
-  }
-
-  private createEmptyStats(): BatchUpdateStats {
-    const emptyStats: BatchUpdateStats = {
-      total: 0,
-      success: 0,
-      failed: 0,
-      duration: 0,
-      averageUpdateTime: 0
-    };
-    return emptyStats;
-  }
-}

+ 0 - 431
entry/src/main/ets/common/widget/FormLayoutManager.ets

@@ -1,431 +0,0 @@
-import { WidgetSize, WidgetData, FormattedWidgetData, WidgetConfig, ContainerPadding, ButtonSize, FontSizeConfig, SpacingConfig, ShowElementsConfig, ResponsiveLayoutParams } from './WidgetTypes';
-import hilog from '@ohos.hilog';
-
-const TAG = 'FormLayoutManager';
-
-/**
- * 卡片布局管理器
- * 负责处理多尺寸卡片的布局适配和UI重构
- * 需求: 5.4, 5.5
- */
-export class FormLayoutManager {
-  private static instance: FormLayoutManager;
-
-  /**
-   * 获取单例实例
-   */
-  public static getInstance(): FormLayoutManager {
-    if (!FormLayoutManager.instance) {
-      FormLayoutManager.instance = new FormLayoutManager();
-    }
-    return FormLayoutManager.instance;
-  }
-
-  private constructor() {
-    hilog.info(0x0000, TAG, 'FormLayoutManager initialized');
-  }
-
-  /**
-   * 根据卡片尺寸适配数据
-   * @param widgetData 原始卡片数据
-   * @param size 卡片尺寸
-   * @returns 适配后的格式化数据
-   */
-  public adaptDataForSize(widgetData: WidgetData, size: WidgetSize): FormattedWidgetData {
-    hilog.info(0x0000, TAG, `Adapting data for size: ${size}, coverImagePath: ${widgetData.currentSong.coverImagePath}`);
-
-    const baseData = this.formatBaseData(widgetData);
-    
-    switch (size) {
-      case WidgetSize.SMALL:
-        return this.adaptForSmallWidget(baseData, widgetData);
-      case WidgetSize.RECTANGLE:
-      case WidgetSize.MEDIUM:
-        return this.adaptForMediumWidget(baseData, widgetData);
-      case WidgetSize.SQUARE:
-        return this.adaptForSquareWidget(baseData, widgetData);
-      case WidgetSize.LARGE:
-        return this.adaptForLargeWidget(baseData, widgetData);
-      default:
-        hilog.warn(0x0000, TAG, `Unknown widget size: ${size}, using medium as default`);
-        return this.adaptForMediumWidget(baseData, widgetData);
-    }
-  }
-
-  /**
-   * 格式化基础数据
-   */
-  private formatBaseData(data: WidgetData): FormattedWidgetData {
-    hilog.info(0x0000, TAG, `Formatting base data: coverImagePath=${data.currentSong.coverImagePath}`);
-    
-    return {
-      // 播放状态
-      isPlaying: data.playState.isPlaying,
-      isPaused: data.playState.isPaused,
-      isLoading: data.playState.isLoading,
-      
-      // 歌曲信息
-      songTitle: this.truncateText(data.currentSong.title, 30),
-      songArtist: this.truncateText(data.currentSong.artist, 20),
-      songAlbum: this.truncateText(data.currentSong.album, 20),
-      coverImage: data.currentSong.coverImagePath || '',
-      
-      // 播放进度
-      currentTime: data.progress.currentTimeText,
-      totalTime: data.progress.totalTimeText,
-      progressPercentage: data.progress.percentage,
-      
-      // 控制按钮状态
-      hasNext: data.playlist.hasNext,
-      hasPrevious: data.playlist.hasPrevious,
-      
-      // 卡片配置
-      showProgress: data.config.showProgress,
-      showCover: data.config.showCover,
-      widgetSize: data.config.size as string,
-      
-      // 时间戳用于强制更新
-      timestamp: Date.now(),
-      
-      // 图片相关字段(初始为空,会在EntryFormAbility中设置)
-      imgName: undefined,
-      formImages: undefined,
-      isFavorite:false
-    };
-  }
-
-  /**
-   * 适配小尺寸卡片
-   */
-  private adaptForSmallWidget(baseData: FormattedWidgetData, widgetData: WidgetData): FormattedWidgetData {
-    return {
-      isPlaying: baseData.isPlaying,
-      isPaused: baseData.isPaused,
-      isLoading: baseData.isLoading,
-      songTitle: this.truncateText(widgetData.currentSong.title, 15),
-      songArtist: this.truncateText(widgetData.currentSong.artist, 12),
-      songAlbum: baseData.songAlbum,
-      coverImage: baseData.coverImage,
-      currentTime: baseData.currentTime,
-      totalTime: baseData.totalTime,
-      progressPercentage: baseData.progressPercentage,
-      hasNext: baseData.hasNext,
-      hasPrevious: baseData.hasPrevious,
-      showProgress: false,
-      showCover: false,
-      widgetSize: baseData.widgetSize,
-      timestamp: baseData.timestamp,
-      imgName: baseData.imgName,
-      formImages: baseData.formImages,
-      isFavorite:baseData.isFavorite
-    };
-  }
-
-  /**
-   * 适配中等尺寸卡片
-   */
-  private adaptForMediumWidget(baseData: FormattedWidgetData, widgetData: WidgetData): FormattedWidgetData {
-    hilog.info(0x0000, TAG, `Adapting for medium widget: coverImage=${baseData.coverImage}`);
-    
-    return {
-      isPlaying: baseData.isPlaying,
-      isPaused: baseData.isPaused,
-      isLoading: baseData.isLoading,
-      songTitle: this.truncateText(widgetData.currentSong.title, 25),
-      songArtist: this.truncateText(widgetData.currentSong.artist, 18),
-      songAlbum: baseData.songAlbum,
-      coverImage: widgetData.currentSong.coverImagePath || '', // 确保coverImage被正确传递
-      currentTime: baseData.currentTime,
-      totalTime: baseData.totalTime,
-      progressPercentage: baseData.progressPercentage,
-      hasNext: baseData.hasNext,
-      hasPrevious: baseData.hasPrevious,
-      showProgress: false,
-      showCover: true,
-      widgetSize: baseData.widgetSize,
-      timestamp: baseData.timestamp,
-      imgName: baseData.imgName,
-      formImages: baseData.formImages,
-      isFavorite:baseData.isFavorite
-    };
-  }
-
-  /**
-   * 适配方形尺寸卡片 (2x2)
-   */
-  private adaptForSquareWidget(baseData: FormattedWidgetData, widgetData: WidgetData): FormattedWidgetData {
-    hilog.info(0x0000, TAG, `Adapting for square widget: coverImage=${baseData.coverImage}`);
-    
-    return {
-      isPlaying: baseData.isPlaying,
-      isPaused: baseData.isPaused,
-      isLoading: baseData.isLoading,
-      songTitle: this.truncateText(widgetData.currentSong.title, 20),
-      songArtist: this.truncateText(widgetData.currentSong.artist, 15),
-      songAlbum: baseData.songAlbum,
-      coverImage: widgetData.currentSong.coverImagePath || '', // 确保coverImage被正确传递
-      currentTime: baseData.currentTime,
-      totalTime: baseData.totalTime,
-      progressPercentage: baseData.progressPercentage,
-      hasNext: baseData.hasNext,
-      hasPrevious: baseData.hasPrevious,
-      showProgress: false,
-      showCover: true,
-      widgetSize: baseData.widgetSize,
-      timestamp: baseData.timestamp,
-      imgName: baseData.imgName,
-      formImages: baseData.formImages,
-      isFavorite:baseData.isFavorite
-    };
-  }
-
-  /**
-   * 适配大尺寸卡片
-   */
-  private adaptForLargeWidget(baseData: FormattedWidgetData, widgetData: WidgetData): FormattedWidgetData {
-    return {
-      isPlaying: baseData.isPlaying,
-      isPaused: baseData.isPaused,
-      isLoading: baseData.isLoading,
-      songTitle: this.truncateText(widgetData.currentSong.title, 35),
-      songArtist: this.truncateText(widgetData.currentSong.artist, 25),
-      songAlbum: baseData.songAlbum,
-      coverImage: baseData.coverImage,
-      currentTime: baseData.currentTime,
-      totalTime: baseData.totalTime,
-      progressPercentage: baseData.progressPercentage,
-      hasNext: baseData.hasNext,
-      hasPrevious: baseData.hasPrevious,
-      showProgress: true,
-      showCover: true,
-      widgetSize: baseData.widgetSize,
-      timestamp: baseData.timestamp,
-      imgName: baseData.imgName,
-      formImages: baseData.formImages,
-      isFavorite:baseData.isFavorite
-    };
-  }
-
-  /**
-   * 截断文本
-   */
-  private truncateText(text: string, maxLength: number): string {
-    if (!text || text.length <= maxLength) {
-      return text || '';
-    }
-    return text.substring(0, maxLength - 1) + '…';
-  }
-
-  /**
-   * 获取卡片尺寸对应的页面路径
-   * @param size 卡片尺寸
-   * @returns 页面路径
-   */
-  public getWidgetPagePath(size: WidgetSize): string {
-    switch (size) {
-      case WidgetSize.SMALL:
-        return 'widget/pages/PlayerWidgetSmall';
-      case WidgetSize.RECTANGLE:
-        return 'widget/pages/PlayerWidgetRectangle';
-      case WidgetSize.MEDIUM:
-        return 'widget/pages/PlayerWidgetMedium';
-      case WidgetSize.SQUARE:
-        return 'widget/pages/PlayerWidgetSquare';
-      case WidgetSize.LARGE:
-        return 'widget/pages/PlayerWidgetLarge';
-      default:
-        hilog.warn(0x0000, TAG, `Unknown widget size: ${size}, using medium as default`);
-        return 'widget/pages/PlayerWidgetMedium';
-    }
-  }
-
-  /**
-   * 检查尺寸变化并返回是否需要重构UI
-   * @param oldSize 旧尺寸
-   * @param newSize 新尺寸
-   * @returns 是否需要重构UI
-   */
-  public shouldRebuildUI(oldSize: WidgetSize, newSize: WidgetSize): boolean {
-    const needsRebuild = oldSize !== newSize;
-    hilog.info(0x0000, TAG, `Size change from ${oldSize} to ${newSize}, needs rebuild: ${needsRebuild}`);
-    return needsRebuild;
-  }
-
-  /**
-   * 获取卡片尺寸的显示配置
-   * @param size 卡片尺寸
-   * @returns 显示配置
-   */
-  public getSizeDisplayConfig(size: WidgetSize): WidgetConfig {
-    const baseConfig: WidgetConfig = {
-      size: size,
-      theme: 'auto',
-      showProgress: true,
-      showCover: true
-    };
-
-    switch (size) {
-      case WidgetSize.SMALL:
-        return {
-          size: baseConfig.size,
-          theme: baseConfig.theme,
-          showProgress: false,
-          showCover: false
-        };
-      case WidgetSize.MEDIUM:
-        return {
-          size: baseConfig.size,
-          theme: baseConfig.theme,
-          showProgress: false,
-          showCover: true
-        };
-      case WidgetSize.SQUARE:
-        return {
-          size: baseConfig.size,
-          theme: baseConfig.theme,
-          showProgress: false,
-          showCover: true
-        };
-      case WidgetSize.LARGE:
-        return {
-          size: baseConfig.size,
-          theme: baseConfig.theme,
-          showProgress: true,
-          showCover: true
-        };
-      default:
-        return baseConfig;
-    }
-  }
-
-  /**
-   * 验证卡片尺寸是否有效
-   * @param size 卡片尺寸
-   * @returns 是否有效
-   */
-  public isValidSize(size: string): boolean {
-    return Object.values(WidgetSize).includes(size as WidgetSize);
-  }
-
-  /**
-   * 从字符串解析卡片尺寸
-   * @param sizeStr 尺寸字符串
-   * @returns 卡片尺寸枚举
-   */
-  public parseSizeFromString(sizeStr: string): WidgetSize {
-    if (this.isValidSize(sizeStr)) {
-      return sizeStr as WidgetSize;
-    }
-    
-    // 尝试从维度字符串解析 (如 "1*2", "2*4", "2*2")
-    switch (sizeStr) {
-      case '1*2':
-      case '1x2':
-        return WidgetSize.SMALL;
-      case '2*4':
-      case '2x4':
-        return WidgetSize.MEDIUM;
-      case '2*2':
-      case '2x2':
-        return WidgetSize.SQUARE;
-      case '4*3':
-      case '4x3':
-        return WidgetSize.LARGE;
-      default:
-        hilog.warn(0x0000, TAG, `Unknown size string: ${sizeStr}, using medium as default`);
-        return WidgetSize.MEDIUM;
-    }
-  }
-
-  /**
-   * 获取响应式布局参数
-   * @param size 卡片尺寸
-   * @returns 布局参数
-   */
-  public getResponsiveLayoutParams(size: WidgetSize): ResponsiveLayoutParams {
-    switch (size) {
-      case WidgetSize.SMALL:
-        const smallPadding: ContainerPadding = { left: 16, right: 16, top: 8, bottom: 8 };
-        const smallButtonSize: ButtonSize = { width: 32, height: 32 };
-        const smallPlayButtonSize: ButtonSize = { width: 36, height: 36 };
-        const smallFontSize: FontSizeConfig = { title: 14, artist: 12, time: 10 };
-        const smallSpacing: SpacingConfig = { horizontal: 8, vertical: 4 };
-        const smallShowElements: ShowElementsConfig = {
-          progress: false,
-          cover: false,
-          album: false,
-          time: false
-        };
-        return {
-          containerPadding: smallPadding,
-          buttonSize: smallButtonSize,
-          playButtonSize: smallPlayButtonSize,
-          fontSize: smallFontSize,
-          spacing: smallSpacing,
-          showElements: smallShowElements
-        };
-      case WidgetSize.MEDIUM:
-        const mediumPadding: ContainerPadding = { left: 16, right: 16, top: 16, bottom: 16 };
-        const mediumButtonSize: ButtonSize = { width: 36, height: 36 };
-        const mediumPlayButtonSize: ButtonSize = { width: 44, height: 44 };
-        const mediumFontSize: FontSizeConfig = { title: 16, artist: 12, time: 10 };
-        const mediumSpacing: SpacingConfig = { horizontal: 12, vertical: 8 };
-        const mediumShowElements: ShowElementsConfig = {
-          progress: true,
-          cover: false,
-          album: true,
-          time: true
-        };
-        return {
-          containerPadding: mediumPadding,
-          buttonSize: mediumButtonSize,
-          playButtonSize: mediumPlayButtonSize,
-          fontSize: mediumFontSize,
-          spacing: mediumSpacing,
-          showElements: mediumShowElements
-        };
-      case WidgetSize.SQUARE:
-        const squarePadding: ContainerPadding = { left: 16, right: 16, top: 16, bottom: 16 };
-        const squareButtonSize: ButtonSize = { width: 40, height: 40 };
-        const squarePlayButtonSize: ButtonSize = { width: 56, height: 56 };
-        const squareFontSize: FontSizeConfig = { title: 18, artist: 14, time: 12 };
-        const squareSpacing: SpacingConfig = { horizontal: 16, vertical: 12 };
-        const squareShowElements: ShowElementsConfig = {
-          progress: false,
-          cover: true,
-          album: false,
-          time: false
-        };
-        return {
-          containerPadding: squarePadding,
-          buttonSize: squareButtonSize,
-          playButtonSize: squarePlayButtonSize,
-          fontSize: squareFontSize,
-          spacing: squareSpacing,
-          showElements: squareShowElements
-        };
-      case WidgetSize.LARGE:
-        const largePadding: ContainerPadding = { left: 16, right: 16, top: 16, bottom: 16 };
-        const largeButtonSize: ButtonSize = { width: 40, height: 40 };
-        const largePlayButtonSize: ButtonSize = { width: 52, height: 52 };
-        const largeFontSize: FontSizeConfig = { title: 16, artist: 13, time: 11 };
-        const largeSpacing: SpacingConfig = { horizontal: 16, vertical: 16 };
-        const largeShowElements: ShowElementsConfig = {
-          progress: true,
-          cover: true,
-          album: true,
-          time: true
-        };
-        return {
-          containerPadding: largePadding,
-          buttonSize: largeButtonSize,
-          playButtonSize: largePlayButtonSize,
-          fontSize: largeFontSize,
-          spacing: largeSpacing,
-          showElements: largeShowElements
-        };
-      default:
-        return this.getResponsiveLayoutParams(WidgetSize.MEDIUM);
-    }
-  }
-}

+ 0 - 78
entry/src/main/ets/common/widget/GlobalWidgetManager.ets

@@ -1,78 +0,0 @@
-import { hilog } from '@kit.PerformanceAnalysisKit';
-import { WidgetSize } from './WidgetTypes';
-
-const TAG = 'Heanup GlobalWidgetManager';
-
-/**
- * 全局卡片管理器
- * 管理所有活跃的卡片实例,避免多个FormExtensionAbility实例之间的冲突
- */
-export class GlobalWidgetManager {
-  private static instance: GlobalWidgetManager | null = null;
-  private static activeWidgets: Map<string, WidgetSize> = new Map();
-
-  private constructor() {}
-
-  public static getInstance(): GlobalWidgetManager {
-    if (!GlobalWidgetManager.instance) {
-      GlobalWidgetManager.instance = new GlobalWidgetManager();
-    }
-    return GlobalWidgetManager.instance;
-  }
-
-  /**
-   * 注册卡片
-   */
-  public registerWidget(formId: string, size: WidgetSize): void {
-    GlobalWidgetManager.activeWidgets.set(formId, size);
-    hilog.info(0x0000, TAG, `Widget registered: ${formId}, size: ${size}, total: ${GlobalWidgetManager.activeWidgets.size}`);
-  }
-
-  /**
-   * 注销卡片
-   */
-  public unregisterWidget(formId: string): void {
-    const removed = GlobalWidgetManager.activeWidgets.delete(formId);
-    hilog.info(0x0000, TAG, `Widget unregistered: ${formId}, removed: ${removed}, total: ${GlobalWidgetManager.activeWidgets.size}`);
-  }
-
-  /**
-   * 获取所有活跃卡片
-   */
-  public getActiveWidgets(): Map<string, WidgetSize> {
-    return new Map(GlobalWidgetManager.activeWidgets);
-  }
-
-  /**
-   * 获取活跃卡片数量
-   */
-  public getActiveWidgetCount(): number {
-    return GlobalWidgetManager.activeWidgets.size;
-  }
-
-  /**
-   * 检查卡片是否存在
-   */
-  public hasWidget(formId: string): boolean {
-    return GlobalWidgetManager.activeWidgets.has(formId);
-  }
-
-  /**
-   * 获取卡片尺寸
-   */
-  public getWidgetSize(formId: string): WidgetSize | undefined {
-    return GlobalWidgetManager.activeWidgets.get(formId);
-  }
-
-  /**
-   * 更新卡片尺寸
-   */
-  public updateWidgetSize(formId: string, size: WidgetSize): void {
-    if (GlobalWidgetManager.activeWidgets.has(formId)) {
-      GlobalWidgetManager.activeWidgets.set(formId, size);
-      hilog.info(0x0000, TAG, `Widget size updated: ${formId}, new size: ${size}`);
-    } else {
-      hilog.warn(0x0000, TAG, `Cannot update size for non-existent widget: ${formId}`);
-    }
-  }
-}

+ 0 - 156
entry/src/main/ets/common/widget/GlobalWidgetService.ets

@@ -1,156 +0,0 @@
-import { hilog } from '@kit.PerformanceAnalysisKit';
-import { PlaylistState, PlayProgress, PlayState, SongInfo, WidgetConfig, WidgetData } from './WidgetTypes';
-import { AvSessionWidgetListener } from './AvSessionWidgetListener';
-import commonEventManager from '@ohos.commonEventManager';
-import {
-  PLAYER_STATE_CHANGED_EVENT,
-  PLAYER_SONG_CHANGED_EVENT,
-  PLAYER_PROGRESS_CHANGED_EVENT
-} from './WidgetEventConstants';
-
-const TAG = 'GlobalWidgetService';
-
-/**
- * 全局卡片服务
- * 用于主应用直接更新卡片数据,绕过跨进程通信限制
- */
-interface GeneratedObjectLiteralInterface_1 {
-  playState: PlayState;
-  currentSong: SongInfo;
-  progress: PlayProgress;
-  playlist: PlaylistState;
-  config: WidgetConfig;
-  timestamp: number;
-  source: string;
-}
-
-export class GlobalWidgetService {
-  private static instance: GlobalWidgetService | null = null;
-  private avSessionListener: AvSessionWidgetListener;
-
-  private constructor() {
-    this.avSessionListener = AvSessionWidgetListener.getInstance();
-  }
-
-  public static getInstance(): GlobalWidgetService {
-    if (!GlobalWidgetService.instance) {
-      GlobalWidgetService.instance = new GlobalWidgetService();
-    }
-    return GlobalWidgetService.instance;
-  }
-
-  /**
-   * 更新卡片数据(主应用调用)
-   */
-  public updateWidgetData(data: WidgetData): void {
-    try {
-      // 在全局服务层面也进行按钮状态验证和修复
-      const correctedData = this.validateAndFixButtonStates(data);
-      
-      // 同步更新主进程的AvSession监听器数据(用于主应用内的逻辑)
-      this.avSessionListener.updateWidgetData(correctedData);
-      
-      // 通过 CommonEvent 发送数据到 Form 进程
-      this.broadcastToFormProcess(correctedData);
-      
-      hilog.info(0x0000, TAG, `Widget data updated globally: isPlaying=${correctedData.playState.isPlaying}, title=${correctedData.currentSong.title}, hasNext=${correctedData.playlist.hasNext}, hasPrevious=${correctedData.playlist.hasPrevious}, currentIndex=${correctedData.playlist.currentIndex}, totalCount=${correctedData.playlist.totalCount}`);
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to update widget data globally: ${error}`);
-    }
-  }
-
-  /**
-   * 通过 CommonEvent 广播数据到 Form 进程
-   */
-  private async broadcastToFormProcess(data: WidgetData): Promise<void> {
-    try {
-      hilog.info(0x0000, TAG, `🚀 Starting broadcast to form process for: ${data.currentSong.title}`);
-      
-      // 构造广播数据
-      const broadcastData: GeneratedObjectLiteralInterface_1 = {
-        playState: data.playState,
-        currentSong: data.currentSong,
-        progress: data.progress,
-        playlist: data.playlist,
-        config: data.config,
-        timestamp: Date.now(),
-        source: 'main_app_global_service'
-      };
-
-      const publishInfo: commonEventManager.CommonEventPublishData = {
-        data: JSON.stringify(broadcastData)
-      };
-
-      hilog.info(0x0000, TAG, `🚀 Publishing CommonEvent: ${PLAYER_STATE_CHANGED_EVENT}, data size: ${publishInfo.data?.length || 0} characters`);
-      
-      // 发送状态变化事件到 Form 进程
-      await commonEventManager.publish(PLAYER_STATE_CHANGED_EVENT, publishInfo, (err) => {
-        if (err) {
-          hilog.error(0x0000, TAG, `❌ Failed to broadcast to form process: ${JSON.stringify(err)}`);
-        } else {
-          hilog.info(0x0000, TAG, `✅ Successfully broadcasted widget data to form process: ${data.currentSong.title}`);
-        }
-      });
-    } catch (error) {
-      hilog.error(0x0000, TAG, `❌ Error broadcasting to form process: ${error}`);
-    }
-  }
-
-  /**
-   * 验证和修复按钮状态
-   */
-  private validateAndFixButtonStates(data: WidgetData): WidgetData {
-    hilog.info(0x0000, TAG, `Validating button states: original hasNext=${data.playlist.hasNext}, hasPrevious=${data.playlist.hasPrevious}, currentIndex=${data.playlist.currentIndex}, totalCount=${data.playlist.totalCount}`);
-    
-    // 创建新的 WidgetData 对象
-    const correctedData: WidgetData = {
-      playState: {
-        isPlaying: data.playState.isPlaying,
-        isPaused: data.playState.isPaused,
-        isLoading: data.playState.isLoading
-      },
-      currentSong: {
-        id: data.currentSong.id,
-        title: data.currentSong.title,
-        artist: data.currentSong.artist,
-        album: data.currentSong.album,
-        coverImagePath: data.currentSong.coverImagePath,
-        duration: data.currentSong.duration
-      },
-      progress: {
-        currentPosition: data.progress.currentPosition,
-        duration: data.progress.duration,
-        percentage: data.progress.percentage,
-        currentTimeText: data.progress.currentTimeText,
-        totalTimeText: data.progress.totalTimeText
-      },
-      playlist: {
-        hasNext: data.playlist.hasNext,
-        hasPrevious: data.playlist.hasPrevious,
-        currentIndex: data.playlist.currentIndex,
-        totalCount: data.playlist.totalCount
-      },
-      config: {
-        size: data.config.size,
-        theme: data.config.theme,
-        showProgress: data.config.showProgress,
-        showCover: data.config.showCover
-      }
-    };
-    
-    // 注意:这里不再简单地基于索引修复按钮状态
-    // 因为按钮状态应该由 UnifiedPlayerService 中的播放模式逻辑正确计算
-    // 在随机播放模式下,按钮状态取决于播放历史记录,而不是简单的索引位置
-    if (data.playlist.totalCount > 1) {
-      // 保持从 UnifiedPlayerService 传来的状态,这些状态已经考虑了播放模式
-      hilog.info(0x0000, TAG, `Keeping original button states from UnifiedPlayerService: hasNext=${data.playlist.hasNext}, hasPrevious=${data.playlist.hasPrevious}`);
-    } else {
-      // 单首歌或无歌曲时,禁用所有按钮
-      correctedData.playlist.hasNext = false;
-      correctedData.playlist.hasPrevious = false;
-      hilog.info(0x0000, TAG, `Single song or empty playlist, disabled all navigation buttons`);
-    }
-    
-    return correctedData;
-  }
-}

+ 0 - 482
entry/src/main/ets/common/widget/PlayerControlService.ets

@@ -1,482 +0,0 @@
-import commonEventManager from '@ohos.commonEventManager';
-import Want from '@ohos.app.ability.Want';
-import common from '@ohos.app.ability.common';
-import { hilog } from '@kit.PerformanceAnalysisKit';
-import { WidgetData, WidgetCommand, EventData, RequestData, WidgetControlParams } from './WidgetTypes';
-import { WidgetTypeHelpers } from './WidgetTypeHelpers';
-import { 
-  WIDGET_CONTROL_EVENT,
-  WIDGET_REQUEST_STATE_EVENT,
-  PLAYER_STATE_CHANGED_EVENT,
-  PLAYER_SONG_CHANGED_EVENT,
-  PLAYER_PROGRESS_CHANGED_EVENT,
-  APP_BUNDLE_NAME,
-  APP_ABILITY_NAME
-} from './WidgetEventConstants';
-import { AvSessionWidgetListener } from './AvSessionWidgetListener';
-
-const TAG = 'Heanup PlayerControlService';
-
-/**
- * 启动参数接口
- */
-interface LaunchParameters {
-  page: string;
-  source: string;
-  timestamp: string;
-}
-
-
-
-/**
- * 播放器控制服务
- * 负责与主应用的播放器进行通信和状态同步
- */
-export class PlayerControlService {
-  private stateListeners: Array<(data: WidgetData) => void> = [];
-  private isListenerRegistered: boolean = false;
-  private avSessionListener: AvSessionWidgetListener;
-
-  constructor() {
-    this.avSessionListener = AvSessionWidgetListener.getInstance();
-    this.initializeEventListener();
-    this.initializeAvSessionListener();
-  }
-
-  /**
-   * 初始化事件监听器
-   */
-  private async initializeEventListener(): Promise<void> {
-    if (this.isListenerRegistered) {
-      hilog.info(0x0000, TAG, 'Event listener already registered');
-      return;
-    }
-
-    try {
-      // 监听播放状态变化事件
-      const subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
-        events: [
-          PLAYER_STATE_CHANGED_EVENT,
-          PLAYER_SONG_CHANGED_EVENT,
-          PLAYER_PROGRESS_CHANGED_EVENT
-        ]
-      };
-
-      hilog.info(0x0000, TAG, `Subscribing to events: ${subscribeInfo.events.join(', ')}`);
-
-      const subscriber = await commonEventManager.createSubscriber(subscribeInfo);
-      
-      await commonEventManager.subscribe(subscriber, (err, data: commonEventManager.CommonEventData) => {
-        if (!err) {
-          hilog.info(0x0000, TAG, `📡 CommonEvent received in Form process: ${data.event}`);
-          hilog.info(0x0000, TAG, `📡 Event data length: ${data.data?.length || 0} characters`);
-          this.handlePlayerStateChange(data);
-        } else {
-          hilog.error(0x0000, TAG, `❌ CommonEvent error: ${JSON.stringify(err)}`);
-        }
-      });
-
-      this.isListenerRegistered = true;
-      hilog.info(0x0000, TAG, 'Event listener initialized successfully');
-      
-      // 立即请求当前状态,确保新进程能获取到最新数据
-      setTimeout(() => {
-        this.requestCurrentState();
-      }, 1000);
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to initialize event listener: ${error}`);
-    }
-  }
-
-  /**
-   * 请求当前播放状态
-   */
-  private async requestCurrentState(): Promise<void> {
-    try {
-      const requestData: RequestData = { 
-        timestamp: Date.now(),
-        source: 'widget_form_process_recovery'
-      };
-      const requestInfo: commonEventManager.CommonEventPublishData = {
-        data: JSON.stringify(requestData)
-      };
-      await commonEventManager.publish(WIDGET_REQUEST_STATE_EVENT, requestInfo, (err) => {
-        if (err) {
-          hilog.error(0x0000, TAG, `Failed to request current state: ${err}`);
-        } else {
-          hilog.info(0x0000, TAG, 'Current state requested from main app for recovery');
-        }
-      });
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to request current state: ${error}`);
-    }
-  }
-
-  /**
-   * 强制重新连接和同步状态
-   */
-  async forceReconnect(): Promise<void> {
-    try {
-      hilog.info(0x0000, TAG, 'Force reconnecting to main app...');
-      
-      // 重新请求当前状态
-      await this.requestCurrentState();
-      
-      // 等待一段时间后再次请求,确保能收到响应
-      setTimeout(async () => {
-        await this.requestCurrentState();
-      }, 2000);
-      
-      hilog.info(0x0000, TAG, 'Force reconnect completed');
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Force reconnect failed: ${error}`);
-    }
-  }
-
-  /**
-   * 发送控制命令到主应用
-   */
-  async sendControlCommand(command: WidgetCommand, params?: WidgetControlParams): Promise<boolean> {
-    try {
-      const defaultParams: WidgetControlParams = {};
-      const eventData: EventData = {
-        command: command,
-        params: params || defaultParams,
-        timestamp: Date.now(),
-        source: 'widget'
-      };
-
-      // 发送CommonEvent到主应用
-      const publishInfo: commonEventManager.CommonEventPublishData = {
-        data: JSON.stringify(eventData)
-      };
-      await commonEventManager.publish(WIDGET_CONTROL_EVENT, publishInfo, (err) => {
-        if (err) {
-          hilog.error(0x0000, TAG, `Failed to publish event: ${err}`);
-        }
-      });
-
-      hilog.info(0x0000, TAG, `Control command sent: ${command}`);
-      return true;
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to send control command: ${error}`);
-      return false;
-    }
-  }
-
-  /**
-   * 获取当前播放状态
-   */
-  async getCurrentPlayState(): Promise<WidgetData> {
-    try {
-      // 优先从AvSession获取当前状态
-      const avSessionData = this.avSessionListener.getCurrentWidgetData();
-      
-      // 同时请求CommonEvent状态作为备用
-      const requestData: RequestData = {
-        timestamp: Date.now(),
-        source: 'widget_form_process'
-      };
-      const requestInfo: commonEventManager.CommonEventPublishData = {
-        data: JSON.stringify(requestData)
-      };
-       commonEventManager.publish(WIDGET_REQUEST_STATE_EVENT, requestInfo, (err) => {
-        if (err) {
-          hilog.error(0x0000, TAG, `Failed to publish request state event: ${err}`);
-        }
-      });
-
-      return avSessionData;
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to get current play state: ${error}`);
-      return this.getDefaultWidgetData();
-    }
-  }
-
-  /**
-   * 初始化AvSession监听器
-   */
-  private initializeAvSessionListener(): void {
-    try {
-      // 注册AvSession状态监听器,这个监听器主要用于EntryFormAbility的全局监听
-      // 不要在这里注册,让EntryFormAbility直接注册到AvSessionWidgetListener
-      hilog.info(0x0000, TAG, 'AvSession listener initialized successfully (no direct registration needed)');
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to initialize AvSession listener: ${error}`);
-    }
-  }
-
-  /**
-   * 注册状态变化监听器
-   */
-  registerStateListener(callback: (data: WidgetData) => void): void {
-    // 检查是否已经注册过相同的监听器,避免重复注册
-    if (this.stateListeners.indexOf(callback) === -1) {
-      this.stateListeners.push(callback);
-      hilog.info(0x0000, TAG, `State listener registered, total listeners: ${this.stateListeners.length}`);
-    } else {
-      hilog.warn(0x0000, TAG, 'State listener already registered, skipping');
-      return;
-    }
-    
-    // 延迟获取当前状态,给主应用时间来广播真实状态
-    setTimeout(() => {
-      try {
-        const currentData = this.avSessionListener.getCurrentWidgetData();
-        hilog.info(0x0000, TAG, `Sending current data to listener: hasNext=${currentData.playlist.hasNext}, hasPrevious=${currentData.playlist.hasPrevious}`);
-        callback(currentData);
-      } catch (error) {
-        hilog.error(0x0000, TAG, `Error getting current AvSession data: ${error}`);
-      }
-    }, 1500); // 延迟1.5秒,确保主应用已经广播了状态
-  }
-
-  /**
-   * 启动主应用
-   */
-  async launchMainApp(page?: string, params?: Record<string, Object>): Promise<boolean> {
-    try {
-      interface LaunchParameters {
-        page: string;
-        source: string;
-        timestamp: string;
-      }
-      
-      const baseParams: LaunchParameters = {
-        page: page || 'main',
-        source: 'widget', // 标识来源是卡片
-        timestamp: Date.now().toString()
-      };
-
-      // 创建Want对象
-      const want: Want = {
-        bundleName: APP_BUNDLE_NAME,
-        abilityName: APP_ABILITY_NAME,
-        parameters: {
-          page: baseParams.page,
-          source: baseParams.source,
-          timestamp: baseParams.timestamp
-        }
-      };
-
-      // 添加额外参数
-      if (params && want.parameters) {
-        const paramKeys = Object.keys(params);
-        for (let i = 0; i < paramKeys.length; i++) {
-          const key = paramKeys[i];
-          want.parameters[key] = params[key];
-        }
-      }
-
-      const context = getContext() as common.UIAbilityContext;
-      await context.startAbility(want);
-      
-      hilog.info(0x0000, TAG, `Main app launched with page: ${page}, params: ${JSON.stringify(params)}`);
-      return true;
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to launch main app: ${error}`);
-      
-      // 如果启动失败,尝试启动到默认页面
-      try {
-        const fallbackWant: Want = {
-          bundleName: APP_BUNDLE_NAME,
-          abilityName: APP_ABILITY_NAME
-        };
-        
-        const context = getContext() as common.UIAbilityContext;
-        await context.startAbility(fallbackWant);
-        
-        hilog.info(0x0000, TAG, 'Main app launched with fallback method');
-        return true;
-      } catch (fallbackError) {
-        hilog.error(0x0000, TAG, `Fallback launch also failed: ${fallbackError}`);
-        return false;
-      }
-    }
-  }
-
-  /**
-   * 处理播放器状态变化
-   */
-  private handlePlayerStateChange(eventData: commonEventManager.CommonEventData): void {
-    try {
-      hilog.info(0x0000, TAG, `📨 Form process handling CommonEvent: ${eventData.event}`);
-      hilog.info(0x0000, TAG, `📨 Event data: ${eventData.data?.substring(0, 200)}...`);
-      
-      const data = JSON.parse(eventData.data || '{}') as Object;
-      let widgetData: WidgetData;
-
-      if (eventData.event === PLAYER_PROGRESS_CHANGED_EVENT) {
-        // 处理进度更新事件
-        widgetData = this.updateProgressData(data);
-      } else {
-        // 处理完整状态更新事件
-        widgetData = this.convertToWidgetData(data);
-      }
-      
-      hilog.info(0x0000, TAG, `📨 Form process converted data: isPlaying=${widgetData.playState.isPlaying}, title=${widgetData.currentSong.title}`);
-      
-      // 只更新AvSession监听器的数据,避免重复通知
-      // AvSession监听器会自动通知所有注册的监听器
-      this.avSessionListener.updateWidgetData(widgetData);
-      
-      hilog.info(0x0000, TAG, `📨 Form process: ${eventData.event} handled, data updated in AvSession`);
-    } catch (error) {
-      hilog.error(0x0000, TAG, `❌ Form process failed to handle player state change: ${error}`);
-    }
-  }
-
-  /**
-   * 更新进度数据
-   */
-  private updateProgressData(progressData: Object): WidgetData {
-    try {
-      const data: Record<string, Object> = progressData as Record<string, Object>;
-      // 获取当前缓存的数据,而不是默认数据
-      const currentData = this.avSessionListener.getCurrentWidgetData();
-      
-      // 只更新进度相关数据,保持其他状态不变
-      currentData.progress = {
-        currentPosition: (data['currentPosition'] as number) || 0,
-        duration: (data['duration'] as number) || 0,
-        percentage: (data['percentage'] as number) || 0,
-        currentTimeText: (data['currentTimeText'] as string) || '00:00',
-        totalTimeText: (data['totalTimeText'] as string) || '00:00'
-      };
-      
-      // 更新缓存
-      this.avSessionListener.updateWidgetData(currentData);
-      
-      hilog.info(0x0000, TAG, `Progress updated: ${currentData.progress.percentage.toFixed(1)}%, ${currentData.progress.currentTimeText}/${currentData.progress.totalTimeText}`);
-      
-      return currentData;
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to update progress data: ${error}`);
-      return this.getDefaultWidgetData();
-    }
-  }
-
-  /**
-   * 转换播放器数据为卡片数据格式
-   */
-  private convertToWidgetData(playerData: Object): WidgetData {
-    try {
-      const data: Record<string, Object> = playerData as Record<string, Object>;
-      
-      // 正确解析PlayerStateBroadcastData结构
-      const playState = (data['playState'] as Record<string, Object>) || {};
-      const currentSong = (data['currentSong'] as Record<string, Object>) || {};
-      const progress = (data['progress'] as Record<string, Object>) || {};
-      const playlist = (data['playlist'] as Record<string, Object>) || {};
-      
-      // 检查是否接收到不完整的数据
-      const isPlaylistDataIncomplete = playlist['hasNext'] === undefined || 
-                                     playlist['hasPrevious'] === undefined || 
-                                     playlist['currentIndex'] === undefined || 
-                                     playlist['totalCount'] === undefined;
-      
-      if (isPlaylistDataIncomplete) {
-        hilog.warn(0x0000, TAG, `Received incomplete playlist data, using cached data`);
-        // 如果接收到不完整的数据,返回当前缓存的数据
-        const cachedData = this.avSessionListener.getCurrentWidgetData();
-        
-        // 只更新非playlist的数据,保持playlist数据不变
-        const updatedData: WidgetData = {
-          playState: {
-            isPlaying: (playState['isPlaying'] as boolean) !== undefined ? (playState['isPlaying'] as boolean) : cachedData.playState.isPlaying,
-            isPaused: (playState['isPaused'] as boolean) !== undefined ? (playState['isPaused'] as boolean) : cachedData.playState.isPaused,
-            isLoading: (playState['isLoading'] as boolean) !== undefined ? (playState['isLoading'] as boolean) : cachedData.playState.isLoading
-          },
-          currentSong: {
-            id: (currentSong['id'] as string) || cachedData.currentSong.id,
-            title: (currentSong['title'] as string) || cachedData.currentSong.title,
-            artist: (currentSong['artist'] as string) || cachedData.currentSong.artist,
-            album: (currentSong['album'] as string) || cachedData.currentSong.album,
-            coverImagePath: (currentSong['coverImagePath'] as string) || cachedData.currentSong.coverImagePath,
-            duration: (currentSong['duration'] as number) || cachedData.currentSong.duration
-          },
-          progress: {
-            currentPosition: (progress['currentPosition'] as number) !== undefined ? (progress['currentPosition'] as number) : cachedData.progress.currentPosition,
-            duration: (progress['duration'] as number) !== undefined ? (progress['duration'] as number) : cachedData.progress.duration,
-            percentage: (progress['percentage'] as number) !== undefined ? (progress['percentage'] as number) : cachedData.progress.percentage,
-            currentTimeText: (progress['currentTimeText'] as string) || cachedData.progress.currentTimeText,
-            totalTimeText: (progress['totalTimeText'] as string) || cachedData.progress.totalTimeText
-          },
-          playlist: cachedData.playlist, // 保持缓存的playlist数据
-          config: cachedData.config
-        };
-        
-        hilog.info(0x0000, TAG, `Using cached playlist data: hasNext=${updatedData.playlist.hasNext}, hasPrevious=${updatedData.playlist.hasPrevious}, currentIndex=${updatedData.playlist.currentIndex}, totalCount=${updatedData.playlist.totalCount}`);
-        return updatedData;
-      }
-      
-      const widgetData: WidgetData = {
-        playState: {
-          isPlaying: (playState['isPlaying'] as boolean) || false,
-          isPaused: (playState['isPaused'] as boolean) || true,
-          isLoading: (playState['isLoading'] as boolean) || false
-        },
-        currentSong: {
-          id: (currentSong['id'] as string) || '',
-          title: (currentSong['title'] as string) || '暂无播放',
-          artist: (currentSong['artist'] as string) || '未知艺术家',
-          album: (currentSong['album'] as string) || '未知专辑',
-          coverImagePath: (currentSong['coverImagePath'] as string) || '',
-          duration: (currentSong['duration'] as number) || 0
-        },
-        progress: {
-          currentPosition: (progress['currentPosition'] as number) || 0,
-          duration: (progress['duration'] as number) || 0,
-          percentage: (progress['percentage'] as number) || 0,
-          currentTimeText: (progress['currentTimeText'] as string) || '00:00',
-          totalTimeText: (progress['totalTimeText'] as string) || '00:00'
-        },
-        playlist: {
-          hasNext: (playlist['hasNext'] as boolean) !== undefined ? (playlist['hasNext'] as boolean) : false,
-          hasPrevious: (playlist['hasPrevious'] as boolean) !== undefined ? (playlist['hasPrevious'] as boolean) : false,
-          currentIndex: (playlist['currentIndex'] as number) !== undefined ? (playlist['currentIndex'] as number) : 0,
-          totalCount: (playlist['totalCount'] as number) !== undefined ? (playlist['totalCount'] as number) : 0
-        },
-        config: {
-          size: 'medium',
-          theme: 'auto',
-          showProgress: true,
-          showCover: true
-        }
-      };
-      
-      // 添加详细的按钮状态调试日志
-      hilog.info(0x0000, TAG, `Raw playlist data: hasNext=${playlist['hasNext']}, hasPrevious=${playlist['hasPrevious']}, currentIndex=${playlist['currentIndex']}, totalCount=${playlist['totalCount']}`);
-      hilog.info(0x0000, TAG, `Converted widget data: isPlaying=${widgetData.playState.isPlaying}, hasNext=${widgetData.playlist.hasNext}, hasPrevious=${widgetData.playlist.hasPrevious}, currentIndex=${widgetData.playlist.currentIndex}, totalCount=${widgetData.playlist.totalCount}, title=${widgetData.currentSong.title}`);
-      
-      return widgetData;
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to convert player data: ${error}`);
-      return this.getDefaultWidgetData();
-    }
-  }
-
-  /**
-   * 获取默认卡片数据
-   */
-  private getDefaultWidgetData(): WidgetData {
-    return WidgetTypeHelpers.createDefaultWidgetData();
-  }
-
-  /**
-   * 计算播放进度百分比
-   */
-  private calculatePercentage(current: number, total: number): number {
-    if (total <= 0) return 0;
-    return Math.min(100, Math.max(0, (current / total) * 100));
-  }
-
-  /**
-   * 格式化时间显示
-   */
-  private formatTime(seconds: number): string {
-    const mins = Math.floor(seconds / 60);
-    const secs = Math.floor(seconds % 60);
-    return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
-  }
-}

+ 0 - 516
entry/src/main/ets/common/widget/WidgetDataManager.ets

@@ -1,516 +0,0 @@
-import formProvider from '@ohos.app.form.formProvider';
-import formBindingData from '@ohos.app.form.formBindingData';
-import preferences from '@ohos.data.preferences';
-import { hilog } from '@kit.PerformanceAnalysisKit';
-import { WidgetData, WidgetSize, WidgetTheme, FormattedWidgetData, PreferencesData, CacheStats } from './WidgetTypes';
-
-const TAG = 'WidgetDataManager';
-const WIDGET_PREFERENCES_NAME = 'widget_data_prefs';
-const CACHE_EXPIRY_TIME = 30 * 1000; // 30秒缓存过期时间
-
-/**
- * 缓存项接口
- */
-interface CacheItem {
-  data: WidgetData;
-  timestamp: number;
-  expiry: number;
-}
-
-/**
- * 卡片数据管理器
- * 负责卡片数据的持久化存储、缓存和更新
- */
-export class WidgetDataManager {
-  private preferencesStore: preferences.Preferences | null = null;
-  private dataCache: Map<string, CacheItem> = new Map();
-  private lastUpdateTime: number = 0;
-  private context: object | null = null;
-
-  constructor(context?: object) {
-    this.context = context || null;
-    this.initPreferences();
-    this.startCacheCleanup();
-  }
-
-  /**
-   * 初始化数据存储
-   */
-  private async initPreferences(): Promise<void> {
-    try {
-      if (this.context) {
-        const store = await preferences.getPreferences(this.context as Context, WIDGET_PREFERENCES_NAME);
-        this.preferencesStore = store;
-        hilog.info(0x0000, TAG, 'Preferences initialized successfully with context');
-      } else {
-        hilog.warn(0x0000, TAG, 'No context provided, preferences initialization skipped');
-      }
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to initialize preferences: ${error}`);
-    }
-  }
-
-  /**
-   * 获取初始卡片数据
-   */
-  getInitialWidgetData(): WidgetData {
-    const initialData: WidgetData = {
-      playState: {
-        isPlaying: false,
-        isPaused: true,
-        isLoading: false
-      },
-      currentSong: {
-        id: '',
-        title: '暂无播放',
-        artist: '未知艺术家',
-        album: '未知专辑',
-        coverImagePath: '',
-        duration: 0
-      },
-      progress: {
-        currentPosition: 0,
-        duration: 0,
-        percentage: 0,
-        currentTimeText: '00:00',
-        totalTimeText: '00:00'
-      },
-      playlist: {
-        hasNext: false,
-        hasPrevious: false,
-        currentIndex: 0,
-        totalCount: 0
-      },
-      config: {
-        size: WidgetSize.MEDIUM,
-        theme: WidgetTheme.AUTO,
-        showProgress: true,
-        showCover: true
-      }
-    };
-    return initialData;
-  }
-
-  /**
-   * 保存卡片数据
-   */
-  async saveWidgetData(formId: string, data: WidgetData | FormattedWidgetData): Promise<void> {
-    try {
-      if (!this.preferencesStore) {
-        await this.initPreferences();
-      }
-      
-      const dataKey = `widget_${formId}`;
-      await this.preferencesStore?.put(dataKey, JSON.stringify(data));
-      await this.preferencesStore?.flush();
-      
-      hilog.info(0x0000, TAG, `Widget data saved for form: ${formId}`);
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to save widget data: ${error}`);
-    }
-  }
-
-  /**
-   * 获取卡片数据
-   */
-  async getWidgetData(formId: string): Promise<WidgetData> {
-    try {
-      if (!this.preferencesStore) {
-        await this.initPreferences();
-      }
-      
-      const dataKey = `widget_${formId}`;
-      const dataStr = await this.preferencesStore?.get(dataKey, '') as string;
-      
-      if (dataStr) {
-        return JSON.parse(dataStr) as WidgetData;
-      } else {
-        return this.getInitialWidgetData() as WidgetData;
-      }
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to get widget data: ${error}`);
-      return this.getInitialWidgetData() as WidgetData;
-    }
-  }
-
-  /**
-   * 更新卡片显示
-   */
-  async updateWidget(formId: string, data: WidgetData | FormattedWidgetData): Promise<void> {
-    try {
-      hilog.info(0x0000, TAG, `Updating widget ${formId} with data type check`);
-      
-      let formattedData: FormattedWidgetData;
-      
-      // 检查数据类型,如果已经是格式化数据则直接使用
-      if (this.isFormattedWidgetData(data)) {
-        hilog.info(0x0000, TAG, `Data is already formatted for widget ${formId}`);
-        formattedData = data as FormattedWidgetData;
-        
-        // 如果是格式化数据,需要转换回WidgetData进行存储
-        const widgetData = this.convertToWidgetData(formattedData);
-        await this.saveWidgetData(formId, widgetData);
-      } else {
-        hilog.info(0x0000, TAG, `Formatting raw data for widget ${formId}`);
-        // 保存原始数据到本地存储
-        await this.saveWidgetData(formId, data as WidgetData);
-        
-        // 格式化数据用于卡片显示
-        formattedData = this.formatDataForWidget(data as WidgetData);
-      }
-      
-      hilog.info(0x0000, TAG, `Final formatted data for ${formId}: isPlaying=${formattedData.isPlaying}, hasNext=${formattedData.hasNext}, hasPrevious=${formattedData.hasPrevious}, title=${formattedData.songTitle}, coverImage=${formattedData.coverImage ? 'present' : 'empty'}, showCover=${formattedData.showCover}`);
-      
-      // 创建卡片绑定数据
-      const formData = formBindingData.createFormBindingData(formattedData);
-      
-      // 更新卡片
-      await formProvider.updateForm(formId, formData);
-      
-      hilog.info(0x0000, TAG, `Widget updated successfully: ${formId}`);
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to update widget: ${error}`);
-    }
-  }
-
-  /**
-   * 批量更新所有卡片
-   */
-  async updateAllWidgets(data?: WidgetData): Promise<void> {
-    try {
-      if (!this.preferencesStore) {
-        await this.initPreferences();
-      }
-      
-      // 获取所有卡片ID
-      const allKeys = await this.preferencesStore?.getAll();
-      const emptyPrefs: PreferencesData = {};
-      const widgetKeys = Object.keys(allKeys || emptyPrefs).filter(key => key.startsWith('widget_'));
-      
-      for (const key of widgetKeys) {
-        const formId: string = key.replace('widget_', '');
-        const widgetData: WidgetData = data || await this.getWidgetData(formId);
-        await this.updateWidget(formId, widgetData);
-      }
-      
-      hilog.info(0x0000, TAG, `Updated ${widgetKeys.length} widgets`);
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to update all widgets: ${error}`);
-    }
-  }
-
-  /**
-   * 删除卡片数据
-   */
-  async removeWidgetData(formId: string): Promise<void> {
-    try {
-      if (!this.preferencesStore) {
-        await this.initPreferences();
-      }
-      
-      const dataKey = `widget_${formId}`;
-      await this.preferencesStore?.delete(dataKey);
-      await this.preferencesStore?.flush();
-      
-      hilog.info(0x0000, TAG, `Widget data removed for form: ${formId}`);
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to remove widget data: ${error}`);
-    }
-  }
-
-  /**
-   * 格式化数据用于卡片显示
-   */
-  public formatDataForWidget(data: WidgetData): FormattedWidgetData {
-    hilog.info(0x0000, TAG, `Formatting data for widget: hasNext=${data.playlist.hasNext}, hasPrevious=${data.playlist.hasPrevious}, currentIndex=${data.playlist.currentIndex}, totalCount=${data.playlist.totalCount}`);
-    
-    // 修复按钮状态:基于当前索引和总数重新计算正确的按钮状态
-    let hasNext = data.playlist.hasNext;
-    let hasPrevious = data.playlist.hasPrevious;
-    
-    hilog.info(0x0000, TAG, `Original button states: hasNext=${hasNext}, hasPrevious=${hasPrevious}, currentIndex=${data.playlist.currentIndex}, totalCount=${data.playlist.totalCount}`);
-    
-    // 如果有播放列表,重新计算按钮状态
-    if (data.playlist.totalCount > 1) {
-      const correctHasNext = data.playlist.currentIndex < data.playlist.totalCount - 1;
-      const correctHasPrevious = data.playlist.currentIndex > 0;
-      
-      // 如果计算出的状态与当前状态不一致,进行修复
-      if (hasNext !== correctHasNext || hasPrevious !== correctHasPrevious) {
-        hasNext = correctHasNext;
-        hasPrevious = correctHasPrevious;
-        hilog.info(0x0000, TAG, `Fixed button states: hasNext=${hasNext}, hasPrevious=${hasPrevious}, currentIndex=${data.playlist.currentIndex}, totalCount=${data.playlist.totalCount}`);
-      } else {
-        hilog.info(0x0000, TAG, `Button states are correct: hasNext=${hasNext}, hasPrevious=${hasPrevious}`);
-      }
-    } else if (data.playlist.totalCount <= 1) {
-      // 如果只有一首歌或没有歌,按钮都应该禁用
-      hasNext = false;
-      hasPrevious = false;
-      hilog.info(0x0000, TAG, `Single or no song, buttons disabled: totalCount=${data.playlist.totalCount}`);
-    }
-    
-    const formattedData: FormattedWidgetData = {
-      // 播放状态
-      isPlaying: data.playState.isPlaying,
-      isPaused: data.playState.isPaused,
-      isLoading: data.playState.isLoading,
-
-      // 歌曲信息
-      songTitle: this.truncateText(data.currentSong.title, 20),
-      songArtist: this.truncateText(data.currentSong.artist, 15),
-      songAlbum: this.truncateText(data.currentSong.album, 15),
-      coverImage: data.currentSong.coverImagePath && data.currentSong.coverImagePath.trim() !== '' ?
-      data.currentSong.coverImagePath : '',
-
-      // 播放进度
-      currentTime: data.progress.currentTimeText,
-      totalTime: data.progress.totalTimeText,
-      progressPercentage: data.progress.percentage,
-
-      // 控制按钮状态(使用修复后的值)
-      hasNext: hasNext,
-      hasPrevious: hasPrevious,
-
-      // 卡片配置
-      showProgress: data.config.showProgress,
-      showCover: data.config.showCover,
-      widgetSize: data.config.size as string,
-
-      // 时间戳用于强制更新
-      timestamp: Date.now(),
-      isFavorite: false
-    };
-    return formattedData;
-  }
-
-  /**
-   * 截断文本
-   */
-  private truncateText(text: string, maxLength: number): string {
-    if (text.length <= maxLength) {
-      return text;
-    }
-    return text.substring(0, maxLength - 1) + '…';
-  }
-
-  /**
-   * 启动缓存清理定时器
-   */
-  private startCacheCleanup(): void {
-    setInterval(() => {
-      this.cleanExpiredCache();
-    }, 60 * 1000); // 每分钟清理一次过期缓存
-  }
-
-  /**
-   * 清理过期缓存
-   */
-  private cleanExpiredCache(): void {
-    const now = Date.now();
-    const expiredKeys: string[] = [];
-    
-    this.dataCache.forEach((item: CacheItem, key: string) => {
-      if (now > item.expiry) {
-        expiredKeys.push(key);
-      }
-    });
-    
-    expiredKeys.forEach((key: string) => {
-      this.dataCache.delete(key);
-    });
-    
-    if (expiredKeys.length > 0) {
-      hilog.info(0x0000, TAG, `Cleaned ${expiredKeys.length} expired cache items`);
-    }
-  }
-
-  /**
-   * 从缓存获取数据
-   */
-  private getCachedData(formId: string): WidgetData | null {
-    const cacheKey = `cache_${formId}`;
-    const cacheItem = this.dataCache.get(cacheKey);
-    
-    if (cacheItem && Date.now() < cacheItem.expiry) {
-      hilog.info(0x0000, TAG, `Cache hit for form: ${formId}`);
-      return cacheItem.data;
-    }
-    
-    if (cacheItem) {
-      // 缓存已过期,删除
-      this.dataCache.delete(cacheKey);
-      hilog.info(0x0000, TAG, `Cache expired for form: ${formId}`);
-    }
-    
-    return null;
-  }
-
-  /**
-   * 设置缓存数据
-   */
-  private setCachedData(formId: string, data: WidgetData): void {
-    const cacheKey = `cache_${formId}`;
-    const now = Date.now();
-    
-    const cacheItem: CacheItem = {
-      data: data,
-      timestamp: now,
-      expiry: now + CACHE_EXPIRY_TIME
-    };
-    
-    this.dataCache.set(cacheKey, cacheItem);
-    hilog.info(0x0000, TAG, `Data cached for form: ${formId}`);
-  }
-
-  /**
-   * 获取卡片数据(带缓存)
-   */
-  async getWidgetDataWithCache(formId: string): Promise<WidgetData> {
-    // 先尝试从缓存获取
-    const cachedData = this.getCachedData(formId);
-    if (cachedData) {
-      return cachedData;
-    }
-    
-    // 缓存未命中,从持久化存储获取
-    const data = await this.getWidgetData(formId);
-    
-    // 设置缓存
-    this.setCachedData(formId, data);
-    
-    return data;
-  }
-
-  /**
-   * 更新卡片数据(带缓存)
-   */
-  async updateWidgetWithCache(formId: string, data: WidgetData): Promise<void> {
-    // 更新缓存
-    this.setCachedData(formId, data);
-    
-    // 更新卡片显示
-    await this.updateWidget(formId, data);
-  }
-
-  /**
-   * 清除指定卡片的缓存
-   */
-  clearWidgetCache(formId: string): void {
-    const cacheKey = `cache_${formId}`;
-    if (this.dataCache.has(cacheKey)) {
-      this.dataCache.delete(cacheKey);
-      hilog.info(0x0000, TAG, `Cache cleared for form: ${formId}`);
-    }
-  }
-
-  /**
-   * 清除所有缓存
-   */
-  clearAllCache(): void {
-    const cacheSize = this.dataCache.size;
-    this.dataCache.clear();
-    hilog.info(0x0000, TAG, `All cache cleared, ${cacheSize} items removed`);
-  }
-
-  /**
-   * 获取缓存统计信息
-   */
-  getCacheStats(): CacheStats {
-    const stats: CacheStats = {
-      size: this.dataCache.size,
-      hitRate: 0, // 可以在实际使用中统计命中率
-      lastUpdate: this.lastUpdateTime
-    };
-    return stats;
-  }
-
-  /**
-   * 预热缓存
-   */
-  async preloadCache(): Promise<void> {
-    try {
-      if (!this.preferencesStore) {
-        await this.initPreferences();
-      }
-      
-      const allKeys = await this.preferencesStore?.getAll();
-      const emptyPrefs: PreferencesData = {};
-      const widgetKeys = Object.keys(allKeys || emptyPrefs).filter(key => key.startsWith('widget_'));
-      
-      for (const key of widgetKeys) {
-        const formId: string = key.replace('widget_', '');
-        const data: WidgetData = await this.getWidgetData(formId);
-        this.setCachedData(formId, data);
-      }
-      
-      hilog.info(0x0000, TAG, `Cache preloaded for ${widgetKeys.length} widgets`);
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to preload cache: ${error}`);
-    }
-  }
-
-  /**
-   * 检查是否为格式化的卡片数据
-   */
-  private isFormattedWidgetData(data: WidgetData | FormattedWidgetData): boolean {
-    // FormattedWidgetData有timestamp字段,而WidgetData没有
-    return (data as FormattedWidgetData).timestamp !== undefined && typeof (data as FormattedWidgetData).timestamp === 'number';
-  }
-
-  /**
-   * 将格式化数据转换为WidgetData
-   */
-  private convertToWidgetData(formattedData: FormattedWidgetData): WidgetData {
-    const widgetData: WidgetData = {
-      playState: {
-        isPlaying: formattedData.isPlaying,
-        isPaused: formattedData.isPaused,
-        isLoading: formattedData.isLoading
-      },
-      currentSong: {
-        id: '', // FormattedWidgetData中没有id,使用空字符串
-        title: formattedData.songTitle,
-        artist: formattedData.songArtist,
-        album: formattedData.songAlbum,
-        coverImagePath: formattedData.coverImage,
-        duration: 0 // FormattedWidgetData中没有duration,使用0
-      },
-      progress: {
-        currentPosition: 0, // 需要从时间文本反推,这里简化处理
-        duration: 0,
-        percentage: formattedData.progressPercentage,
-        currentTimeText: formattedData.currentTime,
-        totalTimeText: formattedData.totalTime
-      },
-      playlist: {
-        hasNext: formattedData.hasNext,
-        hasPrevious: formattedData.hasPrevious,
-        currentIndex: 0,
-        totalCount: 0
-      },
-      config: {
-        size: this.parseWidgetSize(formattedData.widgetSize),
-        theme: WidgetTheme.AUTO,
-        showProgress: formattedData.showProgress,
-        showCover: formattedData.showCover
-      }
-    };
-    return widgetData;
-  }
-
-  /**
-   * 解析卡片尺寸字符串
-   */
-  private parseWidgetSize(sizeStr: string): WidgetSize {
-    switch (sizeStr.toLowerCase()) {
-      case 'small':
-        return WidgetSize.SMALL;
-      case 'large':
-        return WidgetSize.LARGE;
-      case 'medium':
-      default:
-        return WidgetSize.MEDIUM;
-    }
-  }
-}

+ 0 - 67
entry/src/main/ets/common/widget/WidgetEventConstants.ets

@@ -1,67 +0,0 @@
-/**
- * 卡片事件常量 - 简化版本
- */
-
-// 播放控制事件
-export const PLAY_PAUSE_EVENT = 'play_pause';
-export const NEXT_SONG_EVENT = 'next_song';
-export const PREV_SONG_EVENT = 'prev_song';
-export const SEEK_TO_EVENT = 'seek_to';
-
-// 应用启动事件
-export const OPEN_APP_EVENT = 'open_app';
-export const OPEN_PLAYER_EVENT = 'open_player';
-
-// 长按配置事件
-export const LONG_PRESS_MENU_EVENT = 'long_press_menu';
-export const WIDGET_SETTINGS_EVENT = 'widget_settings';
-export const WIDGET_DELETE_EVENT = 'widget_delete';
-export const WIDGET_CONFIG_PAGE_EVENT = 'widget_config_page';
-
-// 其他事件
-export const REFRESH_DATA_EVENT = 'refresh_data';
-export const TOGGLE_FAVORITE_EVENT = 'toggle_favorite';
-
-// 卡片尺寸
-export const WIDGET_SIZE_SMALL = 'small';
-export const WIDGET_SIZE_MEDIUM = 'medium';
-export const WIDGET_SIZE_LARGE = 'large';
-
-// 卡片主题
-export const WIDGET_THEME_AUTO = 'auto';
-export const WIDGET_THEME_LIGHT = 'light';
-export const WIDGET_THEME_DARK = 'dark';
-
-// 通信事件
-export const WIDGET_CONTROL_EVENT = 'com.ttmusic.widget.control';
-export const WIDGET_REQUEST_STATE_EVENT = 'com.ttmusic.widget.request.state';
-export const PLAYER_STATE_CHANGED_EVENT = 'com.ttmusic.player.state.changed';
-export const PLAYER_SONG_CHANGED_EVENT = 'com.ttmusic.player.song.changed';
-export const PLAYER_PROGRESS_CHANGED_EVENT = 'com.ttmusic.player.progress.changed';
-
-// 应用信息
-export const APP_BUNDLE_NAME = 'com.xgplayer.ttmusic.hm';
-export const APP_ABILITY_NAME = 'EntryAbility';
-
-// 页面路由
-export const PAGE_MAIN = 'main';
-export const PAGE_PLAYER = 'player';
-export const PAGE_PLAYLIST = 'playlist';
-export const PAGE_SEARCH = 'search';
-
-// 错误码
-export const ERROR_COMMUNICATION_FAILED = 1001;
-export const ERROR_DATA_SYNC_FAILED = 1002;
-export const ERROR_CONTROL_COMMAND_FAILED = 1003;
-export const ERROR_LAYOUT_ERROR = 1004;
-export const ERROR_PERMISSION_DENIED = 1005;
-
-// 缓存配置
-export const CACHE_EXPIRY_TIME = 30 * 1000; // 30秒
-export const CACHE_MAX_SIZE = 50;
-export const CACHE_CLEANUP_INTERVAL = 60 * 1000; // 1分钟
-
-// 动画配置
-export const ANIMATION_BUTTON_PRESS_DURATION = 150;
-export const ANIMATION_PROGRESS_UPDATE_DURATION = 300;
-export const ANIMATION_FADE_DURATION = 200;

+ 0 - 79
entry/src/main/ets/common/widget/WidgetRegistrationFix.ets

@@ -1,79 +0,0 @@
-import { hilog } from '@kit.PerformanceAnalysisKit';
-import { Context } from '@kit.AbilityKit';
-import { PreferencesUtil } from '../utils/PreferencesUtil';
-import { GlobalWidgetManager } from './GlobalWidgetManager';
-
-const TAG = 'WidgetRegistrationFix';
-
-/**
- * 卡片注册修复工具
- * 用于修复卡片注册和持久化问题
- */
-export class WidgetRegistrationFix {
-  private static instance: WidgetRegistrationFix | null = null;
-  private preferencesUtil: PreferencesUtil = PreferencesUtil.getInstance();
-  private globalWidgetManager: GlobalWidgetManager = GlobalWidgetManager.getInstance();
-
-  private constructor() {}
-
-  public static getInstance(): WidgetRegistrationFix {
-    if (!WidgetRegistrationFix.instance) {
-      WidgetRegistrationFix.instance = new WidgetRegistrationFix();
-    }
-    return WidgetRegistrationFix.instance;
-  }
-
-  /**
-   * 执行卡片注册修复
-   */
-  public async fixWidgetRegistration(context: Context): Promise<void> {
-    try {
-      hilog.info(0x0000, TAG, '🔧 开始卡片注册修复...');
-      
-      // 同步活跃卡片到持久化存储
-      await this.syncActiveWidgetsToPersistence(context);
-      
-      hilog.info(0x0000, TAG, '✅ 卡片注册修复完成');
-      
-    } catch (error) {
-      hilog.error(0x0000, TAG, `❌ 卡片注册修复失败: ${error}`);
-    }
-  }
-
-
-
-  /**
-   * 同步活跃卡片到持久化存储
-   */
-  private async syncActiveWidgetsToPersistence(context: Context): Promise<void> {
-    try {
-      const prefs = await this.preferencesUtil.getPreferences(context);
-      const persistedIds = await this.preferencesUtil.getFormIds(prefs);
-      const activeWidgets = this.globalWidgetManager.getActiveWidgets();
-      const activeIds = Array.from(activeWidgets.keys());
-      
-      hilog.info(0x0000, TAG, `📊 持久化: ${persistedIds.length}个, 活跃: ${activeIds.length}个`);
-      
-      // 将活跃但未持久化的卡片添加到持久化存储
-      const missingInPersistence = activeIds.filter(id => !persistedIds.includes(id));
-      if (missingInPersistence.length > 0) {
-        hilog.info(0x0000, TAG, `🔧 同步 ${missingInPersistence.length} 个活跃卡片到持久化存储`);
-        
-        // 串行处理,避免并发问题
-        for (const formId of missingInPersistence) {
-          try {
-            await this.preferencesUtil.addFormId(prefs, formId);
-            hilog.info(0x0000, TAG, `✅ 同步卡片成功: ${formId}`);
-          } catch (error) {
-            hilog.error(0x0000, TAG, `❌ 同步卡片失败 ${formId}: ${error}`);
-          }
-        }
-      }
-      
-    } catch (error) {
-      hilog.error(0x0000, TAG, `❌ 同步活跃卡片失败: ${error}`);
-    }
-  }
-
-
-}

+ 0 - 304
entry/src/main/ets/common/widget/WidgetSizeAdapter.ets

@@ -1,304 +0,0 @@
-import { WidgetSize, WidgetData, FormattedWidgetData, WidgetConfig, MaxTextLengthConfig } from './WidgetTypes';
-import { FormLayoutManager } from './FormLayoutManager';
-import { hilog } from '@kit.PerformanceAnalysisKit';
-import Want from '@ohos.app.ability.Want';
-
-const TAG = 'Heanup-WidgetSizeAdapter';
-
-/**
- * 卡片尺寸适配器
- * 处理卡片尺寸变化时的UI重构逻辑
- * 需求: 5.4, 5.5
- */
-export class WidgetSizeAdapter {
-  private static instance: WidgetSizeAdapter;
-  private layoutManager: FormLayoutManager;
-  private sizeChangeListeners: Map<string, SizeChangeListener> = new Map();
-
-  /**
-   * 获取单例实例
-   */
-  public static getInstance(): WidgetSizeAdapter {
-    if (!WidgetSizeAdapter.instance) {
-      WidgetSizeAdapter.instance = new WidgetSizeAdapter();
-    }
-    return WidgetSizeAdapter.instance;
-  }
-
-  private constructor() {
-    this.layoutManager = FormLayoutManager.getInstance();
-    hilog.info(0x0000, TAG, 'WidgetSizeAdapter initialized');
-  }
-
-  /**
-   * 从Want参数中检测卡片尺寸
-   * @param want Want对象
-   * @returns 卡片尺寸
-   */
-  public detectSizeFromWant(want: Want): WidgetSize {
-    try {
-      // 从Want参数中获取卡片维度信息
-      const formDimension = want.parameters?.['ohos.extra.param.key.form_dimension'] as number;
-      const formName = want.parameters?.['ohos.extra.param.key.form_name'] as string;
-      
-      hilog.info(0x0000, TAG, `Detecting size from Want - dimension: ${formDimension}, name: ${formName}`);
-      
-      // 根据维度参数判断尺寸
-      if (formDimension !== undefined) {
-        return this.mapDimensionToSize(formDimension);
-      }
-      
-      // 如果没有维度参数,尝试从表单名称推断
-      if (formName) {
-        return this.mapFormNameToSize(formName);
-      }
-      
-      // 默认返回中等尺寸
-      hilog.warn(0x0000, TAG, 'Unable to detect size from Want, using medium as default');
-      return WidgetSize.MEDIUM;
-      
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Error detecting size from Want: ${error}`);
-      return WidgetSize.MEDIUM;
-    }
-  }
-
-  /**
-   * 处理卡片尺寸变化
-   * @param formId 卡片ID
-   * @param oldSize 旧尺寸
-   * @param newSize 新尺寸
-   * @param widgetData 卡片数据
-   * @returns 适配后的数据
-   */
-  public handleSizeChange(
-    formId: string, 
-    oldSize: WidgetSize, 
-    newSize: WidgetSize, 
-    widgetData: WidgetData
-  ): FormattedWidgetData {
-    hilog.info(0x0000, TAG, `Handling size change for form ${formId}: ${oldSize} -> ${newSize}`);
-    
-    // 检查是否需要重构UI
-    const needsRebuild = this.layoutManager.shouldRebuildUI(oldSize, newSize);
-    
-    if (needsRebuild) {
-      // 通知监听器尺寸变化
-      this.notifySizeChange(formId, oldSize, newSize);
-      
-      // 更新卡片配置
-      const sizeConfig = this.layoutManager.getSizeDisplayConfig(newSize);
-      const updatedConfig: WidgetConfig = {
-        size: sizeConfig.size,
-        theme: sizeConfig.theme,
-        showProgress: sizeConfig.showProgress,
-        showCover: sizeConfig.showCover
-      };
-      widgetData.config = updatedConfig;
-    }
-    
-    // 适配数据到新尺寸
-    return this.layoutManager.adaptDataForSize(widgetData, newSize);
-  }
-
-  /**
-   * 注册尺寸变化监听器
-   * @param formId 卡片ID
-   * @param listener 监听器
-   */
-  public registerSizeChangeListener(formId: string, listener: SizeChangeListener): void {
-    this.sizeChangeListeners.set(formId, listener);
-    hilog.info(0x0000, TAG, `Size change listener registered for form: ${formId}`);
-  }
-
-  /**
-   * 注销尺寸变化监听器
-   * @param formId 卡片ID
-   */
-  public unregisterSizeChangeListener(formId: string): void {
-    this.sizeChangeListeners.delete(formId);
-    hilog.info(0x0000, TAG, `Size change listener unregistered for form: ${formId}`);
-  }
-
-  /**
-   * 获取卡片的推荐配置
-   * @param size 卡片尺寸
-   * @returns 推荐配置
-   */
-  public getRecommendedConfig(size: WidgetSize): WidgetSizeConfig {
-    switch (size) {
-      case WidgetSize.SMALL:
-        const smallMaxTextLength: MaxTextLengthConfig = {
-          title: 20,
-          artist: 0,
-          album: 0
-        };
-        const smallConfig: WidgetSizeConfig = {
-          size: size,
-          displayElements: ['title', 'controls'],
-          maxTextLength: smallMaxTextLength,
-          layoutPriority: ['controls', 'title'],
-          animationDuration: 200
-        };
-        return smallConfig;
-      case WidgetSize.MEDIUM:
-        const mediumMaxTextLength: MaxTextLengthConfig = {
-          title: 30,
-          artist: 25,
-          album: 25
-        };
-        const mediumConfig: WidgetSizeConfig = {
-          size: size,
-          displayElements: ['title', 'artist', 'album', 'controls', 'progress'],
-          maxTextLength: mediumMaxTextLength,
-          layoutPriority: ['controls', 'title', 'artist', 'progress'],
-          animationDuration: 300
-        };
-        return mediumConfig;
-      case WidgetSize.LARGE:
-        const largeMaxTextLength: MaxTextLengthConfig = {
-          title: 40,
-          artist: 35,
-          album: 35
-        };
-        const largeConfig: WidgetSizeConfig = {
-          size: size,
-          displayElements: ['cover', 'title', 'artist', 'album', 'controls', 'progress'],
-          maxTextLength: largeMaxTextLength,
-          layoutPriority: ['cover', 'controls', 'title', 'artist', 'album', 'progress'],
-          animationDuration: 400
-        };
-        return largeConfig;
-      default:
-        return this.getRecommendedConfig(WidgetSize.MEDIUM);
-    }
-  }
-
-  /**
-   * 验证尺寸变化的合法性
-   * @param oldSize 旧尺寸
-   * @param newSize 新尺寸
-   * @returns 是否合法
-   */
-  public validateSizeChange(oldSize: WidgetSize, newSize: WidgetSize): boolean {
-    // 检查尺寸是否有效
-    if (!this.layoutManager.isValidSize(oldSize) || !this.layoutManager.isValidSize(newSize)) {
-      hilog.error(0x0000, TAG, `Invalid size change: ${oldSize} -> ${newSize}`);
-      return false;
-    }
-    
-    // 所有尺寸变化都是合法的
-    return true;
-  }
-
-  /**
-   * 获取尺寸变化的动画配置
-   * @param oldSize 旧尺寸
-   * @param newSize 新尺寸
-   * @returns 动画配置
-   */
-  public getSizeChangeAnimation(oldSize: WidgetSize, newSize: WidgetSize): AnimationConfig {
-    const isExpanding = this.isSizeExpanding(oldSize, newSize);
-    
-    const animationConfig: AnimationConfig = {
-      duration: isExpanding ? 300 : 250,
-      curve: isExpanding ? 'ease-out' : 'ease-in',
-      delay: 0,
-      iterations: 1,
-      playMode: 'normal'
-    };
-    return animationConfig;
-  }
-
-  /**
-   * 通知尺寸变化
-   */
-  private notifySizeChange(formId: string, oldSize: WidgetSize, newSize: WidgetSize): void {
-    const listener = this.sizeChangeListeners.get(formId);
-    if (listener) {
-      try {
-        listener.onSizeChanged(formId, oldSize, newSize);
-      } catch (error) {
-        hilog.error(0x0000, TAG, `Error notifying size change listener: ${error}`);
-      }
-    }
-  }
-
-  /**
-   * 将维度参数映射到尺寸枚举
-   */
-  private mapDimensionToSize(dimension: number): WidgetSize {
-    // HarmonyOS卡片维度常量映射
-    switch (dimension) {
-      case 1: // 2x1
-        return WidgetSize.SMALL;
-      case 2: // 4x2
-        return WidgetSize.MEDIUM;
-      case 3: // 4x3
-        return WidgetSize.LARGE;
-      case 4: // 2x4
-        return WidgetSize.RECTANGLE;
-      default:
-        hilog.warn(0x0000, TAG, `Unknown dimension: ${dimension}, using medium as default`);
-        return WidgetSize.MEDIUM;
-    }
-  }
-
-  /**
-   * 将表单名称映射到尺寸枚举
-   */
-  private mapFormNameToSize(formName: string): WidgetSize {
-    const lowerName = formName.toLowerCase();
-    
-    if (lowerName.includes('small') || lowerName.includes('2x1')) {
-      return WidgetSize.SMALL;
-    } else if (lowerName.includes('large') || lowerName.includes('4x3')) {
-      return WidgetSize.LARGE;
-    } else if (lowerName.includes('medium') || lowerName.includes('4x2')) {
-      return WidgetSize.MEDIUM;
-    }
-    
-    // 默认返回中等尺寸
-    return WidgetSize.MEDIUM;
-  }
-
-  /**
-   * 判断尺寸是否在扩大
-   */
-  private isSizeExpanding(oldSize: WidgetSize, newSize: WidgetSize): boolean {
-    const sizeOrder = [WidgetSize.SMALL, WidgetSize.MEDIUM, WidgetSize.LARGE];
-    const oldIndex = sizeOrder.indexOf(oldSize);
-    const newIndex = sizeOrder.indexOf(newSize);
-    
-    return newIndex > oldIndex;
-  }
-}
-
-/**
- * 尺寸变化监听器接口
- */
-export interface SizeChangeListener {
-  onSizeChanged(formId: string, oldSize: WidgetSize, newSize: WidgetSize): void;
-}
-
-/**
- * 卡片尺寸配置接口
- */
-export interface WidgetSizeConfig {
-  size: WidgetSize;
-  displayElements: string[];
-  maxTextLength: MaxTextLengthConfig;
-  layoutPriority: string[];
-  animationDuration: number;
-}
-
-/**
- * 动画配置接口
- */
-export interface AnimationConfig {
-  duration: number;
-  curve: string; // 使用字符串代替Curve枚举
-  delay: number;
-  iterations: number;
-  playMode: string; // 使用字符串代替PlayMode枚举
-}

+ 0 - 1
entry/src/main/ets/common/widget/WidgetTypes.ets

@@ -188,7 +188,6 @@ export interface FormattedWidgetData {
   progressPercentage: number;
   hasNext: boolean;
   hasPrevious: boolean;
-  isFavorite: boolean;
   showProgress: boolean;
   showCover: boolean;
   widgetSize: string;

+ 118 - 99
entry/src/main/ets/entryability/EntryAbility.ets

@@ -17,11 +17,9 @@ import { rpc } from '@kit.IPCKit';
 import { Utility } from '../common/util/Utility';
 import { WXApi, WXEventHandler } from '../common/util/WXApiWrap';
 import { UnifiedPlayerService } from '../common/service/UnifiedPlayerService';
-import { WidgetRegistrationFix } from '../common/widget/WidgetRegistrationFix';
 import { systemShare } from '@kit.ShareKit';
 import { CustomCrashHandler } from '../common/utils/CustomCrashHandler';
 import { smartMobilityCommon } from '@kit.CarKit';
-import { url } from '@kit.ArkTS';
 import { display } from '@kit.ArkUI';
 
 
@@ -29,70 +27,69 @@ import { display } from '@kit.ArkUI';
  * 播放状态广播数据接口
  */
 interface PlayStateBroadcast {
-  isPlaying: boolean;
-  isPaused: boolean;
-  isLoading: boolean;
+    isPlaying: boolean;
+    isPaused: boolean;
+    isLoading: boolean;
 }
 
 interface SongBroadcast {
-  id: string;
-  title: string;
-  artist: string;
-  album: string;
-  coverImagePath: string;
-  duration: number;
+    id: string;
+    title: string;
+    artist: string;
+    album: string;
+    coverImagePath: string;
+    duration: number;
 }
 
 interface ProgressBroadcast {
-  currentPosition: number;
-  duration: number;
-  percentage: number;
-  currentTimeText: string;
-  totalTimeText: string;
+    currentPosition: number;
+    duration: number;
+    percentage: number;
+    currentTimeText: string;
+    totalTimeText: string;
 }
 
 interface PlaylistBroadcast {
-  hasNext: boolean;
-  hasPrevious: boolean;
-  currentIndex: number;
-  totalCount: number;
-  isFavorite: boolean;
+    hasNext: boolean;
+    hasPrevious: boolean;
+    currentIndex: number;
+    totalCount: number;
 }
 
 interface BroadcastData {
-  playState: PlayStateBroadcast;
-  currentSong: SongBroadcast;
-  progress: ProgressBroadcast;
-  playlist: PlaylistBroadcast;
+    playState: PlayStateBroadcast;
+    currentSong: SongBroadcast;
+    progress: ProgressBroadcast;
+    playlist: PlaylistBroadcast;
 }
 
 interface PublishInfo {
-  data: string;
+    data: string;
 }
 
 interface EventDataWrapper {
-  data: BroadcastData;
+    data: BroadcastData;
 }
 /**
  * RPC通信返回类型的实现,用于RPC通信数据序列化和反序列化
  */
 class MyParcelable implements rpc.Parcelable {
-  num: number;
-  str: string;
-  constructor(num: number, str: string) {
-    this.num = num;
-    this.str = str;
-  }
-  marshalling(messageSequence: rpc.MessageSequence): boolean {
-    messageSequence.writeInt(this.num);
-    messageSequence.writeString(this.str);
-    return true;
-  }
-  unmarshalling(messageSequence: rpc.MessageSequence): boolean {
-    this.num = messageSequence.readInt();
-    this.str = messageSequence.readString();
-    return true;
-  }
+    num: number;
+    str: string;
+    constructor(num: number, str: string) {
+        this.num = num;
+        this.str = str;
+    }
+    marshalling(messageSequence: rpc.MessageSequence): boolean {
+        messageSequence.writeInt(this.num);
+        messageSequence.writeString(this.str);
+        return true;
+    }
+    unmarshalling(messageSequence: rpc.MessageSequence): boolean {
+        this.num = messageSequence.readInt();
+        this.str = messageSequence.readString();
+        return true;
+    }
 }
 
 /**
@@ -106,7 +103,7 @@ export default class EntryAbility extends UIAbility {
     // UI上下文对象,用于获取窗口信息
     private uiContext?: UIContext;
     // private awareness: smartMobilityCommon.SmartMobilityAwareness = smartMobilityCommon.getSmartMobilityAwareness();
-    private awareness: smartMobilityCommon.SmartMobilityAwareness|undefined = canIUse("SystemCapability.CarService.DistributedEngine")?smartMobilityCommon.getSmartMobilityAwareness():undefined;
+    private awareness: smartMobilityCommon.SmartMobilityAwareness|undefined = canIUse("SystemCapability.SmartOptimizer.SmartMobility")?smartMobilityCommon.getSmartMobilityAwareness():undefined;
 
     /**
      * 窗口尺寸变化回调函数
@@ -151,15 +148,6 @@ export default class EntryAbility extends UIAbility {
         }
 
     }
-    onDisplayIdChange=(displayId: number)=> {
-        let curDisplay = display.getDisplayByIdSync(displayId);
-        console.info('twocold curDisplay 2 = '+curDisplay.name);
-        if(curDisplay.name =='HiCar'||curDisplay.name =='SuperLauncher'){
-            AppStorage.setOrCreate('curDisplayIsHiCar', true);
-        }else{
-            AppStorage.setOrCreate('curDisplayIsHiCar', false);
-        }
-    }
 
     async onCreate(want:Want, launchParam:AbilityConstant.LaunchParam) {
         AppUtil.init(this.context);
@@ -172,9 +160,6 @@ export default class EntryAbility extends UIAbility {
         // 异步初始化统一播放器服务,避免阻塞生命周期
         this.initializePlayerServiceAsync();
 
-        // 执行卡片注册修复(异步执行,不阻塞启动)
-        this.fixWidgetRegistrationAsync();
-
         // 异步处理Want参数,避免阻塞生命周期
         this.handleWantAsync(want);
 
@@ -274,7 +259,7 @@ export default class EntryAbility extends UIAbility {
             // 解注册智慧出行连接状态的监听 示例2
             this.awareness.off('smartMobilityStatus', types, callBack);
         }
-        }
+    }
 
 
     onWindowStageCreate(windowStage: window.WindowStage) {
@@ -324,7 +309,6 @@ export default class EntryAbility extends UIAbility {
 
             LogUtil.info('onecold  topRectHeight = '+topRectHeight);
             windowClass.on('avoidAreaChange', this.onAvoidAreaChange)
-            windowClass.on('displayIdChange', this.onDisplayIdChange)
         })
 
 
@@ -396,13 +380,9 @@ export default class EntryAbility extends UIAbility {
 
 
     getHiCarStatus(){
-        if (!this.awareness){
-            this.awareness=canIUse("SystemCapability.CarService.DistributedEngine")?smartMobilityCommon.getSmartMobilityAwareness():undefined;
-        }
-        console.log('enter getHiCarStatus,awareness:'+JSON.stringify(this.awareness));
         if(this.awareness){
             // this.awareness = smartMobilityCommon.getSmartMobilityAwareness();
-            console.log('enter awareness');
+
             // 业务类型
             let types: smartMobilityCommon.SmartMobilityType[] = [smartMobilityCommon.SmartMobilityType.HICAR];
             // 获取出行业务连接状态
@@ -521,25 +501,10 @@ export default class EntryAbility extends UIAbility {
                     return new MyParcelable(-4, 'openApp_error');
                 }
             });
-
-            // 监听收藏事件
-            this.callee.on('toggleFavorite', (data: rpc.MessageSequence) => {
-                try {
-                    hilog.info(0x0000, 'Heanup2', `🎵 Widget call: toggleFavorite received`);
-                    const params: Record<string, Object> = JSON.parse(data.readString()) as Record<string, Object>;
-                    hilog.info(0x0000, 'Heanup2', `Widget toggleFavorite params: ${JSON.stringify(params)}`);
-
-                    // 异步发送收藏事件到主应用
-                    this.sendWidgetControlEvent('TOGGLE_FAVORITE', params).catch((error: Error) => {
-                        hilog.error(0x0000, 'Heanup2', `❌ toggleFavorite async error: ${error}`);
-                    });
-
-                    return new MyParcelable(5, 'toggleFavorite_success');
-                } catch (error) {
-                    hilog.error(0x0000, 'Heanup2', `❌ toggleFavorite handler error: ${error}`);
-                    return new MyParcelable(-5, 'toggleFavorite_error');
-                }
-            });
+            this.callee.on("toggleFavorite",(data:rpc.MessageSequence)=>{
+                hilog.info(0x0000, 'Heanup2', `toggleFavorite handler`);
+                return new MyParcelable(-5, 'toggleFavorite');
+            })
 
             hilog.info(0x0000, 'Heanup2', '🎵 Widget call listeners registered successfully (Enhanced)');
         } catch (err) {
@@ -678,12 +643,9 @@ export default class EntryAbility extends UIAbility {
                 case 'OPEN_APP':
                     hilog.info(0x0000, 'Heanup2', '✅ Widget command: Open app (handled by UI)');
                     break;
-
-                case 'TOGGLE_FAVORITE':
-                    await unifiedService.toggleFavorite();
-                    hilog.info(0x0000, 'Heanup2', '✅ Widget command: Toggle favorite');
+                case 'OPEN_APP':
+                    hilog.info(0x0000, 'Heanup2', '✅ Widget command: Open app (handled by UI)');
                     break;
-
                 default:
                     hilog.warn(0x0000, 'Heanup2', `❓ Unknown widget command: ${command}`);
                     break;
@@ -886,24 +848,81 @@ export default class EntryAbility extends UIAbility {
     }
 
     /**
-     * 异步执行卡片注册修复
+     * 广播当前播放器状态给卡片
      */
-    private async fixWidgetRegistrationAsync(): Promise<void> {
-        // 延迟3秒执行,确保应用完全启动
-        setTimeout(async () => {
-            try {
-                const widgetFix = WidgetRegistrationFix.getInstance();
-                await widgetFix.fixWidgetRegistration(this.context);
-            } catch (error) {
-                hilog.error(0x0000, 'Heanup2', `❌ 卡片注册修复失败: ${error}`);
+    private broadcastCurrentPlayerState(): void {
+        try {
+            const unifiedService = UnifiedPlayerService.getInstance();
+            const currentState = unifiedService.getCurrentState();
+            const currentSong = unifiedService.getCurrentSong();
+            const playlist = unifiedService.getPlaylist();
+            const currentIndex = unifiedService.getCurrentIndex();
+
+            if (currentSong) {
+                // 构建播放器状态广播数据
+                const broadcastData: BroadcastData = {
+                    playState: {
+                        isPlaying: currentState.isPlaying || false,
+                        isPaused: currentState.isPaused || true,
+                        isLoading: currentState.isLoading || false
+                    } as PlayStateBroadcast,
+                    currentSong: {
+                        id: currentSong.id || '',
+                        title: currentSong.name || '暂无播放',
+                        artist: currentSong.artist || '未知艺术家',
+                        album: currentSong.album || '未知专辑',
+                        coverImagePath: currentSong.pixelMapPath || '',
+                        duration: currentSong.duration ? Number(currentSong.duration) : 0
+                    } as SongBroadcast,
+                    progress: {
+                        currentPosition: currentState.currentPosition || 0,
+                        duration: currentState.duration || 0,
+                        percentage: this.calculatePercentage(currentState.currentPosition || 0, currentState.duration || 0),
+                        currentTimeText: this.formatTime(Math.floor((currentState.currentPosition || 0) / 1000)),
+                        totalTimeText: this.formatTime(Math.floor((currentState.duration || 0) / 1000))
+                    } as ProgressBroadcast,
+                    playlist: {
+                        hasNext: currentState.hasNext || false,
+                        hasPrevious: currentState.hasPrevious || false,
+                        currentIndex: currentIndex,
+                        totalCount: playlist.length
+                    } as PlaylistBroadcast
+                };
+
+                // 发送状态变化事件
+                const publishInfo: PublishInfo = {
+                    data: JSON.stringify(broadcastData)
+                };
+
+                // 使用emitter发送事件
+                const eventData: EventDataWrapper = {
+                    data: broadcastData
+                };
+                emitter.emit({ eventId: 1001 }, eventData); // 使用特定的事件ID
+
+                hilog.info(0x0000, 'Heanup2', `📡 Broadcasted current player state: ${currentSong.name}, isPlaying=${currentState.isPlaying}`);
+            } else {
+                hilog.info(0x0000, 'Heanup2', '📡 No current song to broadcast');
             }
-        }, 3000);
+        } catch (error) {
+            hilog.error(0x0000, 'Heanup2', `❌ Failed to broadcast current player state: ${error}`);
+        }
     }
 
     /**
-     * 广播当前播放器状态给卡片
+     * 计算播放进度百分比
      */
-    private broadcastCurrentPlayerState(): void {
+    private calculatePercentage(current: number, total: number): number {
+        if (total <= 0) return 0;
+        return Math.min(100, Math.max(0, (current / total) * 100));
+    }
 
+    /**
+     * 格式化时间显示
+     */
+    private formatTime(seconds: number): string {
+        const mins = Math.floor(seconds / 60);
+        const secs = Math.floor(seconds % 60);
+        return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
     }
 }

+ 19 - 646
entry/src/main/ets/entryformability/EntryFormAbility.ets

@@ -1,81 +1,24 @@
 import { formBindingData, FormExtensionAbility, formProvider } from '@kit.FormKit';
 import { Want } from '@kit.AbilityKit';
 import { hilog } from '@kit.PerformanceAnalysisKit';
-import { fileIo } from '@kit.CoreFileKit';
-import { http } from '@kit.NetworkKit';
-
-import { WidgetDataManager } from '../common/widget/WidgetDataManager';
-import { PlayerControlService } from '../common/widget/PlayerControlService';
-import { AvSessionWidgetListener } from '../common/widget/AvSessionWidgetListener';
-import { WidgetData, WidgetSize, FormattedWidgetData } from '../common/widget/WidgetTypes';
-import { FormLayoutManager } from '../common/widget/FormLayoutManager';
-import { GlobalWidgetManager } from '../common/widget/GlobalWidgetManager';
-import { WidgetSizeAdapter, SizeChangeListener } from '../common/widget/WidgetSizeAdapter';
+
+import { WidgetData, WidgetSize } from '../common/widget/WidgetTypes';
 import { PreferencesUtil } from '../common/utils/PreferencesUtil';
+import { UnifiedPlayerService } from '../common/service/UnifiedPlayerService';
+import { VideoItem } from '../viewmodel/VideoItem';
 
 const TAG = 'Heanup EntryFormAbility';
 
 
-/**
- * 扩展的卡片数据接口,支持图片传递
- */
-interface ExtendedWidgetData extends FormattedWidgetData {
-  formImages?: Record<string, number>;
-  isFavorite: boolean;
-}
 
-/**
- * 自定义对象复制函数,替代Object.assign
- */
-function copyWidgetData(target: ExtendedWidgetData, overrides: Partial<ExtendedWidgetData>): ExtendedWidgetData {
-  return {
-    isPlaying: overrides.isPlaying !== undefined ? overrides.isPlaying : target.isPlaying,
-    isPaused: overrides.isPaused !== undefined ? overrides.isPaused : target.isPaused,
-    isLoading: overrides.isLoading !== undefined ? overrides.isLoading : target.isLoading,
-    songTitle: overrides.songTitle !== undefined ? overrides.songTitle : target.songTitle,
-    songArtist: overrides.songArtist !== undefined ? overrides.songArtist : target.songArtist,
-    songAlbum: overrides.songAlbum !== undefined ? overrides.songAlbum : target.songAlbum,
-    coverImage: overrides.coverImage !== undefined ? overrides.coverImage : target.coverImage,
-    currentTime: overrides.currentTime !== undefined ? overrides.currentTime : target.currentTime,
-    totalTime: overrides.totalTime !== undefined ? overrides.totalTime : target.totalTime,
-    progressPercentage: overrides.progressPercentage !== undefined ? overrides.progressPercentage :
-    target.progressPercentage,
-    hasNext: overrides.hasNext !== undefined ? overrides.hasNext : target.hasNext,
-    hasPrevious: overrides.hasPrevious !== undefined ? overrides.hasPrevious : target.hasPrevious,
-    isFavorite: overrides.isFavorite !== undefined ? overrides.isFavorite : target.isFavorite,
-    showProgress: overrides.showProgress !== undefined ? overrides.showProgress : target.showProgress,
-    showCover: overrides.showCover !== undefined ? overrides.showCover : target.showCover,
-    widgetSize: overrides.widgetSize !== undefined ? overrides.widgetSize : target.widgetSize,
-    timestamp: overrides.timestamp !== undefined ? overrides.timestamp : target.timestamp,
-    imgName: overrides.imgName !== undefined ? overrides.imgName : target.imgName,
-    formImages: overrides.formImages !== undefined ? overrides.formImages : target.formImages
-  };
-}
 
 /**
  * 桌面播放器卡片扩展能力
  * 负责处理卡片的生命周期管理和用户交互事件
  * 支持多尺寸适配和UI重构
  */
-export default class EntryFormAbility extends FormExtensionAbility
-implements SizeChangeListener {
-  private widgetDataManager: WidgetDataManager | null = null;
-  private playerControlService: PlayerControlService = new PlayerControlService();
-  private layoutManager: FormLayoutManager = FormLayoutManager.getInstance();
-  private sizeAdapter: WidgetSizeAdapter = WidgetSizeAdapter.getInstance();
-  private globalWidgetManager: GlobalWidgetManager = GlobalWidgetManager.getInstance();
-  // 使用实例变量而不是静态变量,确保每个进程都能正确设置监听器
-  private globalListenerSetup: boolean = false;
-  // 防抖机制:避免短时间内重复更新
-  private lastUpdateTime: number = 0;
-  private updateDebounceDelay: number = 100;
-  // 100ms防抖延迟
-
-  // 进程启动时间,用于检测进程重启
-  private processStartTime: number = Date.now();
-  // 图片下载缓存
-  private downloadingImages: Map<string, Promise<string | null>> = new Map();
-  private imageCache: Map<string, string> = new Map();
+export default class EntryFormAbility extends FormExtensionAbility {
+  private unifiedPlayerService:UnifiedPlayerService = UnifiedPlayerService.getInstance();
 
   // url -> fileName映射
 
@@ -101,57 +44,20 @@ implements SizeChangeListener {
     }
 
     const formId = want.parameters?.['ohos.extra.param.key.form_identity'] as string;
-    const formName = want.parameters?.['ohos.extra.param.key.form_name'] as string;
-    const formDimension = want.parameters?.['ohos.extra.param.key.form_dimension'] as string;
-    const tempFlag = want.parameters?.['ohos.extra.param.key.form_temporary'] as boolean;
 
 
     // 持久化保存 Form ID(异步执行,不阻塞返回)
     this.saveFormIdToPersistence(formId).then(() => {
-
+      console.info('[Heanup] saveFormIdToPersistence success:'+ formId);
     })
 
-    // 检测卡片尺寸并注册到全局管理器
-    const widgetSize = this.sizeAdapter.detectSizeFromWant(want);
-    try {
-      this.globalWidgetManager.registerWidget(formId, widgetSize);
-
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to register widget: ${error}`);
-    }
-
-
-    // 注册各种监听器
-    this.sizeAdapter.registerSizeChangeListener(formId, this);
 
     // 初始化卡片数据
-    this.initializeWidget(formId, widgetSize);
-
-    // 验证监听器设置状态
-    setTimeout(() => {
-      const avSessionListener = AvSessionWidgetListener.getInstance();
-      const listenerCount = avSessionListener.getListenerCount();
-
+    this.initializeWidget(formId);
 
-      if (listenerCount === 0) {
-        hilog.warn(0x0000, TAG, `⚠️ No listeners found! Form process may not receive data updates!`);
-      } else {
-
-      }
-    }, 2000);
-
-    // 获取当前播放状态而不是初始数据
-    this.playerControlService.getCurrentPlayState().then((currentState: WidgetData) => {
-      const adaptedData = this.layoutManager.adaptDataForSize(currentState, widgetSize);
-      const formData = formBindingData.createFormBindingData(adaptedData);
-      // 立即更新卡片以显示当前状态
-      formProvider.updateForm(formId, formData);
-
-    });
 
     // 返回初始数据作为临时显示
-    const initialData = this.widgetDataManager?.getInitialWidgetData() || this.getDefaultWidgetData();
-    const adaptedData = this.layoutManager.adaptDataForSize(initialData, widgetSize);
+    const adaptedData = this.buildWidgetData();
 
     return formBindingData.createFormBindingData(adaptedData);
   }
@@ -160,20 +66,6 @@ implements SizeChangeListener {
    * 卡片更新时调用
    */
   onUpdateForm(formId: string): void {
-
-
-    // 确保服务已初始化
-    if (!this.globalListenerSetup) {
-
-      this.initializeServices();
-    }
-
-    // 确保widget已注册到GlobalWidgetManager
-    if (!this.globalWidgetManager.hasWidget(formId)) {
-
-      this.globalWidgetManager.registerWidget(formId, 'medium' as WidgetSize);
-    }
-
     // 只更新指定的卡片,避免重复更新
     this.updateWidgetData(formId);
   }
@@ -188,16 +80,6 @@ implements SizeChangeListener {
     this.removeFormIdFromPersistence(formId).then(() => {
 
     });
-
-
-    // 注销各种监听器
-    this.sizeAdapter.unregisterSizeChangeListener(formId);
-
-    // 从全局管理器中注销卡片
-    this.globalWidgetManager.unregisterWidget(formId);
-
-    // 清理卡片相关数据和配置
-    this.widgetDataManager?.removeWidgetData(formId);
   }
 
   /**
@@ -227,7 +109,7 @@ implements SizeChangeListener {
 
 
     // 更新所有卡片以适应新配置
-    this.widgetDataManager?.updateAllWidgets();
+    this.unifiedPlayerService.updateAllForms();
   }
 
   /**
@@ -236,12 +118,6 @@ implements SizeChangeListener {
    */
   onSizeChanged(formId: string, oldSize: WidgetSize, newSize: WidgetSize): void {
 
-
-    // 更新全局管理器中的尺寸记录
-    this.globalWidgetManager.updateWidgetSize(formId, newSize);
-
-    // 立即更新卡片数据以适应新尺寸
-    this.updateWidgetData(formId);
   }
 
   /**
@@ -250,20 +126,6 @@ implements SizeChangeListener {
    */
   onAcquireFormState(want: Want): number {
 
-
-    const formId = want.parameters?.['ohos.extra.param.key.form_identity'] as string;
-
-    if (formId) {
-      // 检测新的尺寸
-      const newSize = this.sizeAdapter.detectSizeFromWant(want);
-      const oldSize = this.globalWidgetManager.getWidgetSize(formId);
-
-      if (oldSize && this.sizeAdapter.validateSizeChange(oldSize, newSize)) {
-        // 处理尺寸变化
-        this.handleFormSizeChange(formId, oldSize, newSize);
-      }
-    }
-
     // 返回卡片状态 - 使用数字常量代替枚举
     return 1; // READY状态
   }
@@ -272,109 +134,17 @@ implements SizeChangeListener {
    * 初始化服务
    */
   private initializeServices(): void {
-
-    if (!this.widgetDataManager) {
-      this.widgetDataManager = new WidgetDataManager();
-    }
-
-    // 设置全局状态监听器(每个进程实例设置一次)
-    if (!this.globalListenerSetup) {
-      this.setupGlobalStateListener();
-      this.globalListenerSetup = true;
-    }
-  }
-
-  /**
-   * 设置全局状态监听器
-   */
-  private setupGlobalStateListener(): void {
-    try {
-      const avSessionListener = AvSessionWidgetListener.getInstance();
-      avSessionListener.addStateListener((data: WidgetData) => {
-        this.updateAllWidgetsWithData(data);
-      });
-    } catch (error) {
-      hilog.error(0x0000, TAG,
-        `Heanup EntryFormAbility [Process:${this.processStartTime}] failed to setup global listener: ${error}`);
-    }
-  }
-
-  /**
-   * 使用指定数据更新所有卡片
-   */
-  private updateAllWidgetsWithData(data: WidgetData): void {
-    // 防抖机制:避免短时间内重复更新
-    const now = Date.now();
-    if (now - this.lastUpdateTime < this.updateDebounceDelay) {
-      return;
+    if (!this.unifiedPlayerService) {
+      this.unifiedPlayerService = UnifiedPlayerService.getInstance();
     }
-    this.lastUpdateTime = now;
-
-    const activeWidgets = this.globalWidgetManager.getActiveWidgets();
-
-
-    if (activeWidgets.size === 0) {
-      hilog.warn(0x0000, TAG, 'Heanup EntryFormAbility no widgets to update in this process, skipping');
-      return;
-    }
-
-    activeWidgets.forEach((size: WidgetSize, formId: string) => {
-      this.updateSingleWidget(formId, size, data);
-    });
-
 
   }
 
-  /**
-   * 更新单个卡片,带重试机制和网络图片支持
-   */
-  private updateSingleWidget(formId: string, size: WidgetSize, data: WidgetData, retryCount: number = 0): void {
-    try {
-      // 根据卡片尺寸适配数据
-      const formattedData = this.layoutManager.adaptDataForSize(data, size);
-
-      // 转换为ExtendedWidgetData
-      const adaptedData: ExtendedWidgetData = {
-        isPlaying: formattedData.isPlaying,
-        isPaused: formattedData.isPaused,
-        isLoading: formattedData.isLoading,
-        songTitle: formattedData.songTitle,
-        songArtist: formattedData.songArtist,
-        songAlbum: formattedData.songAlbum,
-        coverImage: formattedData.coverImage,
-        currentTime: formattedData.currentTime,
-        totalTime: formattedData.totalTime,
-        progressPercentage: formattedData.progressPercentage,
-        hasNext: formattedData.hasNext,
-        hasPrevious: formattedData.hasPrevious,
-        isFavorite: formattedData.isFavorite,
-        showProgress: formattedData.showProgress,
-        showCover: formattedData.showCover,
-        widgetSize: formattedData.widgetSize,
-        timestamp: formattedData.timestamp,
-        imgName: formattedData.imgName,
-        formImages: formattedData.formImages
-      };
-
-
-      // 使用统一的图片处理方法
-      this.updateWidgetWithImage(formId, adaptedData, retryCount);
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Heanup widget ${formId} process error: ${error}`);
-
-      // 如果是处理错误,也尝试重试
-      if (retryCount < 2) {
-        setTimeout(() => {
-          this.updateSingleWidget(formId, size, data, retryCount + 1);
-        }, 1000 * (retryCount + 1));
-      }
-    }
-  }
 
   /**
    * 直接更新卡片(无网络图片)
    */
-  private updateWidgetDirectly(formId: string, adaptedData: ExtendedWidgetData, retryCount: number = 0): void {
+  private updateWidgetDirectly(formId: string, adaptedData: VideoItem, retryCount: number = 0): void {
     const formData = formBindingData.createFormBindingData(adaptedData);
     formProvider.updateForm(formId, formData).then(() => {
 
@@ -390,368 +160,6 @@ implements SizeChangeListener {
     });
   }
 
-  /**
-   * 统一处理图片更新
-   */
-  private async updateWidgetWithImage(formId: string, adaptedData: ExtendedWidgetData,
-    retryCount: number = 0): Promise<void> {
-    try {
-      if (!adaptedData.coverImage || adaptedData.coverImage.trim() === '') {
-        // 没有封面图片,直接更新
-        this.updateWidgetDirectly(formId, adaptedData, retryCount);
-        return;
-      }
-
-
-      if (this.isNetworkUrl(adaptedData.coverImage)) {
-        // 处理网络图片
-        await this.updateWidgetWithNetworkImage(formId, adaptedData, retryCount);
-      } else if (this.isLocalFileUri(adaptedData.coverImage)) {
-        // 处理本地文件URI
-        await this.updateWidgetWithLocalImage(formId, adaptedData, retryCount);
-      } else {
-        // 其他情况,可能是相对路径或其他格式,直接使用
-
-        this.updateWidgetDirectly(formId, adaptedData, retryCount);
-      }
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Heanup widget ${formId} image update error: ${error}`);
-      // 失败时使用默认数据
-      const dataWithoutImage: ExtendedWidgetData = copyWidgetData(adaptedData, { coverImage: '' });
-      this.updateWidgetDirectly(formId, dataWithoutImage, retryCount);
-    }
-  }
-
-  /**
-   * 处理本地文件URI图片
-   */
-  private async updateWidgetWithLocalImage(formId: string, adaptedData: ExtendedWidgetData,
-    retryCount: number = 0): Promise<void> {
-    try {
-      const localFileUri: string = adaptedData.coverImage;
-
-
-      // 先用无图片的数据快速更新一次,确保界面响应性
-      const dataWithoutImage: ExtendedWidgetData = copyWidgetData(adaptedData, {
-        coverImage: '',
-        imgName: '',
-        formImages: undefined
-      });
-      this.updateWidgetDirectly(formId, dataWithoutImage, 0);
-
-      // 处理本地图片文件
-      const fileName = await this.processLocalImageFile(localFileUri);
-
-      if (fileName) {
-        try {
-          // 按照官方文档要求,准备 formImages 和文件描述符
-          const imageMap: Record<string, number> = {};
-          const fileDescriptor = await this.getImageFileDescriptor(fileName);
-          imageMap[fileName] = fileDescriptor;
-
-          // 按照官方文档要求,imgName 必须与 formImages 中的 key 相同
-          const dataWithImage: ExtendedWidgetData = copyWidgetData(adaptedData, {
-            coverImage: '', // 清空原路径
-            imgName: fileName, // 设置图片名称用于 memory:// 协议
-            formImages: imageMap  // 必填字段,不可缺省
-          });
-
-          const formDataWithImage = formBindingData.createFormBindingData(dataWithImage);
-          await formProvider.updateForm(formId, formDataWithImage);
-
-
-        } catch (fdError) {
-          hilog.error(0x0000, TAG, `Heanup widget ${formId} failed to get file descriptor: ${fdError}`);
-          // 文件描述符获取失败,使用默认图片
-          this.updateWidgetDirectly(formId, dataWithoutImage, 0);
-        }
-      } else {
-        hilog.warn(0x0000, TAG, `Heanup widget ${formId} failed to process local image, using default`);
-        // 图片处理失败,使用默认图片
-        this.updateWidgetDirectly(formId, dataWithoutImage, 0);
-      }
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Heanup widget ${formId} local image update error: ${error}`);
-
-      // 失败后回退到无图片模式
-      const dataWithoutImage: ExtendedWidgetData = copyWidgetData(adaptedData, {
-        coverImage: '',
-        imgName: '',
-        formImages: undefined
-      });
-      this.updateWidgetDirectly(formId, dataWithoutImage, retryCount);
-    }
-  }
-
-  /**
-   * 使用网络图片更新卡片
-   */
-  private async updateWidgetWithNetworkImage(formId: string, adaptedData: ExtendedWidgetData,
-    retryCount: number = 0): Promise<void> {
-    try {
-      const imageUrl: string = adaptedData.coverImage;
-
-
-      // 先用无图片的数据快速更新一次
-      const dataWithoutImage: ExtendedWidgetData = copyWidgetData(adaptedData, { coverImage: '' });
-      this.updateWidgetDirectly(formId, dataWithoutImage, 0);
-
-      // 下载图片
-      const fileName = await this.downloadNetworkImage(imageUrl);
-
-      if (fileName) {
-        // 准备包含图片的数据
-        const imageMap: Record<string, number> = {};
-        imageMap[fileName] = await this.getImageFileDescriptor(fileName);
-
-        const dataWithImage: ExtendedWidgetData = copyWidgetData(adaptedData, {
-          coverImage: '', // 清空URL
-          imgName: fileName, // 设置图片名称用于memory://协议
-          formImages: imageMap
-        });
-
-        const formDataWithImage = formBindingData.createFormBindingData(dataWithImage);
-        await formProvider.updateForm(formId, formDataWithImage);
-
-
-      } else {
-        hilog.warn(0x0000, TAG, `Heanup widget ${formId} failed to download image, using default`);
-        // 图片下载失败,使用默认图片
-        this.updateWidgetDirectly(formId, dataWithoutImage, 0);
-      }
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Heanup widget ${formId} network image update error: ${error}`);
-
-      // 失败后回退到无图片模式
-      const dataWithoutImage: ExtendedWidgetData = copyWidgetData(adaptedData, { coverImage: '' });
-      this.updateWidgetDirectly(formId, dataWithoutImage, retryCount);
-    }
-  }
-
-  /**
-   * 检查是否为网络URL
-   */
-  private isNetworkUrl(url: string): boolean {
-    return url.startsWith('http://') || url.startsWith('https://');
-  }
-
-  /**
-   * 检查是否为本地文件URI
-   */
-  private isLocalFileUri(url: string): boolean {
-    return url.startsWith('file://');
-  }
-
-  /**
-   * 处理本地图片文件,将其复制到卡片可访问的临时目录
-   */
-  private async processLocalImageFile(fileUri: string): Promise<string | null> {
-    try {
-
-
-      // 检查缓存
-      if (this.imageCache.has(fileUri)) {
-        const fileName = this.imageCache.get(fileUri)!;
-
-
-        // 验证缓存文件是否仍然存在 - 使用 FormExtensionAbility 的 tempDir
-        const formTempDir = this.context.getApplicationContext().tempDir;
-        const tempFilePath = `${formTempDir}/${fileName}`;
-        if (fileIo.accessSync(tempFilePath)) {
-          return fileName;
-        } else {
-          // 缓存文件已不存在,清除缓存记录
-          this.imageCache.delete(fileUri);
-          hilog.warn(0x0000, TAG, `Cached file no longer exists, will reprocess: ${fileName}`);
-        }
-      }
-
-      // 检查是否正在处理
-      if (this.downloadingImages.has(fileUri)) {
-
-        const existingPromise = this.downloadingImages.get(fileUri);
-        if (existingPromise) {
-          return await existingPromise;
-        }
-      }
-
-      // 开始处理本地文件
-      const processPromise = this.performLocalImageCopy(fileUri);
-      this.downloadingImages.set(fileUri, processPromise);
-
-      const fileName = await processPromise;
-
-      // 清理处理状态
-      this.downloadingImages.delete(fileUri);
-
-      if (fileName) {
-        this.imageCache.set(fileUri, fileName);
-
-      }
-
-      return fileName;
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to process local image ${fileUri}: ${error}`);
-      this.downloadingImages.delete(fileUri);
-      return null;
-    }
-  }
-
-  /**
-   * 执行本地图片文件复制
-   */
-  private async performLocalImageCopy(fileUri: string): Promise<string | null> {
-    try {
-
-
-      // 转换 file:// URI 为实际文件路径
-      const realPath = fileUri.replace('file://', '');
-
-      // 检查源文件是否存在
-      if (!fileIo.accessSync(realPath)) {
-        hilog.error(0x0000, TAG, `Source image file does not exist: ${realPath}`);
-        return null;
-      }
-
-      // 生成目标文件名(包含时间戳和随机数,确保每次都不同)
-      const fileExtension = this.getFileExtension(realPath) || 'jpg';
-      const fileName = `widget_local_${Date.now()}_${Math.random().toString(36).substr(2, 9)}.${fileExtension}`;
-
-      // 使用 FormExtensionAbility 的 tempDir(官方文档要求)
-      const formTempDir = this.context.getApplicationContext().tempDir;
-      const tempFilePath = `${formTempDir}/${fileName}`;
-
-
-      // 复制文件到临时目录
-      fileIo.copyFileSync(realPath, tempFilePath);
-
-
-      return fileName;
-
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to copy local image: ${error}`);
-      return null;
-    }
-  }
-
-  /**
-   * 获取文件扩展名
-   */
-  private getFileExtension(filePath: string): string | null {
-    const lastDotIndex = filePath.lastIndexOf('.');
-    if (lastDotIndex === -1 || lastDotIndex === filePath.length - 1) {
-      return null;
-    }
-    return filePath.substring(lastDotIndex + 1).toLowerCase();
-  }
-
-  /**
-   * 下载网络图片
-   */
-  private async downloadNetworkImage(imageUrl: string): Promise<string | null> {
-    try {
-      // 检查缓存
-      if (this.imageCache.has(imageUrl)) {
-        const fileName = this.imageCache.get(imageUrl)!;
-
-        return fileName;
-      }
-
-      // 检查是否正在下载
-      if (this.downloadingImages.has(imageUrl)) {
-
-        const existingPromise = this.downloadingImages.get(imageUrl);
-        if (existingPromise) {
-          return await existingPromise;
-        }
-      }
-
-      // 开始下载
-      const downloadPromise = this.performImageDownload(imageUrl);
-      this.downloadingImages.set(imageUrl, downloadPromise);
-
-      const fileName = await downloadPromise;
-
-      // 清理下载状态
-      this.downloadingImages.delete(imageUrl);
-
-      if (fileName) {
-        this.imageCache.set(imageUrl, fileName);
-      }
-
-      return fileName;
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to download image ${imageUrl}: ${error}`);
-      this.downloadingImages.delete(imageUrl);
-      return null;
-    }
-  }
-
-  /**
-   * 执行图片下载
-   */
-  private async performImageDownload(imageUrl: string): Promise<string | null> {
-    try {
-      // 创建HTTP请求
-      const httpRequest = http.createHttp();
-
-      // 设置超时时间为3秒,适合卡片的快速响应需求
-      const response = await httpRequest.request(imageUrl, {
-        method: http.RequestMethod.GET,
-        expectDataType: http.HttpDataType.ARRAY_BUFFER,
-        connectTimeout: 3000,
-        readTimeout: 3000
-      });
-
-      if (response.responseCode === http.ResponseCode.OK && response.result) {
-        // 生成文件名(确保每次都不同,符合官方文档要求)
-        const fileName = `widget_cover_${Date.now()}_${Math.random().toString(36).substr(2, 9)}.jpg`;
-
-        // 使用 FormExtensionAbility 的 tempDir(官方文档要求)
-        const formTempDir = this.context.getApplicationContext().tempDir;
-        const filePath = `${formTempDir}/${fileName}`;
-
-
-        // 保存文件
-        const file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
-        await fileIo.write(file.fd, response.result as ArrayBuffer);
-        fileIo.closeSync(file);
-
-
-        httpRequest.destroy();
-        return fileName;
-      } else {
-        hilog.error(0x0000, TAG, `HTTP request failed: ${response.responseCode}`);
-        httpRequest.destroy();
-        return null;
-      }
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Download error: ${error}`);
-      return null;
-    }
-  }
-
-  /**
-   * 获取图片文件描述符
-   */
-  private async getImageFileDescriptor(fileName: string): Promise<number> {
-    try {
-      // 使用 FormExtensionAbility 的 tempDir(官方文档要求)
-      const formTempDir = this.context.getApplicationContext().tempDir;
-      const filePath = `${formTempDir}/${fileName}`;
-
-
-      const file = fileIo.openSync(filePath, fileIo.OpenMode.READ_ONLY);
-
-      // 注意:文件描述符会被系统自动管理,不需要手动关闭
-      // 系统会在卡片更新完成后自动关闭文件描述符
-
-      return file.fd;
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to get file descriptor for ${fileName}: ${error}`);
-      throw new Error(`Failed to get file descriptor for ${fileName}: ${error}`);
-    }
-  }
 
   /**
    * 获取默认卡片数据
@@ -796,22 +204,10 @@ implements SizeChangeListener {
   /**
    * 初始化卡片
    */
-  private async initializeWidget(formId: string, widgetSize: WidgetSize): Promise<void> {
+  private async initializeWidget(formId: string): Promise<void> {
     try {
-
-
-      // 获取当前播放状态
-      const currentState = await this.playerControlService.getCurrentPlayState();
-
-
-      // 适配数据到指定尺寸
-      const adaptedData = this.layoutManager.adaptDataForSize(currentState, widgetSize);
-      await this.widgetDataManager?.saveWidgetData(formId, adaptedData);
-
       // 立即更新一次卡片数据
       await this.updateWidgetData(formId);
-
-
     } catch (error) {
       hilog.error(0x0000, TAG, `Failed to initialize widget ${formId}: ${error}`);
     }
@@ -822,13 +218,8 @@ implements SizeChangeListener {
    */
   private async updateWidgetData(formId: string): Promise<void> {
     try {
-      const currentState = await this.playerControlService.getCurrentPlayState();
-
-      // 获取卡片当前尺寸
-      const currentSize = this.globalWidgetManager.getWidgetSize(formId) || WidgetSize.MEDIUM;
-
       // 适配数据到当前尺寸并直接更新
-      const adaptedData = this.layoutManager.adaptDataForSize(currentState, currentSize);
+      const adaptedData = this.buildWidgetData();
       const formData = formBindingData.createFormBindingData(adaptedData);
       await formProvider.updateForm(formId, formData);
 
@@ -838,28 +229,10 @@ implements SizeChangeListener {
     }
   }
 
-
-  /**
-   * 处理表单尺寸变化
-   */
-  private async handleFormSizeChange(formId: string, oldSize: WidgetSize, newSize: WidgetSize): Promise<void> {
-    try {
-
-
-      // 获取当前播放状态
-      const currentState = await this.playerControlService.getCurrentPlayState();
-
-      // 使用适配器处理尺寸变化
-      const adaptedData = this.sizeAdapter.handleSizeChange(formId, oldSize, newSize, currentState);
-
-      // 更新卡片数据
-      await this.widgetDataManager?.updateWidget(formId, adaptedData);
-
-
-    } catch (error) {
-      hilog.error(0x0000, TAG, `Failed to handle form size change: ${error}`);
-    }
-  }
+  private buildWidgetData():VideoItem{
+    let currentSong=this.unifiedPlayerService.getCurrentSong() as VideoItem;
+		return currentSong;
+	}
 
 
   /**

+ 2 - 55
entry/src/main/ets/view/LocalMusic.ets

@@ -37,16 +37,9 @@ import { effectKit } from '@kit.ArkGraphics2D';
 import { ColorConversion } from '../common/util/ColorConversion';
 import { LyricController, LyricParser, LyricView2 } from '@seagazer/cclyric';
 import { AvSessionController } from '../controller/AvSessionController';
-import { AvSessionWidgetListener } from '../common/widget/AvSessionWidgetListener';
-import { WidgetData, PlayProgress, PlayState, SongInfo, PlaylistState, PlayerStateBroadcastData } from '../common/widget/WidgetTypes';
+import { WidgetData, PlayProgress } from '../common/widget/WidgetTypes';
 import { PlayerStateListener, PlayerState, PlayerError } from '../common/service/PlayerStateModel';
-import {
-  WIDGET_CONTROL_EVENT,
-  WIDGET_REQUEST_STATE_EVENT,
-  PLAYER_STATE_CHANGED_EVENT,
-  PLAYER_SONG_CHANGED_EVENT,
-  PLAYER_PROGRESS_CHANGED_EVENT
-} from '../common/widget/WidgetEventConstants';
+
 import {
   IjkMediaPlayer,
   // DeviceChangeReason,
@@ -557,8 +550,6 @@ export struct LocalMusic {
           // 同步进度更新到UI
           this.localMusic.syncProgressFromService(progress);
 
-          // 广播进度更新到卡片
-          this.localMusic.broadcastProgressIfNeeded();
         }
 
         onError(error: PlayerError): void {
@@ -6816,7 +6807,6 @@ export struct LocalMusic {
   eventHub = getContext().eventHub;
   //投播组件
   private avSessionController: AvSessionController = AvSessionController.getInstance(false);
-  private avSessionWidgetListener: AvSessionWidgetListener = AvSessionWidgetListener.getInstance();
   private castController: avSession.AVCastController | undefined = undefined;
   @State isCastPlaying: boolean = false;
   @State isCasting: boolean = false; // 是否正在投播中
@@ -10774,7 +10764,6 @@ export struct LocalMusic {
       if (this.isOpenJump && duration > this.jumpEndTime * 1000) {
         if (position >= duration - this.jumpEndTime * 1000) {
           this.playNext()
-          this.broadcastProgressIfNeeded();
         }
       }
 
@@ -12585,48 +12574,6 @@ export struct LocalMusic {
     // this.status = "广告加载中..."
   }
 
-  /**
-   * 节流广播进度更新
-   */
-  private broadcastProgressIfNeeded(): void {
-    const now = Date.now();
-    if (now - this.lastProgressBroadcastTime >= this.PROGRESS_BROADCAST_INTERVAL) {
-      this.lastProgressBroadcastTime = now;
-      this.broadcastPlayerProgress();
-    }
-  }
-
-  /**
-   * 广播播放进度到卡片
-   */
-  private broadcastPlayerProgress(): void {
-    try {
-      const currentPos: number = this.unifiedPlayerService.getCurrentPosition() || 0;
-      const progressData: PlayProgress = {
-        currentPosition: currentPos,
-        duration: this.duration || 0,
-        percentage: this.duration > 0 ? (currentPos / this.duration) * 100 : 0,
-        currentTimeText: this.currentTime || '00:00',
-        totalTimeText: this.totalTime || '00:00'
-      };
-
-      // 广播播放进度变化
-      const publishInfo: commonEventManager.CommonEventPublishData = {
-        data: JSON.stringify(progressData)
-      };
-
-      commonEventManager.publish(PLAYER_PROGRESS_CHANGED_EVENT, publishInfo, (err) => {
-        if (err) {
-          LogUtils.getInstance().error(`Failed to broadcast player progress: ${JSON.stringify(err)}`);
-        } else {
-          LogUtils.getInstance().LOGI(`Progress broadcasted: ${progressData.percentage.toFixed(1)}%`);
-        }
-      });
-    } catch (error) {
-      LogUtils.getInstance().error(`Failed to broadcast player progress: ${error}`);
-    }
-  }
-
 
 }
 

+ 179 - 168
entry/src/main/ets/widget/pages/PlayerWidgetMedium.ets

@@ -48,6 +48,184 @@ struct PlayerWidgetMedium {
   @LocalStorageProp('imageColorHex') imageColorHex: string = '2A2A2A';
   @LocalStorageProp('imgName') imgName: string = ''; // 图片文件名,用于memory://协议
 
+  build() {
+    Stack() {
+      // 背景和主要内容
+      RelativeContainer() {
+        // 歌曲标题
+        Text(this.getDisplayTitle())
+          .fontSize(16)
+          .fontWeight(FontWeight.Bold)
+          .width('60%')
+          .fontColor(Color.White)
+          .textOverflow({ overflow: TextOverflow.Ellipsis })
+          .maxLines(1)
+          .alignRules(MediumTitleAlignRules)
+          .margin({ left: 16, top: 8 })
+          .id('musicTitle')
+
+        // 艺术家名称
+        Text(this.getDisplayArtist())
+          .fontSize(12)
+          .fontColor('#CCFFFFFF')
+          .fontWeight(FontWeight.Normal)
+          .maxLines(1)
+          .alignRules(MediumSingerAlignRules)
+          .margin({ left: 16, top: 2 })
+          .id('singerText')
+
+        // 专辑封面
+        Stack({ alignContent: Alignment.Center }) {
+          // 黑胶唱片背景
+          Image($r('app.media.ic_music_bg_mini'))
+            .height(88)
+            .width(88)
+
+          // 专辑封面
+          Button()
+            .backgroundImage(this.getCoverImage())
+            .backgroundImageSize(ImageSize.Cover)
+            .height(58)
+            .width(58)
+            .borderRadius(29)
+        }
+        .alignRules(MediumCoverAlignRules)
+        .id('musicCover')
+        .onClick(() => {
+          postCardAction(this, {
+            'action': 'router',
+            'abilityName': 'EntryAbility'
+          });
+        })
+
+        // 播放控制按钮区域
+        Row() {
+          // 上一首按钮
+          Button() {
+            SymbolGlyph($r('sys.symbol.backward_end_fill'))
+              .fontSize(36)
+              .fontColor(['#E5FFFFFF'])
+          }
+          .width(40)
+          .height(40)
+          .backgroundColor(Color.Transparent)
+          .opacity(this.hasPrevious ? 1.0 : 0.5)
+          .onClick((event: ClickEvent) => {
+            console.info(`Heanup PlayerWidgetMedium: Previous button clicked`);
+            if (!this.isLoading && this.hasPrevious) {
+              postCardAction(this, {
+                'action': 'call',
+                'abilityName': 'EntryAbility',
+                'params': {
+                  'formId': this.formId,
+                  'method': 'prevSong'
+                }
+              });
+            }
+          })
+
+          // 播放/暂停按钮
+          Button() {
+            SymbolGlyph(this.isPlaying ? $r('sys.symbol.pause_round_triangle_fill') :
+            $r('sys.symbol.play_round_triangle_fill'))
+              .fontSize(36)
+              .symbolEffect(new ReplaceSymbolEffect(EffectScope.WHOLE), true)
+              .fontColor(['#E5FFFFFF'])
+          }
+          .width(48)
+          .height(48)
+          .backgroundColor(Color.Transparent)
+          .margin({ left: 20, right: 20 })
+          .onClick((event: ClickEvent) => {
+            console.info('Heanup PlayerWidgetMedium: Play/Pause button clicked');
+            if (!this.isLoading) {
+              postCardAction(this, {
+                'action': 'call',
+                'abilityName': 'EntryAbility',
+                'params': {
+                  'formId': this.formId,
+                  'method': 'playPause',
+                  'widgetIsPlaying': this.isPlaying // 传递卡片当前显示的播放状态
+                }
+              });
+            }
+          })
+
+          // 下一首按钮
+          Button() {
+            SymbolGlyph($r('sys.symbol.forward_end_fill'))
+              .fontSize(36)
+              .fontColor(['#E5FFFFFF'])
+          }
+          .width(40)
+          .height(40)
+          .backgroundColor(Color.Transparent)
+          .opacity(this.hasNext ? 1.0 : 0.5)
+          .onClick((event: ClickEvent) => {
+            console.info(`Heanup PlayerWidgetMedium: Next button clicked`);
+            if (!this.isLoading && this.hasNext) {
+              postCardAction(this, {
+                'action': 'call',
+                'abilityName': 'EntryAbility',
+                'params': {
+                  'formId': this.formId,
+                  'method': 'nextSong'
+                }
+              });
+            }
+          })
+        }
+        .width('100%')
+        .justifyContent(FlexAlign.Center)
+        .alignRules(MediumPlayControlAlignRules)
+        .id('playControls')
+      }
+      .height('100%')
+      .width('100%')
+      .padding(12)
+      .backgroundImage(this.getCoverImage())
+      .backgroundBlurStyle(BlurStyle.BACKGROUND_ULTRA_THICK)
+      .backgroundImageSize(ImageSize.Cover)
+      .onClick(() => {
+        console.info('Heanup PlayerWidgetMedium: Container clicked, jumping to main app');
+        postCardAction(this, {
+          'action': 'router',
+          'abilityName': 'EntryAbility'
+        });
+      })
+
+      // 收藏按钮放在Stack顶层,确保可以正常点击
+      Button() {
+        SymbolGlyph(this.isFavorite ? $r('sys.symbol.heart_fill') : $r('sys.symbol.heart'))
+          .fontSize(24)
+          .symbolEffect(new ReplaceSymbolEffect(EffectScope.WHOLE), true)
+          .fontColor(['#E5FFFFFF'])
+      }
+      .width(40)
+      .height(40)
+      .backgroundColor(Color.Transparent)
+      .onClick((event: ClickEvent) => {
+        console.info(`Heanup PlayerWidgetMedium: Favorite button clicked`);
+        postCardAction(this, {
+          'action': 'call',
+          'abilityName': 'EntryAbility',
+          'params': {
+            'formId': this.formId,
+            'method': 'toggleFavorite'
+          }
+        });
+      })
+      .position({
+        x: '100%',
+        y: 0
+      })
+      .translate({ x: -52, y: 12 }) // 调整到右上角位置
+    }
+    .height('100%')
+    .width('100%')
+  }
+
+
   /**
    * 格式化歌曲标题显示
    */
@@ -67,6 +245,7 @@ struct PlayerWidgetMedium {
     }
     return this.songArtist;
   }
+
   /**
    * 检查是否为网络URL
    */
@@ -97,172 +276,4 @@ struct PlayerWidgetMedium {
     console.info(`Heanup PlayerWidgetSquare: Using default cover image`);
     return $r('app.media.ic_avatar4'); // 使用默认专辑封面
   }
-
-  build() {
-    RelativeContainer() {
-      // 收藏按钮
-      Button() {
-        SymbolGlyph(this.isFavorite ? $r('sys.symbol.heart_fill') : $r('sys.symbol.heart'))
-          .fontSize(24)
-          .symbolEffect(new ReplaceSymbolEffect(EffectScope.WHOLE), true)
-          .fontColor(['#E5FFFFFF'])
-      }
-      .width(40)
-      .height(40)
-      .backgroundColor(Color.Transparent)
-      .alignRules(MediumCollectAlignRules)
-      .onClick(() => {
-        console.info(`Heanup PlayerWidgetMedium: Favorite button clicked`);
-        if (!this.isLoading) {
-          postCardAction(this, {
-            'action': 'call',
-            'abilityName': 'EntryAbility',
-            'params': {
-              'formId': this.formId,
-              'method': 'toggleFavorite'
-            }
-          });
-        }
-      })
-      // 歌曲标题
-      Text(this.getDisplayTitle())
-        .fontSize(16)
-        .fontWeight(FontWeight.Bold)
-        .width('60%')
-        .fontColor(Color.White)
-        .textOverflow({ overflow: TextOverflow.Ellipsis })
-        .maxLines(1)
-        .alignRules(MediumTitleAlignRules)
-        .margin({ left: 16, top: 8 })
-        .id('musicTitle')
-
-      // 艺术家名称
-      Text(this.getDisplayArtist())
-        .fontSize(12)
-        .fontColor('#CCFFFFFF')
-        .fontWeight(FontWeight.Normal)
-        .maxLines(1)
-        .alignRules(MediumSingerAlignRules)
-        .margin({ left: 16, top: 2 })
-        .id('singerText')
-
-      // 专辑封面
-      Stack({ alignContent: Alignment.Center }) {
-        // 黑胶唱片背景
-        Image($r('app.media.ic_music_bg_mini'))
-          .height(88)
-          .width(88)
-        
-        // 专辑封面
-        Button()
-          .backgroundImage(this.getCoverImage())
-          .backgroundImageSize(ImageSize.Cover)
-          .height(58)
-          .width(58)
-          .borderRadius(29)
-      }
-      .alignRules(MediumCoverAlignRules)
-      .id('musicCover')
-      .onClick(() => {
-        postCardAction(this, {
-          'action': 'router',
-          'abilityName': 'EntryAbility'
-        });
-      })
-
-      // 播放控制按钮区域
-      Row() {
-        // 上一首按钮
-        Button() {
-          SymbolGlyph($r('sys.symbol.backward_end_fill'))
-            .fontSize(36)
-            .fontColor(['#E5FFFFFF'])
-        }
-        .width(40)
-        .height(40)
-        .backgroundColor(Color.Transparent)
-        .opacity(this.hasPrevious ? 1.0 : 0.5)
-        .onClick(() => {
-          console.info(`Heanup PlayerWidgetMedium: Previous button clicked`);
-          if (!this.isLoading && this.hasPrevious) {
-            postCardAction(this, {
-              'action': 'call',
-              'abilityName': 'EntryAbility',
-              'params': {
-                'formId': this.formId,
-                'method': 'prevSong'
-              }
-            });
-          }
-        })
-
-        // 播放/暂停按钮
-        Button() {
-          SymbolGlyph(this.isPlaying ? $r('sys.symbol.pause_round_triangle_fill') : $r('sys.symbol.play_round_triangle_fill'))
-            .fontSize(36)
-            .symbolEffect(new ReplaceSymbolEffect(EffectScope.WHOLE), true)
-            .fontColor(['#E5FFFFFF'])
-        }
-        .width(48)
-        .height(48)
-        .backgroundColor(Color.Transparent)
-        .margin({ left: 20, right: 20 })
-        .onClick(() => {
-          console.info('Heanup PlayerWidgetMedium: Play/Pause button clicked');
-          if (!this.isLoading) {
-            postCardAction(this, {
-              'action': 'call',
-              'abilityName': 'EntryAbility',
-              'params': {
-                'formId': this.formId,
-                'method': 'playPause',
-                'widgetIsPlaying': this.isPlaying // 传递卡片当前显示的播放状态
-              }
-            });
-          }
-        })
-
-        // 下一首按钮
-        Button() {
-          SymbolGlyph($r('sys.symbol.forward_end_fill'))
-            .fontSize(36)
-            .fontColor(['#E5FFFFFF'])
-        }
-        .width(40)
-        .height(40)
-        .backgroundColor(Color.Transparent)
-        .opacity(this.hasNext ? 1.0 : 0.5)
-        .onClick(() => {
-          console.info(`Heanup PlayerWidgetMedium: Next button clicked`);
-          if (!this.isLoading && this.hasNext) {
-            postCardAction(this, {
-              'action': 'call',
-              'abilityName': 'EntryAbility',
-              'params': {
-                'formId': this.formId,
-                'method': 'nextSong'
-              }
-            });
-          }
-        })
-      }
-      .width('100%')
-      .justifyContent(FlexAlign.Center)
-      .alignRules(MediumPlayControlAlignRules)
-      .id('playControls')
-    }
-    .height('100%')
-    .width('100%')
-    .padding(12)
-    .backgroundImage(this.getCoverImage())
-    .backgroundBlurStyle(BlurStyle.BACKGROUND_ULTRA_THICK)
-    .backgroundImageSize(ImageSize.Cover)
-    .onClick(() => {
-      console.info('Heanup PlayerWidgetMedium: Container clicked, jumping to main app');
-      postCardAction(this, {
-        'action': 'router',
-        'abilityName': 'EntryAbility'
-      });
-    })
-  }
 }