Merge "Fix duplicate network request entry during connection" into udc-qpr-dev
diff --git a/Android.bp b/Android.bp
index d2b8fc7..71e0542 100644
--- a/Android.bp
+++ b/Android.bp
@@ -83,6 +83,7 @@
         "net-utils-framework-common",
         "app-usage-event-protos-lite",
         "battery-event-protos-lite",
+        "power-anomaly-event-protos-lite",
         "settings-contextual-card-protos-lite",
         "settings-log-bridge-protos-lite",
         "settings-telephony-protos-lite",
diff --git a/res/drawable/ic_lock_none.xml b/res/drawable/ic_lock_none.xml
index 31069b7..54b9bb4 100644
--- a/res/drawable/ic_lock_none.xml
+++ b/res/drawable/ic_lock_none.xml
@@ -18,7 +18,8 @@
     android:width="24dp"
     android:height="24dp"
     android:viewportWidth="24"
-    android:viewportHeight="24">
+    android:viewportHeight="24"
+    android:tint="?android:attr/colorControlNormal">
   <path
       android:pathData="M18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6h2c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM18,20L6,20L6,10h12v10z"
       android:fillColor="?android:attr/colorAccent"/>
diff --git a/res/drawable/ic_lock_pin.xml b/res/drawable/ic_lock_pin.xml
index 587f49c..4614f53 100644
--- a/res/drawable/ic_lock_pin.xml
+++ b/res/drawable/ic_lock_pin.xml
@@ -18,7 +18,8 @@
     android:width="24dp"
     android:height="24dp"
     android:viewportWidth="24"
-    android:viewportHeight="24">
+    android:viewportHeight="24"
+    android:tint="?android:attr/colorControlNormal">
   <path
       android:pathData="M6,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,20c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM6,20c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM6,14c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,14c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM16,6c0,1.1 0.9,2 2,2s2,-0.9 2,-2 -0.9,-2 -2,-2 -2,0.9 -2,2zM12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM18,14c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM18,20c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2z"
       android:fillColor="?android:attr/colorAccent"/>
diff --git a/res/drawable/ic_lock_swipe.xml b/res/drawable/ic_lock_swipe.xml
index f7e78b8..fb8302d 100644
--- a/res/drawable/ic_lock_swipe.xml
+++ b/res/drawable/ic_lock_swipe.xml
@@ -18,7 +18,8 @@
     android:width="24dp"
     android:height="24dp"
     android:viewportWidth="24"
-    android:viewportHeight="24">
+    android:viewportHeight="24"
+    android:tint="?android:attr/colorControlNormal">
   <path
       android:pathData="M20.5,2v2.02C18.18,2.13 15.22,1 12,1S5.82,2.13 3.5,4.02V2H2v3.5V7h1.5H7V5.5H4.09c2.11,-1.86 4.88,-3 7.91,-3s5.79,1.14 7.91,3H17V7h3.5H22V5.5V2H20.5z"
       android:fillColor="?android:attr/colorAccent"/>
diff --git a/res/drawable/ic_password.xml b/res/drawable/ic_password.xml
index 341e544..cf3b408 100644
--- a/res/drawable/ic_password.xml
+++ b/res/drawable/ic_password.xml
@@ -18,7 +18,8 @@
     android:width="24dp"
     android:height="24dp"
     android:viewportHeight="24.0"
-    android:viewportWidth="24.0">
+    android:viewportWidth="24.0"
+    android:tint="?android:attr/colorControlNormal">
     <path
         android:fillColor="?android:attr/colorAccent"
         android:pathData="M21.5,9.39l-1.63,0l0.81,-1.42l-0.86,-0.5l-0.82,1.42l-0.82,-1.42l-0.86,0.5l0.81,1.42l-1.63,0l0,1l1.63,0l-0.81,1.41l0.86,0.5l0.82,-1.41l0.82,1.41l0.86,-0.5l-0.81,-1.41l1.63,0z" />
diff --git a/res/drawable/ic_pattern.xml b/res/drawable/ic_pattern.xml
index 788eaa7..e56fb00 100644
--- a/res/drawable/ic_pattern.xml
+++ b/res/drawable/ic_pattern.xml
@@ -18,7 +18,8 @@
     android:width="24dp"
     android:height="24dp"
     android:viewportHeight="24.0"
-    android:viewportWidth="24.0">
+    android:viewportWidth="24.0"
+    android:tint="?android:attr/colorControlNormal">
     <path
         android:fillColor="?android:attr/colorAccent"
         android:pathData="M4,4m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0" />
diff --git a/res/drawable/ic_pin.xml b/res/drawable/ic_pin.xml
index 682e934..8520ec1 100644
--- a/res/drawable/ic_pin.xml
+++ b/res/drawable/ic_pin.xml
@@ -18,7 +18,8 @@
     android:width="24dp"
     android:height="24dp"
     android:viewportHeight="24.0"
-    android:viewportWidth="24.0">
+    android:viewportWidth="24.0"
+    android:tint="?android:attr/colorControlNormal">
     <path
         android:fillColor="?android:attr/colorAccent"
         android:pathData="M20,4L4,4A2,2 0,0 0,2 6L2,18a2,2 0,0 0,2 2L20,20a2,2 0,0 0,2 -2L22,6A2,2 0,0 0,20 4ZM7.1,15L5.9,15L5.9,10.2L4.7,10.2L4.7,9L7.1,9v6ZM13.2,11.4A1.2,1.2 0,0 1,12 12.6L10.8,12.6v1.2h2.4L13.2,15L9.6,15L9.6,12.6a1.2,1.2 0,0 1,1.2 -1.2L12,11.4L12,10.2L9.6,10.2L9.6,9L12,9a1.2,1.2 0,0 1,1.2 1.2v1.2ZM19.3,11.1a0.9,0.9 0,0 1,-0.9 0.9,0.9 0.9,0 0,1 0.9,0.9v0.9A1.2,1.2 0,0 1,18.1 15L15.7,15L15.7,13.8h2.4L18.1,12.6L16.9,12.6L16.9,11.4h1.2L18.1,10.2L15.7,10.2L15.7,9h2.4a1.2,1.2 0,0 1,1.2 1.2v0.9Z" />
diff --git a/res/values/config.xml b/res/values/config.xml
index 432b1ca..687fa15 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -611,23 +611,26 @@
         <item>3</item>
     </integer-array>
 
-    <!-- TODO(b/287448187): add USER_MIN_ASPECT_RATIO_DISPLAY_SIZE entry -->
-    <!-- App screen size settings screen, User aspect ratio override options. Must be the same
+    <!-- App aspect ratio settings screen, user aspect ratio override options. Must be the same
          length and order as config_userAspectRatioOverrideValues below. -->
     <string-array name="config_userAspectRatioOverrideEntries" translatable="false">
         <item>@string/user_aspect_ratio_app_default</item>
+        <item>@string/user_aspect_ratio_fullscreen</item>
         <item>@string/user_aspect_ratio_half_screen</item>
+        <item>@string/user_aspect_ratio_device_size</item>
         <item>@string/user_aspect_ratio_16_9</item>
         <item>@string/user_aspect_ratio_4_3</item>
         <item>@string/user_aspect_ratio_3_2</item>
     </string-array>
 
-    <!-- App screen size settings screen, User aspect ratio override options. Must be the same
+    <!-- App aspect ratio settings screen, user aspect ratio override options. Must be the same
          length and order as config_userAspectRatioOverrideEntries above. The values must
          correspond to PackageManager.UserMinAspectRatio -->
     <integer-array name="config_userAspectRatioOverrideValues" translatable="false">
         <item>0</item> <!-- USER_MIN_ASPECT_RATIO_UNSET -->
+        <item>6</item> <!-- USER_MIN_ASPECT_RATIO_FULLSCREEN -->
         <item>1</item> <!-- USER_MIN_ASPECT_RATIO_SPLIT_SCREEN -->
+        <item>2</item> <!-- USER_MIN_ASPECT_RATIO_DISPLAY_SIZE -->
         <item>4</item> <!-- USER_MIN_ASPECT_RATIO_16_9 -->
         <item>3</item> <!-- USER_MIN_ASPECT_RATIO_4_3 -->
         <item>5</item> <!-- USER_MIN_ASPECT_RATIO_3_2 -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e7b5d13..ba5f72d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -12081,25 +12081,32 @@
     other {Apps installed more than # months ago}
     }</string>
 
