Merge "Delete appWidgetId when removing lockscreen widgets" into jb-mr1.1-dev

This commit is contained in:
Michael Jurka
2012-11-16 15:29:16 -08:00
committed by Android (Google) Code Review
7 changed files with 87 additions and 8 deletions

View File

@ -224,6 +224,22 @@ public class AppWidgetHost {
} }
} }
/**
* Gets a list of all the appWidgetIds that are bound to the current host
*
* @hide
*/
public int[] getAppWidgetIds() {
try {
if (sService == null) {
bindService();
}
return sService.getAppWidgetIdsForHost(mHostId);
} catch (RemoteException e) {
throw new RuntimeException("system server dead?", e);
}
}
private static void checkCallerIsSystem() { private static void checkCallerIsSystem() {
int uid = Process.myUid(); int uid = Process.myUid();
if (UserHandle.getAppId(uid) == Process.SYSTEM_UID || uid == 0) { if (UserHandle.getAppId(uid) == Process.SYSTEM_UID || uid == 0) {

View File

@ -38,6 +38,7 @@ interface IAppWidgetService {
void deleteHost(int hostId); void deleteHost(int hostId);
void deleteAllHosts(); void deleteAllHosts();
RemoteViews getAppWidgetViews(int appWidgetId); RemoteViews getAppWidgetViews(int appWidgetId);
int[] getAppWidgetIdsForHost(int hostId);
// //
// for AppWidgetManager // for AppWidgetManager

View File

@ -26,7 +26,6 @@ import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo; import android.appwidget.AppWidgetProviderInfo;
import android.content.ActivityNotFoundException;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -128,6 +127,8 @@ public class KeyguardHostView extends KeyguardViewBase {
mLockPatternUtils = new LockPatternUtils(context); mLockPatternUtils = new LockPatternUtils(context);
mAppWidgetHost = new AppWidgetHost( mAppWidgetHost = new AppWidgetHost(
context, APPWIDGET_HOST_ID, mOnClickHandler, Looper.myLooper()); context, APPWIDGET_HOST_ID, mOnClickHandler, Looper.myLooper());
cleanupAppWidgetIds();
mAppWidgetManager = AppWidgetManager.getInstance(mContext); mAppWidgetManager = AppWidgetManager.getInstance(mContext);
mSecurityModel = new KeyguardSecurityModel(context); mSecurityModel = new KeyguardSecurityModel(context);
@ -153,6 +154,33 @@ public class KeyguardHostView extends KeyguardViewBase {
} }
} }
private void cleanupAppWidgetIds() {
// Clean up appWidgetIds that are bound to lockscreen, but not actually used
// This is only to clean up after another bug: we used to not call
// deleteAppWidgetId when a user manually deleted a widget in keyguard. This code
// shouldn't have to run more than once per user. AppWidgetProviders rely on callbacks
// that are triggered by deleteAppWidgetId, which is why we're doing this
int[] appWidgetIdsInKeyguardSettings = mLockPatternUtils.getAppWidgets();
int[] appWidgetIdsBoundToHost = mAppWidgetHost.getAppWidgetIds();
for (int i = 0; i < appWidgetIdsBoundToHost.length; i++) {
int appWidgetId = appWidgetIdsBoundToHost[i];
if (!contains(appWidgetIdsInKeyguardSettings, appWidgetId)) {
Log.d(TAG, "Found a appWidgetId that's not being used by keyguard, deleting id "
+ appWidgetId);
mAppWidgetHost.deleteAppWidgetId(appWidgetId);
}
}
}
private static boolean contains(int[] array, int target) {
for (int value : array) {
if (value == target) {
return true;
}
}
return false;
}
private KeyguardUpdateMonitorCallback mUpdateMonitorCallbacks = private KeyguardUpdateMonitorCallback mUpdateMonitorCallbacks =
new KeyguardUpdateMonitorCallback() { new KeyguardUpdateMonitorCallback() {
@Override @Override
@ -331,10 +359,17 @@ public class KeyguardHostView extends KeyguardViewBase {
}; };
@Override @Override
public void onRemoveView(View v) { public void onRemoveView(View v, boolean deletePermanently) {
if (numWidgets() < MAX_WIDGETS) { if (numWidgets() < MAX_WIDGETS) {
setAddWidgetEnabled(true); setAddWidgetEnabled(true);
} }
if (deletePermanently) {
final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID &&
appWidgetId != LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
mAppWidgetHost.deleteAppWidgetId(appWidgetId);
}
}
} }
}; };

View File

@ -237,7 +237,7 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
public void userActivity(); public void userActivity();
public void onUserActivityTimeoutChanged(); public void onUserActivityTimeoutChanged();
public void onAddView(View v); public void onAddView(View v);
public void onRemoveView(View v); public void onRemoveView(View v, boolean deletePermanently);
} }
public void addWidget(View widget) { public void addWidget(View widget) {
@ -245,10 +245,10 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
} }
public void onRemoveView(View v) { public void onRemoveView(View v, final boolean deletePermanently) {
final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId(); final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
if (mCallbacks != null) { if (mCallbacks != null) {
mCallbacks.onRemoveView(v); mCallbacks.onRemoveView(v, deletePermanently);
} }
mBackgroundWorkerHandler.post(new Runnable() { mBackgroundWorkerHandler.post(new Runnable() {
@Override @Override

View File

@ -1457,7 +1457,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
} }
removeView(mDragView); removeView(mDragView);
onRemoveView(mDragView); onRemoveView(mDragView, false);
addView(mDragView, pageUnderPointIndex); addView(mDragView, pageUnderPointIndex);
onAddView(mDragView, pageUnderPointIndex); onAddView(mDragView, pageUnderPointIndex);
mSidePageHoverIndex = -1; mSidePageHoverIndex = -1;
@ -1587,7 +1587,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
} }
//public abstract void onFlingToDelete(View v); //public abstract void onFlingToDelete(View v);
public abstract void onRemoveView(View v); public abstract void onRemoveView(View v, boolean deletePermanently);
public abstract void onAddView(View v, int index); public abstract void onAddView(View v, int index);
private void resetTouchState() { private void resetTouchState() {
@ -2391,7 +2391,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
slideAnimations.start(); slideAnimations.start();
removeView(dragView); removeView(dragView);
onRemoveView(dragView); onRemoveView(dragView, true);
} }
}; };
} }

