Merge "Restriction setters were not getting called since we changed the boot sequence for multi-user model."
diff --git a/car-lib/src/android/car/settings/CarSettings.java b/car-lib/src/android/car/settings/CarSettings.java
index c3a2657..f614601 100644
--- a/car-lib/src/android/car/settings/CarSettings.java
+++ b/car-lib/src/android/car/settings/CarSettings.java
@@ -68,6 +68,14 @@
          */
         public static final String LAST_ACTIVE_USER_ID =
                 "android.car.LAST_ACTIVE_USER_ID";
+
+        /**
+         * Whether default restrictions for users have been set.
+         *
+         * @hide
+         */
+        public static final String DEFAULT_USER_RESTRICTIONS_SET =
+                "android.car.DEFAULT_USER_RESTRICTIONS_SET";
     }
 
     /**
diff --git a/service/src/com/android/car/user/CarUserService.java b/service/src/com/android/car/user/CarUserService.java
index 8716aed..72e313f 100644
--- a/service/src/com/android/car/user/CarUserService.java
+++ b/service/src/com/android/car/user/CarUserService.java
@@ -17,6 +17,7 @@
 package com.android.car.user;
 
 import android.annotation.Nullable;
+import android.car.settings.CarSettings;
 import android.car.userlib.CarUserManagerHelper;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -25,6 +26,7 @@
 import android.location.LocationManager;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.Settings;
 import android.util.Log;
 
 import com.android.car.CarServiceBase;
@@ -86,10 +88,16 @@
         }
 
         if (Intent.ACTION_LOCKED_BOOT_COMPLETED.equals(intent.getAction())) {
-            if (mCarUserManagerHelper.getAllUsers().size() == 0) {
+            // We want to set restrictions on system and guest users only once. These are persisted
+            // onto disk, so it's sufficient to do it once + we minimize the number of disk writes.
+            if (Settings.Global.getInt(mContext.getContentResolver(),
+                    CarSettings.Global.DEFAULT_USER_RESTRICTIONS_SET, /* default= */ 0) == 0) {
                 setSystemUserRestrictions();
                 mCarUserManagerHelper.initDefaultGuestRestrictions();
+                Settings.Global.putInt(mContext.getContentResolver(),
+                        CarSettings.Global.DEFAULT_USER_RESTRICTIONS_SET, 1);
             }
+
         } else if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
             // Update last active user if the switched-to user is a persistent, non-system user.
             int currentUser = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
diff --git a/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java b/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java
index 595f6e3..1947c8f 100644
--- a/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java
@@ -20,8 +20,10 @@
 
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
+import android.car.settings.CarSettings;
 import android.car.userlib.CarUserManagerHelper;
 import android.content.Context;
 import android.content.Intent;
@@ -30,7 +32,9 @@
 import android.location.LocationManager;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.Settings;
 
+import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
@@ -77,10 +81,15 @@
         MockitoAnnotations.initMocks(this);
         doReturn(mApplicationContext).when(mMockContext).getApplicationContext();
         doReturn(mLocationManager).when(mMockContext).getSystemService(Context.LOCATION_SERVICE);
+        doReturn(InstrumentationRegistry.getTargetContext().getContentResolver())
+                .when(mMockContext).getContentResolver();
 
         mCarUserService = new CarUserService(mMockContext, mCarUserManagerHelper);
 
         doReturn(new ArrayList<>()).when(mCarUserManagerHelper).getAllUsers();
+
+        // Restore default value at the beginning of each test.
+        putSettingsInt(CarSettings.Global.DEFAULT_USER_RESTRICTIONS_SET, 0);
     }
 
     /**
@@ -118,8 +127,6 @@
         systemUser.id = UserHandle.USER_SYSTEM;
         doReturn(systemUser).when(mCarUserManagerHelper).getSystemUserInfo();
 
-        mockAdmin(10);
-
         mCarUserService.onReceive(mMockContext,
                 new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED));
 
@@ -128,12 +135,29 @@
     }
 
     /**
+     * Test that the {@link CarUserService} does not set restrictions on user 0 if they have already
+     * been set.
+     */
+    @Test
+    public void testDoesNotSetSystemUserRestrictions_IfRestrictionsAlreadySet() {
+        // Mock system user.
+        UserInfo systemUser = new UserInfo();
+        systemUser.id = UserHandle.USER_SYSTEM;
+        doReturn(systemUser).when(mCarUserManagerHelper).getSystemUserInfo();
+
+        putSettingsInt(CarSettings.Global.DEFAULT_USER_RESTRICTIONS_SET, 1);
+        mCarUserService.onReceive(mMockContext,
+                new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED));
+
+        verify(mCarUserManagerHelper, never())
+                .setUserRestriction(systemUser, UserManager.DISALLOW_MODIFY_ACCOUNTS, true);
+    }
+
+    /**
      * Test that the {@link CarUserService} disable location service for user 0 upon first run.
      */
     @Test
     public void testDisableLocationForSystemUserOnFirstRun() {
-        mockAdmin(/* adminId= */ 10);
-
         mCarUserService.onReceive(mMockContext,
                 new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED));
 
@@ -162,13 +186,31 @@
      * Test that the {@link CarUserService} sets default guest restrictions on first boot.
      */
     @Test
-    public void testInitializeGuestRestrictionsOnFirstRun() {
-        mockAdmin(/* adminId= */ 10);
-
-        mCarUserService.onReceive(mMockContext,
-                new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED));
-
+    public void testInitializeGuestRestrictions_IfNotAlreadySet() {
+        mCarUserService.onReceive(mMockContext, new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED));
         verify(mCarUserManagerHelper).initDefaultGuestRestrictions();
+        assertThat(getSettingsInt(CarSettings.Global.DEFAULT_USER_RESTRICTIONS_SET)).isEqualTo(1);
+    }
+
+    /**
+     * Test that the {@link CarUserService} does not set restrictions after they have been set once.
+     */
+    @Test
+    public void test_DoesNotInitializeGuestRestrictions_IfAlreadySet() {
+        putSettingsInt(CarSettings.Global.DEFAULT_USER_RESTRICTIONS_SET, 1);
+        mCarUserService.onReceive(mMockContext, new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED));
+        verify(mCarUserManagerHelper, never()).initDefaultGuestRestrictions();
+    }
+
+    private void putSettingsInt(String key, int value) {
+        Settings.Global.putInt(InstrumentationRegistry.getTargetContext().getContentResolver(),
+                key, value);
+    }
+
+    private int getSettingsInt(String key) {
+        return Settings.Global.getInt(
+                InstrumentationRegistry.getTargetContext().getContentResolver(),
+                key, /* default= */ 0);
     }
 
     private UserInfo mockAdmin(int adminId) {