Merge "Treble-ize tmpfs access"
diff --git a/tests/EmbeddedKitchenSinkApp/res/layout/notification_fragment.xml b/tests/EmbeddedKitchenSinkApp/res/layout/notification_fragment.xml
index 1dc40f6..4e8e1b3 100644
--- a/tests/EmbeddedKitchenSinkApp/res/layout/notification_fragment.xml
+++ b/tests/EmbeddedKitchenSinkApp/res/layout/notification_fragment.xml
@@ -13,73 +13,138 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical" >
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Ongoing notifications can only be dismissed by the CANCEL ALL button."/>
+
     <Button
         android:id="@+id/cancel_all_button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_margin="10dp"
         android:text="Cancel All"
-        android:textSize="35sp"/>
-    <Button
-        android:id="@+id/importance_high_button"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Importance: HIGH (Shows heads-up)"
-        android:textSize="35sp"/>
-    <Button
-        android:id="@+id/importance_high_button_2"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Importance: HIGH (Shows heads-up) 2"
-        android:textSize="35sp"/>
-    <Button
-        android:id="@+id/importance_default_button"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Importance: DEFAULT"
-        android:textSize="35sp"/>
-    <Button
-        android:id="@+id/importance_low_button"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Importance: LOW"
-        android:textSize="35sp"/>
-    <Button
-        android:id="@+id/importance_min_button"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Importance: MIN"
-        android:textSize="35sp"/>
-    <Button
-        android:id="@+id/ongoing_button"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Ongoing"
-        android:textSize="35sp"/>
-    <Button
-        android:id="@+id/category_message_button"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Category: CATEGORY_MESSAGE"
-        android:textSize="35sp"/>
+        android:textSize="30sp"/>
+
     <LinearLayout
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="horizontal" >
-         <Button
-        android:id="@+id/category_car_emerg_button"
-        android:layout_width="wrap_content"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:text="Category: CATEGORY_EMERG"
-        android:textSize="35sp"/>
-         <Button
-        android:id="@+id/category_car_warning_button"
-        android:layout_width="wrap_content"
+        android:background="#334666"
+        android:orientation="horizontal">
+
+        <Button
+            android:id="@+id/category_message_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="10dp"
+            android:text="Message"
+            android:textSize="30sp"/>
+
+        <Button
+            android:id="@+id/navigation_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="10dp"
+            android:text="Navigation"
+            android:textSize="30sp"/>
+
+        <Button
+            android:id="@+id/ongoing_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="10dp"
+            android:text="Persistent (No heads-up)"
+            android:textSize="30sp"/>
+
+        <Button
+            android:id="@+id/progress_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="10dp"
+            android:text="Progress (No heads-up)"
+            android:textSize="30sp"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:text="Category: CATEGORY_WARN"
-        android:textSize="35sp"/>
+        android:background="#5a6633"
+        android:orientation="horizontal">
+
+        <Button
+            android:id="@+id/importance_high_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="10dp"
+            android:text="Importance: HIGH"
+            android:textSize="30sp"/>
+
+        <Button
+            android:id="@+id/importance_default_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="10dp"
+            android:text="Importance: DEFAULT (No heads-up)"
+            android:textSize="30sp"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="#5a6633"
+        android:orientation="horizontal">
+
+        <Button
+            android:id="@+id/importance_low_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="10dp"
+            android:text="Importance: LOW (No heads-up)"
+            android:textSize="30sp"/>
+
+        <Button
+            android:id="@+id/importance_min_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="10dp"
+            android:text="Importance: MIN (No heads-up)"
+            android:textSize="30sp"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="#33664d"
+        android:orientation="horizontal">
+
+        <Button
+            android:id="@+id/category_car_emergency_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="10dp"
+            android:text="Car Emergency"
+            android:textSize="30sp"/>
+
+        <Button
+            android:id="@+id/category_car_warning_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="10dp"
+            android:text="Car Warning"
+            android:textSize="30sp"/>
+
+        <Button
+            android:id="@+id/category_car_info_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="10dp"
+            android:text="Car Information (No heads-up)"
+            android:textSize="30sp"/>
     </LinearLayout>
 </LinearLayout>
diff --git a/tests/EmbeddedKitchenSinkApp/res/layout/users.xml b/tests/EmbeddedKitchenSinkApp/res/layout/users.xml
new file mode 100644
index 0000000..5a862bf
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/res/layout/users.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical" >
+    <ListView
+        android:id="@+id/user_restrictions_list"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:scrollbars="vertical"/>
+
+    <Button
+        android:id="@+id/apply_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="@dimen/users_button_padding"
+        android:textSize="@dimen/users_button_text_size"
+        android:text="@string/users_apply_button" />
+</LinearLayout>
diff --git a/tests/EmbeddedKitchenSinkApp/res/values/dimens.xml b/tests/EmbeddedKitchenSinkApp/res/values/dimens.xml
index eb6b739..437d69d 100644
--- a/tests/EmbeddedKitchenSinkApp/res/values/dimens.xml
+++ b/tests/EmbeddedKitchenSinkApp/res/values/dimens.xml
@@ -63,4 +63,10 @@
     <dimen name="car_keyline_2">108dp</dimen>
     <dimen name="car_keyline_3">152dp</dimen>
     <dimen name="car_keyline_4">182dp</dimen>