-    <!-- App Screen Size (User Aspect Ratio Override) -->
-    <!-- [CHAR LIMIT=60] Screen size app list title setting to choose aspect ratio -->
-    <string name="screen_size_title">Screen size</string>
-    <!-- [CHAR LIMIT=NONE] Screen size setting summary to choose aspect ratio for apps unoptimized for device -->
-    <string name="screen_size_summary">Choose an aspect ratio for apps if they haven’t been optimized for your <xliff:g id="device_name">%1$s</xliff:g></string>
+    <!-- App Aspect Ratio (User Aspect Ratio Override) -->
+    <!-- [CHAR LIMIT=60] Aspect ratio title setting to choose app aspect ratio -->
+    <string name="aspect_ratio_title">Aspect ratio</string>
+    <!-- [CHAR LIMIT=NONE] Aspect ratio setting summary to choose aspect ratio for apps unoptimized for device -->
+    <string name="aspect_ratio_summary">Choose an aspect ratio to view this app if it hasn\'t been designed to fit your <xliff:g id="device_name">%1$s</xliff:g></string>
     <!-- [CHAR LIMIT=NONE] Aspect ratio suggested apps filter label -->
     <string name="user_aspect_ratio_suggested_apps_label">Suggested apps</string>
     <!-- [CHAR LIMIT=NONE] Filter label for apps that have user aspect ratio override applied -->
     <string name="user_aspect_ratio_overridden_apps_label">Apps you have overridden</string>
     <!-- [CHAR LIMIT=NONE] App default aspect ratio entry -->
     <string name="user_aspect_ratio_app_default">App default</string>
-    <!-- [CHAR LIMIT=NONE] Half-screen aspect ratio entry -->
-    <string name="user_aspect_ratio_half_screen">Half-screen</string>
+    <!-- [CHAR LIMIT=NONE] Fullscreen aspect ratio entry -->
+    <string name="user_aspect_ratio_fullscreen">Full screen</string>
+    <!-- [CHAR LIMIT=NONE] Half screen aspect ratio entry -->
+    <string name="user_aspect_ratio_half_screen">Half screen</string>
+    <!-- [CHAR LIMIT=NONE] Device display size aspect ratio entry -->
+    <string name="user_aspect_ratio_device_size">Device aspect ratio</string>
     <!-- [CHAR LIMIT=NONE] 16:9 aspect ratio entry -->
     <string name="user_aspect_ratio_16_9">16:9</string>
     <!-- [CHAR LIMIT=NONE] 3:2 aspect ratio entry -->
     <string name="user_aspect_ratio_3_2">3:2</string>
     <!-- [CHAR LIMIT=NONE] 4:3 aspect ratio entry -->
     <string name="user_aspect_ratio_4_3">4:3</string>
+    <!-- [CHAR LIMIT=NONE] Warning description for app info aspect ratio page -->
+    <string name="app_aspect_ratio_footer">The app will restart when you change aspect ratio. You may lose unsaved changes.</string>
+
 
     <!-- Accessibility label for fingerprint sensor [CHAR LIMIT=NONE] -->
     <string name="accessibility_fingerprint_label">Fingerprint sensor</string>
diff --git a/res/xml/apps.xml b/res/xml/apps.xml
index 386a07b..73bcbc9 100644
--- a/res/xml/apps.xml
+++ b/res/xml/apps.xml
@@ -81,7 +81,7 @@
 
     <Preference
         android:key="aspect_ratio_apps"
-        android:title="@string/screen_size_title"
+        android:title="@string/aspect_ratio_title"
         android:summary="@string/summary_placeholder"
         android:order="14"
         settings:controller="com.android.settings.applications.appcompat.UserAspectRatioAppsPreferenceController"
diff --git a/res/xml/user_aspect_ratio_details.xml b/res/xml/user_aspect_ratio_details.xml
new file mode 100644
index 0000000..fc921dd
--- /dev/null
+++ b/res/xml/user_aspect_ratio_details.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 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.
+  -->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:title="@string/aspect_ratio_title">
+
+    <com.android.settingslib.widget.ActionButtonsPreference
+        android:key="header_view" />
+
+    <com.android.settingslib.widget.SelectorWithWidgetPreference
+        android:key="app_default_pref"
+        android:title="@string/user_aspect_ratio_app_default"/>
+
+    <com.android.settingslib.widget.SelectorWithWidgetPreference
+        android:key="fullscreen_pref"
+        android:title="@string/user_aspect_ratio_fullscreen"/>
+
+    <com.android.settingslib.widget.SelectorWithWidgetPreference
+        android:key="half_screen_pref"
+        android:title="@string/user_aspect_ratio_half_screen"/>
+
+    <com.android.settingslib.widget.SelectorWithWidgetPreference
+        android:key="display_size_pref"
+        android:title="@string/user_aspect_ratio_device_size"/>
+
+    <com.android.settingslib.widget.SelectorWithWidgetPreference
+        android:key="16_9_pref"
+        android:title="@string/user_aspect_ratio_16_9"/>
+
+    <com.android.settingslib.widget.SelectorWithWidgetPreference
+        android:key="4_3_pref"
+        android:title="@string/user_aspect_ratio_4_3"/>
+
+    <com.android.settingslib.widget.SelectorWithWidgetPreference
+        android:key="3_2_pref"
+        android:title="@string/user_aspect_ratio_3_2"/>
+
+    <com.android.settingslib.widget.FooterPreference
+        android:title="@string/app_aspect_ratio_footer"
+        android:selectable="false"
+        settings:searchable="false"/>
+
+</PreferenceScreen>
\ No newline at end of file
diff --git a/src/com/android/settings/applications/appcompat/UserAspectRatioAppsPreferenceController.java b/src/com/android/settings/applications/appcompat/UserAspectRatioAppsPreferenceController.java
index 6ec2528..ff68fb0 100644
--- a/src/com/android/settings/applications/appcompat/UserAspectRatioAppsPreferenceController.java
+++ b/src/com/android/settings/applications/appcompat/UserAspectRatioAppsPreferenceController.java
@@ -43,6 +43,6 @@
 
     @Override
     public CharSequence getSummary() {
-        return mContext.getResources().getString(R.string.screen_size_summary, Build.MODEL);
+        return mContext.getResources().getString(R.string.aspect_ratio_summary, Build.MODEL);
     }
 }
