diff options
6 files changed, 129 insertions, 6 deletions
diff --git a/packages/SettingsProvider/res/values/arrays.xml b/packages/SettingsProvider/res/values/arrays.xml new file mode 100644 index 000000000000..e56d0f206d45 --- /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 4c255a556954..11fa8f43290d 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 @@ public class SystemSettings {                  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 8e320054028c..30c4ee55842e 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.annotations.VisibleForTesting;  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; @@ -91,6 +94,7 @@ public class SettingsBackupAgent extends BackupAgentHelper {      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"; @@ -115,7 +119,6 @@ public class SettingsBackupAgent extends BackupAgentHelper {      // 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; @@ -214,10 +217,19 @@ public class SettingsBackupAgent extends BackupAgentHelper {      // 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(); @@ -933,6 +945,23 @@ public class SettingsBackupAgent extends BackupAgentHelper {                      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); @@ -940,6 +969,32 @@ public class SettingsBackupAgent extends BackupAgentHelper {          }      } + +    @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 7be15af11228..6c3183191163 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java @@ -403,6 +403,7 @@ public class SettingsHelper {          // 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: @@ -422,8 +423,6 @@ public class SettingsHelper {                  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 f05f6b53afce..473955f9b679 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -897,6 +897,7 @@ public class SettingsBackupTest {                          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 433aac7abc45..d4ca4a35ed26 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.database.MatrixCursor;  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 android.test.mock.MockContentResolver;  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.Map;  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 @@ public class SettingsBackupAgentTest extends BaseSettingsProviderTest {          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()) {  |