+
+    <!-- Users -->
+    <dimen name="users_button_padding">10dp</dimen>
+    <dimen name="users_button_text_size">24sp</dimen>
+    <dimen name="users_checkbox_padding">5dp</dimen>
+    <dimen name="users_checkbox_text_size">32sp</dimen>
 </resources>
diff --git a/tests/EmbeddedKitchenSinkApp/res/values/strings.xml b/tests/EmbeddedKitchenSinkApp/res/values/strings.xml
index 5894892..f1a645e 100644
--- a/tests/EmbeddedKitchenSinkApp/res/values/strings.xml
+++ b/tests/EmbeddedKitchenSinkApp/res/values/strings.xml
@@ -301,4 +301,7 @@
     <string name="weblink_nytimes" translatable="false">www.nytimes.com</string>
     <string name="weblink_support_name" translatable="false">support.google.com</string>
     <string name="weblink_support" translatable="false">https://support.google.com/chrome/answer/95414?hl=en&amp;ref_topic=7438008</string>
+
+    <!-- Users -->
+    <string name="users_apply_button" translatable="false">Apply</string>
 </resources>
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
index 4d888d3..3c220ca 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
@@ -61,11 +61,12 @@
 import com.google.android.car.kitchensink.setting.CarServiceSettingsActivity;
 import com.google.android.car.kitchensink.storagelifetime.StorageLifetimeFragment;
 import com.google.android.car.kitchensink.touch.TouchTestFragment;
+import com.google.android.car.kitchensink.users.UsersFragment;
 import com.google.android.car.kitchensink.vhal.VehicleHalFragment;
 import com.google.android.car.kitchensink.volume.VolumeTestFragment;
 import com.google.android.car.kitchensink.weblinks.WebLinksTestFragment;
 
-import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 
@@ -145,47 +146,40 @@
         }
     }
 
-    private final List<MenuEntry> mMenuEntries = new ArrayList<MenuEntry>() {
-        {
-            add("alert window", AlertDialogTestFragment.class);
-            add("assistant", CarAssistantFragment.class);
-            add("audio", AudioTestFragment.class);
-            add("bluetooth headset",BluetoothHeadsetFragment.class);
-            add("bluetooth messaging test", MapMceTestFragment.class);
-            add("carboard", KeyboardTestFragment.class);
-            add("cubes test", CubesTestFragment.class);
-            add("diagnostic", DiagnosticTestFragment.class);
-            add("display info", DisplayInfoFragment.class);
-            add("hvac", HvacTestFragment.class);
-            add("inst cluster", InstrumentClusterFragment.class);
-            add("input test", InputTestFragment.class);
-            add("notification", NotificationFragment.class);
-            add("orientation test", OrientationTestFragment.class);
-            add("power test", PowerTestFragment.class);
-            add("property test", PropertyTestFragment.class);
-            add("sensors", SensorsTestFragment.class);
-            add("storage lifetime", StorageLifetimeFragment.class);
-            add("touch test", TouchTestFragment.class);
-            add("volume test", VolumeTestFragment.class);
-            add("vehicle hal", VehicleHalFragment.class);
-            add("car service settings", () -> {
+    private final List<MenuEntry> mMenuEntries = Arrays.asList(
+            new FragmentMenuEntry("activity view", ActivityViewTestFragment.class),
+            new FragmentMenuEntry("alert window", AlertDialogTestFragment.class),
+            new FragmentMenuEntry("assistant", CarAssistantFragment.class),
+            new FragmentMenuEntry("audio", AudioTestFragment.class),
+            new FragmentMenuEntry("bluetooth headset", BluetoothHeadsetFragment.class),
+            new FragmentMenuEntry("bluetooth messaging test", MapMceTestFragment.class),
+            new OnClickMenuEntry("car service settings", () -> {
                 Intent intent = new Intent(KitchenSinkActivity.this,
-                    CarServiceSettingsActivity.class);
+                        CarServiceSettingsActivity.class);
                 startActivity(intent);
-            });
-            add("activity view", ActivityViewTestFragment.class);
-            add("connectivity", ConnectivityFragment.class);
-            add("web links", WebLinksTestFragment.class);
-            add("quit", KitchenSinkActivity.this::finish);
-        }
+            }),
+            new FragmentMenuEntry("carboard", KeyboardTestFragment.class),
+            new FragmentMenuEntry("connectivity", ConnectivityFragment.class),
+            new FragmentMenuEntry("cubes test", CubesTestFragment.class),
+            new FragmentMenuEntry("diagnostic", DiagnosticTestFragment.class),
+            new FragmentMenuEntry("display info", DisplayInfoFragment.class),
+            new FragmentMenuEntry("hvac", HvacTestFragment.class),
+            new FragmentMenuEntry("inst cluster", InstrumentClusterFragment.class),
+            new FragmentMenuEntry("input test", InputTestFragment.class),
+            new FragmentMenuEntry("notification", NotificationFragment.class),
+            new FragmentMenuEntry("orientation test", OrientationTestFragment.class),
+            new FragmentMenuEntry("power test", PowerTestFragment.class),
+            new FragmentMenuEntry("property test", PropertyTestFragment.class),
+            new FragmentMenuEntry("sensors", SensorsTestFragment.class),
+            new FragmentMenuEntry("storage lifetime", StorageLifetimeFragment.class),
+            new FragmentMenuEntry("touch test", TouchTestFragment.class),
+            new FragmentMenuEntry("users", UsersFragment.class),
+            new FragmentMenuEntry("volume test", VolumeTestFragment.class),
+            new FragmentMenuEntry("vehicle hal", VehicleHalFragment.class),
+            new FragmentMenuEntry("web links", WebLinksTestFragment.class),
+            new OnClickMenuEntry("quit", KitchenSinkActivity.this::finish)
+    );
 
