am 17d5e266: am 92d42057: Merge "Exclude bound app widgets from idle app list" into mnc-dev

* commit '17d5e2660663b4c09b3e94c9a92d8e80f657ed95':
  Exclude bound app widgets from idle app list
This commit is contained in:
Amith Yamasani
2015-05-01 18:48:15 +00:00
committed by Android Git Automerger
4 changed files with 124 additions and 10 deletions

View File

@@ -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) {

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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;
@@ -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;
@@ -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;
@@ -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());
}
@@ -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);
}