*/
public abstract int startActivitiesAsPackage(String packageName,
int userId, Intent[] intents, Bundle bOptions);
+
+ /**
+ * Get the procstate for the UID. The return value will be between
+ * {@link ActivityManager#MIN_PROCESS_STATE} and {@link ActivityManager#MAX_PROCESS_STATE}.
+ * Note if the UID doesn't exist, it'll return {@link ActivityManager#PROCESS_STATE_NONEXISTENT}
+ * (-1).
+ */
+ public abstract int getUidProcessState(int uid);
}
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
import android.app.ActivityManagerNative;
import android.app.AppGlobals;
import android.app.IUidObserver;
private final PackageManagerInternal mPackageManagerInternal;
private final UserManager mUserManager;
private final UsageStatsManagerInternal mUsageStatsManagerInternal;
+ private final ActivityManagerInternal mActivityManagerInternal;
@GuardedBy("mLock")
final SparseIntArray mUidState = new SparseIntArray();
mUserManager = Preconditions.checkNotNull(context.getSystemService(UserManager.class));
mUsageStatsManagerInternal = Preconditions.checkNotNull(
LocalServices.getService(UsageStatsManagerInternal.class));
+ mActivityManagerInternal = Preconditions.checkNotNull(
+ LocalServices.getService(ActivityManagerInternal.class));
if (onlyForPackageManagerApis) {
return; // Don't do anything further. For unit tests only.
}
private boolean isProcessStateForeground(int processState) {
- return processState <= PROCESS_STATE_FOREGROUND_THRESHOLD;
+ return (processState != ActivityManager.PROCESS_STATE_NONEXISTENT)
+ && (processState <= PROCESS_STATE_FOREGROUND_THRESHOLD);
}
boolean isUidForegroundLocked(int uid) {
// so it's foreground anyway.
return true;
}
- return isProcessStateForeground(mUidState.get(uid, ActivityManager.MAX_PROCESS_STATE));
+ // First, check with the local cache.
+ if (isProcessStateForeground(mUidState.get(uid, ActivityManager.MAX_PROCESS_STATE))) {
+ return true;
+ }
+ // If the cache says background, reach out to AM. Since it'll internally need to hold
+ // the AM lock, we use it as a last resort.
+ return isProcessStateForeground(mActivityManagerInternal.getUidProcessState(uid));
}
long getUidLastForegroundElapsedTimeLocked(int uid) {
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.Activity;
+import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.IUidObserver;
import android.app.usage.UsageStatsManagerInternal;
return b(mRunningUsers.get(userId)) && b(mUnlockedUsers.get(userId));
}));
+ when(mMockActivityManagerInternal.getUidProcessState(anyInt())).thenReturn(
+ ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+
// User 0 and P0 are always running
mRunningUsers.put(USER_0, true);
mRunningUsers.put(USER_10, false);