-        <T extends Fragment> void add(String text, Class<T> clazz) {
-            add(new FragmentMenuEntry(text, clazz));
-        }
-        void add(String text, ClickHandler onClick) {
-            add(new OnClickMenuEntry(text, onClick));
-        }
-    };
     private Car mCarApi;
     private CarHvacManager mHvacManager;
     private CarPowerManager mPowerManager;
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/notification/NotificationFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/notification/NotificationFragment.java
index 4de7e5a..e458df2 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/notification/NotificationFragment.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/notification/NotificationFragment.java
@@ -1,220 +1,400 @@
 package com.google.android.car.kitchensink.notification;
 
-import static android.security.KeyStore.getApplicationContext;
-
 import android.annotation.Nullable;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
-import android.app.Person;
-import android.app.RemoteInput;
 import android.content.Context;
 import android.content.Intent;
-import android.graphics.drawable.Icon;
 import android.os.Bundle;
+import android.os.Handler;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.Button;
 
+import androidx.core.app.NotificationCompat;
+import androidx.core.app.NotificationCompat.Action;
+import androidx.core.app.NotificationCompat.MessagingStyle;
+import androidx.core.app.Person;
+import androidx.core.app.RemoteInput;
 import androidx.fragment.app.Fragment;
 
 import com.google.android.car.kitchensink.KitchenSinkActivity;
 import com.google.android.car.kitchensink.R;
 