diff --git a/src/com/android/settings/applications/appcompat/UserAspectRatioDetails.java b/src/com/android/settings/applications/appcompat/UserAspectRatioDetails.java
new file mode 100644
index 0000000..f8406f9
--- /dev/null
+++ b/src/com/android/settings/applications/appcompat/UserAspectRatioDetails.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2023 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.settings.applications.appcompat;
+
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_16_9;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_4_3;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_DISPLAY_SIZE;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
+
+import android.app.ActivityManager;
+import android.app.IActivityManager;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.R;
+import com.android.settings.applications.AppInfoWithHeader;
+import com.android.settingslib.widget.ActionButtonsPreference;
+import com.android.settingslib.widget.SelectorWithWidgetPreference;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * App specific activity to show aspect ratio overrides
+ */
+public class UserAspectRatioDetails extends AppInfoWithHeader implements
+        SelectorWithWidgetPreference.OnClickListener {
+    private static final String TAG = UserAspectRatioDetails.class.getSimpleName();
+
+    private static final String KEY_HEADER_BUTTONS = "header_view";
+    private static final String KEY_PREF_FULLSCREEN = "fullscreen_pref";
+    private static final String KEY_PREF_HALF_SCREEN = "half_screen_pref";
+    private static final String KEY_PREF_DISPLAY_SIZE = "display_size_pref";
+    private static final String KEY_PREF_16_9 = "16_9_pref";
+    private static final String KEY_PREF_4_3 = "4_3_pref";
+    @VisibleForTesting
+    static final String KEY_PREF_DEFAULT = "app_default_pref";
+    @VisibleForTesting
+    static final String KEY_PREF_3_2 = "3_2_pref";
+
+    private final List<SelectorWithWidgetPreference> mAspectRatioPreferences = new ArrayList<>();
+
+    @NonNull private UserAspectRatioManager mUserAspectRatioManager;
+    @NonNull private String mSelectedKey = KEY_PREF_DEFAULT;
+
+    @Override
+    public void onCreate(@NonNull Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mUserAspectRatioManager = new UserAspectRatioManager(getContext());
+        initPreferences();
+        try {
+            final int userAspectRatio = mUserAspectRatioManager
+                    .getUserMinAspectRatioValue(mPackageName, mUserId);
+            mSelectedKey = getSelectedKey(userAspectRatio);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to get user min aspect ratio");
+        }
+        refreshUi();
+    }
+
+    @Override
+    public void onRadioButtonClicked(@NonNull SelectorWithWidgetPreference selected) {
+        final String selectedKey = selected.getKey();
+        if (mSelectedKey.equals(selectedKey)) {
+            return;
+        }
+        final int userAspectRatio = getSelectedUserMinAspectRatio(selectedKey);
+        try {
+            getAspectRatioManager().setUserMinAspectRatio(mPackageName, mUserId, userAspectRatio);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to set user min aspect ratio");
+            return;
+        }
+        // Only update to selected aspect ratio if nothing goes wrong
+        mSelectedKey = selectedKey;
+        updateAllPreferences(mSelectedKey);
+        Log.d(TAG, "Killing application process " + mPackageName);
+        try {
+            final IActivityManager am = ActivityManager.getService();
+            am.stopAppForUser(mPackageName, mUserId);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to stop application " + mPackageName);
+        }
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        // TODO(b/292566895): add metrics for logging
+        return 0;
+    }
+
+    @Override
+    protected boolean refreshUi() {
+        if (mPackageInfo == null || mPackageInfo.applicationInfo == null) {
+            return false;
+        }
+        updateAllPreferences(mSelectedKey);
+        return true;
+    }
+
+    @Override
+    protected AlertDialog createDialog(int id, int errorCode) {
+        return null;
+    }
+
+    private void launchApplication() {
+        Intent launchIntent = mPm.getLaunchIntentForPackage(mPackageName)
+                .addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP);
+        if (launchIntent != null) {
+            getContext().startActivityAsUser(launchIntent, new UserHandle(mUserId));
+        }
+    }
+
+    @PackageManager.UserMinAspectRatio
+    private int getSelectedUserMinAspectRatio(@NonNull String selectedKey) {
+        switch (selectedKey) {
+            case KEY_PREF_FULLSCREEN:
+                return USER_MIN_ASPECT_RATIO_FULLSCREEN;
+            case KEY_PREF_HALF_SCREEN:
+                return USER_MIN_ASPECT_RATIO_SPLIT_SCREEN;
+            case KEY_PREF_DISPLAY_SIZE:
+                return USER_MIN_ASPECT_RATIO_DISPLAY_SIZE;
+            case KEY_PREF_3_2:
+                return USER_MIN_ASPECT_RATIO_3_2;
+            case KEY_PREF_4_3:
+                return USER_MIN_ASPECT_RATIO_4_3;
+            case KEY_PREF_16_9:
+                return USER_MIN_ASPECT_RATIO_16_9;
+            default:
+                return USER_MIN_ASPECT_RATIO_UNSET;
+        }
+    }
+
+    @NonNull
+    private String getSelectedKey(@PackageManager.UserMinAspectRatio int userMinAspectRatio) {
+        switch (userMinAspectRatio) {
+            case USER_MIN_ASPECT_RATIO_FULLSCREEN:
+                return KEY_PREF_FULLSCREEN;
+            case USER_MIN_ASPECT_RATIO_SPLIT_SCREEN:
+                return KEY_PREF_HALF_SCREEN;
+            case USER_MIN_ASPECT_RATIO_DISPLAY_SIZE:
+                return KEY_PREF_DISPLAY_SIZE;
+            case USER_MIN_ASPECT_RATIO_3_2:
+                return KEY_PREF_3_2;
+            case USER_MIN_ASPECT_RATIO_4_3:
+                return KEY_PREF_4_3;
+            case USER_MIN_ASPECT_RATIO_16_9:
+                return KEY_PREF_16_9;
+            default:
+                return KEY_PREF_DEFAULT;
+        }
+    }
+
+    private void initPreferences() {
+        addPreferencesFromResource(R.xml.user_aspect_ratio_details);
+
+        ((ActionButtonsPreference) findPreference(KEY_HEADER_BUTTONS))
+                .setButton1Text(R.string.launch_instant_app)
+                .setButton1Icon(R.drawable.ic_settings_open)
+                .setButton1OnClickListener(v -> launchApplication());
+
+        addPreference(KEY_PREF_DEFAULT, USER_MIN_ASPECT_RATIO_UNSET);
+        addPreference(KEY_PREF_FULLSCREEN, USER_MIN_ASPECT_RATIO_FULLSCREEN);
+        addPreference(KEY_PREF_DISPLAY_SIZE, USER_MIN_ASPECT_RATIO_DISPLAY_SIZE);
+        addPreference(KEY_PREF_HALF_SCREEN, USER_MIN_ASPECT_RATIO_SPLIT_SCREEN);
+        addPreference(KEY_PREF_16_9, USER_MIN_ASPECT_RATIO_16_9);
+        addPreference(KEY_PREF_4_3, USER_MIN_ASPECT_RATIO_4_3);
+        addPreference(KEY_PREF_3_2, USER_MIN_ASPECT_RATIO_3_2);
+    }
+
+    private void addPreference(@NonNull String key,
+            @PackageManager.UserMinAspectRatio int aspectRatio) {
+        final SelectorWithWidgetPreference pref = findPreference(key);
+        if (pref == null) {
+            return;
+        }
+        if (!mUserAspectRatioManager.containsAspectRatioOption(aspectRatio)) {
+            pref.setVisible(false);
+            return;
+        }
+        pref.setTitle(mUserAspectRatioManager.getUserMinAspectRatioEntry(aspectRatio));
+        pref.setOnClickListener(this);
+        mAspectRatioPreferences.add(pref);
+    }
+
+    private void updateAllPreferences(@NonNull String selectedKey) {
+        for (SelectorWithWidgetPreference pref : mAspectRatioPreferences) {
+            pref.setChecked(selectedKey.equals(pref.getKey()));
+        }
+    }
+
+    @VisibleForTesting
+    UserAspectRatioManager getAspectRatioManager() {
+        return mUserAspectRatioManager;
+    }
+}
diff --git a/src/com/android/settings/applications/appcompat/UserAspectRatioManager.java b/src/com/android/settings/applications/appcompat/UserAspectRatioManager.java
index 35bd7a9..c132fd0 100644
--- a/src/com/android/settings/applications/appcompat/UserAspectRatioManager.java
+++ b/src/com/android/settings/applications/appcompat/UserAspectRatioManager.java
@@ -28,6 +28,7 @@
 import android.util.ArrayMap;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 import com.android.settings.R;
 
@@ -49,6 +50,9 @@
     @VisibleForTesting
     static final String KEY_ENABLE_USER_ASPECT_RATIO_SETTINGS =
             "enable_app_compat_user_aspect_ratio_settings";
+    static final String KEY_ENABLE_USER_ASPECT_RATIO_FULLSCREEN =
+            "enable_app_compat_user_aspect_ratio_fullscreen";
+    private static final boolean DEFAULT_VALUE_ENABLE_USER_ASPECT_RATIO_FULLSCREEN = true;
 
     private final Context mContext;
     private final IPackageManager mIPm;
