summaryrefslogtreecommitdiffstats
path: root/services/appwidget
diff options
context:
space:
mode:
authorAmith Yamasani <yamasani@google.com>2015-04-30 17:32:25 -0700
committerAmith Yamasani <yamasani@google.com>2015-05-01 11:17:27 -0700
commite4a8da8ea241858b52d8122480316db79582c44d (patch)
tree4bb2aaa2e55c435a2c60426466683835dcfad9f8 /services/appwidget
parent403ac2d64f7ad53ecf9ccd713951cf151ea2f2bc (diff)
downloadframeworks_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')
-rw-r--r--services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java110
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);