+import java.util.HashMap;
+
 /**
  * Test fragment that can send all sorts of notifications.
  */
 public class NotificationFragment extends Fragment {
-    private static final String CHANNEL_ID_1 = "kitchensink.channel1";
-    private static final String CHANNEL_ID_2 = "kitchensink.channel2";
-    private static final String CHANNEL_ID_3 = "kitchensink.channel3";
-    private static final String CHANNEL_ID_4 = "kitchensink.channel4";
-    private static final String CHANNEL_ID_5 = "kitchensink.channel5";
-    private static final String CHANNEL_ID_6 = "kitchensink.channel6";
+    private static final String IMPORTANCE_HIGH_ID = "importance_high";
+    private static final String IMPORTANCE_HIGH_NO_SOUND_ID = "importance_high_no_sound";
+    private static final String IMPORTANCE_DEFAULT_ID = "importance_default";
+    private static final String IMPORTANCE_LOW_ID = "importance_low";
+    private static final String IMPORTANCE_MIN_ID = "importance_min";
+    private static final String IMPORTANCE_NONE_ID = "importance_none";
+    private int mCurrentNotificationId = 0;
+    private NotificationManager mManager;
+    private Context mContext;
+    private Handler mHandler = new Handler();
+    private HashMap<Integer, Runnable> mUpdateRunnables = new HashMap<>();
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mManager =
+                (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
+        mContext = getActivity();
+
+        mManager.createNotificationChannel(new NotificationChannel(
+                IMPORTANCE_HIGH_ID, "Importance High", NotificationManager.IMPORTANCE_HIGH));
+
+        NotificationChannel noSoundChannel = new NotificationChannel(
+                IMPORTANCE_HIGH_NO_SOUND_ID, "No sound", NotificationManager.IMPORTANCE_HIGH);
+        noSoundChannel.setSound(null, null);
+        mManager.createNotificationChannel(noSoundChannel);
+
+        mManager.createNotificationChannel(new NotificationChannel(
+                IMPORTANCE_DEFAULT_ID,
+                "Importance Default",
+                NotificationManager.IMPORTANCE_DEFAULT));
+
+        mManager.createNotificationChannel(new NotificationChannel(
+                IMPORTANCE_LOW_ID, "Importance Low", NotificationManager.IMPORTANCE_LOW));
+
+        mManager.createNotificationChannel(new NotificationChannel(
+                IMPORTANCE_MIN_ID, "Importance Min", NotificationManager.IMPORTANCE_MIN));
+
+        mManager.createNotificationChannel(new NotificationChannel(
+                IMPORTANCE_NONE_ID, "Importance None", NotificationManager.IMPORTANCE_NONE));
+    }
 
     @Override
     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
             @Nullable Bundle savedInstanceState) {
         View view = inflater.inflate(R.layout.notification_fragment, container, false);
-        Button cancelAllButton = view.findViewById(R.id.cancel_all_button);
-        Button importanceHighButton = view.findViewById(R.id.importance_high_button);
-        Button importanceHighButton2 = view.findViewById(R.id.importance_high_button_2);
-        Button importanceLowButton = view.findViewById(R.id.importance_low_button);
-        Button importanceMinButton = view.findViewById(R.id.importance_min_button);
-        Button importanceDefaultButton = view.findViewById(R.id.importance_default_button);
-        Button ongoingButton = view.findViewById(R.id.ongoing_button);
-        Button messageButton = view.findViewById(R.id.category_message_button);
-        Button emerg = view.findViewById(R.id.category_car_emerg_button);
-        Button warn = view.findViewById(R.id.category_car_warning_button);
 
-        NotificationManager manager =
-                (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
+        initCancelAllButton(view);
 
-        // cancel all button
-        cancelAllButton.setOnClickListener(v -> manager.cancelAll());
+        initCarCategoriesButton(view);
 
-        // importance high notifications
-        NotificationChannel highImportanceChannel =
-                new NotificationChannel(
-                        CHANNEL_ID_1, "Importance High", NotificationManager.IMPORTANCE_HIGH);
-        manager.createNotificationChannel(highImportanceChannel);
+        initImportanceHighBotton(view);
+        initImportanceDefaultButton(view);
+        initImportanceLowButton(view);
+        initImportanceMinButton(view);
 
-        importanceHighButton.setOnClickListener(v -> {
+        initOngoingButton(view);
+        initMessagingStyleButton(view);
+        initProgressButton(view);
+        initNavigationButton(view);
 
-            Notification notification = new Notification.Builder(getActivity(), CHANNEL_ID_1)
-                    .setContentTitle("Importance High")
-                    .setContentText("blah")
+        return view;
+    }
+
+    private void initCancelAllButton(View view) {
+        view.findViewById(R.id.cancel_all_button).setOnClickListener(v -> {
+            for (Runnable runnable : mUpdateRunnables.values()) {
+                mHandler.removeCallbacks(runnable);
+            }
+            mUpdateRunnables.clear();
+            mManager.cancelAll();
+        });
+    }
+
+    private void initCarCategoriesButton(View view) {
+        view.findViewById(R.id.category_car_emergency_button).setOnClickListener(v -> {
+            Notification notification = new Notification
+                    .Builder(getActivity(), IMPORTANCE_DEFAULT_ID)
+                    .setContentTitle("Car Emergency")
+                    .setContentText("Shows heads-up; Shows on top of the list; Does not group")
+                    .setCategory(Notification.CATEGORY_CAR_EMERGENCY)
                     .setSmallIcon(R.drawable.car_ic_mode)
                     .build();
-            manager.notify(1, notification);
+            mManager.notify(mCurrentNotificationId++, notification);
         });
 
-        importanceHighButton2.setOnClickListener(v -> {
-            Notification notification = new Notification.Builder(getActivity(), CHANNEL_ID_1)
-                    .setContentTitle("Importance High 2")
-                    .setContentText("blah blah blah")
+        view.findViewById(R.id.category_car_warning_button).setOnClickListener(v -> {
+
+            Notification notification = new Notification
+                    .Builder(getActivity(), IMPORTANCE_MIN_ID)
+                    .setContentTitle("Car Warning")
+                    .setContentText(
+                            "Shows heads-up; Shows on top of the list but below Car Emergency; "
+                                    + "Does not group")
+                    .setCategory(Notification.CATEGORY_CAR_WARNING)
+                    .setColor(mContext.getColor(android.R.color.holo_orange_dark))
+                    .setColorized(true)
                     .setSmallIcon(R.drawable.car_ic_mode)
                     .build();
-            manager.notify(2, notification);
+            mManager.notify(mCurrentNotificationId++, notification);
         });
 
-        // importance default
-        importanceDefaultButton.setOnClickListener(v -> {
-            NotificationChannel channel =
-                    new NotificationChannel(
-                            CHANNEL_ID_3,
-                            "Importance Default",
-                            NotificationManager.IMPORTANCE_DEFAULT);
-            manager.createNotificationChannel(channel);
-
-            Notification notification = new Notification.Builder(getActivity(), CHANNEL_ID_3)
-                    .setContentTitle("Importance Default")
+        view.findViewById(R.id.category_car_info_button).setOnClickListener(v -> {
+            Notification notification = new Notification
+                    .Builder(getActivity(), IMPORTANCE_DEFAULT_ID)
+                    .setContentTitle("Car information")
+                    .setContentText("Doesn't show heads-up; Importance Default; Groups")
+                    .setCategory(Notification.CATEGORY_CAR_INFORMATION)
+                    .setColor(mContext.getColor(android.R.color.holo_orange_light))
+                    .setColorized(true)
                     .setSmallIcon(R.drawable.car_ic_mode)
                     .build();
-            manager.notify(4, notification);
+            mManager.notify(mCurrentNotificationId++, notification);
         });
 
-        // importance low
-        importanceLowButton.setOnClickListener(v -> {
-            NotificationChannel channel =
-                    new NotificationChannel(
-                            CHANNEL_ID_4, "Importance Low", NotificationManager.IMPORTANCE_LOW);
-            manager.createNotificationChannel(channel);
+    }
 
-            Notification notification = new Notification.Builder(getActivity(), CHANNEL_ID_4)
+    private void initImportanceHighBotton(View view) {
+        Intent mIntent = new Intent(getActivity(), KitchenSinkActivity.class);
+        PendingIntent mPendingIntent = PendingIntent.getActivity(getActivity(), 0, mIntent, 0);
+
+        Notification notification1 = new Notification
+                .Builder(getActivity(), IMPORTANCE_HIGH_ID)
+                .setContentTitle("Importance High: Shows as a heads-up")
+                .setContentText(
+                        "Each click generates a new notification. And some "
+                                + "looooooong text. "
+                                + "Loooooooooooooooooooooong. "
+                                + "Loooooooooooooooooooooooooooooooooooooooooooooooooong.")
+                .setSmallIcon(R.drawable.car_ic_mode)
+                .addAction(
+                        new Notification.Action.Builder(
+                                null, "Long Action (no-op)", mPendingIntent).build())
+                .addAction(
+                        new Notification.Action.Builder(
+                                null, "Action (no-op)", mPendingIntent).build())
+                .addAction(
+                        new Notification.Action.Builder(
+                                null, "Long Action (no-op)", mPendingIntent).build())
+                .setColor(mContext.getColor(android.R.color.holo_red_light))
+                .build();
+
+        view.findViewById(R.id.importance_high_button).setOnClickListener(
+                v -> mManager.notify(mCurrentNotificationId++, notification1)
+        );
+    }
+
+    private void initImportanceDefaultButton(View view) {
+        view.findViewById(R.id.importance_default_button).setOnClickListener(v -> {
+            Notification notification = new Notification
+                    .Builder(getActivity(), IMPORTANCE_DEFAULT_ID)
+                    .setContentTitle("No heads-up; Importance Default; Groups")
+                    .setSmallIcon(R.drawable.car_ic_mode)
+                    .build();
+            mManager.notify(mCurrentNotificationId++, notification);
+        });
+    }
+
+    private void initImportanceLowButton(View view) {
+        view.findViewById(R.id.importance_low_button).setOnClickListener(v -> {
+
+            Notification notification = new Notification.Builder(getActivity(), IMPORTANCE_LOW_ID)
                     .setContentTitle("Importance Low")
-                    .setContentText("low low low")
+                    .setContentText("No heads-up; Below Importance Default; Groups")
                     .setSmallIcon(R.drawable.car_ic_mode)
                     .build();
-            manager.notify(5, notification);
+            mManager.notify(mCurrentNotificationId++, notification);
         });
+    }
 
-        // importance min
-        importanceMinButton.setOnClickListener(v -> {
-            NotificationChannel channel =
-                    new NotificationChannel(
-                            CHANNEL_ID_5, "Importance Min", NotificationManager.IMPORTANCE_MIN);
-            manager.createNotificationChannel(channel);
+    private void initImportanceMinButton(View view) {
+        view.findViewById(R.id.importance_min_button).setOnClickListener(v -> {
 
-            Notification notification = new Notification.Builder(getActivity(), CHANNEL_ID_5)
+            Notification notification = new Notification.Builder(getActivity(), IMPORTANCE_MIN_ID)
                     .setContentTitle("Importance Min")
-                    .setContentText("min min min")
+                    .setContentText("No heads-up; Below Importance Low; Groups")
                     .setSmallIcon(R.drawable.car_ic_mode)
                     .build();
-            manager.notify(6, notification);
+            mManager.notify(mCurrentNotificationId++, notification);
         });
+    }
 
-        // ongoing
-        ongoingButton.setOnClickListener(v -> {
-            NotificationChannel channel =
-                    new NotificationChannel(
-                            CHANNEL_ID_6, "Ongoing", NotificationManager.IMPORTANCE_DEFAULT);
-            manager.createNotificationChannel(channel);
+    private void initOngoingButton(View view) {
+        view.findViewById(R.id.ongoing_button).setOnClickListener(v -> {
 
-            Notification notification = new Notification.Builder(getActivity(), CHANNEL_ID_6)
-                    .setContentTitle("Playing music or something")
+            Notification notification = new Notification
+                    .Builder(getActivity(), IMPORTANCE_DEFAULT_ID)
+                    .setContentTitle("Persistent/Ongoing Notification")
+                    .setContentText("Cannot be dismissed; No heads-up; Importance default; Groups")
                     .setSmallIcon(R.drawable.car_ic_mode)
                     .setOngoing(true)
                     .build();
-            manager.notify(7, notification);
+            mManager.notify(mCurrentNotificationId++, notification);
         });
+    }
 
-        // category message
-        messageButton.setOnClickListener(v -> {
-            NotificationChannel channel =
-                    new NotificationChannel(
-                            CHANNEL_ID_2, "Message", NotificationManager.IMPORTANCE_HIGH);
-            manager.createNotificationChannel(channel);
+    private void initMessagingStyleButton(View view) {
+        int id = mCurrentNotificationId++;
 
-            Intent intent = new Intent(getActivity(), KitchenSinkActivity.class);
-            PendingIntent readIntent = PendingIntent.getActivity(getActivity(), 0, intent, 0);
+        view.findViewById(R.id.category_message_button).setOnClickListener(v -> {
 
-            RemoteInput remoteInput = new RemoteInput.Builder("voice reply").build();
-            PendingIntent replyIntent = PendingIntent.getBroadcast(getApplicationContext(),
-                    12345,
-                    intent,
-                    PendingIntent.FLAG_UPDATE_CURRENT);
+            PendingIntent replyIntent = createServiceIntent(id, "reply");
+            PendingIntent markAsReadIntent = createServiceIntent(id, "read");
 
             Person personJohn = new Person.Builder()
                     .setName("John Doe")
-                    .setIcon(Icon.createWithResource(v.getContext(), R.drawable.avatar1))
                     .build();
             Person personJane = new Person.Builder()
                     .setName("Jane Roe")
-                    .setIcon(Icon.createWithResource(v.getContext(), R.drawable.avatar2))
                     .build();
-            Notification.MessagingStyle messagingStyle =
-                    new Notification.MessagingStyle(personJohn)
-                            .setConversationTitle("Whassup")
-                            .addHistoricMessage(
-                                    new Notification.MessagingStyle.Message(
-                                            "historic message",
+            MessagingStyle messagingStyle =
+                    new MessagingStyle(personJohn)
+                            .setConversationTitle("Heads-up: New Message")
+                            .addMessage(
+                                    new MessagingStyle.Message(
+                                            "The meaning of life, or the answer to the question"
+                                                    + "What is the meaning of life?, pertains to "
+                                                    + "the significance of living or existence in"
+                                                    + " general. Many other related questions "
+                                                    + "include: Why are we here?, What is "
+                                                    + "life all about?, or What is the "
+                                                    + "purpose of existence?",
                                             System.currentTimeMillis() - 3600,
                                             personJohn))
-                            .addMessage(new Notification.MessagingStyle.Message(
-                                    "message", System.currentTimeMillis(), personJane));
+                            .addMessage(
+                                    new MessagingStyle.Message(
+                                            "Importance High; Groups", System.currentTimeMillis(),
+                                            personJane));
 
-            Notification notification = new Notification.Builder(getActivity(), CHANNEL_ID_2)
+            NotificationCompat.Builder notification = new NotificationCompat
+                    .Builder(getActivity(), IMPORTANCE_HIGH_ID)
                     .setContentTitle("Message from someone")
                     .setContentText("hi")
+                    .setShowWhen(true)
                     .setCategory(Notification.CATEGORY_MESSAGE)
                     .setSmallIcon(R.drawable.car_ic_mode)
                     .setStyle(messagingStyle)
                     .setAutoCancel(true)
+                    .setColor(mContext.getColor(android.R.color.holo_green_light))
                     .addAction(
-                            new Notification.Action.Builder(null, "read", readIntent).build())
+                            new Action.Builder(R.drawable.ic_check_box, "read", markAsReadIntent)
+                                    .setSemanticAction(Action.SEMANTIC_ACTION_MARK_AS_READ)
+                                    .setShowsUserInterface(false)
+                                    .build())
                     .addAction(
-                            new Notification.Action.Builder(null, "reply", replyIntent)
-                                    .addRemoteInput(remoteInput).build())
-                    .extend(new Notification.CarExtender().setColor(R.color.car_red_500))
-                    .build();
-            manager.notify(3, notification);
+                            new Action.Builder(R.drawable.ic_check_box, "reply", replyIntent)
+                                    .setSemanticAction(Action.SEMANTIC_ACTION_REPLY)
+                                    .setShowsUserInterface(false)
+                                    .addRemoteInput(new RemoteInput.Builder("input").build())
+                                    .build());
+
+            mManager.notify(id, notification.build());
         });
+    }
 
-        emerg.setOnClickListener(v -> {
+    private PendingIntent createServiceIntent(int notificationId, String action) {
+        Intent intent = new Intent(mContext, KitchenSinkActivity.class).setAction(action);
 
-            Notification notification = new Notification.Builder(getActivity(), CHANNEL_ID_1)
-                    .setContentTitle("OMG")
-                    .setContentText("This is of top importance")
-                    .setCategory(Notification.CATEGORY_CAR_EMERGENCY)
+        return PendingIntent.getForegroundService(mContext, notificationId, intent,
+                PendingIntent.FLAG_UPDATE_CURRENT);
+    }
+
+    private void initProgressButton(View view) {
+        view.findViewById(R.id.progress_button).setOnClickListener(v -> {
+            int id = mCurrentNotificationId++;
+
+            Notification notification = new Notification
+                    .Builder(getActivity(), IMPORTANCE_DEFAULT_ID)
+                    .setContentTitle("Progress")
+                    .setContentText("Doesn't show heads-up; Importance Default; Groups")
+                    .setProgress(100, 0, false)
+                    .setColor(mContext.getColor(android.R.color.holo_purple))
+                    .setContentInfo("0%")
                     .setSmallIcon(R.drawable.car_ic_mode)
                     .build();
-            manager.notify(10, notification);
+            mManager.notify(id, notification);
+
+            Runnable runnable = new Runnable() {
+                int mProgress = 0;
+
+                @Override
+                public void run() {
+                    Notification updateNotification = new Notification
+                            .Builder(getActivity(), IMPORTANCE_DEFAULT_ID)
+                            .setContentTitle("Progress")
+                            .setContentText("Doesn't show heads-up; Importance Default; Groups")
+                            .setProgress(100, mProgress, false)
+                            .setColor(mContext.getColor(android.R.color.holo_purple))
+                            .setContentInfo(mProgress + "%")
+                            .setSmallIcon(R.drawable.car_ic_mode)
+                            .build();
+                    mManager.notify(id, updateNotification);
+                    mProgress += 5;
+                    if (mProgress <= 100) {
+                        mHandler.postDelayed(this, 1000);
+                    }
+                }
+            };
+            mUpdateRunnables.put(id, runnable);
+            mHandler.post(runnable);
         });
+    }
 
-        warn.setOnClickListener(v -> {
+    private void initNavigationButton(View view) {
+        view.findViewById(R.id.navigation_button).setOnClickListener(v -> {
+            int id = mCurrentNotificationId++;
 
-            Notification notification = new Notification.Builder(getActivity(), CHANNEL_ID_1)
-                    .setContentTitle("OMG -ish ")
-                    .setContentText("This is of less importance but still")
-                    .setCategory(Notification.CATEGORY_CAR_WARNING)
+            Notification notification = new Notification
+                    .Builder(getActivity(), IMPORTANCE_HIGH_ID)
+                    .setContentTitle("Navigation")
+                    .setContentText("Turn right in 900 ft")
+                    .setColor(mContext.getColor(android.R.color.holo_green_dark))
+                    .setColorized(true)
+                    .setSubText("900 ft")
                     .setSmallIcon(R.drawable.car_ic_mode)
                     .build();
-            manager.notify(11, notification);
-        });
+            mManager.notify(id, notification);
 
-        return view;
+            Runnable rightTurnRunnable = new Runnable() {
+                int mDistance = 800;
+
+                @Override
+                public void run() {
+                    Notification updateNotification = new Notification
+                            .Builder(getActivity(), IMPORTANCE_HIGH_NO_SOUND_ID)
+                            .setContentTitle("Navigation")
+                            .setContentText("Turn right in " + mDistance + " ft")
+                            .setColor(mContext.getColor(android.R.color.holo_green_dark))
+                            .setColorized(true)
+                            .setSubText(mDistance + " ft")
+                            .setSmallIcon(R.drawable.car_ic_mode)
+                            .build();
+                    mManager.notify(id, updateNotification);
+                    mDistance -= 100;
+                    if (mDistance >= 0) {
+                        mHandler.postDelayed(this, 1000);
+                    }
+                }
+            };
+
+            Runnable exitRunnable = new Runnable() {
+                int mDistance = 9;
+
+                @Override
+                public void run() {
+                    Notification updateNotification = new Notification
+                            .Builder(getActivity(), IMPORTANCE_HIGH_NO_SOUND_ID)
+                            .setContentTitle("Navigation")
+                            .setContentText("Exit in " + mDistance + " miles")
+                            .setColor(mContext.getColor(android.R.color.holo_green_dark))
+                            .setColorized(true)
+                            .setSubText(mDistance + " miles")
+                            .setSmallIcon(R.drawable.car_ic_mode)
+                            .build();
+                    mManager.notify(id, updateNotification);
+                    mDistance -= 1;
+                    if (mDistance >= 0) {
+                        mHandler.postDelayed(this, 1000);
+                    }
+                }
+            };
+
+            mUpdateRunnables.put(id, rightTurnRunnable);
+            mUpdateRunnables.put(id, exitRunnable);
+            mHandler.postDelayed(rightTurnRunnable, 1000);
+            mHandler.postDelayed(exitRunnable, 10000);
+        });
     }
 }
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/users/UserRestrictionAdapter.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/users/UserRestrictionAdapter.java
new file mode 100644
index 0000000..00c7192
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/users/UserRestrictionAdapter.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2019 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.google.android.car.kitchensink.users;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.CheckBox;
+
+import com.google.android.car.kitchensink.R;
+
+import java.util.List;
+
+/**
+ * Adapter to display a set of user restrictions
+ */
+public class UserRestrictionAdapter extends BaseAdapter {
+
+    private final Context mContext;
+    private final List<UserRestrictionListItem> mItems;
+
+    public UserRestrictionAdapter(Context context, List<UserRestrictionListItem> items) {
+        mContext = context;
+        mItems = items;
+    }
+
+    @Override
+    public int getCount() {
+        return mItems.size();
+    }
+
+    @Override
+    public Object getItem(int index) {
+        return mItems.get(index);
+    }
+
+    @Override
+    public long getItemId(int index) {
+        return index;
+    }
+
+    @Override
+    public View getView(int index, View convertView, ViewGroup parent) {
+        return convertView == null
+                ? createCheckBox((UserRestrictionListItem) getItem(index))
+                : convertView;
+    }
+
+    private CheckBox createCheckBox(UserRestrictionListItem item) {
+        Resources resources = mContext.getResources();
+        CheckBox checkBox = new CheckBox(mContext);
+        checkBox.setTextSize(resources.getDimensionPixelSize(R.dimen.users_checkbox_text_size));
+        int padding = resources.getDimensionPixelSize(R.dimen.users_checkbox_padding);
+        checkBox.setPadding(padding, padding, padding, padding);
+        checkBox.setText(item.getKey());
+        checkBox.setOnCheckedChangeListener((v, isChecked) -> item.setIsChecked(isChecked));
+        checkBox.setChecked(item.getIsChecked());
+        return checkBox;
+    }
+}
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/users/UserRestrictionListItem.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/users/UserRestrictionListItem.java
new file mode 100644
index 0000000..0454f75
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/users/UserRestrictionListItem.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 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.google.android.car.kitchensink.users;
+
+/**
+ * Represents a user restriction in a list.  Contains the key for the user restriction and the
+ * "checked" status of the checkbox in the list.
+ */
+public class UserRestrictionListItem {
+    private final String mKey;
+    private boolean mIsChecked;
+
+    public UserRestrictionListItem(String key, boolean isChecked) {
+        mKey = key;
+        mIsChecked = isChecked;
+    }
+
+    public String getKey() {
+        return mKey;
+    }
+
+    public void setIsChecked(boolean value) {
+        mIsChecked = value;
+    }
+
+    public boolean getIsChecked() {
+        return mIsChecked;
+    }
+}
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/users/UsersFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/users/UsersFragment.java
new file mode 100644
index 0000000..3272c30
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/users/UsersFragment.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2019 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.google.android.car.kitchensink.users;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ListView;
+import android.widget.Toast;
+
+import androidx.fragment.app.Fragment;
+
+import com.google.android.car.kitchensink.R;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Manipulate users in various ways
+ */
+public class UsersFragment extends Fragment {
+
+    private static final List<String> CONFIGURABLE_USER_RESTRICTIONS =
+            Arrays.asList(
+                    UserManager.DISALLOW_ADD_USER,
+                    UserManager.DISALLOW_BLUETOOTH,
+                    UserManager.DISALLOW_FACTORY_RESET,
+                    UserManager.DISALLOW_INSTALL_APPS,
+                    UserManager.DISALLOW_MODIFY_ACCOUNTS,
+                    UserManager.DISALLOW_OUTGOING_CALLS,
+                    UserManager.DISALLOW_REMOVE_USER,
+                    UserManager.DISALLOW_SMS,
+                    UserManager.DISALLOW_UNINSTALL_APPS,
+                    UserManager.DISALLOW_USER_SWITCH
+            );
+
+    @Nullable
+    @Override
+    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
+            @Nullable Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.users, container, false);
+    }
+
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        ListView userRestrictionsList = view.findViewById(R.id.user_restrictions_list);
+        userRestrictionsList.setAdapter(
+                new UserRestrictionAdapter(getContext(), createUserRestrictionItems()));
+
+        Button applyButton = view.findViewById(R.id.apply_button);
+        applyButton.setOnClickListener(v -> {
+            UserRestrictionAdapter adapter =
+                    (UserRestrictionAdapter) userRestrictionsList.getAdapter();
+            int count = adapter.getCount();
+            UserManager userManager =
+                    (UserManager) getContext().getSystemService(Context.USER_SERVICE);
+
+            // Iterate through all of the user restrictions and set their values
+            for (int i = 0; i < count; i++) {
+                UserRestrictionListItem item = (UserRestrictionListItem) adapter.getItem(i);
+                userManager.setUserRestriction(item.getKey(), item.getIsChecked());
+            }
+
+            Toast.makeText(
+                    getContext(), "User restrictions have been set!", Toast.LENGTH_SHORT)
+                    .show();
+        });
+    }
+
+    private List<UserRestrictionListItem> createUserRestrictionItems() {
+        UserManager userManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
+        ArrayList<UserRestrictionListItem> list = new ArrayList<>();
+        for (String key : CONFIGURABLE_USER_RESTRICTIONS) {
+            list.add(new UserRestrictionListItem(key, userManager.hasUserRestriction(key)));
+        }
+        return list;
+    }
+}
diff --git a/user/car-user-lib/src/android/car/userlib/CarUserManagerHelper.java b/user/car-user-lib/src/android/car/userlib/CarUserManagerHelper.java
index fe39d51..23186aa 100644
--- a/user/car-user-lib/src/android/car/userlib/CarUserManagerHelper.java
+++ b/user/car-user-lib/src/android/car/userlib/CarUserManagerHelper.java
@@ -68,6 +68,17 @@
     );
 
     /**
+     * Additional optional set of restrictions for Non-Admin users.
+     */
+    public static final Set<String> OPTIONAL_NON_ADMIN_RESTRICTIONS = Sets.newArraySet(
+            UserManager.DISALLOW_ADD_USER,
+            UserManager.DISALLOW_OUTGOING_CALLS,
+            UserManager.DISALLOW_SMS,
+            UserManager.DISALLOW_INSTALL_APPS,
+            UserManager.DISALLOW_UNINSTALL_APPS
+    );
+
+    /**
      * Default set of restrictions for Guest users.
      */
     private static final Set<String> DEFAULT_GUEST_RESTRICTIONS = Sets.newArraySet(
@@ -733,6 +744,7 @@
 
         // Remove restrictions imposed on non-admins.
         setDefaultNonAdminRestrictions(user, /* enable= */ false);
+        setOptionalNonAdminRestrictions(user, /* enable= */ false);
     }
 
     /**
@@ -810,6 +822,18 @@
     }
 
     /**
+     * Sets the values of settings controllable restrictions to the passed in value.
+     *
+     * @param userInfo User to set restrictions on.
+     * @param enable If true, restriction is ON, If false, restriction is OFF.
+     */
+    private void setOptionalNonAdminRestrictions(UserInfo userInfo, boolean enable) {
+        for (String restriction : OPTIONAL_NON_ADMIN_RESTRICTIONS) {
+            setUserRestriction(userInfo, restriction, enable);
+        }
+    }
+
+    /**
      * Sets the value of the specified restriction for the specified user.
      *
      * @param userInfo the user whose restriction is to be changed