@@ -70,7 +74,8 @@
     public static boolean isFeatureEnabled(Context context) {
         final boolean isBuildTimeFlagEnabled = context.getResources().getBoolean(
                 com.android.internal.R.bool.config_appCompatUserAppAspectRatioSettingsIsEnabled);
-        return isBuildTimeFlagEnabled && getValueFromDeviceConfig();
+        return getValueFromDeviceConfig(KEY_ENABLE_USER_ASPECT_RATIO_SETTINGS,
+                DEFAULT_VALUE_ENABLE_USER_ASPECT_RATIO_SETTINGS) && isBuildTimeFlagEnabled;
     }
 
     /**
@@ -79,7 +84,9 @@
     @PackageManager.UserMinAspectRatio
     public int getUserMinAspectRatioValue(@NonNull String packageName, int uid)
             throws RemoteException {
-        return mIPm.getUserMinAspectRatio(packageName, uid);
+        final int aspectRatio = mIPm.getUserMinAspectRatio(packageName, uid);
+        return containsAspectRatioOption(aspectRatio)
+                ? aspectRatio : PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
     }
 
     /**
@@ -87,8 +94,41 @@
      */
     @NonNull
     public String getUserMinAspectRatioEntry(@PackageManager.UserMinAspectRatio int aspectRatio) {
-        return mUserAspectRatioMap.getOrDefault(
-                aspectRatio, mContext.getString(R.string.user_aspect_ratio_app_default));
+        if (!containsAspectRatioOption(aspectRatio))  {
+            return mUserAspectRatioMap.get(PackageManager.USER_MIN_ASPECT_RATIO_UNSET);
+        }
+        return mUserAspectRatioMap.get(aspectRatio);
+    }
+
+    /**
+     * @return corresponding aspect ratio string for package name and user
+     */
+    @NonNull
+    public String getUserMinAspectRatioEntry(@NonNull String packageName, int uid)
+            throws RemoteException {
+        final int aspectRatio = getUserMinAspectRatioValue(packageName, uid);
+        return getUserMinAspectRatioEntry(aspectRatio);
+    }
+
+    /**
+     * Whether user aspect ratio option is specified in
+     * {@link R.array.config_userAspectRatioOverrideValues}
+     * and is enabled by device config
+     */
+    public boolean containsAspectRatioOption(@PackageManager.UserMinAspectRatio int option) {
+        if (option == PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN
+                && !isFullscreenOptionEnabled()) {
+            return false;
+        }
+        return mUserAspectRatioMap.containsKey(option);
+    }
+
+    /**
+     * Sets user-specified {@link PackageManager.UserMinAspectRatio} override for an app
+     */
+    public void setUserMinAspectRatio(@NonNull String packageName, int uid,
+            @PackageManager.UserMinAspectRatio int aspectRatio) throws RemoteException {
+        mIPm.setUserMinAspectRatio(packageName, uid, aspectRatio);
     }
 
     /**
@@ -101,11 +141,20 @@
         return hasLauncherEntry;
     }
 
-    private static boolean getValueFromDeviceConfig() {
-        return DeviceConfig.getBoolean(
-                DeviceConfig.NAMESPACE_WINDOW_MANAGER,
-                KEY_ENABLE_USER_ASPECT_RATIO_SETTINGS,
-                DEFAULT_VALUE_ENABLE_USER_ASPECT_RATIO_SETTINGS);
+    /**
+     * Whether fullscreen option in per-app user aspect ratio settings is enabled
+     */
+    @VisibleForTesting
+    boolean isFullscreenOptionEnabled() {
+        final boolean isBuildTimeFlagEnabled = mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_appCompatUserAppAspectRatioFullscreenIsEnabled);
+        return isBuildTimeFlagEnabled && getValueFromDeviceConfig(
+                KEY_ENABLE_USER_ASPECT_RATIO_FULLSCREEN,
+                DEFAULT_VALUE_ENABLE_USER_ASPECT_RATIO_FULLSCREEN);
+    }
+
+    private static boolean getValueFromDeviceConfig(String name, boolean defaultValue) {
+        return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER, name, defaultValue);
     }
 
     @NonNull
@@ -122,14 +171,18 @@
         final Map<Integer, String> userMinAspectRatioMap = new ArrayMap<>();
         for (int i = 0; i < userMinAspectRatioValues.length; i++) {
             final int aspectRatioVal = userMinAspectRatioValues[i];
+            final String aspectRatioString = getAspectRatioStringOrDefault(
+                    userMinAspectRatioStrings[i], aspectRatioVal);
             switch (aspectRatioVal) {
                 // Only map known values of UserMinAspectRatio and ignore unknown entries
+                case PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN:
                 case PackageManager.USER_MIN_ASPECT_RATIO_UNSET:
                 case PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN:
+                case PackageManager.USER_MIN_ASPECT_RATIO_DISPLAY_SIZE:
                 case PackageManager.USER_MIN_ASPECT_RATIO_4_3:
                 case PackageManager.USER_MIN_ASPECT_RATIO_16_9:
                 case PackageManager.USER_MIN_ASPECT_RATIO_3_2:
-                    userMinAspectRatioMap.put(aspectRatioVal, userMinAspectRatioStrings[i]);
+                    userMinAspectRatioMap.put(aspectRatioVal, aspectRatioString);
             }
         }
         if (!userMinAspectRatioMap.containsKey(PackageManager.USER_MIN_ASPECT_RATIO_UNSET)) {
@@ -139,6 +192,31 @@
         return userMinAspectRatioMap;
     }
 
+    @NonNull
+    private String getAspectRatioStringOrDefault(@Nullable String aspectRatioString,
+            @PackageManager.UserMinAspectRatio int aspectRatioVal) {
+        if (aspectRatioString != null) {
+            return aspectRatioString;
+        }
+        // Options are customized per device and if strings are set to @null, use default
+        switch (aspectRatioVal) {
+            case PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN:
+                return mContext.getString(R.string.user_aspect_ratio_fullscreen);
+            case PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN:
+                return mContext.getString(R.string.user_aspect_ratio_half_screen);
+            case PackageManager.USER_MIN_ASPECT_RATIO_DISPLAY_SIZE:
+                return mContext.getString(R.string.user_aspect_ratio_device_size);
+            case PackageManager.USER_MIN_ASPECT_RATIO_4_3:
+                return mContext.getString(R.string.user_aspect_ratio_4_3);
+            case PackageManager.USER_MIN_ASPECT_RATIO_16_9:
+                return mContext.getString(R.string.user_aspect_ratio_16_9);
+            case PackageManager.USER_MIN_ASPECT_RATIO_3_2:
+                return mContext.getString(R.string.user_aspect_ratio_3_2);
+            default:
+                return mContext.getString(R.string.user_aspect_ratio_app_default);
+        }
+    }
+
     @VisibleForTesting
     void addInfoHasLauncherEntry(@NonNull ResolveInfo infoHasLauncherEntry) {
         mInfoHasLauncherEntryList.add(infoHasLauncherEntry);
diff --git a/src/com/android/settings/dream/WhenToDreamPicker.java b/src/com/android/settings/dream/WhenToDreamPicker.java
index 13cdadf..3052d20 100644
--- a/src/com/android/settings/dream/WhenToDreamPicker.java
+++ b/src/com/android/settings/dream/WhenToDreamPicker.java
@@ -50,7 +50,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return SettingsEnums.DREAM;
+        return SettingsEnums.SETTINGS_WHEN_TO_DREAM;
     }
 
     @Override
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
index c06e7f0..d345be9 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.os.Bundle;
 import android.util.ArrayMap;
 import android.util.SparseIntArray;
 
@@ -129,9 +130,14 @@
     boolean delayHourlyJobWhenBooting();
 
     /**
-     * Insert device usage data for anomaly detection
+     * Insert settings configuration data for anomaly detection
      */
