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) {