View File

@ -146,6 +146,11 @@ class AppWidgetService extends IAppWidgetService.Stub
return getImplForUser(getCallingOrCurrentUserId()).allocateAppWidgetId( return getImplForUser(getCallingOrCurrentUserId()).allocateAppWidgetId(
packageName, hostId); packageName, hostId);
} }
@Override
public int[] getAppWidgetIdsForHost(int hostId) throws RemoteException {
return getImplForUser(getCallingOrCurrentUserId()).getAppWidgetIdsForHost(hostId);
}
@Override @Override
public void deleteAppWidgetId(int appWidgetId) throws RemoteException { public void deleteAppWidgetId(int appWidgetId) throws RemoteException {

View File

@ -1358,6 +1358,28 @@ class AppWidgetServiceImpl {
} }
} }
static int[] getAppWidgetIds(Host h) {
int instancesSize = h.instances.size();
int appWidgetIds[] = new int[instancesSize];
for (int i = 0; i < instancesSize; i++) {
appWidgetIds[i] = h.instances.get(i).appWidgetId;
}
return appWidgetIds;
}
public int[] getAppWidgetIdsForHost(int hostId) {
synchronized (mAppWidgetIds) {
ensureStateLoadedLocked();
int callingUid = Binder.getCallingUid();
Host host = lookupHostLocked(callingUid, hostId);
if (host != null) {
return getAppWidgetIds(host);
} else {
return new int[0];
}
}
}
private Provider parseProviderInfoXml(ComponentName component, ResolveInfo ri) { private Provider parseProviderInfoXml(ComponentName component, ResolveInfo ri) {
Provider p = null; Provider p = null;