Merge "Pushing state persistence to a background thread" into jb-mr1.1-dev
This commit is contained in:
@ -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);
|
||||
|
@ -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,
|
||||
|
Reference in New Issue
Block a user