-    void insertSettingsData(Context context);
+    void insertSettingsData(Context context, double displayDrain);
+
+    /**
+     * Returns {@link Bundle} for settings anomaly detection result
+     */
+    Bundle detectSettingsAnomaly(Context context, double displayDrain);
 
     /**
      * Gets an intent for one time bypass charge limited to resume charging.
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
index 89d793a..e4c6fd9d 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.os.Bundle;
 import android.os.Process;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -161,7 +162,12 @@
     }
 
     @Override
-    public void insertSettingsData(Context context)  {}
+    public void insertSettingsData(Context context, double displayDrain) {}
+
+    @Override
+    public Bundle detectSettingsAnomaly(Context context, double displayDrain) {
+        return null;
+    }
 
     @Override
     public Set<Integer> getOthersSystemComponentSet() {
diff --git a/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java b/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java
index 254cf04..e08f4ba 100644
--- a/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java
@@ -18,6 +18,7 @@
 
 import android.content.ComponentName;
 import android.content.Context;
+import android.os.BatteryManager;
 import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
@@ -139,7 +140,10 @@
         if (Utils.containsIncompatibleChargers(mContext, TAG)) {
             return mContext.getString(R.string.battery_info_status_not_charging);
         }
-        if (!info.discharging && info.chargeLabel != null) {
+        if (info.batteryStatus == BatteryManager.BATTERY_STATUS_NOT_CHARGING) {
+            // Present status only if no remaining time or status anomalous
+            return info.statusLabel;
+        } else if (!info.discharging && info.chargeLabel != null) {
             return info.chargeLabel;
         } else if (info.remainingLabel == null) {
             return info.batteryPercentString;
diff --git a/src/com/android/settings/fuelgauge/protos/Android.bp b/src/com/android/settings/fuelgauge/protos/Android.bp
index 3af2aef..1f3cdd9 100644
--- a/src/com/android/settings/fuelgauge/protos/Android.bp
+++ b/src/com/android/settings/fuelgauge/protos/Android.bp
@@ -30,3 +30,11 @@
     },
     srcs: ["fuelgauge_usage_state.proto"],
 }
+
+java_library {
+    name: "power-anomaly-event-protos-lite",
+    proto: {
+        type: "lite",
+    },
+    srcs: ["power_anomaly_event.proto"],
+}
diff --git a/src/com/android/settings/fuelgauge/protos/power_anomaly_event.proto b/src/com/android/settings/fuelgauge/protos/power_anomaly_event.proto
new file mode 100644
index 0000000..b4277c4
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/protos/power_anomaly_event.proto
@@ -0,0 +1,37 @@
+syntax = "proto2";
+
+option java_multiple_files = true;
+option java_package = "com.android.settings.fuelgauge.batteryusage";
+option java_outer_classname = "PowerAnomalyEventProto";
+
+message PowerAnomalyEvent {
+  optional int64 timestamp = 1;
+  optional string type = 2;  // e.g. settings, apps
+  optional string key = 3;  // e.g. brightness, significant_increase
+  optional float score = 4;
+  oneof info {
+    WarningBannerInfo warning_banner_info = 5;
+    WarningItemInfo warning_item_info = 6;
+  }
+}
+
+message WarningBannerInfo {
+  optional string title_string = 1;
+  optional string description_string = 2;
+  optional string main_button_string = 3;
+  optional string main_button_action = 4;
+  optional string cancel_button_string = 5;
+  optional string cancel_button_action = 6;
+}
+
+message WarningItemInfo {
+  optional int64 start_timestamp = 1;
+  optional int64 end_timestamp = 2;
+  optional string top_card_string = 3;
+  optional string title_string = 4;
+  optional string description_string = 5;
+  optional string main_button_string = 6;
+  optional string main_button_action = 7;
+  optional string cancel_button_string = 8;
+  optional string cancel_button_action = 9;
+}
diff --git a/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppPreference.kt b/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppPreference.kt
new file mode 100644
index 0000000..3680715
--- /dev/null
+++ b/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppPreference.kt
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2023 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.settings.spa.app.appcompat
+
+import android.content.Context
+import android.content.pm.ApplicationInfo
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringResource
+import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.android.settings.R
+import com.android.settings.applications.appcompat.UserAspectRatioDetails
+import com.android.settings.applications.appcompat.UserAspectRatioManager
+import com.android.settings.applications.appinfo.AppInfoDashboardFragment
+import com.android.settings.spa.app.appinfo.AppInfoSettingsProvider
+import com.android.settingslib.spa.widget.preference.Preference
+import com.android.settingslib.spa.widget.preference.PreferenceModel
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.flowOn
+
+@OptIn(ExperimentalLifecycleComposeApi::class)
+@Composable
+fun UserAspectRatioAppPreference(app: ApplicationInfo) {
+    val context = LocalContext.current
+    val presenter = remember { UserAspectRatioAppPresenter(context, app) }
+    if (!presenter.isAvailableFlow.collectAsStateWithLifecycle(initialValue = false).value) return
+
+    Preference(object : PreferenceModel {
+        override val title = stringResource(R.string.aspect_ratio_title)
+        override val summary = presenter.summaryFlow.collectAsStateWithLifecycle(
+            initialValue = stringResource(R.string.summary_placeholder),
+        )
+        override val onClick = presenter::startActivity
+    })
+}
+
+class UserAspectRatioAppPresenter(
+    private val context: Context,
+    private val app: ApplicationInfo,
+) {
+    private val manager = UserAspectRatioManager(context)
+
+    val isAvailableFlow = flow {
+        emit(UserAspectRatioManager.isFeatureEnabled(context)
+                && manager.canDisplayAspectRatioUi(app))
+    }.flowOn(Dispatchers.IO)
+
+    fun startActivity() =
+        navigateToAppAspectRatioSettings(context, app)
+
+    val summaryFlow = flow {
+        emit(manager.getUserMinAspectRatioEntry(app.packageName, context.userId))
+    }.flowOn(Dispatchers.IO)
+}
+
+fun navigateToAppAspectRatioSettings(context: Context, app: ApplicationInfo) {
+    AppInfoDashboardFragment.startAppInfoFragment(
+        UserAspectRatioDetails::class.java,
+        app,
+        context,
+        AppInfoSettingsProvider.METRICS_CATEGORY,
+    )
+}
\ No newline at end of file
diff --git a/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppsPageProvider.kt b/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppsPageProvider.kt
index 34b6b66..ff90492 100644
--- a/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppsPageProvider.kt
+++ b/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppsPageProvider.kt
@@ -36,7 +36,6 @@
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.settings.R
 import com.android.settings.applications.appcompat.UserAspectRatioManager
-import com.android.settings.spa.app.appinfo.AppInfoSettingsProvider
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
 import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
@@ -81,7 +80,7 @@
     @VisibleForTesting
     fun EntryItem() =
         Preference(object : PreferenceModel {
-            override val title = stringResource(R.string.screen_size_title)
+            override val title = stringResource(R.string.aspect_ratio_title)
             override val summary = getSummary().toState()
             override val onClick = navigator(name)
         })
@@ -94,7 +93,7 @@
 
     @Composable
     @VisibleForTesting
-    fun getSummary(): String = stringResource(R.string.screen_size_summary, Build.MODEL)
+    fun getSummary(): String = stringResource(R.string.aspect_ratio_summary, Build.MODEL)
 }
 
 @Composable
@@ -103,7 +102,7 @@
     = { AppList() },
 ) {
     AppListPage(
-        title = stringResource(R.string.screen_size_title),
+        title = stringResource(R.string.aspect_ratio_title),
         listModel = rememberContext(::UserAspectRatioAppListModel),
         appList = appList,
         header = {
@@ -148,7 +147,7 @@
     override fun AppListItemModel<UserAspectRatioAppListItemModel>.AppItem() {
         val app = record.app
         AppListItem(
-            onClick = AppInfoSettingsProvider.navigator(app)
+            onClick = { navigateToAppAspectRatioSettings(context, app) }
         )
     }
 
diff --git a/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt b/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt
index d59a4f7..e6df933 100644
--- a/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt
+++ b/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt
@@ -35,6 +35,7 @@
 import com.android.settings.applications.AppInfoBase
 import com.android.settings.applications.appinfo.AppInfoDashboardFragment
 import com.android.settings.spa.SpaActivity.Companion.startSpaActivity
+import com.android.settings.spa.app.appcompat.UserAspectRatioAppPreference
 import com.android.settings.spa.app.specialaccess.AlarmsAndRemindersAppListProvider
 import com.android.settings.spa.app.specialaccess.DisplayOverOtherAppsAppListProvider
 import com.android.settings.spa.app.specialaccess.InstallUnknownAppsListProvider
@@ -150,6 +151,7 @@
         }
 
         Category(title = stringResource(R.string.advanced_apps)) {
+            UserAspectRatioAppPreference(app)
             DisplayOverOtherAppsAppListProvider.InfoPageEntryItem(app)
             ModifySystemSettingsAppListProvider.InfoPageEntryItem(app)
             PictureInPictureListProvider.InfoPageEntryItem(app)
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 93b7c78..b0816fd 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -1628,7 +1628,7 @@
             mRemovingUserId = -1;
             updateUserList();
             if (mCreateUserDialogController.isActive()) {
-                mCreateUserDialogController.clear();
+                mCreateUserDialogController.finish();
             }
         }
     }
diff --git a/tests/robotests/src/com/android/settings/applications/appcompat/UserAspectRatioDetailsTest.java b/tests/robotests/src/com/android/settings/applications/appcompat/UserAspectRatioDetailsTest.java
new file mode 100644
index 0000000..31ff76c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/appcompat/UserAspectRatioDetailsTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2023 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.settings.applications.appcompat;
+
+import static com.android.settings.applications.appcompat.UserAspectRatioDetails.KEY_PREF_3_2;
+import static com.android.settings.applications.appcompat.UserAspectRatioDetails.KEY_PREF_DEFAULT;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.IActivityManager;
+import android.content.Context;
+import android.os.RemoteException;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.testutils.shadow.ShadowActivityManager;
+import com.android.settingslib.widget.SelectorWithWidgetPreference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+/**
+ * To run test: atest SettingsRoboTests:UserAspectRatioDetailsTest
+ */
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowActivityManager.class})
+public class UserAspectRatioDetailsTest {
+
+    @Mock
+    private UserAspectRatioManager mUserAspectRatioManager;
+    @Mock
+    private IActivityManager mAm;
+
+    private SelectorWithWidgetPreference mRadioButtonPref;
+    private Context mContext;
+    private UserAspectRatioDetails mFragment;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        mFragment = spy(new UserAspectRatioDetails());
+        when(mFragment.getContext()).thenReturn(mContext);
+        when(mFragment.getAspectRatioManager()).thenReturn(mUserAspectRatioManager);
+        ShadowActivityManager.setService(mAm);
+        mRadioButtonPref = new SelectorWithWidgetPreference(mContext);
+    }
+
+    @Test
+    public void onRadioButtonClicked_prefChange_shouldStopActivity() throws RemoteException {
+        // Default was already selected
+        mRadioButtonPref.setKey(KEY_PREF_DEFAULT);
+        mFragment.onRadioButtonClicked(mRadioButtonPref);
+        // Preference changed
+        mRadioButtonPref.setKey(KEY_PREF_3_2);
+        mFragment.onRadioButtonClicked(mRadioButtonPref);
+        // Only triggered once when preference change
+        verify(mAm).stopAppForUser(any(), anyInt());
+    }
+
+    @Test
+    public void onRadioButtonClicked_prefChange_shouldSetAspectRatio() throws RemoteException {
+        // Default was already selected
+        mRadioButtonPref.setKey(KEY_PREF_DEFAULT);
+        mFragment.onRadioButtonClicked(mRadioButtonPref);
+        // Preference changed
+        mRadioButtonPref.setKey(KEY_PREF_3_2);
+        mFragment.onRadioButtonClicked(mRadioButtonPref);
+        // Only triggered once when preference changes
+        verify(mUserAspectRatioManager).setUserMinAspectRatio(
+                any(), anyInt(), anyInt());
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceControllerTest.java
index b444309..f6bc297 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceControllerTest.java
@@ -31,6 +31,7 @@
 import android.hardware.usb.UsbManager;
 import android.hardware.usb.UsbPort;
 import android.hardware.usb.UsbPortStatus;
+import android.os.BatteryManager;
 
 import androidx.preference.Preference;
 import androidx.test.core.app.ApplicationProvider;
@@ -146,6 +147,17 @@
     }
 
     @Test
