Don't remove widget providers when whitelist changes.

When a widget provider is removed from the whitelist
of widgets that work across profiles just remove the
currently bound widgets don't remove the provider.
This allows the provider to be added back to the whitelist
or to be used from widget hosts within the profile.

Bug: 21180997
Change-Id: I5d3a81fb088092b65cc4e8e158be4a292c5c8288
This commit is contained in:
Kenny Guy
2015-09-14 15:52:31 +01:00
parent 5ef65ea163
commit 415f111335

View File

@@ -1870,19 +1870,28 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
return false;
}
private void deleteProviderLocked(Provider provider) {
int N = provider.widgets.size();
// Remove widgets for provider that are hosted in userId.
private void deleteWidgetsLocked(Provider provider, int userId) {
final int N = provider.widgets.size();
for (int i = N - 1; i >= 0; i--) {
Widget widget = provider.widgets.remove(i);
// Call back with empty RemoteViews
updateAppWidgetInstanceLocked(widget, null, false);
// clear out references to this appWidgetId
widget.host.widgets.remove(widget);
removeWidgetLocked(widget);
widget.provider = null;
pruneHostLocked(widget.host);
widget.host = null;
Widget widget = provider.widgets.get(i);
if (userId == UserHandle.USER_ALL
|| userId == widget.host.getUserId()) {
provider.widgets.remove(i);
// Call back with empty RemoteViews
updateAppWidgetInstanceLocked(widget, null, false);
// clear out references to this appWidgetId
widget.host.widgets.remove(widget);
removeWidgetLocked(widget);
widget.provider = null;
pruneHostLocked(widget.host);
widget.host = null;
}
}
}
private void deleteProviderLocked(Provider provider) {
deleteWidgetsLocked(provider, UserHandle.USER_ALL);
mProviders.remove(provider);
// no need to send the DISABLE broadcast, since the receiver is gone anyway
@@ -2930,6 +2939,19 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
return providersUpdated;
}
// Remove widgets for provider in userId that are hosted in parentUserId
private void removeWidgetsForPackageLocked(String pkgName, int userId, int parentUserId) {
final int N = mProviders.size();
for (int i = 0; i < N; ++i) {
Provider provider = mProviders.get(i);
if (pkgName.equals(provider.info.provider.getPackageName())
&& provider.getUserId() == userId
&& provider.widgets.size() > 0) {
deleteWidgetsLocked(provider, parentUserId);
}
}
}
private boolean removeProvidersForPackageLocked(String pkgName, int userId) {
boolean removed = false;
@@ -3041,14 +3063,14 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
userId, null);
}
// Some packages are no longer whitelisted.
// Remove widgets from hosts in parent user for packages not in the whitelist
final int removedCount = previousPackages.size();
for (int i = 0; i < removedCount; ++i) {
providersChanged |= removeProvidersForPackageLocked(
previousPackages.valueAt(i), userId);
removeWidgetsForPackageLocked(previousPackages.valueAt(i),
userId, parentId);
}
if (providersChanged) {
if (providersChanged || removedCount > 0) {
saveGroupStateAsync(userId);
scheduleNotifyGroupHostsForProvidersChangedLocked(userId);
}