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.content.pm.PackageManager;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.HandlerThread;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
@@ -54,13 +56,19 @@ class AppWidgetService extends IAppWidgetService.Stub
|
|||||||
Locale mLocale;
|
Locale mLocale;
|
||||||
PackageManager mPackageManager;
|
PackageManager mPackageManager;
|
||||||
boolean mSafeMode;
|
boolean mSafeMode;
|
||||||
|
private final Handler mSaveStateHandler;
|
||||||
|
|
||||||
private final SparseArray<AppWidgetServiceImpl> mAppWidgetServices;
|
private final SparseArray<AppWidgetServiceImpl> mAppWidgetServices;
|
||||||
|
|
||||||
AppWidgetService(Context context) {
|
AppWidgetService(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
|
||||||
|
HandlerThread handlerThread = new HandlerThread("AppWidgetService -- Save state");
|
||||||
|
handlerThread.start();
|
||||||
|
mSaveStateHandler = new Handler(handlerThread.getLooper());
|
||||||
|
|
||||||
mAppWidgetServices = new SparseArray<AppWidgetServiceImpl>(5);
|
mAppWidgetServices = new SparseArray<AppWidgetServiceImpl>(5);
|
||||||
AppWidgetServiceImpl primary = new AppWidgetServiceImpl(context, 0);
|
AppWidgetServiceImpl primary = new AppWidgetServiceImpl(context, 0, mSaveStateHandler);
|
||||||
mAppWidgetServices.append(0, primary);
|
mAppWidgetServices.append(0, primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,7 +237,7 @@ class AppWidgetService extends IAppWidgetService.Stub
|
|||||||
if (service == null) {
|
if (service == null) {
|
||||||
Slog.i(TAG, "Unable to find AppWidgetServiceImpl for user " + userId + ", adding");
|
Slog.i(TAG, "Unable to find AppWidgetServiceImpl for user " + userId + ", adding");
|
||||||
// TODO: Verify that it's a valid user
|
// TODO: Verify that it's a valid user
|
||||||
service = new AppWidgetServiceImpl(mContext, userId);
|
service = new AppWidgetServiceImpl(mContext, userId, mSaveStateHandler);
|
||||||
service.systemReady(mSafeMode);
|
service.systemReady(mSafeMode);
|
||||||
// Assume that BOOT_COMPLETED was received, as this is a non-primary user.
|
// Assume that BOOT_COMPLETED was received, as this is a non-primary user.
|
||||||
mAppWidgetServices.append(userId, service);
|
mAppWidgetServices.append(userId, service);
|
||||||
|
|||||||
@@ -41,7 +41,10 @@ import android.net.Uri;
|
|||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.HandlerThread;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.Looper;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
@@ -180,15 +183,18 @@ class AppWidgetServiceImpl {
|
|||||||
boolean mStateLoaded;
|
boolean mStateLoaded;
|
||||||
int mMaxWidgetBitmapMemory;
|
int mMaxWidgetBitmapMemory;
|
||||||
|
|
||||||
|
private final Handler mSaveStateHandler;
|
||||||
|
|
||||||
// These are for debugging only -- widgets are going missing in some rare instances
|
// These are for debugging only -- widgets are going missing in some rare instances
|
||||||
ArrayList<Provider> mDeletedProviders = new ArrayList<Provider>();
|
ArrayList<Provider> mDeletedProviders = new ArrayList<Provider>();
|
||||||
ArrayList<Host> mDeletedHosts = new ArrayList<Host>();
|
ArrayList<Host> mDeletedHosts = new ArrayList<Host>();
|
||||||
|
|
||||||
AppWidgetServiceImpl(Context context, int userId) {
|
AppWidgetServiceImpl(Context context, int userId, Handler saveStateHandler) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mPm = AppGlobals.getPackageManager();
|
mPm = AppGlobals.getPackageManager();
|
||||||
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
|
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
|
||||||
mUserId = userId;
|
mUserId = userId;
|
||||||
|
mSaveStateHandler = saveStateHandler;
|
||||||
computeMaximumWidgetBitmapMemory();
|
computeMaximumWidgetBitmapMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +242,7 @@ class AppWidgetServiceImpl {
|
|||||||
updateProvidersForPackageLocked(cn.getPackageName(), removedProviders);
|
updateProvidersForPackageLocked(cn.getPackageName(), removedProviders);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
saveStateLocked();
|
saveStateAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -286,7 +292,7 @@ class AppWidgetServiceImpl {
|
|||||||
providersModified |= addProvidersForPackageLocked(pkgName);
|
providersModified |= addProvidersForPackageLocked(pkgName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
saveStateLocked();
|
saveStateAsync();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Bundle extras = intent.getExtras();
|
Bundle extras = intent.getExtras();
|
||||||
@@ -297,7 +303,7 @@ class AppWidgetServiceImpl {
|
|||||||
ensureStateLoadedLocked();
|
ensureStateLoadedLocked();
|
||||||
for (String pkgName : pkgList) {
|
for (String pkgName : pkgList) {
|
||||||
providersModified |= removeProvidersForPackageLocked(pkgName);
|
providersModified |= removeProvidersForPackageLocked(pkgName);
|
||||||
saveStateLocked();
|
saveStateAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -410,7 +416,7 @@ class AppWidgetServiceImpl {
|
|||||||
|
|
||||||
private void ensureStateLoadedLocked() {
|
private void ensureStateLoadedLocked() {
|
||||||
if (!mStateLoaded) {
|
if (!mStateLoaded) {
|
||||||
loadAppWidgetList();
|
loadAppWidgetListLocked();
|
||||||
loadStateLocked();
|
loadStateLocked();
|
||||||
mStateLoaded = true;
|
mStateLoaded = true;
|
||||||
}
|
}
|
||||||
@@ -431,7 +437,7 @@ class AppWidgetServiceImpl {
|
|||||||
host.instances.add(id);
|
host.instances.add(id);
|
||||||
mAppWidgetIds.add(id);
|
mAppWidgetIds.add(id);
|
||||||
|
|
||||||
saveStateLocked();
|
saveStateAsync();
|
||||||
if (DBG) log("Allocating AppWidgetId for " + packageName + " host=" + hostId
|
if (DBG) log("Allocating AppWidgetId for " + packageName + " host=" + hostId
|
||||||
+ " id=" + appWidgetId);
|
+ " id=" + appWidgetId);
|
||||||
return appWidgetId;
|
return appWidgetId;
|
||||||
@@ -444,7 +450,7 @@ class AppWidgetServiceImpl {
|
|||||||
AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
|
AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
deleteAppWidgetLocked(id);
|
deleteAppWidgetLocked(id);
|
||||||
saveStateLocked();
|
saveStateAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -456,7 +462,7 @@ class AppWidgetServiceImpl {
|
|||||||
Host host = lookupHostLocked(callingUid, hostId);
|
Host host = lookupHostLocked(callingUid, hostId);
|
||||||
if (host != null) {
|
if (host != null) {
|
||||||
deleteHostLocked(host);
|
deleteHostLocked(host);
|
||||||
saveStateLocked();
|
saveStateAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -475,7 +481,7 @@ class AppWidgetServiceImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
saveStateLocked();
|
saveStateAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -591,7 +597,7 @@ class AppWidgetServiceImpl {
|
|||||||
|
|
||||||
// schedule the future updates
|
// schedule the future updates
|
||||||
registerForBroadcastsLocked(p, getAppWidgetIds(p));
|
registerForBroadcastsLocked(p, getAppWidgetIds(p));
|
||||||
saveStateLocked();
|
saveStateAsync();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
Binder.restoreCallingIdentity(ident);
|
Binder.restoreCallingIdentity(ident);
|
||||||
@@ -655,8 +661,8 @@ class AppWidgetServiceImpl {
|
|||||||
} else {
|
} else {
|
||||||
mPackagesWithBindWidgetPermission.remove(packageName);
|
mPackagesWithBindWidgetPermission.remove(packageName);
|
||||||
}
|
}
|
||||||
|
saveStateAsync();
|
||||||
}
|
}
|
||||||
saveStateLocked();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Binds to a specific RemoteViewsService
|
// 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) {
|
public void updateAppWidgetOptions(int appWidgetId, Bundle options) {
|
||||||
synchronized (mAppWidgetIds) {
|
synchronized (mAppWidgetIds) {
|
||||||
options = cloneIfLocalBinder(options);
|
options = cloneIfLocalBinder(options);
|
||||||
@@ -913,7 +933,7 @@ class AppWidgetServiceImpl {
|
|||||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id.appWidgetId);
|
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id.appWidgetId);
|
||||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, id.options);
|
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, id.options);
|
||||||
mContext.sendBroadcastAsUser(intent, new UserHandle(mUserId));
|
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);
|
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
|
||||||
try {
|
try {
|
||||||
List<ResolveInfo> broadcastReceivers = mPm.queryIntentReceivers(intent,
|
List<ResolveInfo> broadcastReceivers = mPm.queryIntentReceivers(intent,
|
||||||
|
|||||||
Reference in New Issue
Block a user