diff options
author | Amith Yamasani <yamasani@google.com> | 2015-04-30 17:32:25 -0700 |
---|---|---|
committer | Amith Yamasani <yamasani@google.com> | 2015-05-01 11:17:27 -0700 |
commit | e4a8da8ea241858b52d8122480316db79582c44d (patch) | |
tree | 4bb2aaa2e55c435a2c60426466683835dcfad9f8 /services/appwidget/java | |
parent | 403ac2d64f7ad53ecf9ccd713951cf151ea2f2bc (diff) | |
download | frameworks_base-e4a8da8ea241858b52d8122480316db79582c44d.zip frameworks_base-e4a8da8ea241858b52d8122480316db79582c44d.tar.gz frameworks_base-e4a8da8ea241858b52d8122480316db79582c44d.tar.bz2 |
Exclude bound app widgets from idle app list
Track package names of bound app widgets and use the list when
querying for idle apps.
Bug: 20066058
Change-Id: If8039397a061ef04bb13aa38d57cd7f0221f5fc7
Diffstat (limited to 'services/appwidget/java')
-rw-r--r-- | services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java | 110 |
1 files changed, 100 insertions, 10 deletions
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index 17c7e0c..78cbac9 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -63,6 +63,7 @@ import android.util.AtomicFile; import android.util.AttributeSet; import android.util.Pair; import android.util.Slog; +import android.util.SparseArray; import android.util.SparseIntArray; import android.util.TypedValue; import android.util.Xml; @@ -171,6 +172,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku private final SparseIntArray mLoadedUserIds = new SparseIntArray(); + private final SparseArray<ArraySet<String>> mWidgetPackages = new SparseArray<>(); + private final BackupRestoreController mBackupRestoreController; private final Context mContext; @@ -572,7 +575,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku widget.host = host; host.widgets.add(widget); - mWidgets.add(widget); + addWidgetLocked(widget); saveGroupStateAsync(userId); @@ -800,6 +803,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku widget.provider = provider; widget.options = (options != null) ? cloneIfLocalBinder(options) : new Bundle(); + onWidgetProviderAddedOrChangedLocked(widget); + // We need to provide a default value for the widget category if it is not specified if (!widget.options.containsKey(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY)) { widget.options.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, @@ -1410,7 +1415,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku host.widgets.remove(widget); pruneHostLocked(host); - mWidgets.remove(widget); + removeWidgetLocked(widget); Provider provider = widget.provider; if (provider != null) { @@ -1874,7 +1879,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku updateAppWidgetInstanceLocked(widget, null, false); // clear out references to this appWidgetId widget.host.widgets.remove(widget); - mWidgets.remove(widget); + removeWidgetLocked(widget); widget.provider = null; pruneHostLocked(widget.host); widget.host = null; @@ -2277,14 +2282,14 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku if (version >= 0) { // Hooke'm up... - bindLoadedWidgets(loadedWidgets); + bindLoadedWidgetsLocked(loadedWidgets); // upgrade the database if needed performUpgradeLocked(version); } else { // failed reading, clean up Slog.w(TAG, "Failed to read state, clearing widgets and hosts."); - mWidgets.clear(); + clearWidgetsLocked(); mHosts.clear(); final int N = mProviders.size(); for (int i = 0; i < N; i++) { @@ -2293,7 +2298,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } } - private void bindLoadedWidgets(List<LoadedWidgetState> loadedWidgets) { + private void bindLoadedWidgetsLocked(List<LoadedWidgetState> loadedWidgets) { final int loadedWidgetCount = loadedWidgets.size(); for (int i = loadedWidgetCount - 1; i >= 0; i--) { LoadedWidgetState loadedWidget = loadedWidgets.remove(i); @@ -2314,7 +2319,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku widget.provider.widgets.add(widget); widget.host.widgets.add(widget); - mWidgets.add(widget); + addWidgetLocked(widget); } } @@ -2346,6 +2351,91 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku return null; } + /** + * Adds the widget to mWidgets and tracks the package name in mWidgetPackages. + */ + void addWidgetLocked(Widget widget) { + mWidgets.add(widget); + + onWidgetProviderAddedOrChangedLocked(widget); + } + + /** + * Checks if the provider is assigned and updates the mWidgetPackages to track packages + * that have bound widgets. + */ + void onWidgetProviderAddedOrChangedLocked(Widget widget) { + if (widget.provider == null) return; + + int userId = widget.provider.getUserId(); + ArraySet<String> packages = mWidgetPackages.get(userId); + if (packages == null) { + mWidgetPackages.put(userId, packages = new ArraySet<String>()); + } + packages.add(widget.provider.info.provider.getPackageName()); + } + + /** + * Removes a widget from mWidgets and updates the cache of bound widget provider packages. + * If there are other widgets with the same package, leaves it in the cache, otherwise it + * removes the associated package from the cache. + */ + void removeWidgetLocked(Widget widget) { + mWidgets.remove(widget); + + onWidgetRemovedLocked(widget); + } + + private void onWidgetRemovedLocked(Widget widget) { + if (widget.provider == null) return; + + final int userId = widget.provider.getUserId(); + final String packageName = widget.provider.info.provider.getPackageName(); + ArraySet<String> packages = mWidgetPackages.get(userId); + if (packages == null) { + return; + } + // Check if there is any other widget with the same package name. + // Remove packageName if none. + final int N = mWidgets.size(); + for (int i = 0; i < N; i++) { + Widget w = mWidgets.get(i); + if (w.provider == null) continue; + if (w.provider.getUserId() == userId + && packageName.equals(w.provider.info.provider.getPackageName())) { + return; + } + } + packages.remove(packageName); + } + + /** + * Clears all widgets and associated cache of packages with bound widgets. + */ + void clearWidgetsLocked() { + mWidgets.clear(); + + onWidgetsClearedLocked(); + } + + private void onWidgetsClearedLocked() { + mWidgetPackages.clear(); + } + + @Override + public boolean isBoundWidgetPackage(String packageName, int userId) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Only the system process can call this"); + } + synchronized (mLock) { + final ArraySet<String> packages = mWidgetPackages.get(userId); + if (packages != null) { + return packages.contains(packageName); + } + } + return false; + } + private void saveStateLocked(int userId) { tagProvidersAndHosts(); @@ -2692,7 +2782,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku // as we do not want to make host callbacks and provider broadcasts // as the host and the provider will be killed. if (hostInUser && (!hasProvider || providerInUser)) { - mWidgets.remove(i); + removeWidgetLocked(widget); widget.host.widgets.remove(widget); widget.host = null; if (hasProvider) { @@ -3751,7 +3841,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku Slog.i(TAG, "New restored id " + restoredId + " now " + id); } - mWidgets.add(id); + addWidgetLocked(id); } if (id.provider.info != null) { stashProviderRestoreUpdateLocked(id.provider, @@ -4013,7 +4103,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku host.widgets.remove(widget); provider.widgets.remove(widget); unbindAppWidgetRemoteViewsServicesLocked(widget); - mWidgets.remove(i); + removeWidgetLocked(widget); } } mPrunedApps.add(pkg); |