Loading core/java/android/appwidget/AppWidgetManager.java +14 −0 Original line number Diff line number Diff line Loading @@ -1053,6 +1053,20 @@ public class AppWidgetManager { } } /** * @hide */ public boolean isBoundWidgetPackage(String packageName, int userId) { if (mService == null) { return false; } try { return mService.isBoundWidgetPackage(packageName, userId); } catch (RemoteException re) { throw new RuntimeException("system server dead?", re); } } private boolean bindAppWidgetIdIfAllowed(int appWidgetId, int profileId, ComponentName provider, Bundle options) { if (mService == null) { Loading core/java/com/android/internal/appwidget/IAppWidgetService.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -65,5 +65,6 @@ interface IAppWidgetService { in IBinder connection); void unbindRemoteViewsService(String callingPackage, int appWidgetId, in Intent intent); int[] getAppWidgetIds(in ComponentName providerComponent); boolean isBoundWidgetPackage(String packageName, int userId); } services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +100 −10 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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, Loading Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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++) { Loading @@ -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); Loading @@ -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); } } Loading Loading @@ -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(); Loading Loading @@ -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) { Loading Loading @@ -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, Loading Loading @@ -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); Loading services/usage/java/com/android/server/usage/UsageStatsService.java +9 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.app.usage.UsageEvents.Event; import android.app.usage.UsageStats; import android.app.usage.UsageStatsManagerInternal; import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener; import android.appwidget.AppWidgetManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -56,6 +57,7 @@ import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; import com.android.internal.appwidget.IAppWidgetService; import com.android.internal.os.BackgroundThread; import com.android.internal.util.IndentingPrintWriter; import com.android.server.SystemConfig; Loading Loading @@ -96,6 +98,7 @@ public class UsageStatsService extends SystemService implements Handler mHandler; AppOpsManager mAppOps; UserManager mUserManager; AppWidgetManager mAppWidgetManager; private final SparseArray<UserUsageStatsService> mUserState = new SparseArray<>(); private File mUsageStatsDir; Loading Loading @@ -158,6 +161,7 @@ public class UsageStatsService extends SystemService implements if (phase == PHASE_SYSTEM_SERVICES_READY) { // Observe changes to the threshold new SettingsObserver(mHandler).registerObserver(); mAppWidgetManager = getContext().getSystemService(AppWidgetManager.class); } else if (phase == PHASE_BOOT_COMPLETED) { setAppIdleParoled(getContext().getSystemService(BatteryManager.class).isCharging()); } Loading Loading @@ -500,6 +504,11 @@ public class UsageStatsService extends SystemService implements return false; } if (mAppWidgetManager != null && mAppWidgetManager.isBoundWidgetPackage(packageName, userId)) { return false; } final long lastUsed = getLastPackageAccessTime(packageName, userId); return hasPassedIdleDuration(lastUsed); } Loading Loading
core/java/android/appwidget/AppWidgetManager.java +14 −0 Original line number Diff line number Diff line Loading @@ -1053,6 +1053,20 @@ public class AppWidgetManager { } } /** * @hide */ public boolean isBoundWidgetPackage(String packageName, int userId) { if (mService == null) { return false; } try { return mService.isBoundWidgetPackage(packageName, userId); } catch (RemoteException re) { throw new RuntimeException("system server dead?", re); } } private boolean bindAppWidgetIdIfAllowed(int appWidgetId, int profileId, ComponentName provider, Bundle options) { if (mService == null) { Loading
core/java/com/android/internal/appwidget/IAppWidgetService.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -65,5 +65,6 @@ interface IAppWidgetService { in IBinder connection); void unbindRemoteViewsService(String callingPackage, int appWidgetId, in Intent intent); int[] getAppWidgetIds(in ComponentName providerComponent); boolean isBoundWidgetPackage(String packageName, int userId); }
services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +100 −10 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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, Loading Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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++) { Loading @@ -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); Loading @@ -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); } } Loading Loading @@ -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(); Loading Loading @@ -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) { Loading Loading @@ -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, Loading Loading @@ -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); Loading
services/usage/java/com/android/server/usage/UsageStatsService.java +9 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.app.usage.UsageEvents.Event; import android.app.usage.UsageStats; import android.app.usage.UsageStatsManagerInternal; import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener; import android.appwidget.AppWidgetManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -56,6 +57,7 @@ import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; import com.android.internal.appwidget.IAppWidgetService; import com.android.internal.os.BackgroundThread; import com.android.internal.util.IndentingPrintWriter; import com.android.server.SystemConfig; Loading Loading @@ -96,6 +98,7 @@ public class UsageStatsService extends SystemService implements Handler mHandler; AppOpsManager mAppOps; UserManager mUserManager; AppWidgetManager mAppWidgetManager; private final SparseArray<UserUsageStatsService> mUserState = new SparseArray<>(); private File mUsageStatsDir; Loading Loading @@ -158,6 +161,7 @@ public class UsageStatsService extends SystemService implements if (phase == PHASE_SYSTEM_SERVICES_READY) { // Observe changes to the threshold new SettingsObserver(mHandler).registerObserver(); mAppWidgetManager = getContext().getSystemService(AppWidgetManager.class); } else if (phase == PHASE_BOOT_COMPLETED) { setAppIdleParoled(getContext().getSystemService(BatteryManager.class).isCharging()); } Loading Loading @@ -500,6 +504,11 @@ public class UsageStatsService extends SystemService implements return false; } if (mAppWidgetManager != null && mAppWidgetManager.isBoundWidgetPackage(packageName, userId)) { return false; } final long lastUsed = getLastPackageAccessTime(packageName, userId); return hasPassedIdleDuration(lastUsed); } Loading