diff --git a/core/proto/android/server/background_install_control.proto b/core/proto/android/server/background_install_control.proto
new file mode 100644
index 0000000..38e6b4d
--- /dev/null
+++ b/core/proto/android/server/background_install_control.proto
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+syntax = "proto2";
+package com.android.server.pm;
+
+option java_multiple_files = true;
+
+// Proto for the background installed packages.
+// It's used for serializing the background installed package info to disk.
+message BackgroundInstalledPackagesProto {
+  repeated BackgroundInstalledPackageProto bg_installed_pkg = 1;
+}
+
+// Proto for the background installed package entry
+message BackgroundInstalledPackageProto {
+  optional string package_name = 1;
+  optional int32 user_id = 2;
+}
diff --git a/services/core/java/com/android/server/pm/BackgroundInstallControlService.java b/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
index df95f86..d4c4c69 100644
--- a/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
+++ b/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
@@ -17,19 +17,46 @@
 package com.android.server.pm;
 
 import android.annotation.NonNull;
+import android.app.usage.UsageEvents;
+import android.app.usage.UsageStatsManagerInternal;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.IBackgroundInstallControlService;
 import android.content.pm.IPackageManager;
+import android.content.pm.InstallSourceInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.ParceledListSlice;
-import android.os.IBinder;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.ArraySet;
+import android.util.AtomicFile;
+import android.util.Slog;
 import android.util.SparseArrayMap;
+import android.util.SparseSetArray;
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.LocalServices;
+import com.android.server.ServiceThread;
 import com.android.server.SystemService;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ListIterator;