+    public void getDashboardLabel_notChargingState_returnsCorrectLabel() {
+        mController.mPreference = new Preference(mContext);
+        BatteryInfo info = new BatteryInfo();
+        info.batteryStatus = BatteryManager.BATTERY_STATUS_NOT_CHARGING;
+        info.statusLabel = "expected returned label";
+
+        assertThat(mController.getDashboardLabel(mContext, info, true))
+                .isEqualTo(info.statusLabel);
+    }
+
+    @Test
     public void getSummary_batteryNotPresent_shouldShowWarningMessage() {
         mController.mIsBatteryPresent = false;
         assertThat(mController.getSummary())
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
index 09914f1..feea768 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
@@ -27,10 +27,8 @@
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
-import static android.provider.DeviceConfig.NAMESPACE_AUTO_PIN_CONFIRMATION;
 import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
 
-import static com.android.internal.widget.LockPatternUtils.FLAG_ENABLE_AUTO_PIN_CONFIRMATION;
 import static com.android.internal.widget.LockPatternUtils.PASSWORD_TYPE_KEY;
 import static com.android.settings.password.ChooseLockGeneric.CONFIRM_CREDENTIALS;
 
@@ -45,7 +43,6 @@
 import android.app.admin.PasswordPolicy;
 import android.content.Intent;
 import android.os.UserHandle;
-import android.provider.DeviceConfig;
 import android.view.View;
 import android.widget.CheckBox;
 import android.widget.TextView;
@@ -55,7 +52,6 @@
 import com.android.settings.password.ChooseLockPassword.ChooseLockPasswordFragment;
 import com.android.settings.password.ChooseLockPassword.IntentBuilder;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
-import com.android.settings.testutils.shadow.ShadowDeviceConfig;
 import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
 import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
 import com.android.settings.testutils.shadow.ShadowUtils;
@@ -79,7 +75,6 @@
         ShadowLockPatternUtils.class,
         ShadowUtils.class,
         ShadowDevicePolicyManager.class,
-        ShadowDeviceConfig.class,
 })
 public class ChooseLockPasswordTest {
     @Before
@@ -435,8 +430,6 @@
 
     @Test
     public void autoPinConfirmOption_featureEnabledAndUntouchedByUser_changeStateAsPerRules() {
-        DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
-                /* value= */ "true", /* makeDefault= */ false);
         ChooseLockPassword passwordActivity = setupActivityWithPinTypeAndDefaultPolicy();
 
         ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(passwordActivity);
@@ -473,8 +466,6 @@
 
     @Test
     public void autoPinConfirmOption_featureEnabledAndModifiedByUser_shouldChangeStateAsPerRules() {
-        DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
-                /* value= */ "true", /* makeDefault= */ false);
         ChooseLockPassword passwordActivity = setupActivityWithPinTypeAndDefaultPolicy();
 
         ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(passwordActivity);
diff --git a/tests/robotests/src/com/android/settings/security/screenlock/AutoPinConfirmPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/screenlock/AutoPinConfirmPreferenceControllerTest.java
index 715913c..86c1244 100644
--- a/tests/robotests/src/com/android/settings/security/screenlock/AutoPinConfirmPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/screenlock/AutoPinConfirmPreferenceControllerTest.java
@@ -16,22 +16,16 @@
 
 package com.android.settings.security.screenlock;
 
-import static android.provider.DeviceConfig.NAMESPACE_AUTO_PIN_CONFIRMATION;
-
-import static com.android.internal.widget.LockPatternUtils.FLAG_ENABLE_AUTO_PIN_CONFIRMATION;
-
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
-import android.provider.DeviceConfig;
 
 import androidx.preference.SwitchPreference;
 import androidx.test.core.app.ApplicationProvider;
 
 import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.testutils.shadow.ShadowDeviceConfig;
 import com.android.settingslib.core.lifecycle.ObservablePreferenceFragment;
 
 import org.junit.Before;
@@ -40,10 +34,8 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
 
 @RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowDeviceConfig.class})
 public class AutoPinConfirmPreferenceControllerTest {
     private static final Integer TEST_USER_ID = 1;
     @Mock
@@ -65,8 +57,6 @@
 
     @Test
     public void isAvailable_featureEnabledAndLockSetToNone_shouldReturnFalse() {
-        DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
-                "true", /* makeDefault */ false);
         when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
 
         assertThat(mController.isAvailable()).isFalse();
@@ -74,8 +64,6 @@
 
     @Test
     public void isAvailable_featureEnabledAndLockSetToPassword_shouldReturnFalse() {
-        DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
-                "true", /* makeDefault */ false);
         when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
         when(mLockPatternUtils.getCredentialTypeForUser(TEST_USER_ID))
                 .thenReturn(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
@@ -85,8 +73,6 @@
 
     @Test
     public void isAvailable_featureEnabledAndLockSetToPIN_lengthLessThanSix_shouldReturnFalse() {
-        DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
-                "true", /* makeDefault */ false);
         when(mLockPatternUtils.getCredentialTypeForUser(TEST_USER_ID))
                 .thenReturn(LockPatternUtils.CREDENTIAL_TYPE_PIN);
         when(mLockPatternUtils.getPinLength(TEST_USER_ID)).thenReturn(5);
@@ -96,8 +82,6 @@
 
     @Test
     public void isAvailable_featureEnabledAndLockSetToPIN_lengthMoreThanEqSix_shouldReturnTrue() {
-        DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
-                "true", /* makeDefault */ false);
         when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
         when(mLockPatternUtils.getCredentialTypeForUser(TEST_USER_ID))
                 .thenReturn(LockPatternUtils.CREDENTIAL_TYPE_PIN);
@@ -107,20 +91,7 @@
     }
 
     @Test
-    public void isAvailable_featureDisabledAndLockSetToPIN_shouldReturnFalse() {
-        DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
-                "false", /* makeDefault */ false);
-        when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
-        when(mLockPatternUtils.getCredentialTypeForUser(TEST_USER_ID))
-                .thenReturn(LockPatternUtils.CREDENTIAL_TYPE_PIN);
-
-        assertThat(mController.isAvailable()).isFalse();
-    }
-
-    @Test
     public void updateState_ChangingSettingState_shouldSetPreferenceToAppropriateCheckedState() {
-        DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
-                "true", /* makeDefault */ false);
         // When auto_pin_confirm setting is disabled, switchPreference is unchecked
         when(mLockPatternUtils.isAutoPinConfirmEnabled(TEST_USER_ID)).thenReturn(false);
         mController.updateState(mPreference);
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppPreferenceTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppPreferenceTest.kt
new file mode 100644
index 0000000..342405a
--- /dev/null
+++ b/tests/spa_unit/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppPreferenceTest.kt
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2023 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.settings.spa.app.appcompat
+
+import android.content.Context
+import android.content.pm.ActivityInfo
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
+import android.content.pm.ResolveInfo
+import android.os.Build
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.assertIsEnabled
+import androidx.compose.ui.test.assertIsNotDisplayed
+import androidx.compose.ui.test.hasTextExactly
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onRoot
+import androidx.compose.ui.test.performClick
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.dx.mockito.inline.extended.ExtendedMockito
+import android.provider.DeviceConfig.NAMESPACE_WINDOW_MANAGER
+import com.android.settings.R
+import com.android.settings.applications.appinfo.AppInfoDashboardFragment
+import com.android.settings.applications.appcompat.UserAspectRatioDetails
+import com.android.settings.applications.appcompat.UserAspectRatioManager
+import com.android.settings.spa.app.appinfo.AppInfoSettingsProvider
+import com.android.settings.testutils.TestDeviceConfig
+import com.android.settingslib.spa.testutils.delay
+import com.android.settingslib.spa.testutils.waitUntilExists
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.any
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.eq
+import org.mockito.Mockito.mock
+import org.mockito.MockitoSession
+import org.mockito.Spy
+import org.mockito.quality.Strictness
+import org.mockito.Mockito.`when` as whenever
+
+/**
+ * To run this test: atest SettingsSpaUnitTests:UserAspectRatioAppPreferenceTest
+ */
+@RunWith(AndroidJUnit4::class)
+class UserAspectRatioAppPreferenceTest {
+    @get:Rule
+    val composeTestRule = createComposeRule()
+
+    private lateinit var mockSession: MockitoSession
+
+    @Spy
+    private val context: Context = ApplicationProvider.getApplicationContext()
+
+    @Spy
+    private val resources = context.resources
+
+    private val aspectRatioEnabledConfig =
+        TestDeviceConfig(NAMESPACE_WINDOW_MANAGER, "enable_app_compat_user_aspect_ratio_settings")
+
+    private lateinit var userAspectRatioManager: UserAspectRatioManager
+
+    @Mock
+    private lateinit var packageManager: PackageManager
+
+    @Before
+    fun setUp() {
+        mockSession = ExtendedMockito.mockitoSession()
+            .initMocks(this)
+            .mockStatic(UserAspectRatioDetails::class.java)
+            .mockStatic(AppInfoDashboardFragment::class.java)
+            .strictness(Strictness.LENIENT)
+            .startMocking()
+        whenever(context.resources).thenReturn(resources)
+        whenever(context.packageManager).thenReturn(packageManager)
+        userAspectRatioManager = mock(UserAspectRatioManager::class.java)
+    }
+
+    @After
+    fun tearDown() {
+        aspectRatioEnabledConfig.reset()
+        mockSession.finishMocking()
+    }
+
+    @Test
+    fun whenConfigIsFalse_notDisplayed() {
+        setConfig(false)
+
+        setContent()
+
+        composeTestRule.onRoot().assertIsNotDisplayed()
+    }
+
+    @Test
+    fun whenCannotDisplayAspectRatioUi_notDisplayed() {
+        setContent()
+
+        composeTestRule.onRoot().assertIsNotDisplayed()
+    }
+
+    @Test
+    fun whenCanDisplayAspectRatioUiAndConfigFalse_notDisplayed() {
+        setConfig(false)
+        whenever(packageManager.queryIntentActivities(any(), anyInt()))
+            .thenReturn(listOf(RESOLVE_INFO))
+
+        setContent()
+
+        composeTestRule.onRoot().assertIsNotDisplayed()
+    }
+
+    @Test
+    fun whenCannotDisplayAspectRatioUiAndConfigTrue_notDisplayed() {
+        setConfig(true)
+
+        setContent()
+
+        composeTestRule.onRoot().assertIsNotDisplayed()
+    }
+
+    @Test
+    fun whenCanDisplayAspectRatioUiAndConfigTrue_Displayed() {
+        setConfig(true)
+        whenever(packageManager.queryIntentActivities(any(), anyInt()))
+            .thenReturn(listOf(RESOLVE_INFO))
+
+        setContent()
+
+        composeTestRule.onNode(
+            hasTextExactly(
+                context.getString(R.string.aspect_ratio_title),
+                context.getString(R.string.user_aspect_ratio_app_default)
+            ),
+        ).assertIsDisplayed().assertIsEnabled()
+    }
+
+    @Test
+    fun onClick_startActivity() {
+        setConfig(true)
+        whenever(packageManager.queryIntentActivities(any(), anyInt()))
+            .thenReturn(listOf(RESOLVE_INFO))
+
+        setContent()
+        composeTestRule.onRoot().performClick()
+
+        ExtendedMockito.verify {
+            AppInfoDashboardFragment.startAppInfoFragment(
+                UserAspectRatioDetails::class.java,
+                APP,
+                context,
+                AppInfoSettingsProvider.METRICS_CATEGORY,
+            )
+        }
+    }
+
+    private fun setConfig(enabled: Boolean) {
+        whenever(resources.getBoolean(
+            com.android.internal.R.bool.config_appCompatUserAppAspectRatioSettingsIsEnabled
+        )).thenReturn(enabled)
+        aspectRatioEnabledConfig.override(enabled)
+    }
+
+    private fun setContent() {
+        composeTestRule.setContent {
+            CompositionLocalProvider(LocalContext provides context) {
+                UserAspectRatioAppPreference(APP)
+            }
+        }
+        composeTestRule.delay()
+    }
+
+    private companion object {
+        const val PACKAGE_NAME = "package.name"
+        const val UID = 123
+        val APP = ApplicationInfo().apply {
+            packageName = PACKAGE_NAME
+            uid = UID
+        }
+        private val RESOLVE_INFO = ResolveInfo().apply {
+            activityInfo = ActivityInfo().apply {
+                packageName = PACKAGE_NAME
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppsPageProviderTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppsPageProviderTest.kt
index e0eb5b2..0d2869c 100644
--- a/tests/spa_unit/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppsPageProviderTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/app/appcompat/UserAspectRatioAppsPageProviderTest.kt
@@ -60,21 +60,21 @@
     @Test
     fun injectEntry_title() {
         setInjectEntry()
-        composeTestRule.onNodeWithText(context.getString(R.string.screen_size_title))
+        composeTestRule.onNodeWithText(context.getString(R.string.aspect_ratio_title))
             .assertIsDisplayed()
     }
 
     @Test
     fun injectEntry_summary() {
         setInjectEntry()
-        composeTestRule.onNodeWithText(context.getString(R.string.screen_size_summary, Build.MODEL))
+        composeTestRule.onNodeWithText(context.getString(R.string.aspect_ratio_summary, Build.MODEL))
             .assertIsDisplayed()
     }
 
     @Test
     fun injectEntry_onClick_navigate() {
         setInjectEntry()
-        composeTestRule.onNodeWithText(context.getString(R.string.screen_size_title)).performClick()
+        composeTestRule.onNodeWithText(context.getString(R.string.aspect_ratio_title)).performClick()
         assertThat(fakeNavControllerWrapper.navigateCalledWith).isEqualTo("UserAspectRatioAppsPage")
     }
 
@@ -92,7 +92,7 @@
             UserAspectRatioAppList {}
         }
 
-        composeTestRule.onNodeWithText(context.getString(R.string.screen_size_title))
+        composeTestRule.onNodeWithText(context.getString(R.string.aspect_ratio_title))
             .assertIsDisplayed()
     }
 
diff --git a/tests/unit/src/com/android/settings/applications/appcompat/UserAspectRatioManagerTest.java b/tests/unit/src/com/android/settings/applications/appcompat/UserAspectRatioManagerTest.java
index 36f2f54..f4dcaf8 100644
--- a/tests/unit/src/com/android/settings/applications/appcompat/UserAspectRatioManagerTest.java
+++ b/tests/unit/src/com/android/settings/applications/appcompat/UserAspectRatioManagerTest.java
@@ -19,9 +19,11 @@
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_16_9;
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_4_3;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN;
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
 
+import static com.android.settings.applications.appcompat.UserAspectRatioManager.KEY_ENABLE_USER_ASPECT_RATIO_FULLSCREEN;
 import static com.android.settings.applications.appcompat.UserAspectRatioManager.KEY_ENABLE_USER_ASPECT_RATIO_SETTINGS;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -30,16 +32,19 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
 import android.provider.DeviceConfig;
 
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
+import com.android.internal.R;
 import com.android.settings.testutils.ResourcesUtils;
 
 import org.junit.After;
@@ -54,21 +59,35 @@
 public class UserAspectRatioManagerTest {
 
     private Context mContext;
+    private Resources mResources;
     private UserAspectRatioManager mUtils;
-    private String mOriginalFlag;
+    private String mOriginalSettingsFlag;
+    private String mOriginalFullscreenFlag;
 
     @Before
     public void setUp() {
         mContext = spy(ApplicationProvider.getApplicationContext());
+        mResources = spy(mContext.getResources());
         mUtils = spy(new UserAspectRatioManager(mContext));
-        mOriginalFlag = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
-                KEY_ENABLE_USER_ASPECT_RATIO_SETTINGS);
+
+        when(mContext.getResources()).thenReturn(mResources);
+
+        mOriginalSettingsFlag = DeviceConfig.getProperty(
+                DeviceConfig.NAMESPACE_WINDOW_MANAGER, KEY_ENABLE_USER_ASPECT_RATIO_SETTINGS);
+        setAspectRatioSettingsBuildTimeFlagEnabled(true);
+        setAspectRatioSettingsDeviceConfigEnabled("true" /* enabled */, false /* makeDefault */);
+
+        mOriginalFullscreenFlag = DeviceConfig.getProperty(
+                DeviceConfig.NAMESPACE_WINDOW_MANAGER, KEY_ENABLE_USER_ASPECT_RATIO_FULLSCREEN);
+        setAspectRatioFullscreenBuildTimeFlagEnabled(true);
+        setAspectRatioFullscreenDeviceConfigEnabled("true" /* enabled */, false /* makeDefault */);
     }
 
     @After
     public void tearDown() {
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
-                KEY_ENABLE_USER_ASPECT_RATIO_SETTINGS, mOriginalFlag, true /* makeDefault */);
+        setAspectRatioSettingsDeviceConfigEnabled(mOriginalSettingsFlag, true /* makeDefault */);
+        setAspectRatioFullscreenDeviceConfigEnabled(mOriginalFullscreenFlag,
+                true /* makeDefault */);
     }
 
     @Test
@@ -87,14 +106,53 @@
 
     @Test
     public void testIsFeatureEnabled() {
-        assertFalse(UserAspectRatioManager.isFeatureEnabled(mContext));
-
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
-                KEY_ENABLE_USER_ASPECT_RATIO_SETTINGS, "true", false /* makeDefault */);
         assertTrue(UserAspectRatioManager.isFeatureEnabled(mContext));
     }
 
     @Test
