4141import android .os .Binder ;
4242import android .os .Bundle ;
4343import android .os .Environment ;
44+ import android .os .Handler ;
45+ import android .os .HandlerThread ;
4446import android .os .IBinder ;
47+ import android .os .Looper ;
4548import android .os .Process ;
4649import android .os .RemoteException ;
4750import android .os .SystemClock ;
@@ -180,15 +183,18 @@ public void disconnect() {
180183 boolean mStateLoaded ;
181184 int mMaxWidgetBitmapMemory ;
182185
186+ private final Handler mSaveStateHandler ;
187+
183188 // These are for debugging only -- widgets are going missing in some rare instances
184189 ArrayList <Provider > mDeletedProviders = new ArrayList <Provider >();
185190 ArrayList <Host > mDeletedHosts = new ArrayList <Host >();
186191
187- AppWidgetServiceImpl (Context context , int userId ) {
192+ AppWidgetServiceImpl (Context context , int userId , Handler saveStateHandler ) {
188193 mContext = context ;
189194 mPm = AppGlobals .getPackageManager ();
190195 mAlarmManager = (AlarmManager ) mContext .getSystemService (Context .ALARM_SERVICE );
191196 mUserId = userId ;
197+ mSaveStateHandler = saveStateHandler ;
192198 computeMaximumWidgetBitmapMemory ();
193199 }
194200
@@ -236,7 +242,7 @@ void onConfigurationChanged() {
236242 updateProvidersForPackageLocked (cn .getPackageName (), removedProviders );
237243 }
238244 }
239- saveStateLocked ();
245+ saveStateAsync ();
240246 }
241247 }
242248 }
@@ -286,7 +292,7 @@ void onBroadcastReceived(Intent intent) {
286292 providersModified |= addProvidersForPackageLocked (pkgName );
287293 }
288294 }
289- saveStateLocked ();
295+ saveStateAsync ();
290296 }
291297 } else {
292298 Bundle extras = intent .getExtras ();
@@ -297,7 +303,7 @@ void onBroadcastReceived(Intent intent) {
297303 ensureStateLoadedLocked ();
298304 for (String pkgName : pkgList ) {
299305 providersModified |= removeProvidersForPackageLocked (pkgName );
300- saveStateLocked ();
306+ saveStateAsync ();
301307 }
302308 }
303309 }
@@ -410,7 +416,7 @@ void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
410416
411417 private void ensureStateLoadedLocked () {
412418 if (!mStateLoaded ) {
413- loadAppWidgetList ();
419+ loadAppWidgetListLocked ();
414420 loadStateLocked ();
415421 mStateLoaded = true ;
416422 }
@@ -431,7 +437,7 @@ public int allocateAppWidgetId(String packageName, int hostId) {
431437 host .instances .add (id );
432438 mAppWidgetIds .add (id );
433439
434- saveStateLocked ();
440+ saveStateAsync ();
435441 if (DBG ) log ("Allocating AppWidgetId for " + packageName + " host=" + hostId
436442 + " id=" + appWidgetId );
437443 return appWidgetId ;
@@ -444,7 +450,7 @@ public void deleteAppWidgetId(int appWidgetId) {
444450 AppWidgetId id = lookupAppWidgetIdLocked (appWidgetId );
445451 if (id != null ) {
446452 deleteAppWidgetLocked (id );
447- saveStateLocked ();
453+ saveStateAsync ();
448454 }
449455 }
450456 }
@@ -456,7 +462,7 @@ public void deleteHost(int hostId) {
456462 Host host = lookupHostLocked (callingUid , hostId );
457463 if (host != null ) {
458464 deleteHostLocked (host );
459- saveStateLocked ();
465+ saveStateAsync ();
460466 }
461467 }
462468 }
@@ -475,7 +481,7 @@ public void deleteAllHosts() {
475481 }
476482 }
477483 if (changed ) {
478- saveStateLocked ();
484+ saveStateAsync ();
479485 }
480486 }
481487 }
@@ -591,7 +597,7 @@ private void bindAppWidgetIdImpl(int appWidgetId, ComponentName provider, Bundle
591597
592598 // schedule the future updates
593599 registerForBroadcastsLocked (p , getAppWidgetIds (p ));
594- saveStateLocked ();
600+ saveStateAsync ();
595601 }
596602 } finally {
597603 Binder .restoreCallingIdentity (ident );
@@ -655,8 +661,8 @@ public void setBindAppWidgetPermission(String packageName, boolean permission) {
655661 } else {
656662 mPackagesWithBindWidgetPermission .remove (packageName );
657663 }
664+ saveStateAsync ();
658665 }
659- saveStateLocked ();
660666 }
661667
662668 // Binds to a specific RemoteViewsService
@@ -893,6 +899,20 @@ public void updateAppWidgetIds(int[] appWidgetIds, RemoteViews views) {
893899 }
894900 }
895901
902+ private void saveStateAsync () {
903+ mSaveStateHandler .post (mSaveStateRunnable );
904+ }
905+
906+ private final Runnable mSaveStateRunnable = new Runnable () {
907+ @ Override
908+ public void run () {
909+ synchronized (mAppWidgetIds ) {
910+ ensureStateLoadedLocked ();
911+ saveStateLocked ();
912+ }
913+ }
914+ };
915+
896916 public void updateAppWidgetOptions (int appWidgetId , Bundle options ) {
897917 synchronized (mAppWidgetIds ) {
898918 options = cloneIfLocalBinder (options );
@@ -913,7 +933,7 @@ public void updateAppWidgetOptions(int appWidgetId, Bundle options) {
913933 intent .putExtra (AppWidgetManager .EXTRA_APPWIDGET_ID , id .appWidgetId );
914934 intent .putExtra (AppWidgetManager .EXTRA_APPWIDGET_OPTIONS , id .options );
915935 mContext .sendBroadcastAsUser (intent , new UserHandle (mUserId ));
916- saveStateLocked ();
936+ saveStateAsync ();
917937 }
918938 }
919939
@@ -1214,7 +1234,7 @@ void pruneHostLocked(Host host) {
12141234 }
12151235 }
12161236
1217- void loadAppWidgetList () {
1237+ void loadAppWidgetListLocked () {
12181238 Intent intent = new Intent (AppWidgetManager .ACTION_APPWIDGET_UPDATE );
12191239 try {
12201240 List <ResolveInfo > broadcastReceivers = mPm .queryIntentReceivers (intent ,
0 commit comments