+import java.util.Set;
+import java.util.TreeSet;
 
 /**
  * @hide
@@ -37,14 +64,30 @@
 public class BackgroundInstallControlService extends SystemService {
     private static final String TAG = "BackgroundInstallControlService";
 
+    private static final String DISK_FILE_NAME = "states";
+    private static final String DISK_DIR_NAME = "bic";
+
+    private static final int MAX_FOREGROUND_TIME_FRAMES_SIZE = 10;
+
+    private static final int MSG_USAGE_EVENT_RECEIVED = 0;
+    private static final int MSG_PACKAGE_ADDED = 1;
+    private static final int MSG_PACKAGE_REMOVED = 2;
+
     private final Context mContext;
     private final BinderService mBinderService;
     private final IPackageManager mIPackageManager;
+    private final PackageManagerInternal mPackageManagerInternal;
+    private final UsageStatsManagerInternal mUsageStatsManagerInternal;
+    private final PermissionManagerServiceInternal mPermissionManager;
+    private final Handler mHandler;
+    private final File mDiskFile;
 
-    // User ID -> package name -> time diff
-    // The time diff between the last foreground activity installer and
-    // the "onPackageAdded" function call.
-    private final SparseArrayMap<String, Long> mBackgroundInstalledPackages =
+
+    private SparseSetArray<String> mBackgroundInstalledPackages = null;
+
+    // User ID -> package name -> set of foreground time frame
+    private final SparseArrayMap<String,
+            TreeSet<ForegroundTimeFrame>> mInstallerForegroundTimeFrames =
             new SparseArrayMap<>();
 
     public BackgroundInstallControlService(@NonNull Context context) {
@@ -56,49 +99,385 @@
         super(injector.getContext());
         mContext = injector.getContext();
         mIPackageManager = injector.getIPackageManager();
+        mPackageManagerInternal = injector.getPackageManagerInternal();
+        mPermissionManager = injector.getPermissionManager();
+        mHandler = new EventHandler(injector.getLooper(), this);
+        mDiskFile = injector.getDiskFile();
+        mUsageStatsManagerInternal = injector.getUsageStatsManagerInternal();
+        mUsageStatsManagerInternal.registerListener(
+                (userId, event) ->
+                        mHandler.obtainMessage(MSG_USAGE_EVENT_RECEIVED,
+                                userId,
+                                0,
+                                event).sendToTarget()
+        );
         mBinderService = new BinderService(this);
     }
 
     private static final class BinderService extends IBackgroundInstallControlService.Stub {
         final BackgroundInstallControlService mService;
 
-        BinderService(BackgroundInstallControlService service)  {
+        BinderService(BackgroundInstallControlService service) {
             mService = service;
         }
 
         @Override
         public ParceledListSlice<PackageInfo> getBackgroundInstalledPackages(
                 @PackageManager.PackageInfoFlagsBits long flags, int userId) {
-            ParceledListSlice<PackageInfo> packages;
-            try {
-                packages = mService.mIPackageManager.getInstalledPackages(flags, userId);
-            } catch (RemoteException e) {
-                throw new IllegalStateException("Package manager not available", e);
-            }
-
-            // TODO(b/244216300): to enable the test the usage by BinaryTransparencyService,
-            // we currently comment out the actual implementation.
-            // The fake implementation is just to filter out the first app of the list.
-            // for (int i = 0, size = packages.getList().size(); i < size; i++) {
-            //     String packageName = packages.getList().get(i).packageName;
-            //     if (!mBackgroundInstalledPackages.contains(userId, packageName) {
-            //         packages.getList().remove(i);
-            //     }
-            // }
-            if (packages.getList().size() > 0) {
-                packages.getList().remove(0);
-            }
-            return packages;
+            return mService.getBackgroundInstalledPackages(flags, userId);
         }
     }
 
-    /**
-     * Called when the system service should publish a binder service using
-     * {@link #publishBinderService(String, IBinder).}
-     */
+    @VisibleForTesting
+    ParceledListSlice<PackageInfo> getBackgroundInstalledPackages(
+            @PackageManager.PackageInfoFlagsBits long flags, int userId) {
+        ParceledListSlice<PackageInfo> packages;
+        try {
+            packages = mIPackageManager.getInstalledPackages(flags, userId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+
+        initBackgroundInstalledPackages();
+
+        ListIterator<PackageInfo> iter = packages.getList().listIterator();
+        while (iter.hasNext()) {
+            String packageName = iter.next().packageName;
+            if (!mBackgroundInstalledPackages.contains(userId, packageName)) {
+                iter.remove();
+            }
+        }
+
+        return packages;
+    }
+
+    private static class EventHandler extends Handler {
+        private final BackgroundInstallControlService mService;
+
+        EventHandler(Looper looper, BackgroundInstallControlService service) {
+            super(looper);
+            mService = service;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_USAGE_EVENT_RECEIVED: {
+                    mService.handleUsageEvent((UsageEvents.Event) msg.obj, msg.arg1 /* userId */);
+                    break;
+                }
+                case MSG_PACKAGE_ADDED: {
+                    mService.handlePackageAdd((String) msg.obj, msg.arg1 /* userId */);
+                    break;
+                }
+                case MSG_PACKAGE_REMOVED: {
+                    mService.handlePackageRemove((String) msg.obj, msg.arg1 /* userId */);
+                    break;
+                }
+                default:
+                    Slog.w(TAG, "Unknown message: " + msg.what);
+            }
+        }
+    }
+
+    void handlePackageAdd(String packageName, int userId) {
+        InstallSourceInfo installSourceInfo = null;
+        try {
+            installSourceInfo = mIPackageManager.getInstallSourceInfo(packageName);
+        } catch (RemoteException e) {
+            // Failed to talk to PackageManagerService Should never happen!
+            throw e.rethrowFromSystemServer();
+        }
+        String installerPackageName =
+                installSourceInfo == null ? null : installSourceInfo.getInstallingPackageName();
+        if (installerPackageName == null) {
+            Slog.w(TAG, "fails to get installerPackageName for " + packageName);
+            return;
+        }
+
+        ApplicationInfo appInfo = null;
+        try {
+            appInfo = mIPackageManager.getApplicationInfo(packageName,
+                    0, userId);
+        } catch (RemoteException e) {
+            // Failed to talk to PackageManagerService Should never happen!
+            throw e.rethrowFromSystemServer();
+        }
+
+        if (appInfo == null) {
+            Slog.w(TAG, "fails to get appInfo for " + packageName);
+            return;
+        }
+
+        // convert up-time to current time.
+        final long installTimestamp = System.currentTimeMillis()
+                - (SystemClock.uptimeMillis() - appInfo.createTimestamp);
+
+        if (wasForegroundInstallation(installerPackageName, userId, installTimestamp)) {
+            return;
+        }
+
+        initBackgroundInstalledPackages();
+        mBackgroundInstalledPackages.add(userId, packageName);
+        writeBackgroundInstalledPackagesToDisk();
+    }
+
+    private boolean wasForegroundInstallation(String installerPackageName,
+            int userId, long installTimestamp) {
+        TreeSet<BackgroundInstallControlService.ForegroundTimeFrame> foregroundTimeFrames =
+                mInstallerForegroundTimeFrames.get(userId, installerPackageName);
+
+        // The installer never run in foreground.
+        if (foregroundTimeFrames == null) {
+            return false;
+        }
+
+        for (var foregroundTimeFrame : foregroundTimeFrames) {
+            // the foreground time frame starts later than the installation.
+            // so the installation is outside the foreground time frame.
+            if (foregroundTimeFrame.startTimeStampMillis > installTimestamp) {
+                continue;
+            }
+
+            // the foreground time frame is not over yet.
+            // the installation is inside the foreground time frame.
+            if (!foregroundTimeFrame.isDone()) {
+                return true;
+            }
+
+            // the foreground time frame ends later than the installation.
+            // the installation is inside the foreground time frame.
+            if (installTimestamp <= foregroundTimeFrame.endTimeStampMillis) {
+                return true;
+            }
+        }
+
+        // the installation is not inside any of foreground time frames.
+        // so it is not a foreground installation.
+        return false;
+    }
+
+    void handlePackageRemove(String packageName, int userId) {
+        initBackgroundInstalledPackages();
+        mBackgroundInstalledPackages.remove(userId, packageName);
+        writeBackgroundInstalledPackagesToDisk();
+    }
+
+    void handleUsageEvent(UsageEvents.Event event, int userId) {
+        if (event.mEventType != UsageEvents.Event.ACTIVITY_RESUMED
+                && event.mEventType != UsageEvents.Event.ACTIVITY_PAUSED
+                && event.mEventType != UsageEvents.Event.ACTIVITY_STOPPED) {
+            return;
+        }
+
+        if (!isInstaller(event.mPackage, userId)) {
+            return;
+        }
+
+        if (!mInstallerForegroundTimeFrames.contains(userId, event.mPackage)) {
+            mInstallerForegroundTimeFrames.add(userId, event.mPackage, new TreeSet<>());
+        }
+
+        TreeSet<BackgroundInstallControlService.ForegroundTimeFrame> foregroundTimeFrames =
+                mInstallerForegroundTimeFrames.get(userId, event.mPackage);
+
+        if ((foregroundTimeFrames.size() == 0) || foregroundTimeFrames.last().isDone()) {
+            // ignore the other events if there is no open ForegroundTimeFrame.
+            if (event.mEventType != UsageEvents.Event.ACTIVITY_RESUMED) {
+                return;
+            }
+            foregroundTimeFrames.add(new ForegroundTimeFrame(event.mTimeStamp));
+        }
+
+        foregroundTimeFrames.last().addEvent(event);
+
+        if (foregroundTimeFrames.size() > MAX_FOREGROUND_TIME_FRAMES_SIZE) {
+            foregroundTimeFrames.pollFirst();
+        }
+    }
+
+    @VisibleForTesting
+    void writeBackgroundInstalledPackagesToDisk() {
+        AtomicFile atomicFile = new AtomicFile(mDiskFile);
+        FileOutputStream fileOutputStream;
+        try {
+            fileOutputStream = atomicFile.startWrite();
+        } catch (IOException e) {
+            Slog.e(TAG, "Failed to start write to states protobuf.", e);
+            return;
+        }
+
+        try {
+            ProtoOutputStream protoOutputStream = new ProtoOutputStream(fileOutputStream);
+            for (int i = 0; i < mBackgroundInstalledPackages.size(); i++) {
+                int userId = mBackgroundInstalledPackages.keyAt(i);
+                for (String packageName : mBackgroundInstalledPackages.get(userId)) {
+                    long token = protoOutputStream.start(
+                            BackgroundInstalledPackagesProto.BG_INSTALLED_PKG);
+                    protoOutputStream.write(
+                            BackgroundInstalledPackageProto.PACKAGE_NAME, packageName);
+                    protoOutputStream.write(
+                            BackgroundInstalledPackageProto.USER_ID, userId + 1);
+                    protoOutputStream.end(token);
+                }
+            }
+            protoOutputStream.flush();
+            atomicFile.finishWrite(fileOutputStream);
+        } catch (Exception e) {
+            Slog.e(TAG, "Failed to finish write to states protobuf.", e);
+            atomicFile.failWrite(fileOutputStream);
+        }
+    }
+
+    @VisibleForTesting
+    void initBackgroundInstalledPackages() {
+        if (mBackgroundInstalledPackages != null) {
+            return;
+        }
+
+        mBackgroundInstalledPackages = new SparseSetArray<>();
+
+        if (!mDiskFile.exists()) {
+            return;
+        }
+
+        AtomicFile atomicFile = new AtomicFile(mDiskFile);
+        try (FileInputStream fileInputStream = atomicFile.openRead()) {
+            ProtoInputStream protoInputStream = new ProtoInputStream(fileInputStream);
+
+            while (protoInputStream.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+                if (protoInputStream.getFieldNumber()
+                        != (int) BackgroundInstalledPackagesProto.BG_INSTALLED_PKG) {
+                    continue;
+                }
+                long token = protoInputStream.start(
+                        BackgroundInstalledPackagesProto.BG_INSTALLED_PKG);
+                String packageName = null;
+                int userId = UserHandle.USER_NULL;
+                while (protoInputStream.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+                    switch (protoInputStream.getFieldNumber()) {
+                        case (int) BackgroundInstalledPackageProto.PACKAGE_NAME:
+                            packageName = protoInputStream.readString(
+                                    BackgroundInstalledPackageProto.PACKAGE_NAME);
+                            break;
+                        case (int) BackgroundInstalledPackageProto.USER_ID:
+                            userId = protoInputStream.readInt(
+                                    BackgroundInstalledPackageProto.USER_ID) - 1;
+                            break;
+                        default:
+                            Slog.w(TAG, "Undefined field in proto: "
+                                    + protoInputStream.getFieldNumber());
+                    }
+                }
+                protoInputStream.end(token);
+                if (packageName != null && userId != UserHandle.USER_NULL) {
+                    mBackgroundInstalledPackages.add(userId, packageName);
+                } else {
+                    Slog.w(TAG, "Fails to get packageName or UserId from proto file");
+                }
+            }
+        } catch (IOException e) {
+            Slog.w(TAG, "Error reading state from the disk", e);
+        }
+    }
+
+    @VisibleForTesting
+    SparseSetArray<String> getBackgroundInstalledPackages() {
+        return mBackgroundInstalledPackages;
+    }
+
+    @VisibleForTesting
+    SparseArrayMap<String, TreeSet<ForegroundTimeFrame>> getInstallerForegroundTimeFrames() {
+        return mInstallerForegroundTimeFrames;
+    }
+
+    private boolean isInstaller(String pkgName, int userId) {
+        if (mInstallerForegroundTimeFrames.contains(userId, pkgName)) {
+            return true;
+        }
+        return mPermissionManager.checkPermission(pkgName,
+                android.Manifest.permission.INSTALL_PACKAGES,
+                userId) == PackageManager.PERMISSION_GRANTED;
+    }
+
     @Override
     public void onStart() {
-        publishBinderService(Context.BACKGROUND_INSTALL_CONTROL_SERVICE, mBinderService);
+        onStart(/* isForTesting= */ false);
+    }
+
+    @VisibleForTesting
+    void onStart(boolean isForTesting) {
+        if (!isForTesting) {
+            publishBinderService(Context.BACKGROUND_INSTALL_CONTROL_SERVICE, mBinderService);
+        }
+
+        mPackageManagerInternal.getPackageList(new PackageManagerInternal.PackageListObserver() {
+            @Override
+            public void onPackageAdded(String packageName, int uid) {
+                final int userId = UserHandle.getUserId(uid);
+                mHandler.obtainMessage(MSG_PACKAGE_ADDED,
+                        userId, 0, packageName).sendToTarget();
+            }
+
+            @Override
+            public void onPackageRemoved(String packageName, int uid) {
+                final int userId = UserHandle.getUserId(uid);
+                mHandler.obtainMessage(MSG_PACKAGE_REMOVED,
+                        userId, 0, packageName).sendToTarget();
+            }
+        });
+    }
+
+    // The foreground time frame (ForegroundTimeFrame) represents the period
+    // when a package's activities continuously occupy the foreground.
+    // Each ForegroundTimeFrame starts with an ACTIVITY_RESUMED event,
+    // and then ends with an ACTIVITY_PAUSED or ACTIVITY_STOPPED event.
+    // The startTimeStampMillis stores the timestamp of the ACTIVITY_RESUMED event.
+    // The endTimeStampMillis stores the timestamp of the ACTIVITY_PAUSED or ACTIVITY_STOPPED event
+    // that wraps up the ForegroundTimeFrame.
+    // The activities are designed to handle the edge case in which a package's one activity
+    // seamlessly replace another activity of the same package. Thus, we count these activities
+    // together as a ForegroundTimeFrame. For this scenario, only when all the activities terminate
+    // shall consider the completion of the ForegroundTimeFrame.
+    static final class ForegroundTimeFrame implements Comparable<ForegroundTimeFrame> {
+        public final long startTimeStampMillis;
+        public long endTimeStampMillis;
+        public final Set<Integer> activities;
+
+        public int compareTo(ForegroundTimeFrame o) {
+            int comp = Long.compare(startTimeStampMillis, o.startTimeStampMillis);
+            if (comp != 0) return comp;
+
+            return Integer.compare(hashCode(), o.hashCode());
+        }
+
+        ForegroundTimeFrame(long startTimeStampMillis) {
+            this.startTimeStampMillis = startTimeStampMillis;
+            endTimeStampMillis = 0;
+            activities = new ArraySet<>();
+        }
+
+        public boolean isDone() {
+            return endTimeStampMillis != 0;
+        }
+
+        public void addEvent(UsageEvents.Event event) {
+            switch (event.mEventType) {
+                case UsageEvents.Event.ACTIVITY_RESUMED:
+                    activities.add(event.mInstanceId);
+                    break;
+                case UsageEvents.Event.ACTIVITY_PAUSED:
+                case UsageEvents.Event.ACTIVITY_STOPPED:
+                    if (activities.contains(event.mInstanceId)) {
+                        activities.remove(event.mInstanceId);
+                        if (activities.size() == 0) {
+                            endTimeStampMillis = event.mTimeStamp;
+                        }
+                    }
+                    break;
+                default:
+            }
+        }
     }
 
     /**
@@ -108,6 +487,16 @@
         Context getContext();
 
         IPackageManager getIPackageManager();
+
+        PackageManagerInternal getPackageManagerInternal();
+
+        UsageStatsManagerInternal getUsageStatsManagerInternal();
+
+        PermissionManagerServiceInternal getPermissionManager();
+
+        Looper getLooper();
+
+        File getDiskFile();
     }
 
     private static final class InjectorImpl implements Injector {
@@ -126,5 +515,36 @@
         public IPackageManager getIPackageManager() {
             return IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
         }
+
+        @Override
+        public PackageManagerInternal getPackageManagerInternal() {
+            return LocalServices.getService(PackageManagerInternal.class);
+        }
+
+        @Override
+        public UsageStatsManagerInternal getUsageStatsManagerInternal() {
+            return LocalServices.getService(UsageStatsManagerInternal.class);
+        }
+
+        @Override
+        public PermissionManagerServiceInternal getPermissionManager() {
+            return LocalServices.getService(PermissionManagerServiceInternal.class);
+        }
+
+        @Override
+        public Looper getLooper() {
+            ServiceThread serviceThread = new ServiceThread(TAG,
+                    android.os.Process.THREAD_PRIORITY_FOREGROUND, true /* allowIo */);
+            serviceThread.start();
+            return serviceThread.getLooper();
+
+        }
+
+        @Override
+        public File getDiskFile() {
+            File dir = new File(Environment.getDataSystemDirectory(), DISK_DIR_NAME);
+            File file = new File(dir, DISK_FILE_NAME);
+            return file;
+        }
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/BackgroundInstallControlServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/BackgroundInstallControlServiceTest.java
new file mode 100644
index 0000000..54fa272
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/BackgroundInstallControlServiceTest.java
@@ -0,0 +1,840 @@
+/*
+ * Copyright (C) 2022 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.pm;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.usage.UsageEvents;
+import android.app.usage.UsageEvents.Event;
+import android.app.usage.UsageStatsManagerInternal;
+import android.app.usage.UsageStatsManagerInternal.UsageEventListener;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.InstallSourceInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+import android.content.pm.ParceledListSlice;
+import android.os.FileUtils;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.test.TestLooper;
+import android.platform.test.annotations.Presubmit;
+import android.util.AtomicFile;
+import android.util.SparseSetArray;
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoOutputStream;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.internal.util.reflection.FieldSetter;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link com.android.server.pm.BackgroundInstallControlService}
+ */
+@Presubmit
+public final class BackgroundInstallControlServiceTest {
+    private static final String INSTALLER_NAME_1 = "installer1";
+    private static final String INSTALLER_NAME_2 = "installer2";
+    private static final String PACKAGE_NAME_1 = "package1";
+    private static final String PACKAGE_NAME_2 = "package2";
+    private static final String PACKAGE_NAME_3 = "package3";
+    private static final int USER_ID_1 = 1;
+    private static final int USER_ID_2 = 2;
+    private static final long USAGE_EVENT_TIMESTAMP_1 = 1000;
+    private static final long USAGE_EVENT_TIMESTAMP_2 = 2000;
+    private static final long USAGE_EVENT_TIMESTAMP_3 = 3000;
+    private static final long PACKAGE_ADD_TIMESTAMP_1 = 1500;
+
+    private BackgroundInstallControlService mBackgroundInstallControlService;
+    private PackageManagerInternal.PackageListObserver mPackageListObserver;
+    private UsageEventListener mUsageEventListener;
+    private TestLooper mTestLooper;
+    private Looper mLooper;
+    private File mFile;
+
+
+    @Mock
+    private Context mContext;
+    @Mock
+    private IPackageManager mIPackageManager;
+    @Mock
+    private PackageManagerInternal mPackageManagerInternal;
+    @Mock
+    private UsageStatsManagerInternal mUsageStatsManagerInternal;
+    @Mock
+    private PermissionManagerServiceInternal mPermissionManager;
+    @Captor
+    private ArgumentCaptor<PackageManagerInternal.PackageListObserver> mPackageListObserverCaptor;
+    @Captor
+    private ArgumentCaptor<UsageEventListener> mUsageEventListenerCaptor;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mTestLooper = new TestLooper();
+        mLooper = mTestLooper.getLooper();
+        mFile = new File(
+                InstrumentationRegistry.getInstrumentation().getContext().getCacheDir(),
+                "test");
+        mBackgroundInstallControlService = new BackgroundInstallControlService(
+                new MockInjector(mContext));
+
+        verify(mUsageStatsManagerInternal).registerListener(mUsageEventListenerCaptor.capture());
+        mUsageEventListener = mUsageEventListenerCaptor.getValue();
+
+        mBackgroundInstallControlService.onStart(true);
+        verify(mPackageManagerInternal).getPackageList(mPackageListObserverCaptor.capture());
+        mPackageListObserver = mPackageListObserverCaptor.getValue();
+    }
+
+    @After
+    public void tearDown() {
+        FileUtils.deleteContentsAndDir(mFile);
+    }
+
+    @Test
+    public void testInitBackgroundInstalledPackages_empty() {
+        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
+        mBackgroundInstallControlService.initBackgroundInstalledPackages();
+        assertNotNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
+        assertEquals(0,
+                mBackgroundInstallControlService.getBackgroundInstalledPackages().size());
+    }
+
+    @Test
+    public void testInitBackgroundInstalledPackages_one() {
+        AtomicFile atomicFile = new AtomicFile(mFile);
+        FileOutputStream fileOutputStream;
+        try {
+            fileOutputStream = atomicFile.startWrite();
+        } catch (IOException e) {
+            fail("Failed to start write to states protobuf." + e);
+            return;
+        }
+
+        // Write test data to the file on the disk.
+        try {
+            ProtoOutputStream protoOutputStream = new ProtoOutputStream(fileOutputStream);
+            long token = protoOutputStream.start(
+                    BackgroundInstalledPackagesProto.BG_INSTALLED_PKG);
+            protoOutputStream.write(
+                    BackgroundInstalledPackageProto.PACKAGE_NAME, PACKAGE_NAME_1);
+            protoOutputStream.write(
+                    BackgroundInstalledPackageProto.USER_ID, USER_ID_1 + 1);
+            protoOutputStream.end(token);
+            protoOutputStream.flush();
+            atomicFile.finishWrite(fileOutputStream);
+        } catch (Exception e) {
+            fail("Failed to finish write to states protobuf. " + e);
+            atomicFile.failWrite(fileOutputStream);
+        }
+
+        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
+        mBackgroundInstallControlService.initBackgroundInstalledPackages();
+        var packages = mBackgroundInstallControlService.getBackgroundInstalledPackages();
+        assertNotNull(packages);
+        assertEquals(1, packages.size());
+        assertTrue(packages.contains(USER_ID_1, PACKAGE_NAME_1));
+    }
+
+    @Test
+    public void testInitBackgroundInstalledPackages_two() {
+        AtomicFile atomicFile = new AtomicFile(mFile);
+        FileOutputStream fileOutputStream;
+        try {
+            fileOutputStream = atomicFile.startWrite();
+        } catch (IOException e) {
+            fail("Failed to start write to states protobuf." + e);
+            return;
+        }
+
+        // Write test data to the file on the disk.
+        try {
+            ProtoOutputStream protoOutputStream = new ProtoOutputStream(fileOutputStream);
+
+            long token = protoOutputStream.start(
+                    BackgroundInstalledPackagesProto.BG_INSTALLED_PKG);
+            protoOutputStream.write(
+                    BackgroundInstalledPackageProto.PACKAGE_NAME, PACKAGE_NAME_1);
+            protoOutputStream.write(
+                    BackgroundInstalledPackageProto.USER_ID, USER_ID_1 + 1);
+            protoOutputStream.end(token);
+
+            token = protoOutputStream.start(
+                    BackgroundInstalledPackagesProto.BG_INSTALLED_PKG);
+            protoOutputStream.write(
+                    BackgroundInstalledPackageProto.PACKAGE_NAME, PACKAGE_NAME_2);
+            protoOutputStream.write(
+                    BackgroundInstalledPackageProto.USER_ID, USER_ID_2 + 1);
+            protoOutputStream.end(token);
+
+            protoOutputStream.flush();
+            atomicFile.finishWrite(fileOutputStream);
+        } catch (Exception e) {
+            fail("Failed to finish write to states protobuf. " + e);
+            atomicFile.failWrite(fileOutputStream);
+        }
+
+        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
+        mBackgroundInstallControlService.initBackgroundInstalledPackages();
+        var packages = mBackgroundInstallControlService.getBackgroundInstalledPackages();
+        assertNotNull(packages);
+        assertEquals(2, packages.size());
+        assertTrue(packages.contains(USER_ID_1, PACKAGE_NAME_1));
+        assertTrue(packages.contains(USER_ID_2, PACKAGE_NAME_2));
+    }
+
+    @Test
+    public void testWriteBackgroundInstalledPackagesToDisk_empty() {
+        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
+        mBackgroundInstallControlService.initBackgroundInstalledPackages();
+        var packages = mBackgroundInstallControlService.getBackgroundInstalledPackages();
+        assertNotNull(packages);
+        mBackgroundInstallControlService.writeBackgroundInstalledPackagesToDisk();
+
+        // Read the file on the disk to verify
+        var packagesInDisk = new SparseSetArray<>();
+        AtomicFile atomicFile = new AtomicFile(mFile);
+        try (FileInputStream fileInputStream  = atomicFile.openRead()) {
+            ProtoInputStream protoInputStream = new ProtoInputStream(fileInputStream);
+
+            while (protoInputStream.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+                if (protoInputStream.getFieldNumber()
+                        != (int) BackgroundInstalledPackagesProto.BG_INSTALLED_PKG) {
+                    continue;
+                }
+                long token = protoInputStream.start(
+                        BackgroundInstalledPackagesProto.BG_INSTALLED_PKG);
+                String packageName = null;
+                int userId = UserHandle.USER_NULL;
+                while (protoInputStream.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+                    switch (protoInputStream.getFieldNumber()) {
+                        case (int) BackgroundInstalledPackageProto.PACKAGE_NAME:
+                            packageName = protoInputStream.readString(
+                                    BackgroundInstalledPackageProto.PACKAGE_NAME);
+                            break;
+                        case (int) BackgroundInstalledPackageProto.USER_ID:
+                            userId = protoInputStream.readInt(
+                                    BackgroundInstalledPackageProto.USER_ID) - 1;
+                            break;
+                        default:
+                            fail("Undefined field in proto: "
+                                    + protoInputStream.getFieldNumber());
+                    }
+                }
+                protoInputStream.end(token);
+                if (packageName != null && userId != UserHandle.USER_NULL) {
+                    packagesInDisk.add(userId, packageName);
+                } else {
+                    fail("Fails to get packageName or UserId from proto file");
+                }
+            }
+        } catch (IOException e) {
+            fail("Error reading state from the disk. " + e);
+        }
+
+        assertEquals(0, packagesInDisk.size());
+        assertEquals(packages.size(), packagesInDisk.size());
+    }
+
+    @Test
+    public void testWriteBackgroundInstalledPackagesToDisk_one() {
+        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
+        mBackgroundInstallControlService.initBackgroundInstalledPackages();
+        var packages = mBackgroundInstallControlService.getBackgroundInstalledPackages();
+        assertNotNull(packages);
+
+        packages.add(USER_ID_1, PACKAGE_NAME_1);
+        mBackgroundInstallControlService.writeBackgroundInstalledPackagesToDisk();
+
+        // Read the file on the disk to verify
+        var packagesInDisk = new SparseSetArray<>();
+        AtomicFile atomicFile = new AtomicFile(mFile);
+        try (FileInputStream fileInputStream  = atomicFile.openRead()) {
+            ProtoInputStream protoInputStream = new ProtoInputStream(fileInputStream);
+
+            while (protoInputStream.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+                if (protoInputStream.getFieldNumber()
+                        != (int) BackgroundInstalledPackagesProto.BG_INSTALLED_PKG) {
+                    continue;
+                }
+                long token = protoInputStream.start(
+                        BackgroundInstalledPackagesProto.BG_INSTALLED_PKG);
+                String packageName = null;
+                int userId = UserHandle.USER_NULL;
+                while (protoInputStream.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+                    switch (protoInputStream.getFieldNumber()) {
+                        case (int) BackgroundInstalledPackageProto.PACKAGE_NAME:
+                            packageName = protoInputStream.readString(
+                                    BackgroundInstalledPackageProto.PACKAGE_NAME);
+                            break;
+                        case (int) BackgroundInstalledPackageProto.USER_ID:
+                            userId = protoInputStream.readInt(
+                                    BackgroundInstalledPackageProto.USER_ID) - 1;
+                            break;
+                        default:
+                            fail("Undefined field in proto: "
+                                    + protoInputStream.getFieldNumber());
+                    }
+                }
+                protoInputStream.end(token);
+                if (packageName != null && userId != UserHandle.USER_NULL) {
+                    packagesInDisk.add(userId, packageName);
+                } else {
+                    fail("Fails to get packageName or UserId from proto file");
+                }
+            }
+        } catch (IOException e) {
+            fail("Error reading state from the disk. " + e);
+        }
+
+        assertEquals(1, packagesInDisk.size());
+        assertEquals(packages.size(), packagesInDisk.size());
+        assertTrue(packages.contains(USER_ID_1, PACKAGE_NAME_1));
+    }
+
+    @Test
+    public void testWriteBackgroundInstalledPackagesToDisk_two() {
+        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
+        mBackgroundInstallControlService.initBackgroundInstalledPackages();
+        var packages = mBackgroundInstallControlService.getBackgroundInstalledPackages();
+        assertNotNull(packages);
+
+        packages.add(USER_ID_1, PACKAGE_NAME_1);
+        packages.add(USER_ID_2, PACKAGE_NAME_2);
+        mBackgroundInstallControlService.writeBackgroundInstalledPackagesToDisk();
+
+        // Read the file on the disk to verify
+        var packagesInDisk = new SparseSetArray<>();
+        AtomicFile atomicFile = new AtomicFile(mFile);
+        try (FileInputStream fileInputStream  = atomicFile.openRead()) {
+            ProtoInputStream protoInputStream = new ProtoInputStream(fileInputStream);
+
+            while (protoInputStream.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+                if (protoInputStream.getFieldNumber()
+                        != (int) BackgroundInstalledPackagesProto.BG_INSTALLED_PKG) {
+                    continue;
+                }
+                long token = protoInputStream.start(
+                        BackgroundInstalledPackagesProto.BG_INSTALLED_PKG);
+                String packageName = null;
+                int userId = UserHandle.USER_NULL;
+                while (protoInputStream.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+                    switch (protoInputStream.getFieldNumber()) {
+                        case (int) BackgroundInstalledPackageProto.PACKAGE_NAME:
+                            packageName = protoInputStream.readString(
+                                    BackgroundInstalledPackageProto.PACKAGE_NAME);
+                            break;
+                        case (int) BackgroundInstalledPackageProto.USER_ID:
+                            userId = protoInputStream.readInt(
+                                    BackgroundInstalledPackageProto.USER_ID) - 1;
+                            break;
+                        default:
+                            fail("Undefined field in proto: "
+                                    + protoInputStream.getFieldNumber());
+                    }
+                }
+                protoInputStream.end(token);
+                if (packageName != null && userId != UserHandle.USER_NULL) {
+                    packagesInDisk.add(userId, packageName);
+                } else {
+                    fail("Fails to get packageName or UserId from proto file");
+                }
+            }
+        } catch (IOException e) {
+            fail("Error reading state from the disk. " + e);
+        }
+
+        assertEquals(2, packagesInDisk.size());
+        assertEquals(packages.size(), packagesInDisk.size());
+        assertTrue(packages.contains(USER_ID_1, PACKAGE_NAME_1));
+        assertTrue(packages.contains(USER_ID_2, PACKAGE_NAME_2));
+    }
+
+    @Test
+    public void testHandleUsageEvent_permissionDenied() {
+        assertEquals(0,
+                mBackgroundInstallControlService.getInstallerForegroundTimeFrames().numMaps());
+        doReturn(PackageManager.PERMISSION_DENIED).when(mPermissionManager).checkPermission(
+                anyString(), anyString(), anyInt());
+        generateUsageEvent(UsageEvents.Event.ACTIVITY_RESUMED,
+                USER_ID_1, INSTALLER_NAME_1, 0);
+        mTestLooper.dispatchAll();
+        assertEquals(0,
+                mBackgroundInstallControlService.getInstallerForegroundTimeFrames().numMaps());
+    }
+
+    @Test
+    public void testHandleUsageEvent_permissionGranted() {
+        assertEquals(0,
+                mBackgroundInstallControlService.getInstallerForegroundTimeFrames().numMaps());
+        doReturn(PackageManager.PERMISSION_GRANTED).when(mPermissionManager).checkPermission(
+                anyString(), anyString(), anyInt());
+        generateUsageEvent(UsageEvents.Event.ACTIVITY_RESUMED,
+                USER_ID_1, INSTALLER_NAME_1, 0);
+        mTestLooper.dispatchAll();
+        assertEquals(1,
+                mBackgroundInstallControlService.getInstallerForegroundTimeFrames().numMaps());
+    }
+
+    @Test
+    public void testHandleUsageEvent_ignoredEvent() {
+        assertEquals(0,
+                mBackgroundInstallControlService.getInstallerForegroundTimeFrames().numMaps());
+        doReturn(PackageManager.PERMISSION_GRANTED).when(mPermissionManager).checkPermission(
+                anyString(), anyString(), anyInt());
+        generateUsageEvent(UsageEvents.Event.USER_INTERACTION,
+                USER_ID_1, INSTALLER_NAME_1, 0);
+        mTestLooper.dispatchAll();
+        assertEquals(0,
+                mBackgroundInstallControlService.getInstallerForegroundTimeFrames().numMaps());
+    }
+
+    @Test
+    public void testHandleUsageEvent_firstActivityResumedHalfTimeFrame() {
+        assertEquals(0,
+                mBackgroundInstallControlService.getInstallerForegroundTimeFrames().numMaps());
+        doReturn(PackageManager.PERMISSION_GRANTED).when(mPermissionManager).checkPermission(
+                anyString(), anyString(), anyInt());
+        generateUsageEvent(UsageEvents.Event.ACTIVITY_RESUMED,
+                USER_ID_1, INSTALLER_NAME_1, USAGE_EVENT_TIMESTAMP_1);
+        mTestLooper.dispatchAll();
+
+        var installerForegroundTimeFrames =
+                mBackgroundInstallControlService.getInstallerForegroundTimeFrames();
+        assertEquals(1, installerForegroundTimeFrames.numMaps());
+        assertEquals(1, installerForegroundTimeFrames.numElementsForKey(USER_ID_1));
+
+        var foregroundTimeFrames = installerForegroundTimeFrames.get(USER_ID_1, INSTALLER_NAME_1);
+        assertEquals(1, foregroundTimeFrames.size());
+
+        var foregroundTimeFrame = foregroundTimeFrames.first();
+        assertEquals(USAGE_EVENT_TIMESTAMP_1, foregroundTimeFrame.startTimeStampMillis);
+        assertFalse(foregroundTimeFrame.isDone());
+    }
+
+    @Test
+    public void testHandleUsageEvent_firstActivityResumedOneTimeFrame() {
+        assertEquals(0,
+                mBackgroundInstallControlService.getInstallerForegroundTimeFrames().numMaps());
+        doReturn(PackageManager.PERMISSION_GRANTED).when(mPermissionManager).checkPermission(
+                anyString(), anyString(), anyInt());
+        generateUsageEvent(UsageEvents.Event.ACTIVITY_RESUMED,
+                USER_ID_1, INSTALLER_NAME_1, USAGE_EVENT_TIMESTAMP_1);
+        generateUsageEvent(Event.ACTIVITY_STOPPED,
+                USER_ID_1, INSTALLER_NAME_1, USAGE_EVENT_TIMESTAMP_2);
+        mTestLooper.dispatchAll();
+
+        var installerForegroundTimeFrames =
+                mBackgroundInstallControlService.getInstallerForegroundTimeFrames();
+        assertEquals(1, installerForegroundTimeFrames.numMaps());
+        assertEquals(1, installerForegroundTimeFrames.numElementsForKey(USER_ID_1));
+
+        var foregroundTimeFrames = installerForegroundTimeFrames.get(USER_ID_1, INSTALLER_NAME_1);
+        assertEquals(1, foregroundTimeFrames.size());
+
+        var foregroundTimeFrame = foregroundTimeFrames.first();
+        assertEquals(USAGE_EVENT_TIMESTAMP_1, foregroundTimeFrame.startTimeStampMillis);
+        assertTrue(foregroundTimeFrame.isDone());
+    }
+
+    @Test
+    public void testHandleUsageEvent_firstActivityResumedOneAndHalfTimeFrame() {
+        assertEquals(0,
+                mBackgroundInstallControlService.getInstallerForegroundTimeFrames().numMaps());
+        doReturn(PackageManager.PERMISSION_GRANTED).when(mPermissionManager).checkPermission(
+                anyString(), anyString(), anyInt());
+        generateUsageEvent(UsageEvents.Event.ACTIVITY_RESUMED,
+                USER_ID_1, INSTALLER_NAME_1, USAGE_EVENT_TIMESTAMP_1);
+        generateUsageEvent(Event.ACTIVITY_STOPPED,
+                USER_ID_1, INSTALLER_NAME_1, USAGE_EVENT_TIMESTAMP_2);
+        generateUsageEvent(UsageEvents.Event.ACTIVITY_RESUMED,
+                USER_ID_1, INSTALLER_NAME_1, USAGE_EVENT_TIMESTAMP_3);
+        mTestLooper.dispatchAll();
+
+        var installerForegroundTimeFrames =
+                mBackgroundInstallControlService.getInstallerForegroundTimeFrames();
+        assertEquals(1, installerForegroundTimeFrames.numMaps());
+        assertEquals(1, installerForegroundTimeFrames.numElementsForKey(USER_ID_1));
+
+        var foregroundTimeFrames = installerForegroundTimeFrames.get(USER_ID_1, INSTALLER_NAME_1);
+        assertEquals(2, foregroundTimeFrames.size());
+
+        var foregroundTimeFrame1 = foregroundTimeFrames.first();
+        assertEquals(USAGE_EVENT_TIMESTAMP_1, foregroundTimeFrame1.startTimeStampMillis);
+        assertTrue(foregroundTimeFrame1.isDone());
+
+        var foregroundTimeFrame2 = foregroundTimeFrames.last();
+        assertEquals(USAGE_EVENT_TIMESTAMP_3, foregroundTimeFrame2.startTimeStampMillis);
+        assertFalse(foregroundTimeFrame2.isDone());
+    }
+
+    @Test
+    public void testHandleUsageEvent_firstNoneActivityResumed() {
+        assertEquals(0,
+                mBackgroundInstallControlService.getInstallerForegroundTimeFrames().numMaps());
+        doReturn(PackageManager.PERMISSION_GRANTED).when(mPermissionManager).checkPermission(
+                anyString(), anyString(), anyInt());
+        generateUsageEvent(Event.ACTIVITY_STOPPED,
+                USER_ID_1, INSTALLER_NAME_1, USAGE_EVENT_TIMESTAMP_1);
+        mTestLooper.dispatchAll();
+
+        var installerForegroundTimeFrames =
+                mBackgroundInstallControlService.getInstallerForegroundTimeFrames();
+        assertEquals(1, installerForegroundTimeFrames.numMaps());
+        assertEquals(1, installerForegroundTimeFrames.numElementsForKey(USER_ID_1));
+
+        var foregroundTimeFrames = installerForegroundTimeFrames.get(USER_ID_1, INSTALLER_NAME_1);
+        assertEquals(0, foregroundTimeFrames.size());
+    }
+
+    @Test
+    public void testHandleUsageEvent_packageAddedNoUsageEvent() throws
+            RemoteException, NoSuchFieldException {
+        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
+        InstallSourceInfo installSourceInfo = new InstallSourceInfo(
+                /* initiatingPackageName = */ null, /* initiatingPackageSigningInfo = */ null,
+                /* originatingPackageName = */ null,
+                /* installingPackageName = */ INSTALLER_NAME_1);
+        assertEquals(installSourceInfo.getInstallingPackageName(), INSTALLER_NAME_1);
+        when(mIPackageManager.getInstallSourceInfo(anyString())).thenReturn(installSourceInfo);
+        ApplicationInfo appInfo = mock(ApplicationInfo.class);
+
+        when(mIPackageManager.getApplicationInfo(
+                eq(PACKAGE_NAME_1),
+                eq(0L),
+                anyInt())
+        ).thenReturn(appInfo);
+
+        long createTimestamp = PACKAGE_ADD_TIMESTAMP_1
+                - (System.currentTimeMillis() - SystemClock.uptimeMillis());
+        FieldSetter.setField(appInfo,
+                ApplicationInfo.class.getDeclaredField("createTimestamp"),
+                createTimestamp);
+
+        int uid = USER_ID_1 * UserHandle.PER_USER_RANGE;
+        assertEquals(USER_ID_1, UserHandle.getUserId(uid));
+
+        mPackageListObserver.onPackageAdded(PACKAGE_NAME_1, uid);
+        mTestLooper.dispatchAll();
+
+        var packages = mBackgroundInstallControlService.getBackgroundInstalledPackages();
+        assertNotNull(packages);
+        assertEquals(1, packages.size());
+        assertTrue(packages.contains(USER_ID_1, PACKAGE_NAME_1));
+    }
+
+    @Test
+    public void testHandleUsageEvent_packageAddedInsideTimeFrame() throws
+            RemoteException, NoSuchFieldException {
+        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
+        InstallSourceInfo installSourceInfo = new InstallSourceInfo(
+                /* initiatingPackageName = */ null, /* initiatingPackageSigningInfo = */ null,
+                /* originatingPackageName = */ null,
+                /* installingPackageName = */ INSTALLER_NAME_1);
+        assertEquals(installSourceInfo.getInstallingPackageName(), INSTALLER_NAME_1);
+        when(mIPackageManager.getInstallSourceInfo(anyString())).thenReturn(installSourceInfo);
+        ApplicationInfo appInfo = mock(ApplicationInfo.class);
+
+        when(mIPackageManager.getApplicationInfo(
+                eq(PACKAGE_NAME_1),
+                eq(0L),
+                anyInt())
+        ).thenReturn(appInfo);
+
+        long createTimestamp = PACKAGE_ADD_TIMESTAMP_1
+                - (System.currentTimeMillis() - SystemClock.uptimeMillis());
+        FieldSetter.setField(appInfo,
+                ApplicationInfo.class.getDeclaredField("createTimestamp"),
+                createTimestamp);
+
+        int uid = USER_ID_1 * UserHandle.PER_USER_RANGE;
+        assertEquals(USER_ID_1, UserHandle.getUserId(uid));
+
+        // The following 2 usage events generation is the only difference from the
+        // testHandleUsageEvent_packageAddedNoUsageEvent test.
+        // The 2 usage events make the package adding inside a time frame.
+        // So it's not a background install. Thus, it's null for the return of
+        // mBackgroundInstallControlService.getBackgroundInstalledPackages()
+        doReturn(PackageManager.PERMISSION_GRANTED).when(mPermissionManager).checkPermission(
+                anyString(), anyString(), anyInt());
+        generateUsageEvent(UsageEvents.Event.ACTIVITY_RESUMED,
+                USER_ID_1, INSTALLER_NAME_1, USAGE_EVENT_TIMESTAMP_1);
+        generateUsageEvent(Event.ACTIVITY_STOPPED,
+                USER_ID_1, INSTALLER_NAME_1, USAGE_EVENT_TIMESTAMP_2);
+
+        mPackageListObserver.onPackageAdded(PACKAGE_NAME_1, uid);
+        mTestLooper.dispatchAll();
+        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
+    }
+
+    @Test
+    public void testHandleUsageEvent_packageAddedOutsideTimeFrame1() throws
+            RemoteException, NoSuchFieldException {
+        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
+        InstallSourceInfo installSourceInfo = new InstallSourceInfo(
+                /* initiatingPackageName = */ null, /* initiatingPackageSigningInfo = */ null,
+                /* originatingPackageName = */ null,
+                /* installingPackageName = */ INSTALLER_NAME_1);
+        assertEquals(installSourceInfo.getInstallingPackageName(), INSTALLER_NAME_1);
+        when(mIPackageManager.getInstallSourceInfo(anyString())).thenReturn(installSourceInfo);
+        ApplicationInfo appInfo = mock(ApplicationInfo.class);
+
+        when(mIPackageManager.getApplicationInfo(
+                eq(PACKAGE_NAME_1),
+                eq(0L),
+                anyInt())
+        ).thenReturn(appInfo);
+
+        long createTimestamp = PACKAGE_ADD_TIMESTAMP_1
+                - (System.currentTimeMillis() - SystemClock.uptimeMillis());
+        FieldSetter.setField(appInfo,
+                ApplicationInfo.class.getDeclaredField("createTimestamp"),
+                createTimestamp);
+
+        int uid = USER_ID_1 * UserHandle.PER_USER_RANGE;
+        assertEquals(USER_ID_1, UserHandle.getUserId(uid));
+
+        // The following 2 usage events generation is the only difference from the
+        // testHandleUsageEvent_packageAddedNoUsageEvent test.
+        // The 2 usage events make the package adding outside a time frame.
+        // Compared to testHandleUsageEvent_packageAddedInsideTimeFrame,
+        // it's a background install. Thus, it's not null for the return of
+        // mBackgroundInstallControlService.getBackgroundInstalledPackages()
+        doReturn(PackageManager.PERMISSION_GRANTED).when(mPermissionManager).checkPermission(
+                anyString(), anyString(), anyInt());
+        generateUsageEvent(UsageEvents.Event.ACTIVITY_RESUMED,
+                USER_ID_1, INSTALLER_NAME_1, USAGE_EVENT_TIMESTAMP_2);
+        generateUsageEvent(Event.ACTIVITY_STOPPED,
+                USER_ID_1, INSTALLER_NAME_1, USAGE_EVENT_TIMESTAMP_3);
+
+        mPackageListObserver.onPackageAdded(PACKAGE_NAME_1, uid);
+        mTestLooper.dispatchAll();
+
+        var packages = mBackgroundInstallControlService.getBackgroundInstalledPackages();
+        assertNotNull(packages);
+        assertEquals(1, packages.size());
+        assertTrue(packages.contains(USER_ID_1, PACKAGE_NAME_1));
+    }
+    @Test
+    public void testHandleUsageEvent_packageAddedOutsideTimeFrame2() throws
+            RemoteException, NoSuchFieldException {
+        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
+        InstallSourceInfo installSourceInfo = new InstallSourceInfo(
+                /* initiatingPackageName = */ null, /* initiatingPackageSigningInfo = */ null,
+                /* originatingPackageName = */ null,
+                /* installingPackageName = */ INSTALLER_NAME_1);
+        assertEquals(installSourceInfo.getInstallingPackageName(), INSTALLER_NAME_1);
+        when(mIPackageManager.getInstallSourceInfo(anyString())).thenReturn(installSourceInfo);
+        ApplicationInfo appInfo = mock(ApplicationInfo.class);
+
+        when(mIPackageManager.getApplicationInfo(
+                eq(PACKAGE_NAME_1),
+                eq(0L),
+                anyInt())
+        ).thenReturn(appInfo);
+
+        long createTimestamp = PACKAGE_ADD_TIMESTAMP_1
+                - (System.currentTimeMillis() - SystemClock.uptimeMillis());
+        FieldSetter.setField(appInfo,
+                ApplicationInfo.class.getDeclaredField("createTimestamp"),
+                createTimestamp);
+
+        int uid = USER_ID_1 * UserHandle.PER_USER_RANGE;
+        assertEquals(USER_ID_1, UserHandle.getUserId(uid));
+
+        // The following 2 usage events generation is the only difference from the
+        // testHandleUsageEvent_packageAddedNoUsageEvent test.
+        // These 2 usage events are triggered by INSTALLER_NAME_2.
+        // The 2 usage events make the package adding outside a time frame.
+        // Compared to testHandleUsageEvent_packageAddedInsideTimeFrame,
+        // it's a background install. Thus, it's not null for the return of
+        // mBackgroundInstallControlService.getBackgroundInstalledPackages()
+        doReturn(PackageManager.PERMISSION_GRANTED).when(mPermissionManager).checkPermission(
+                anyString(), anyString(), anyInt());
+        generateUsageEvent(UsageEvents.Event.ACTIVITY_RESUMED,
+                USER_ID_2, INSTALLER_NAME_2, USAGE_EVENT_TIMESTAMP_2);
+        generateUsageEvent(Event.ACTIVITY_STOPPED,
+                USER_ID_2, INSTALLER_NAME_2, USAGE_EVENT_TIMESTAMP_3);
+
+        mPackageListObserver.onPackageAdded(PACKAGE_NAME_1, uid);
+        mTestLooper.dispatchAll();
+
+        var packages = mBackgroundInstallControlService.getBackgroundInstalledPackages();
+        assertNotNull(packages);
+        assertEquals(1, packages.size());
+        assertTrue(packages.contains(USER_ID_1, PACKAGE_NAME_1));
+    }
+
+    @Test
+    public void testPackageRemoved() {
+        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
+        mBackgroundInstallControlService.initBackgroundInstalledPackages();
+        var packages = mBackgroundInstallControlService.getBackgroundInstalledPackages();
+        assertNotNull(packages);
+
+        packages.add(USER_ID_1, PACKAGE_NAME_1);
+        packages.add(USER_ID_2, PACKAGE_NAME_2);
+
+        assertEquals(2, packages.size());
+        assertTrue(packages.contains(USER_ID_1, PACKAGE_NAME_1));
+        assertTrue(packages.contains(USER_ID_2, PACKAGE_NAME_2));
+
+        int uid = USER_ID_1 * UserHandle.PER_USER_RANGE;
+        assertEquals(USER_ID_1, UserHandle.getUserId(uid));
+
+        mPackageListObserver.onPackageRemoved(PACKAGE_NAME_1, uid);
+        mTestLooper.dispatchAll();
+
+        assertEquals(1, packages.size());
+        assertFalse(packages.contains(USER_ID_1, PACKAGE_NAME_1));
+        assertTrue(packages.contains(USER_ID_2, PACKAGE_NAME_2));
+    }
+
+    @Test
+    public void testGetBackgroundInstalledPackages() throws RemoteException {
+        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
+        mBackgroundInstallControlService.initBackgroundInstalledPackages();
+        var bgPackages = mBackgroundInstallControlService.getBackgroundInstalledPackages();
+        assertNotNull(bgPackages);
+
+        bgPackages.add(USER_ID_1, PACKAGE_NAME_1);
+        bgPackages.add(USER_ID_2, PACKAGE_NAME_2);
+
+        assertEquals(2, bgPackages.size());
+        assertTrue(bgPackages.contains(USER_ID_1, PACKAGE_NAME_1));
+        assertTrue(bgPackages.contains(USER_ID_2, PACKAGE_NAME_2));
+
+        List<PackageInfo> packages = new ArrayList<>();
+        var packageInfo1 = makePackageInfo(PACKAGE_NAME_1);
+        packages.add(packageInfo1);
+        var packageInfo2 = makePackageInfo(PACKAGE_NAME_2);
+        packages.add(packageInfo2);
+        var packageInfo3 = makePackageInfo(PACKAGE_NAME_3);
+        packages.add(packageInfo3);
+        doReturn(new ParceledListSlice<>(packages)).when(mIPackageManager).getInstalledPackages(
+                anyLong(), anyInt());
+
+        var resultPackages =
+                mBackgroundInstallControlService.getBackgroundInstalledPackages(0L, USER_ID_1);
+        assertEquals(1, resultPackages.getList().size());
+        assertTrue(resultPackages.getList().contains(packageInfo1));
+        assertFalse(resultPackages.getList().contains(packageInfo2));
+        assertFalse(resultPackages.getList().contains(packageInfo3));
+    }
+
+    /**
+     * Mock a usage event occurring.
+     *
+     * @param usageEventId id of a usage event
+     * @param userId user id of a usage event
+     * @param pkgName package name of a usage event
+     * @param timestamp timestamp of a usage event
+     */
+    private void generateUsageEvent(int usageEventId,
+            int userId,
+            String pkgName,
+            long timestamp) {
+        Event event = new Event(usageEventId, timestamp);
+        event.mPackage = pkgName;
+        mUsageEventListener.onUsageEvent(userId, event);
+    }
+
+    private PackageInfo makePackageInfo(String packageName) {
+        PackageInfo pkg = new PackageInfo();
+        pkg.packageName = packageName;
+        pkg.applicationInfo = new ApplicationInfo();
+        return pkg;
+    }
+
+    private class MockInjector implements BackgroundInstallControlService.Injector {
+        private final Context mContext;
+
+        MockInjector(Context context) {
+            mContext = context;
+        }
+
+        @Override
+        public Context getContext() {
+            return mContext;
+        }
+
+        @Override
+        public IPackageManager getIPackageManager() {
+            return mIPackageManager;
+        }
+
+        @Override
+        public PackageManagerInternal getPackageManagerInternal() {
+            return mPackageManagerInternal;
+        }
+
+        @Override
+        public UsageStatsManagerInternal getUsageStatsManagerInternal() {
+            return mUsageStatsManagerInternal;
+        }
+
+        @Override
+        public PermissionManagerServiceInternal getPermissionManager() {
+            return mPermissionManager;
+        }
+
+        @Override
+        public Looper getLooper() {
+            return mLooper;
+        }
+
+        @Override
+        public File getDiskFile() {
+            return mFile;
+        }
+    }
+}