+    public void testIsFeatureEnabled_disabledBuildTimeFlag_returnFalse() {
+        setAspectRatioSettingsBuildTimeFlagEnabled(false);
+        assertFalse(UserAspectRatioManager.isFeatureEnabled(mContext));
+    }
+
+    @Test
+    public void testIsFeatureEnabled_disabledRuntimeFlag_returnFalse() {
+        setAspectRatioSettingsDeviceConfigEnabled("false" /* enabled */, false /* makeDefault */);
+        assertFalse(UserAspectRatioManager.isFeatureEnabled(mContext));
+    }
+
+    @Test
+    public void testIsFullscreenOptionEnabled() {
+        assertTrue(mUtils.isFullscreenOptionEnabled());
+    }
+
+    @Test
+    public void testIsFullscreenOptionEnabled_settingsDisabled_returnFalse() {
+        setAspectRatioFullscreenBuildTimeFlagEnabled(false);
+        assertFalse(mUtils.isFullscreenOptionEnabled());
+    }
+
+    @Test
+    public void testIsFullscreenOptionEnabled_disabledBuildTimeFlag_returnFalse() {
+        setAspectRatioFullscreenBuildTimeFlagEnabled(false);
+        assertFalse(mUtils.isFullscreenOptionEnabled());
+    }
+
+    @Test
+    public void testIsFullscreenOptionEnabled_disabledRuntimeFlag_returnFalse() {
+        setAspectRatioFullscreenDeviceConfigEnabled("false" /* enabled */, false /*makeDefault */);
+        assertFalse(mUtils.isFullscreenOptionEnabled());
+    }
+
+    @Test
+    public void containsAspectRatioOption_fullscreen() {
+        assertTrue(mUtils.containsAspectRatioOption(USER_MIN_ASPECT_RATIO_FULLSCREEN));
+
+        when(mUtils.isFullscreenOptionEnabled()).thenReturn(false);
+        assertFalse(mUtils.containsAspectRatioOption(USER_MIN_ASPECT_RATIO_FULLSCREEN));
+    }
+
+    @Test
     public void testGetUserMinAspectRatioEntry() {
         // R.string.user_aspect_ratio_app_default
         final String appDefault = ResourcesUtils.getResourcesString(mContext,
@@ -117,6 +175,38 @@
         // R.string.user_aspect_ratio_16_9
         assertThat(mUtils.getUserMinAspectRatioEntry(USER_MIN_ASPECT_RATIO_16_9))
                 .isEqualTo(ResourcesUtils.getResourcesString(mContext, "user_aspect_ratio_16_9"));
+        // R.string.user_aspect_ratio_fullscreen
+        assertThat(mUtils.getUserMinAspectRatioEntry(USER_MIN_ASPECT_RATIO_FULLSCREEN))
+                .isEqualTo(ResourcesUtils.getResourcesString(mContext,
+                        "user_aspect_ratio_fullscreen"));
+    }
+
+    @Test
+    public void testGetUserMinAspectRatioEntry_fullscreenDisabled_shouldReturnDefault() {
+        setAspectRatioFullscreenBuildTimeFlagEnabled(false);
+        assertThat(mUtils.getUserMinAspectRatioEntry(USER_MIN_ASPECT_RATIO_FULLSCREEN))
+                .isEqualTo(ResourcesUtils.getResourcesString(mContext,
+                        "user_aspect_ratio_app_default"));
+    }
+
+    private void setAspectRatioSettingsBuildTimeFlagEnabled(boolean enabled) {
+        when(mResources.getBoolean(R.bool.config_appCompatUserAppAspectRatioSettingsIsEnabled))
+                .thenReturn(enabled);
+    }
+
+    private void setAspectRatioSettingsDeviceConfigEnabled(String enabled, boolean makeDefault) {
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                KEY_ENABLE_USER_ASPECT_RATIO_SETTINGS, enabled, makeDefault);
+    }
+
+    private void setAspectRatioFullscreenBuildTimeFlagEnabled(boolean enabled) {
+        when(mResources.getBoolean(R.bool.config_appCompatUserAppAspectRatioFullscreenIsEnabled))
+                .thenReturn(enabled);
+    }
+
+    private void setAspectRatioFullscreenDeviceConfigEnabled(String enabled, boolean makeDefault) {
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                KEY_ENABLE_USER_ASPECT_RATIO_FULLSCREEN, enabled, makeDefault);
     }
 
     private void addResolveInfoLauncherEntry(String packageName) {