Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 33525d2f authored by Makoto Onuki's avatar Makoto Onuki
Browse files

ShortcutManager: Update foreground check.

- When the cached UID state says a UID is in the background,
check with AM and get the latest state, since the state
might just have been changed.

Bug 30640208

Change-Id: If448f6f21f290fa0fc13550d9c740f56aa8bfce0
parent 4a051a84
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -171,4 +171,12 @@ public abstract class ActivityManagerInternal {
     */
    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);
}
+5 −0
Original line number Diff line number Diff line
@@ -21942,6 +21942,11 @@ public final class ActivityManagerService extends ActivityManagerNative
                        /*resultTo*/ null, bOptions, userId);
            }
        }
        @Override
        public int getUidProcessState(int uid) {
            return getUidState(uid);
        }
    }
    private final class SleepTokenImpl extends SleepToken {
+13 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
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;
@@ -284,6 +285,7 @@ public class ShortcutService extends IShortcutService.Stub {
    private final PackageManagerInternal mPackageManagerInternal;
    private final UserManager mUserManager;
    private final UsageStatsManagerInternal mUsageStatsManagerInternal;
    private final ActivityManagerInternal mActivityManagerInternal;

    @GuardedBy("mLock")
    final SparseIntArray mUidState = new SparseIntArray();
@@ -372,6 +374,8 @@ public class ShortcutService extends IShortcutService.Stub {
        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.
@@ -456,7 +460,8 @@ public class ShortcutService extends IShortcutService.Stub {
    }

    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) {
@@ -465,7 +470,13 @@ public class ShortcutService extends IShortcutService.Stub {
            // 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) {
+4 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import static org.mockito.Mockito.when;
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;
@@ -715,6 +716,9 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
                    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);