/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.server;

import static com.android.server.ForceAppStandbyTracker.TARGET_OP;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.AppOpsManager.OpEntry;
import android.app.AppOpsManager.PackageOps;
import android.app.IActivityManager;
import android.app.IUidObserver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager.ServiceType;
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.util.ArraySet;
import android.util.Pair;

import com.android.internal.app.IAppOpsCallback;
import com.android.internal.app.IAppOpsService;
import com.android.server.ForceAppStandbyTracker.Listener;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class ForceAppStandbyTrackerTest {

    private class ForceAppStandbyTrackerTestable extends ForceAppStandbyTracker {
        ForceAppStandbyTrackerTestable() {
            super(mMockContext, Looper.getMainLooper());
        }

        @Override
        AppOpsManager injectAppOpsManager() {
            return mMockAppOpsManager;
        }

        @Override
        IAppOpsService injectIAppOpsService() {
            return mMockIAppOpsService;
        }

        @Override
        IActivityManager injectIActivityManager() {
            return mMockIActivityManager;
        }

        @Override
        PowerManagerInternal injectPowerManagerInternal() {
            return mMockPowerManagerInternal;
        }
    }

    private static final int UID_1 = Process.FIRST_APPLICATION_UID + 1;
    private static final int UID_2 = Process.FIRST_APPLICATION_UID + 2;
    private static final int UID_3 = Process.FIRST_APPLICATION_UID + 3;
    private static final int UID_10_1 = UserHandle.getUid(10, UID_1);
    private static final int UID_10_2 = UserHandle.getUid(10, UID_2);
    private static final int UID_10_3 = UserHandle.getUid(10, UID_3);
    private static final String PACKAGE_1 = "package1";
    private static final String PACKAGE_2 = "package2";
    private static final String PACKAGE_3 = "package3";
    private static final String PACKAGE_SYSTEM = "android";

    private Handler mMainHandler;

    @Mock
    private Context mMockContext;

    @Mock
    private IActivityManager mMockIActivityManager;

    @Mock
    private AppOpsManager mMockAppOpsManager;

    @Mock
    private IAppOpsService mMockIAppOpsService;

    @Mock
    private PowerManagerInternal mMockPowerManagerInternal;

    private IUidObserver mIUidObserver;
    private IAppOpsCallback.Stub mAppOpsCallback;
    private Consumer<PowerSaveState> mPowerSaveObserver;
    private BroadcastReceiver mReceiver;

    private boolean mPowerSaveMode;

    private final ArraySet<Pair<Integer, String>> mRestrictedPackages = new ArraySet();

    @Before
    public void setUp() {
        mMainHandler = new Handler(Looper.getMainLooper());
    }

    private void waitUntilMainHandlerDrain() throws Exception {
        final CountDownLatch l = new CountDownLatch(1);
        mMainHandler.post(() -> {
            l.countDown();
        });
        assertTrue(l.await(5, TimeUnit.SECONDS));
    }

    private PowerSaveState getPowerSaveState() {
        return new PowerSaveState.Builder().setBatterySaverEnabled(mPowerSaveMode).build();
    }

    private ForceAppStandbyTrackerTestable newInstance() throws Exception {
        MockitoAnnotations.initMocks(this);

        when(mMockIAppOpsService.checkOperation(eq(TARGET_OP), anyInt(), anyString()))
                .thenAnswer(inv -> {
                    return mRestrictedPackages.indexOf(
                            Pair.create(inv.getArgument(1), inv.getArgument(2))) >= 0 ?
                            AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED;
                });

        final ForceAppStandbyTrackerTestable instance = new ForceAppStandbyTrackerTestable();

        return instance;
    }

    private void callStart(ForceAppStandbyTrackerTestable instance) throws RemoteException {

        // Set up functions that start() calls.
        when(mMockPowerManagerInternal.getLowPowerState(eq(ServiceType.FORCE_ALL_APPS_STANDBY)))
                .thenAnswer(inv -> getPowerSaveState());
        when(mMockAppOpsManager.getPackagesForOps(
                any(int[].class)
                )).thenAnswer(inv -> new ArrayList<AppOpsManager.PackageOps>());

        // Call start.
        instance.start();

        // Capture the listeners.
        ArgumentCaptor<IUidObserver> uidObserverArgumentCaptor =
                ArgumentCaptor.forClass(IUidObserver.class);
        ArgumentCaptor<IAppOpsCallback.Stub> appOpsCallbackCaptor =
                ArgumentCaptor.forClass(IAppOpsCallback.Stub.class);
        ArgumentCaptor<Consumer<PowerSaveState>> powerSaveObserverCaptor =
                ArgumentCaptor.forClass(Consumer.class);
        ArgumentCaptor<BroadcastReceiver> receiverCaptor =
                ArgumentCaptor.forClass(BroadcastReceiver.class);

        verify(mMockIActivityManager).registerUidObserver(
                uidObserverArgumentCaptor.capture(),
                eq(ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_IDLE
                        | ActivityManager.UID_OBSERVER_ACTIVE),
                eq(ActivityManager.PROCESS_STATE_UNKNOWN),
                isNull());
        verify(mMockIAppOpsService).startWatchingMode(
                eq(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND),
                isNull(),
                appOpsCallbackCaptor.capture());
        verify(mMockPowerManagerInternal).registerLowPowerModeObserver(
                eq(ServiceType.FORCE_ALL_APPS_STANDBY),
                powerSaveObserverCaptor.capture());

        verify(mMockContext).registerReceiver(
                receiverCaptor.capture(), any(IntentFilter.class));

        mIUidObserver = uidObserverArgumentCaptor.getValue();
        mAppOpsCallback = appOpsCallbackCaptor.getValue();
        mPowerSaveObserver = powerSaveObserverCaptor.getValue();
        mReceiver = receiverCaptor.getValue();

        assertNotNull(mIUidObserver);
        assertNotNull(mAppOpsCallback);
        assertNotNull(mPowerSaveObserver);
        assertNotNull(mReceiver);
    }

    private void setAppOps(int uid, String packageName, boolean restrict) throws RemoteException {
        final Pair p = Pair.create(uid, packageName);
        if (restrict) {
            mRestrictedPackages.add(p);
        } else {
            mRestrictedPackages.remove(p);
        }
        if (mAppOpsCallback != null) {
            mAppOpsCallback.opChanged(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName);
        }
    }

    private static final int NONE = 0;
    private static final int ALARMS_ONLY = 1 << 0;
    private static final int JOBS_ONLY = 1 << 1;
    private static final int JOBS_AND_ALARMS = ALARMS_ONLY | JOBS_ONLY;

    private void areRestricted(ForceAppStandbyTrackerTestable instance, int uid, String packageName,
            int restrictionTypes) {
        assertEquals(((restrictionTypes & JOBS_ONLY) != 0),
                instance.areJobsRestricted(uid, packageName));
        assertEquals(((restrictionTypes & ALARMS_ONLY) != 0),
                instance.areAlarmsRestricted(uid, packageName));
    }

    @Test
    public void testAll() throws Exception {
        final ForceAppStandbyTrackerTestable instance = newInstance();
        callStart(instance);

        assertFalse(instance.isForceAllAppsStandbyEnabled());
        areRestricted(instance, UID_1, PACKAGE_1, NONE);
        areRestricted(instance, UID_2, PACKAGE_2, NONE);
        areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);

        mPowerSaveMode = true;
        mPowerSaveObserver.accept(getPowerSaveState());

        assertTrue(instance.isForceAllAppsStandbyEnabled());

        areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
        areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
        areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);

        // Toggle the foreground state.
        mPowerSaveMode = true;
        mPowerSaveObserver.accept(getPowerSaveState());

        assertFalse(instance.isInForeground(UID_1));
        assertFalse(instance.isInForeground(UID_2));
        assertTrue(instance.isInForeground(Process.SYSTEM_UID));

        mIUidObserver.onUidActive(UID_1);
        areRestricted(instance, UID_1, PACKAGE_1, NONE);
        areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
        areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
        assertTrue(instance.isInForeground(UID_1));
        assertFalse(instance.isInForeground(UID_2));

        mIUidObserver.onUidGone(UID_1, /*disable=*/ false);
        areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
        areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
        areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
        assertFalse(instance.isInForeground(UID_1));
        assertFalse(instance.isInForeground(UID_2));

        mIUidObserver.onUidActive(UID_1);
        areRestricted(instance, UID_1, PACKAGE_1, NONE);
        areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
        areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);

        mIUidObserver.onUidIdle(UID_1, /*disable=*/ false);
        areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
        areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
        areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
        assertFalse(instance.isInForeground(UID_1));
        assertFalse(instance.isInForeground(UID_2));

        // Toggle the app ops.
        mPowerSaveMode = false;
        mPowerSaveObserver.accept(getPowerSaveState());

        assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1));
        assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_1, PACKAGE_1));
        assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
        assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));

        areRestricted(instance, UID_1, PACKAGE_1, NONE);
        areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
        areRestricted(instance, UID_2, PACKAGE_2, NONE);
        areRestricted(instance, UID_10_2, PACKAGE_2, NONE);
        areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);

        setAppOps(UID_1, PACKAGE_1, true);
        setAppOps(UID_10_2, PACKAGE_2, true);
        assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1));
        assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_1, PACKAGE_1));
        assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
        assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));

        areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
        areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
        areRestricted(instance, UID_2, PACKAGE_2, NONE);
        areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
        areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);

        // Toggle power saver, should still be the same.
        mPowerSaveMode = true;
        mPowerSaveObserver.accept(getPowerSaveState());

        mPowerSaveMode = false;
        mPowerSaveObserver.accept(getPowerSaveState());

        areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
        areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
        areRestricted(instance, UID_2, PACKAGE_2, NONE);
        areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
        areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);

        // Clear the app ops and update the whitelist.
        setAppOps(UID_1, PACKAGE_1, false);
        setAppOps(UID_10_2, PACKAGE_2, false);

        mPowerSaveMode = true;
        mPowerSaveObserver.accept(getPowerSaveState());

        areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
        areRestricted(instance, UID_10_1, PACKAGE_1, JOBS_AND_ALARMS);
        areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
        areRestricted(instance, UID_10_2, PACKAGE_2, JOBS_AND_ALARMS);
        areRestricted(instance, UID_3, PACKAGE_3, JOBS_AND_ALARMS);
        areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS);
        areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);

        instance.setPowerSaveWhitelistAppIds(new int[] {UID_1}, new int[] {UID_2});

        areRestricted(instance, UID_1, PACKAGE_1, NONE);
        areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
        areRestricted(instance, UID_2, PACKAGE_2, ALARMS_ONLY);
        areRestricted(instance, UID_10_2, PACKAGE_2, ALARMS_ONLY);
        areRestricted(instance, UID_3, PACKAGE_3, JOBS_AND_ALARMS);
        areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS);
        areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);

        // Again, make sure toggling the global state doesn't change it.
        mPowerSaveMode = false;
        mPowerSaveObserver.accept(getPowerSaveState());

        mPowerSaveMode = true;
        mPowerSaveObserver.accept(getPowerSaveState());

        areRestricted(instance, UID_1, PACKAGE_1, NONE);
        areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
        areRestricted(instance, UID_2, PACKAGE_2, ALARMS_ONLY);
        areRestricted(instance, UID_10_2, PACKAGE_2, ALARMS_ONLY);
        areRestricted(instance, UID_3, PACKAGE_3, JOBS_AND_ALARMS);
        areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS);
        areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);

        assertTrue(instance.isUidPowerSaveWhitelisted(UID_1));
        assertTrue(instance.isUidPowerSaveWhitelisted(UID_10_1));
        assertFalse(instance.isUidPowerSaveWhitelisted(UID_2));
        assertFalse(instance.isUidPowerSaveWhitelisted(UID_10_2));

        assertFalse(instance.isUidTempPowerSaveWhitelisted(UID_1));
        assertFalse(instance.isUidTempPowerSaveWhitelisted(UID_10_1));
        assertTrue(instance.isUidTempPowerSaveWhitelisted(UID_2));
        assertTrue(instance.isUidTempPowerSaveWhitelisted(UID_10_2));
    }

    public void loadPersistedAppOps() throws Exception {
        final ForceAppStandbyTrackerTestable instance = newInstance();

        final List<PackageOps> ops = new ArrayList<>();

        //--------------------------------------------------
        List<OpEntry> entries = new ArrayList<>();
        entries.add(new AppOpsManager.OpEntry(
                AppOpsManager.OP_ACCESS_NOTIFICATIONS,
                AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
        entries.add(new AppOpsManager.OpEntry(
                ForceAppStandbyTracker.TARGET_OP,
                AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));

        ops.add(new PackageOps(PACKAGE_1, UID_1, entries));

        //--------------------------------------------------
        entries = new ArrayList<>();
        entries.add(new AppOpsManager.OpEntry(
                ForceAppStandbyTracker.TARGET_OP,
                AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));

        ops.add(new PackageOps(PACKAGE_2, UID_2, entries));

        //--------------------------------------------------
        entries = new ArrayList<>();
        entries.add(new AppOpsManager.OpEntry(
                ForceAppStandbyTracker.TARGET_OP,
                AppOpsManager.MODE_ALLOWED, 0, 0, 0, 0, null));

        ops.add(new PackageOps(PACKAGE_1, UID_10_1, entries));

        //--------------------------------------------------
        entries = new ArrayList<>();
        entries.add(new AppOpsManager.OpEntry(
                ForceAppStandbyTracker.TARGET_OP,
                AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
        entries.add(new AppOpsManager.OpEntry(
                AppOpsManager.OP_ACCESS_NOTIFICATIONS,
                AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));

        ops.add(new PackageOps(PACKAGE_3, UID_10_3, entries));

        callStart(instance);

        assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1));
        assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
        assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_3, PACKAGE_3));

        assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_1, PACKAGE_1));
        assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
        assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_3, PACKAGE_3));
    }

    private void assertNoCallbacks(Listener l) throws Exception {
        waitUntilMainHandlerDrain();
        verify(l, times(0)).updateAllJobs();
        verify(l, times(0)).updateJobsForUid(anyInt());
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);
    }

    @Test
    public void testPowerSaveListener() throws Exception {
        final ForceAppStandbyTrackerTestable instance = newInstance();
        callStart(instance);

        ForceAppStandbyTracker.Listener l = mock(ForceAppStandbyTracker.Listener.class);
        instance.addListener(l);

        // Power save on.
        mPowerSaveMode = true;
        mPowerSaveObserver.accept(getPowerSaveState());

        waitUntilMainHandlerDrain();
        verify(l, times(1)).updateAllJobs();
        verify(l, times(0)).updateJobsForUid(anyInt());
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        // Power save off.
        mPowerSaveMode = false;
        mPowerSaveObserver.accept(getPowerSaveState());

        waitUntilMainHandlerDrain();
        verify(l, times(1)).updateAllJobs();
        verify(l, times(0)).updateJobsForUid(anyInt());
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(1)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        // Power save on.
        mPowerSaveMode = true;
        mPowerSaveObserver.accept(getPowerSaveState());

        assertNoCallbacks(l);
    }

    @Test
    public void testAllListeners() throws Exception {
        final ForceAppStandbyTrackerTestable instance = newInstance();
        callStart(instance);

        ForceAppStandbyTracker.Listener l = mock(ForceAppStandbyTracker.Listener.class);
        instance.addListener(l);

        // -------------------------------------------------------------------------
        // Test with apppops.

        setAppOps(UID_10_2, PACKAGE_2, true);

        waitUntilMainHandlerDrain();
        verify(l, times(0)).updateAllJobs();
        verify(l, times(0)).updateJobsForUid(anyInt());
        verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        setAppOps(UID_10_2, PACKAGE_2, false);

        waitUntilMainHandlerDrain();
        verify(l, times(0)).updateAllJobs();
        verify(l, times(0)).updateJobsForUid(anyInt());
        verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));
        reset(l);

        setAppOps(UID_10_2, PACKAGE_2, false);

        verify(l, times(0)).updateAllJobs();
        verify(l, times(0)).updateJobsForUid(anyInt());
        verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());

        // Unrestrict while battery saver is on. Shouldn't fire.
        mPowerSaveMode = true;
        mPowerSaveObserver.accept(getPowerSaveState());

        // Note toggling appops while BS is on will suppress unblockAlarmsForUidPackage().
        setAppOps(UID_10_2, PACKAGE_2, true);

        waitUntilMainHandlerDrain();
        verify(l, times(1)).updateAllJobs();
        verify(l, times(0)).updateJobsForUid(anyInt());
        verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        // Battery saver off.
        mPowerSaveMode = false;
        mPowerSaveObserver.accept(getPowerSaveState());

        waitUntilMainHandlerDrain();
        verify(l, times(1)).updateAllJobs();
        verify(l, times(0)).updateJobsForUid(anyInt());
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(1)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        // -------------------------------------------------------------------------
        // Tests with system/user/temp whitelist.

        instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {});

        waitUntilMainHandlerDrain();
        verify(l, times(1)).updateAllJobs();
        verify(l, times(0)).updateJobsForUid(anyInt());
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {});

        waitUntilMainHandlerDrain();
        verify(l, times(1)).updateAllJobs();
        verify(l, times(0)).updateJobsForUid(anyInt());
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(1)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        // Update temp whitelist.
        instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_1, UID_3});

        waitUntilMainHandlerDrain();
        verify(l, times(1)).updateAllJobs();
        verify(l, times(0)).updateJobsForUid(anyInt());
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_3});

        waitUntilMainHandlerDrain();
        verify(l, times(1)).updateAllJobs();
        verify(l, times(0)).updateJobsForUid(anyInt());
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        // Do the same thing with battery saver on. (Currently same callbacks are called.)
        mPowerSaveMode = true;
        mPowerSaveObserver.accept(getPowerSaveState());

        instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {});

        waitUntilMainHandlerDrain();
        verify(l, times(1)).updateAllJobs();
        verify(l, times(0)).updateJobsForUid(anyInt());
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {});

        waitUntilMainHandlerDrain();
        verify(l, times(1)).updateAllJobs();
        verify(l, times(0)).updateJobsForUid(anyInt());
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(1)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        // Update temp whitelist.
        instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_1, UID_3});

        waitUntilMainHandlerDrain();
        verify(l, times(1)).updateAllJobs();
        verify(l, times(0)).updateJobsForUid(anyInt());
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_3});

        waitUntilMainHandlerDrain();
        verify(l, times(1)).updateAllJobs();
        verify(l, times(0)).updateJobsForUid(anyInt());
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);


        // -------------------------------------------------------------------------
        // Tests with proc state changes.

        // With battery save.
        mPowerSaveMode = true;
        mPowerSaveObserver.accept(getPowerSaveState());

        mIUidObserver.onUidActive(UID_10_1);

        waitUntilMainHandlerDrain();
        verify(l, times(0)).updateAllJobs();
        verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        mIUidObserver.onUidGone(UID_10_1, true);

        waitUntilMainHandlerDrain();
        verify(l, times(0)).updateAllJobs();
        verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        mIUidObserver.onUidActive(UID_10_1);

        waitUntilMainHandlerDrain();
        verify(l, times(0)).updateAllJobs();
        verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        mIUidObserver.onUidIdle(UID_10_1, true);

        waitUntilMainHandlerDrain();
        verify(l, times(0)).updateAllJobs();
        verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        // Without battery save.
        mPowerSaveMode = false;
        mPowerSaveObserver.accept(getPowerSaveState());

        mIUidObserver.onUidActive(UID_10_1);

        waitUntilMainHandlerDrain();
        verify(l, times(0)).updateAllJobs();
        verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        mIUidObserver.onUidGone(UID_10_1, true);

        waitUntilMainHandlerDrain();
        verify(l, times(0)).updateAllJobs();
        verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        mIUidObserver.onUidActive(UID_10_1);

        waitUntilMainHandlerDrain();
        verify(l, times(0)).updateAllJobs();
        verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);

        mIUidObserver.onUidIdle(UID_10_1, true);

        waitUntilMainHandlerDrain();
        verify(l, times(0)).updateAllJobs();
        verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());

        verify(l, times(0)).unblockAllUnrestrictedAlarms();
        verify(l, times(0)).unblockAlarmsForUid(anyInt());
        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
        reset(l);
    }

    @Test
    public void testUserRemoved() throws Exception {
        final ForceAppStandbyTrackerTestable instance = newInstance();
        callStart(instance);

        mIUidObserver.onUidActive(UID_1);
        mIUidObserver.onUidActive(UID_10_1);

        setAppOps(UID_2, PACKAGE_2, true);
        setAppOps(UID_10_2, PACKAGE_2, true);

        assertTrue(instance.isInForeground(UID_1));
        assertTrue(instance.isInForeground(UID_10_1));

        assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
        assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));

        final Intent intent = new Intent(Intent.ACTION_USER_REMOVED);
        intent.putExtra(Intent.EXTRA_USER_HANDLE, 10);
        mReceiver.onReceive(mMockContext, intent);

        waitUntilMainHandlerDrain();

        assertTrue(instance.isInForeground(UID_1));
        assertFalse(instance.isInForeground(UID_10_1));

        assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_2, PACKAGE_2));
        assertTrue(instance.isRunAnyInBackgroundAppOpsAllowed(UID_10_2, PACKAGE_2));
    }

    static int[] array(int... appIds) {
        Arrays.sort(appIds);
        return appIds;
    }

    private final Random mRandom = new Random();

    int[] makeRandomArray() {
        final ArrayList<Integer> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            if (mRandom.nextDouble() < 0.5) {
                list.add(i);
            }
        }
        return Arrays.stream(list.toArray(new Integer[list.size()]))
                .mapToInt(Integer::intValue).toArray();
    }

    static boolean isAnyAppIdUnwhitelistedSlow(int[] prevArray, int[] newArray) {
        Arrays.sort(newArray); // Just in case...
        for (int p : prevArray) {
            if (Arrays.binarySearch(newArray, p) < 0) {
                return true;
            }
        }
        return false;
    }

    private void checkAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray, boolean expected) {
        assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray),
                expected, ForceAppStandbyTracker.isAnyAppIdUnwhitelisted(prevArray, newArray));

        // Also test isAnyAppIdUnwhitelistedSlow.
        assertEquals("Input: " + Arrays.toString(prevArray) + " " + Arrays.toString(newArray),
                expected, isAnyAppIdUnwhitelistedSlow(prevArray, newArray));
    }

    @Test
    public void isAnyAppIdUnwhitelisted() {
        checkAnyAppIdUnwhitelisted(array(), array(), false);

        checkAnyAppIdUnwhitelisted(array(1), array(), true);
        checkAnyAppIdUnwhitelisted(array(1), array(1), false);
        checkAnyAppIdUnwhitelisted(array(1), array(0, 1), false);
        checkAnyAppIdUnwhitelisted(array(1), array(0, 1, 2), false);
        checkAnyAppIdUnwhitelisted(array(1), array(0, 1, 2), false);

        checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(), true);
        checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(1, 2), true);
        checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(1, 2, 10), false);
        checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(2, 10), true);
        checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(0, 1, 2, 4, 3, 10), false);
        checkAnyAppIdUnwhitelisted(array(1, 2, 10), array(0, 0, 1, 2, 10), false);

        // Random test
        int trueCount = 0;
        final int count = 10000;
        for (int i = 0; i < count; i++) {
            final int[] array1 = makeRandomArray();
            final int[] array2 = makeRandomArray();

            final boolean expected = isAnyAppIdUnwhitelistedSlow(array1, array2);
            final boolean actual = ForceAppStandbyTracker.isAnyAppIdUnwhitelisted(array1, array2);

            assertEquals("Input: " + Arrays.toString(array1) + " " + Arrays.toString(array2),
                    expected, actual);
            if (expected) {
                trueCount++;
            }
        }

        // Make sure makeRandomArray() didn't generate all same arrays by accident.
        assertTrue(trueCount > 0);
        assertTrue(trueCount < count);
    }
}
