diff options
author | Adam Cohen <adamcohen@google.com> | 2012-11-01 14:06:16 -0700 |
---|---|---|
committer | Adam Cohen <adamcohen@google.com> | 2012-11-15 13:44:34 -0800 |
commit | a1a2f967e2a0de4c4190a775ac314ad32288727e (patch) | |
tree | f8b6ac2a07d96e4ef108d7a84de3f980894cf1a0 | |
parent | df2670f162dc7756899f4036750ba6866f5326c6 (diff) | |
download | frameworks_base-a1a2f967e2a0de4c4190a775ac314ad32288727e.zip frameworks_base-a1a2f967e2a0de4c4190a775ac314ad32288727e.tar.gz frameworks_base-a1a2f967e2a0de4c4190a775ac314ad32288727e.tar.bz2 |
Pushing state persistence to a background thread
Change-Id: If776bc22c48525ba91dc7e4dd0e27de92612f2f5
-rw-r--r-- | services/java/com/android/server/AppWidgetService.java | 12 | ||||
-rw-r--r-- | services/java/com/android/server/AppWidgetServiceImpl.java | 46 |
2 files changed, 43 insertions, 15 deletions
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java index 06d37dc..532b36a 100644 --- a/services/java/com/android/server/AppWidgetService.java +++ b/services/java/com/android/server/AppWidgetService.java @@ -26,6 +26,8 @@ import android.content.IntentFilter; import android.content.pm.PackageManager; import android.os.Binder; import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerThread; import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; @@ -54,13 +56,19 @@ class AppWidgetService extends IAppWidgetService.Stub Locale mLocale; PackageManager mPackageManager; boolean mSafeMode; + private final Handler mSaveStateHandler; private final SparseArray<AppWidgetServiceImpl> mAppWidgetServices; AppWidgetService(Context context) { mContext = context; + + HandlerThread handlerThread = new HandlerThread("AppWidgetService -- Save state"); + handlerThread.start(); + mSaveStateHandler = new Handler(handlerThread.getLooper()); + mAppWidgetServices = new SparseArray<AppWidgetServiceImpl>(5); - AppWidgetServiceImpl primary = new AppWidgetServiceImpl(context, 0); + AppWidgetServiceImpl primary = new AppWidgetServiceImpl(context, 0, mSaveStateHandler); mAppWidgetServices.append(0, primary); } @@ -229,7 +237,7 @@ class AppWidgetService extends IAppWidgetService.Stub if (service == null) { Slog.i(TAG, "Unable to find AppWidgetServiceImpl for user " + userId + ", adding"); // TODO: Verify that it's a valid user - service = new AppWidgetServiceImpl(mContext, userId); + service = new AppWidgetServiceImpl(mContext, userId, mSaveStateHandler); service.systemReady(mSafeMode); // Assume that BOOT_COMPLETED was received, as this is a non-primary user. mAppWidgetServices.append(userId, service); diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java index daa82f2..a8611d1 100644 --- a/services/java/com/android/server/AppWidgetServiceImpl.java +++ b/services/java/com/android/server/AppWidgetServiceImpl.java @@ -41,7 +41,10 @@ import android.net.Uri; import android.os.Binder; import android.os.Bundle; import android.os.Environment; +import android.os.Handler; +import android.os.HandlerThread; import android.os.IBinder; +import android.os.Looper; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; @@ -180,15 +183,18 @@ class AppWidgetServiceImpl { boolean mStateLoaded; int mMaxWidgetBitmapMemory; + private final Handler mSaveStateHandler; + // These are for debugging only -- widgets are going missing in some rare instances ArrayList<Provider> mDeletedProviders = new ArrayList<Provider>(); ArrayList<Host> mDeletedHosts = new ArrayList<Host>(); - AppWidgetServiceImpl(Context context, int userId) { + AppWidgetServiceImpl(Context context, int userId, Handler saveStateHandler) { mContext = context; mPm = AppGlobals.getPackageManager(); mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); mUserId = userId; + mSaveStateHandler = saveStateHandler; computeMaximumWidgetBitmapMemory(); } @@ -236,7 +242,7 @@ class AppWidgetServiceImpl { updateProvidersForPackageLocked(cn.getPackageName(), removedProviders); } } - saveStateLocked(); + saveStateAsync(); } } } @@ -286,7 +292,7 @@ class AppWidgetServiceImpl { providersModified |= addProvidersForPackageLocked(pkgName); } } - saveStateLocked(); + saveStateAsync(); } } else { Bundle extras = intent.getExtras(); @@ -297,7 +303,7 @@ class AppWidgetServiceImpl { ensureStateLoadedLocked(); for (String pkgName : pkgList) { providersModified |= removeProvidersForPackageLocked(pkgName); - saveStateLocked(); + saveStateAsync(); } } } @@ -410,7 +416,7 @@ class AppWidgetServiceImpl { private void ensureStateLoadedLocked() { if (!mStateLoaded) { - loadAppWidgetList(); + loadAppWidgetListLocked(); loadStateLocked(); mStateLoaded = true; } @@ -431,7 +437,7 @@ class AppWidgetServiceImpl { host.instances.add(id); mAppWidgetIds.add(id); - saveStateLocked(); + saveStateAsync(); if (DBG) log("Allocating AppWidgetId for " + packageName + " host=" + hostId + " id=" + appWidgetId); return appWidgetId; @@ -444,7 +450,7 @@ class AppWidgetServiceImpl { AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId); if (id != null) { deleteAppWidgetLocked(id); - saveStateLocked(); + saveStateAsync(); } } } @@ -456,7 +462,7 @@ class AppWidgetServiceImpl { Host host = lookupHostLocked(callingUid, hostId); if (host != null) { deleteHostLocked(host); - saveStateLocked(); + saveStateAsync(); } } } @@ -475,7 +481,7 @@ class AppWidgetServiceImpl { } } if (changed) { - saveStateLocked(); + saveStateAsync(); } } } @@ -591,7 +597,7 @@ class AppWidgetServiceImpl { // schedule the future updates registerForBroadcastsLocked(p, getAppWidgetIds(p)); - saveStateLocked(); + saveStateAsync(); } } finally { Binder.restoreCallingIdentity(ident); @@ -655,8 +661,8 @@ class AppWidgetServiceImpl { } else { mPackagesWithBindWidgetPermission.remove(packageName); } + saveStateAsync(); } - saveStateLocked(); } // Binds to a specific RemoteViewsService @@ -893,6 +899,20 @@ class AppWidgetServiceImpl { } } + private void saveStateAsync() { + mSaveStateHandler.post(mSaveStateRunnable); + } + + private final Runnable mSaveStateRunnable = new Runnable() { + @Override + public void run() { + synchronized (mAppWidgetIds) { + ensureStateLoadedLocked(); + saveStateLocked(); + } + } + }; + public void updateAppWidgetOptions(int appWidgetId, Bundle options) { synchronized (mAppWidgetIds) { options = cloneIfLocalBinder(options); @@ -913,7 +933,7 @@ class AppWidgetServiceImpl { intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id.appWidgetId); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, id.options); mContext.sendBroadcastAsUser(intent, new UserHandle(mUserId)); - saveStateLocked(); + saveStateAsync(); } } @@ -1214,7 +1234,7 @@ class AppWidgetServiceImpl { } } - void loadAppWidgetList() { + void loadAppWidgetListLocked() { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); try { List<ResolveInfo> broadcastReceivers = mPm.queryIntentReceivers(intent, |