From 415f111335b7ea46047233d05acd685432b0f92e Mon Sep 17 00:00:00 2001 From: Kenny Guy Date: Mon, 14 Sep 2015 15:52:31 +0100 Subject: [PATCH] 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 --- .../appwidget/AppWidgetServiceImpl.java | 52 +++++++++++++------ 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index fa87270d6984c..24f9f27e12cd1 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -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); }