Merge "Handle different font scale values during B&R" into 24D1-dev
diff --git a/packages/SettingsProvider/res/values/arrays.xml b/packages/SettingsProvider/res/values/arrays.xml
new file mode 100644
index 0000000..e56d0f2
--- /dev/null
+++ b/packages/SettingsProvider/res/values/arrays.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2024 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- NOTE: if you change this, you must also add the corresponding scale key and lookup table to
+ frameworks/base/core/java/android/content/res/FontScaleConverterFactory.java
+ TODO(b/341235102): Remove font_scale array duplication
+ -->
+ <string-array name="entryvalues_font_size" translatable="false">
+ <item>0.85</item>
+ <item>1.0</item>
+ <item>1.15</item>
+ <item>1.30</item>
+ <item>1.50</item>
+ <item>1.80</item>
+ <item>2.0</item>
+ </string-array>
+
+</resources>
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
index 4c255a5..11fa8f4 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
@@ -48,7 +48,6 @@
Settings.System.WIFI_STATIC_DNS2,
Settings.System.BLUETOOTH_DISCOVERABILITY,
Settings.System.BLUETOOTH_DISCOVERABILITY_TIMEOUT,
- Settings.System.DEFAULT_DEVICE_FONT_SCALE,
Settings.System.FONT_SCALE,
Settings.System.DIM_SCREEN,
Settings.System.SCREEN_OFF_TIMEOUT,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 7b49608..77c6528 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -16,6 +16,8 @@
package com.android.providers.settings;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.backup.BackupAgentHelper;
import android.app.backup.BackupDataInput;
@@ -57,6 +59,7 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.settingslib.display.DisplayDensityConfiguration;
+import com.android.window.flags.Flags;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
@@ -88,6 +91,7 @@
private static final byte[] NULL_VALUE = new byte[0];
private static final int NULL_SIZE = -1;
+ private static final float FONT_SCALE_DEF_VALUE = 1.0f;
private static final String KEY_SYSTEM = "system";
private static final String KEY_SECURE = "secure";
@@ -111,7 +115,6 @@
// Versioning of the Network Policies backup payload.
private static final int NETWORK_POLICIES_BACKUP_VERSION = 1;
-
// Slots in the checksum array. Never insert new items in the middle
// of this array; new slots must be appended.
private static final int STATE_SYSTEM = 0;
@@ -208,10 +211,19 @@
// Populated in onRestore().
private int mRestoredFromSdkInt;
+ // The available font scale for the current device
+ @Nullable
+ private String[] mAvailableFontScales;
+
+ // The font_scale default value for this device.
+ private float mDefaultFontScale;
+
@Override
public void onCreate() {
if (DEBUG_BACKUP) Log.d(TAG, "onCreate() invoked");
-
+ mDefaultFontScale = getBaseContext().getResources().getFloat(R.dimen.def_device_font_scale);
+ mAvailableFontScales = getBaseContext().getResources()
+ .getStringArray(R.array.entryvalues_font_size);
mSettingsHelper = new SettingsHelper(this);
mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
super.onCreate();
@@ -917,6 +929,23 @@
continue;
}
}
+
+ if (Settings.System.FONT_SCALE.equals(key)) {
+ // If the current value is different from the default it means that it's been
+ // already changed for a11y reason. In that case we don't need to restore
+ // the new value.
+ final float currentValue = Settings.System.getFloat(cr, Settings.System.FONT_SCALE,
+ mDefaultFontScale);
+ if (currentValue != mDefaultFontScale) {
+ Log.d(TAG, "Font scale not restored because changed for a11y reason.");
+ continue;
+ }
+ final String toRestore = value;
+ value = findClosestAllowedFontScale(value, mAvailableFontScales);
+ Log.d(TAG, "Restored font scale from: " + toRestore + " to " + value);
+ }
+
+
settingsHelper.restoreValue(this, cr, contentValues, destination, key, value,
mRestoredFromSdkInt);
@@ -924,6 +953,32 @@
}
}
+
+ @VisibleForTesting
+ static String findClosestAllowedFontScale(@NonNull String requestedFontScale,
+ @NonNull String[] availableFontScales) {
+ if (Flags.configurableFontScaleDefault()) {
+ final float requestedValue = Float.parseFloat(requestedFontScale);
+ // Whatever is the requested value, we search the closest allowed value which is
+ // equals or larger. Note that if the requested value is the previous default,
+ // and this is still available, the value will be preserved.
+ float candidate = 0.0f;
+ boolean fontScaleFound = false;
+ for (int i = 0; !fontScaleFound && i < availableFontScales.length; i++) {
+ final float fontScale = Float.parseFloat(availableFontScales[i]);
+ if (fontScale >= requestedValue) {
+ candidate = fontScale;
+ fontScaleFound = true;
+ }
+ }
+ // If the current value is greater than all the allowed ones, we return the
+ // largest possible.
+ return fontScaleFound ? String.valueOf(candidate) : String.valueOf(
+ availableFontScales[availableFontScales.length - 1]);
+ }
+ return requestedFontScale;
+ }
+
@VisibleForTesting
SettingsBackupWhitelist getBackupWhitelist(Uri contentUri) {
// Figure out the white list and redirects to the global table. We restore anything
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 3e0d05c..140c566 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -386,6 +386,7 @@
// it means that the user has performed a global gesture to enable accessibility or set
// these settings in the Accessibility portion of the Setup Wizard, and definitely needs
// these features working after the restore.
+ // Note: Settings.Secure.FONT_SCALE is already handled in the caller class.
switch (name) {
case Settings.Secure.ACCESSIBILITY_ENABLED:
case Settings.Secure.TOUCH_EXPLORATION_ENABLED:
@@ -405,8 +406,6 @@
float currentScale = Settings.Secure.getFloat(
mContext.getContentResolver(), name, defaultScale);
return Math.abs(currentScale - defaultScale) >= FLOAT_TOLERANCE;
- case Settings.System.FONT_SCALE:
- return Settings.System.getFloat(mContext.getContentResolver(), name, 1.0f) != 1.0f;
default:
return false;
}
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 4f9e11a..ecc22ef 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -907,6 +907,7 @@
Settings.System.APPEND_FOR_LAST_AUDIBLE, // suffix deprecated since API 2
Settings.System.EGG_MODE, // I am the lolrus
Settings.System.END_BUTTON_BEHAVIOR, // bug?
+ Settings.System.DEFAULT_DEVICE_FONT_SCALE, // Non configurable
Settings.System
.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY,
// candidate for backup?
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
index 433aac7..d4ca4a3 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
@@ -31,6 +31,7 @@
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
+import android.platform.test.annotations.EnableFlags;
import android.provider.Settings;
import android.provider.settings.validators.SettingsValidators;
import android.provider.settings.validators.Validator;
@@ -39,6 +40,8 @@
import androidx.test.runner.AndroidJUnit4;
+import com.android.window.flags.Flags;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -54,8 +57,12 @@
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
-/** Tests for the SettingsHelperTest */
+/**
+ * Tests for the SettingsHelperTest
+ * Usage: atest SettingsProviderTest:SettingsBackupAgentTest
+ */
@RunWith(AndroidJUnit4.class)
public class SettingsBackupAgentTest extends BaseSettingsProviderTest {
private static final Uri TEST_URI = Uri.EMPTY;
@@ -213,6 +220,32 @@
assertFalse(settingsHelper.mWrittenValues.containsKey(PRESERVED_TEST_SETTING));
}
+ @Test
+ @EnableFlags(Flags.FLAG_CONFIGURABLE_FONT_SCALE_DEFAULT)
+ public void testFindClosestAllowedFontScale() {
+ final String[] availableFontScales = new String[]{"0.5", "0.9", "1.0", "1.1", "1.5"};
+ final Function<String, String> testedMethod =
+ (value) -> SettingsBackupAgent.findClosestAllowedFontScale(value,
+ availableFontScales);
+
+ // Any allowed value needs to be preserved.
+ assertEquals("0.5", testedMethod.apply("0.5"));
+ assertEquals("0.9", testedMethod.apply("0.9"));
+ assertEquals("1.0", testedMethod.apply("1.0"));
+ assertEquals("1.1", testedMethod.apply("1.1"));
+ assertEquals("1.5", testedMethod.apply("1.5"));
+
+ // When the current value is not one of the available, the first larger is returned
+ assertEquals("0.5", testedMethod.apply("0.3"));
+ assertEquals("0.9", testedMethod.apply("0.8"));
+ assertEquals("1.1", testedMethod.apply("1.05"));
+ assertEquals("1.5", testedMethod.apply("1.2"));
+
+ // When the current value is larger than the only one available, the largest allowed
+ // is returned.
+ assertEquals("1.5", testedMethod.apply("1.8"));
+ }
+
private byte[] generateBackupData(Map<String, String> keyValueData) {
int totalBytes = 0;
for (String key : keyValueData.keySet()) {