From ad389346c8e394826aa58536a1e80da866b3fc79 Mon Sep 17 00:00:00 2001 From: Roozbeh Pournader Date: Wed, 12 Jul 2017 11:37:59 -0700 Subject: [PATCH 1/6] Reland "Don't use framework strings for formatting file sizes" Reland http://ag/2529020 because the over-translation issue should be resolved now. Modify various formatters to avoid using framework strings for formatting file sizes. Also update README instructions for running unit tests. Bug: 36994779 Bug: 71580745 Bug: 217592956 Test: no new test failures from RunSettingsRoboTests Test: manual opening the settings page. Change-Id: Ic4689ab1b76622028004d05e69858228bdc441cf --- res/layout/data_usage_bytes_editor.xml | 3 +- res/values/strings.xml | 5 - .../datausage/BillingCycleSettings.java | 14 +++ .../settings/utils/FileSizeFormatter.java | 105 +++++++++++++----- .../settings/utils/FileSizeFormatterTest.java | 14 ++- tests/unit/README | 6 +- 6 files changed, 106 insertions(+), 41 deletions(-) diff --git a/res/layout/data_usage_bytes_editor.xml b/res/layout/data_usage_bytes_editor.xml index a72352dbf45..bcfc25e8eb0 100644 --- a/res/layout/data_usage_bytes_editor.xml +++ b/res/layout/data_usage_bytes_editor.xml @@ -38,7 +38,6 @@ android:id="@+id/size_spinner" android:layout_width="wrap_content" android:layout_height="match_parent" - android:layout_gravity="center_vertical" - android:entries="@array/bytes_picker_sizes" /> + android:layout_gravity="center_vertical" /> diff --git a/res/values/strings.xml b/res/values/strings.xml index e7f9990a6f0..8be1a9787b6 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -11307,11 +11307,6 @@ If device is locked, prevent typing replies or other text in notifications - - @*android:string/megabyteShort - @*android:string/gigabyteShort - - Default spell checker diff --git a/src/com/android/settings/datausage/BillingCycleSettings.java b/src/com/android/settings/datausage/BillingCycleSettings.java index 57931c1b36b..9e83e4cc451 100644 --- a/src/com/android/settings/datausage/BillingCycleSettings.java +++ b/src/com/android/settings/datausage/BillingCycleSettings.java @@ -22,6 +22,8 @@ import android.app.settings.SettingsEnums; import android.content.Context; import android.content.DialogInterface; import android.content.res.Resources; +import android.icu.text.MeasureFormat; +import android.icu.util.MeasureUnit; import android.net.NetworkPolicy; import android.net.NetworkTemplate; import android.os.Bundle; @@ -30,6 +32,7 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.inputmethod.EditorInfo; +import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.NumberPicker; import android.widget.Spinner; @@ -301,6 +304,17 @@ public class BillingCycleSettings extends DataUsageBaseFragment implements : editor.getPolicyWarningBytes(template); final long limitDisabled = isLimit ? LIMIT_DISABLED : WARNING_DISABLED; + final MeasureFormat formatter = MeasureFormat.getInstance( + getContext().getResources().getConfiguration().locale, + MeasureFormat.FormatWidth.SHORT); + final String[] unitNames = new String[] { + formatter.getUnitDisplayName(MeasureUnit.MEGABYTE), + formatter.getUnitDisplayName(MeasureUnit.GIGABYTE) + }; + final ArrayAdapter adapter = new ArrayAdapter( + getContext(), android.R.layout.simple_spinner_item, unitNames); + type.setAdapter(adapter); + final boolean unitInGigaBytes = (bytes > 1.5f * GIB_IN_BYTES); final String bytesText = formatText(bytes, unitInGigaBytes ? GIB_IN_BYTES : MIB_IN_BYTES); diff --git a/src/com/android/settings/utils/FileSizeFormatter.java b/src/com/android/settings/utils/FileSizeFormatter.java index e56388af543..9ef0fe256fd 100644 --- a/src/com/android/settings/utils/FileSizeFormatter.java +++ b/src/com/android/settings/utils/FileSizeFormatter.java @@ -16,11 +16,20 @@ package com.android.settings.utils; +import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; -import android.content.res.Resources; +import android.icu.text.DecimalFormat; +import android.icu.text.MeasureFormat; +import android.icu.text.NumberFormat; +import android.icu.util.Measure; +import android.icu.util.MeasureUnit; import android.text.BidiFormatter; -import android.text.format.Formatter; +import android.text.TextUtils; +import android.view.View; + +import java.math.BigDecimal; +import java.util.Locale; /** * Utility class to aid in formatting file sizes always with the same unit. This is modified from @@ -31,6 +40,61 @@ public final class FileSizeFormatter { public static final long MEGABYTE_IN_BYTES = KILOBYTE_IN_BYTES * 1000; public static final long GIGABYTE_IN_BYTES = MEGABYTE_IN_BYTES * 1000; + private static class RoundedBytesResult { + public final float value; + public final MeasureUnit units; + public final int fractionDigits; + public final long roundedBytes; + + private RoundedBytesResult( + float value, MeasureUnit units, int fractionDigits, long roundedBytes) { + this.value = value; + this.units = units; + this.fractionDigits = fractionDigits; + this.roundedBytes = roundedBytes; + } + } + + private static Locale localeFromContext(@NonNull Context context) { + return context.getResources().getConfiguration().locale; + } + + private static String bidiWrap(@NonNull Context context, String source) { + final Locale locale = localeFromContext(context); + if (TextUtils.getLayoutDirectionFromLocale(locale) == View.LAYOUT_DIRECTION_RTL) { + return BidiFormatter.getInstance(true /* RTL*/).unicodeWrap(source); + } else { + return source; + } + } + + private static NumberFormat getNumberFormatter(Locale locale, int fractionDigits) { + final NumberFormat numberFormatter = NumberFormat.getInstance(locale); + numberFormatter.setMinimumFractionDigits(fractionDigits); + numberFormatter.setMaximumFractionDigits(fractionDigits); + numberFormatter.setGroupingUsed(false); + if (numberFormatter instanceof DecimalFormat) { + // We do this only for DecimalFormat, since in the general NumberFormat case, calling + // setRoundingMode may throw an exception. + numberFormatter.setRoundingMode(BigDecimal.ROUND_HALF_UP); + } + return numberFormatter; + } + + private static String formatMeasureShort(Locale locale, NumberFormat numberFormatter, + float value, MeasureUnit units) { + final MeasureFormat measureFormatter = MeasureFormat.getInstance( + locale, MeasureFormat.FormatWidth.SHORT, numberFormatter); + return measureFormatter.format(new Measure(value, units)); + } + + private static String formatRoundedBytesResult( + @NonNull Context context, @NonNull RoundedBytesResult input) { + final Locale locale = localeFromContext(context); + final NumberFormat numberFormatter = getNumberFormatter(locale, input.fractionDigits); + return formatMeasureShort(locale, numberFormatter, input.value, input.units); + } + /** * Formats a content size to be in the form of bytes, kilobytes, megabytes, etc. * @@ -47,23 +111,17 @@ public final class FileSizeFormatter { * * @param context Context to use to load the localized units * @param sizeBytes size value to be formatted, in bytes - * @param suffix String id for the unit suffix. - * @param mult Amount of bytes in the unit. * @return formatted string with the number + * @param unit The unit used for formatting. + * @param mult Amount of bytes in the unit. + * @return formatted string with the number */ public static String formatFileSize( - @Nullable Context context, long sizeBytes, int suffix, long mult) { + @Nullable Context context, long sizeBytes, MeasureUnit unit, long mult) { if (context == null) { return ""; } - final Formatter.BytesResult res = - formatBytes(context.getResources(), sizeBytes, suffix, mult); - return BidiFormatter.getInstance() - .unicodeWrap(context.getString(getFileSizeSuffix(context), res.value, res.units)); - } - - private static int getFileSizeSuffix(Context context) { - final Resources res = context.getResources(); - return res.getIdentifier("fileSizeSuffix", "string", "android"); + final RoundedBytesResult res = formatBytes(sizeBytes, unit, mult); + return bidiWrap(context, formatRoundedBytesResult(context, res)); } /** @@ -76,8 +134,8 @@ public final class FileSizeFormatter { * @param suffix String id for the unit suffix. * @param mult Amount of bytes in the unit. */ - private static Formatter.BytesResult formatBytes( - Resources res, long sizeBytes, int suffix, long mult) { + private static RoundedBytesResult formatBytes( + long sizeBytes, MeasureUnit unit, long mult) { final boolean isNegative = (sizeBytes < 0); float result = isNegative ? -sizeBytes : sizeBytes; result = result / mult; @@ -85,32 +143,29 @@ public final class FileSizeFormatter { // compute the rounded value. String.format("%f", 0.1) might not return "0.1" due to // floating point errors. final int roundFactor; - final String roundFormat; + final int roundDigits; if (mult == 1) { roundFactor = 1; - roundFormat = "%.0f"; + roundDigits = 0; } else if (result < 1) { roundFactor = 100; - roundFormat = "%.2f"; + roundDigits = 2; } else if (result < 10) { roundFactor = 10; - roundFormat = "%.1f"; + roundDigits = 1; } else { // 10 <= result < 100 roundFactor = 1; - roundFormat = "%.0f"; + roundDigits = 0; } if (isNegative) { result = -result; } - final String roundedString = String.format(roundFormat, result); // Note this might overflow if abs(result) >= Long.MAX_VALUE / 100, but that's like 80PB so // it's okay (for now)... final long roundedBytes = (((long) Math.round(result * roundFactor)) * mult / roundFactor); - final String units = res.getString(suffix); - - return new Formatter.BytesResult(roundedString, units, roundedBytes); + return new RoundedBytesResult(result, unit, roundDigits, roundedBytes); } } diff --git a/tests/legacy_unit/src/com/android/settings/utils/FileSizeFormatterTest.java b/tests/legacy_unit/src/com/android/settings/utils/FileSizeFormatterTest.java index a255d0b8b6b..953bd341614 100644 --- a/tests/legacy_unit/src/com/android/settings/utils/FileSizeFormatterTest.java +++ b/tests/legacy_unit/src/com/android/settings/utils/FileSizeFormatterTest.java @@ -18,9 +18,11 @@ package com.android.settings.utils; import static com.android.settings.utils.FileSizeFormatter.GIGABYTE_IN_BYTES; import static com.android.settings.utils.FileSizeFormatter.MEGABYTE_IN_BYTES; + import static com.google.common.truth.Truth.assertThat; import android.content.Context; +import android.icu.util.MeasureUnit; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -46,7 +48,7 @@ public class FileSizeFormatterTest { FileSizeFormatter.formatFileSize( mContext, 0 /* size */, - com.android.internal.R.string.gigabyteShort, + MeasureUnit.GIGABYTE, GIGABYTE_IN_BYTES)) .isEqualTo("0.00 GB"); } @@ -57,7 +59,7 @@ public class FileSizeFormatterTest { FileSizeFormatter.formatFileSize( mContext, MEGABYTE_IN_BYTES * 11 /* size */, - com.android.internal.R.string.gigabyteShort, + MeasureUnit.GIGABYTE, GIGABYTE_IN_BYTES)) .isEqualTo("0.01 GB"); } @@ -68,7 +70,7 @@ public class FileSizeFormatterTest { FileSizeFormatter.formatFileSize( mContext, MEGABYTE_IN_BYTES * 155 /* size */, - com.android.internal.R.string.gigabyteShort, + MeasureUnit.GIGABYTE, GIGABYTE_IN_BYTES)) .isEqualTo("0.16 GB"); } @@ -79,7 +81,7 @@ public class FileSizeFormatterTest { FileSizeFormatter.formatFileSize( mContext, MEGABYTE_IN_BYTES * 1551 /* size */, - com.android.internal.R.string.gigabyteShort, + MeasureUnit.GIGABYTE, GIGABYTE_IN_BYTES)) .isEqualTo("1.6 GB"); } @@ -91,7 +93,7 @@ public class FileSizeFormatterTest { FileSizeFormatter.formatFileSize( mContext, GIGABYTE_IN_BYTES * 15 + MEGABYTE_IN_BYTES * 50 /* size */, - com.android.internal.R.string.gigabyteShort, + MeasureUnit.GIGABYTE, GIGABYTE_IN_BYTES)) .isEqualTo("15 GB"); } @@ -102,7 +104,7 @@ public class FileSizeFormatterTest { FileSizeFormatter.formatFileSize( mContext, MEGABYTE_IN_BYTES * -155 /* size */, - com.android.internal.R.string.gigabyteShort, + MeasureUnit.GIGABYTE, GIGABYTE_IN_BYTES)) .isEqualTo("-0.16 GB"); } diff --git a/tests/unit/README b/tests/unit/README index 5a85603debe..262c8bf3443 100644 --- a/tests/unit/README +++ b/tests/unit/README @@ -7,14 +7,14 @@ $ atest -c // The following instrutions show how to run the test suite using make + adb // To build the tests you can use the following command at the root of your android source tree -$ make SettingsUnitTests +$ make -j SettingsUnitTests The test apk then needs to be installed onto your test device. The apk's location will vary depending on your device model and architecture. At the end of the make command's output, there should be a line similar to the following: -"Copy: out/target/product/shamu/testcases/SettingsUnitTests/arm64/SettingsUnitTests.apk" +"Copy: ${ANDROID_PRODUCT_OUT}/testcases/SettingsUnitTests/arm64/SettingsUnitTests.apk" Install via the following command: -$ adb install -r out/target/product/shamu/testcases/SettingsUnitTests/arm64/SettingsUnitTests.apk +$ adb install -r ${ANDROID_PRODUCT_OUT}/testcases/SettingsUnitTests/arm64/SettingsUnitTests.apk To run all tests: $ adb shell am instrument -w com.android.settings.tests.unit/androidx.test.runner.AndroidJUnitRunner From dceda96854bac32981a1b17d4e92129dc5044a65 Mon Sep 17 00:00:00 2001 From: Alan Huang Date: Thu, 19 May 2022 09:17:23 +0000 Subject: [PATCH 2/6] [VolumePanel] Add Hearable control slice in VolumePanel Bug: 229048602 Test: make -j64 RunSettingsRoboTests Change-Id: Ia799a805594803a9a014eef76bb3db5a50a13524 --- .../android/settings/panel/VolumePanel.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/com/android/settings/panel/VolumePanel.java b/src/com/android/settings/panel/VolumePanel.java index e0d8a7f1fb3..98939cfe14c 100644 --- a/src/com/android/settings/panel/VolumePanel.java +++ b/src/com/android/settings/panel/VolumePanel.java @@ -27,30 +27,43 @@ import static com.android.settings.slices.CustomSliceRegistry.VOLUME_MEDIA_URI; import static com.android.settings.slices.CustomSliceRegistry.VOLUME_RINGER_URI; import android.app.settings.SettingsEnums; +import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; import android.provider.Settings; +import android.text.TextUtils; +import android.util.Log; import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.OnLifecycleEvent; import com.android.settings.R; +import com.android.settings.bluetooth.Utils; +import com.android.settingslib.bluetooth.A2dpProfile; +import com.android.settingslib.bluetooth.BluetoothUtils; +import com.android.settingslib.bluetooth.LocalBluetoothManager; +import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import com.android.settingslib.media.MediaOutputConstants; import java.util.ArrayList; +import java.util.IllegalFormatException; import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.FutureTask; /** * Panel data class for Volume settings. */ public class VolumePanel implements PanelContent, LifecycleObserver { + private static final String TAG = "VolumePanel"; private final Context mContext; private PanelContentCallback mCallback; + private LocalBluetoothProfileManager mProfileManager; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @@ -67,6 +80,21 @@ public class VolumePanel implements PanelContent, LifecycleObserver { private VolumePanel(Context context) { mContext = context.getApplicationContext(); + + final FutureTask localBtManagerFutureTask = new FutureTask<>( + // Avoid StrictMode ThreadPolicy violation + () -> Utils.getLocalBtManager(mContext)); + LocalBluetoothManager localBluetoothManager; + try { + localBtManagerFutureTask.run(); + localBluetoothManager = localBtManagerFutureTask.get(); + } catch (InterruptedException | ExecutionException e) { + Log.w(TAG, "Error getting LocalBluetoothManager."); + return; + } + if (localBluetoothManager != null) { + mProfileManager = localBluetoothManager.getProfileManager(); + } } /** Invoked when the panel is resumed. */ @@ -95,6 +123,11 @@ public class VolumePanel implements PanelContent, LifecycleObserver { uris.add(REMOTE_MEDIA_SLICE_URI); uris.add(VOLUME_MEDIA_URI); + Uri controlUri = getExtraControlUri(); + if (controlUri != null) { + Log.d(TAG, "add extra control slice"); + uris.add(controlUri); + } uris.add(MEDIA_OUTPUT_INDICATOR_SLICE_URI); uris.add(VOLUME_CALL_URI); uris.add(VOLUME_RINGER_URI); @@ -121,4 +154,33 @@ public class VolumePanel implements PanelContent, LifecycleObserver { public void registerCallback(PanelContentCallback callback) { mCallback = callback; } + + private Uri getExtraControlUri() { + Uri controlUri = null; + final BluetoothDevice bluetoothDevice = findActiveDevice(); + if (bluetoothDevice != null) { + final int width = mContext.getResources().getDimensionPixelSize( + R.dimen.settings_panel_width); + final String uri = BluetoothUtils.getControlUriMetaData(bluetoothDevice); + if (!TextUtils.isEmpty(uri)) { + try { + controlUri = Uri.parse(String.format(uri, width)); + } catch (IllegalFormatException | NullPointerException exception) { + Log.d(TAG, "unable to parse uri"); + controlUri = null; + } + } + } + return controlUri; + } + + private BluetoothDevice findActiveDevice() { + if (mProfileManager != null) { + final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile(); + if (a2dpProfile != null) { + return a2dpProfile.getActiveDevice(); + } + } + return null; + } } \ No newline at end of file From f9b665e30252fedd7d4492fd02dfc50563887701 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 20 May 2022 06:57:34 -0700 Subject: [PATCH 3/6] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I6bab2e5fd4e3902f5a2858f9cec57685e975460d --- res/values-b+sr+Latn/arrays.xml | 2 +- res/values-hi/arrays.xml | 2 +- res/values-kn/arrays.xml | 2 +- res/values-sk/arrays.xml | 2 +- res/values-sr/arrays.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/res/values-b+sr+Latn/arrays.xml b/res/values-b+sr+Latn/arrays.xml index b2c2c95a0f9..d2b9f1abb0a 100644 --- a/res/values-b+sr+Latn/arrays.xml +++ b/res/values-b+sr+Latn/arrays.xml @@ -389,7 +389,7 @@ "Veoma mala" "Mala" - "Srednje" + "Srednja" "Velika" "Veoma velika" diff --git a/res/values-hi/arrays.xml b/res/values-hi/arrays.xml index a938b387053..1265c29ca7c 100644 --- a/res/values-hi/arrays.xml +++ b/res/values-hi/arrays.xml @@ -421,7 +421,7 @@ "बटन" - "जेस्चर (हाव-भाव)" + "जेस्चर" "छोटा" diff --git a/res/values-kn/arrays.xml b/res/values-kn/arrays.xml index 62411f074a4..db8031c44b9 100644 --- a/res/values-kn/arrays.xml +++ b/res/values-kn/arrays.xml @@ -331,7 +331,7 @@ "ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ ಓದಿ" "ಕ್ಲಿಪ್‌ಬೋರ್ಡ್ ಮಾರ್ಪಡಿಸಿ" "ಮಾಧ್ಯಮ ಬಟನ್‌ಗಳು" - "ಆಡಿಯೊ ಫೋಕಸ್" + "ಆಡಿಯೋ ಫೋಕಸ್" "ಮಾಸ್ಟರ್ ವಾಲ್ಯೂಮ್" "ಧ್ವನಿ ವಾಲ್ಯೂಮ್" "ರಿಂಗ್ ವಾಲ್ಯೂಮ್" diff --git a/res/values-sk/arrays.xml b/res/values-sk/arrays.xml index 977f8abb364..9ce6e5a46c3 100644 --- a/res/values-sk/arrays.xml +++ b/res/values-sk/arrays.xml @@ -389,7 +389,7 @@ "Veľmi malé" "Malé" - "Stredná" + "Stredné" "Veľké" "Veľmi veľké" diff --git a/res/values-sr/arrays.xml b/res/values-sr/arrays.xml index 843c5b0b90b..019e8a6c8a5 100644 --- a/res/values-sr/arrays.xml +++ b/res/values-sr/arrays.xml @@ -389,7 +389,7 @@ "Веома мала" "Мала" - "Средње" + "Средња" "Велика" "Веома велика" From 26e5e919c85c69ee96e32aa4d3a73ccfb2fd3d78 Mon Sep 17 00:00:00 2001 From: Binyi Wu Date: Mon, 23 May 2022 17:40:21 +0800 Subject: [PATCH 4/6] Prevent keyboard from blocking the input box for WiFi configuration page. Bug: 223980567 Test: manual Change-Id: I2b95b065394e2395396ff71b00bd949ac824dac3 --- res/layout/wifi_add_network_view.xml | 3 ++- src/com/android/settings/wifi/AddNetworkFragment.java | 5 +++++ .../android/settings/wifi/ConfigureWifiEntryFragment.java | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/res/layout/wifi_add_network_view.xml b/res/layout/wifi_add_network_view.xml index d698adfc06c..480d5972e47 100644 --- a/res/layout/wifi_add_network_view.xml +++ b/res/layout/wifi_add_network_view.xml @@ -18,7 +18,8 @@ + android:layout_height="wrap_content" + android:fitsSystemWindows="true"> Date: Thu, 19 May 2022 09:20:30 +0800 Subject: [PATCH 5/6] Fix talkback speak "double tap to activate" on LabeledSeekBarPreference - SeekBarPreference should be unselectable - remove unnecessary handling of Summary - set currect Title color when preference is enabled and unselectable Bug: 230553896 Test: robotest Change-Id: Ie5d819088dc3c435005ddd00e232b2f6992b234a --- .../accessibility_text_reading_options.xml | 2 - res/xml/gesture_navigation_settings.xml | 2 - res/xml/power_menu_settings.xml | 1 - .../widget/LabeledSeekBarPreference.java | 45 +++++-------------- .../settings/widget/SeekBarPreference.java | 12 +---- 5 files changed, 13 insertions(+), 49 deletions(-) diff --git a/res/xml/accessibility_text_reading_options.xml b/res/xml/accessibility_text_reading_options.xml index 7fd5ff9a581..513920b978e 100644 --- a/res/xml/accessibility_text_reading_options.xml +++ b/res/xml/accessibility_text_reading_options.xml @@ -27,7 +27,6 @@ @@ -54,7 +53,6 @@ android:key="gesture_right_back_sensitivity" android:title="@string/right_edge" android:max="2" - android:selectable="true" settings:textStart="@string/low_label" settings:textEnd="@string/high_label"/> diff --git a/res/xml/power_menu_settings.xml b/res/xml/power_menu_settings.xml index 864cf1b09eb..e5e2daa7492 100644 --- a/res/xml/power_menu_settings.xml +++ b/res/xml/power_menu_settings.xml @@ -36,7 +36,6 @@ android:key="gesture_power_menu_long_press_for_assist_sensitivity" android:title="@string/power_menu_long_press_for_assist_sensitivity_title" android:summary="@string/power_menu_long_press_for_assist_sensitivity_summary" - android:selectable="true" settings:textStart="@string/power_menu_long_press_for_assist_sensitivity_low_label" settings:textEnd="@string/power_menu_long_press_for_assist_sensitivity_high_label" settings:controller="com.android.settings.gestures.LongPressPowerSensitivityPreferenceController" diff --git a/src/com/android/settings/widget/LabeledSeekBarPreference.java b/src/com/android/settings/widget/LabeledSeekBarPreference.java index 3e095239d18..5d1011634c7 100644 --- a/src/com/android/settings/widget/LabeledSeekBarPreference.java +++ b/src/com/android/settings/widget/LabeledSeekBarPreference.java @@ -26,12 +26,12 @@ import android.widget.ImageView; import android.widget.SeekBar; import android.widget.TextView; -import androidx.annotation.Nullable; import androidx.core.content.res.TypedArrayUtils; import androidx.preference.PreferenceViewHolder; import com.android.internal.util.Preconditions; import com.android.settings.R; +import com.android.settings.Utils; /** * A labeled {@link SeekBarPreference} with left and right text label, icon label, or both. @@ -61,8 +61,6 @@ public class LabeledSeekBarPreference extends SeekBarPreference { private final int mIconStartContentDescriptionId; private final int mIconEndContentDescriptionId; private OnPreferenceChangeListener mStopListener; - @Nullable - private CharSequence mSummary; private SeekBar.OnSeekBarChangeListener mSeekBarChangeListener; public LabeledSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr, @@ -97,8 +95,6 @@ public class LabeledSeekBarPreference extends SeekBarPreference { Preconditions.checkArgument(!(mIconEndContentDescriptionId != 0 && mIconEndId == 0), "The resource of the iconEnd attribute may be invalid or not set, " + "you should set the iconEnd attribute and have the valid resource."); - - mSummary = styledAttrs.getText(R.styleable.Preference_android_summary); styledAttrs.recycle(); } @@ -112,6 +108,17 @@ public class LabeledSeekBarPreference extends SeekBarPreference { public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); + final TextView summaryView = (TextView) holder.findViewById(android.R.id.summary); + boolean isSummaryVisible = false; + if (summaryView != null) { + isSummaryVisible = (summaryView.getVisibility() == View.VISIBLE); + } + final TextView titleView = (TextView) holder.findViewById(android.R.id.title); + if (titleView != null && !isSelectable() && isEnabled() && isSummaryVisible) { + titleView.setTextColor( + Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary)); + } + final TextView startText = (TextView) holder.findViewById(android.R.id.text1); if (mTextStartId > 0) { startText.setText(mTextStartId); @@ -132,15 +139,6 @@ public class LabeledSeekBarPreference extends SeekBarPreference { seekBar.setTickMark(tickMark); } - final TextView summary = (TextView) holder.findViewById(android.R.id.summary); - if (mSummary != null) { - summary.setText(mSummary); - summary.setVisibility(View.VISIBLE); - } else { - summary.setText(null); - summary.setVisibility(View.GONE); - } - final ViewGroup iconStartFrame = (ViewGroup) holder.findViewById(R.id.icon_start_frame); final ImageView iconStartView = (ImageView) holder.findViewById(R.id.icon_start); updateIconStartIfNeeded(iconStartFrame, iconStartView, seekBar); @@ -188,25 +186,6 @@ public class LabeledSeekBarPreference extends SeekBarPreference { notifyChanged(); } - @Override - public void setSummary(CharSequence summary) { - super.setSummary(summary); - mSummary = summary; - notifyChanged(); - } - - @Override - public void setSummary(int summaryResId) { - super.setSummary(summaryResId); - mSummary = getContext().getText(summaryResId); - notifyChanged(); - } - - @Override - public CharSequence getSummary() { - return mSummary; - } - public void setOnSeekBarChangeListener(SeekBar.OnSeekBarChangeListener seekBarChangeListener) { mSeekBarChangeListener = seekBarChangeListener; } diff --git a/src/com/android/settings/widget/SeekBarPreference.java b/src/com/android/settings/widget/SeekBarPreference.java index 62a19b945e9..b262627a489 100644 --- a/src/com/android/settings/widget/SeekBarPreference.java +++ b/src/com/android/settings/widget/SeekBarPreference.java @@ -78,12 +78,7 @@ public class SeekBarPreference extends RestrictedPreference com.android.internal.R.layout.preference_widget_seekbar); a.recycle(); - a = context.obtainStyledAttributes( - attrs, com.android.internal.R.styleable.Preference, defStyleAttr, defStyleRes); - final boolean isSelectable = a.getBoolean( - com.android.settings.R.styleable.Preference_android_selectable, false); - setSelectable(isSelectable); - a.recycle(); + setSelectable(false); setLayoutResource(layoutResId); } @@ -170,11 +165,6 @@ public class SeekBarPreference extends RestrictedPreference }); } - @Override - public CharSequence getSummary() { - return null; - } - @Override protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { setProgress(restoreValue ? getPersistedInt(mProgress) From 03d8d119145da8b8d030053014f2e53d274b2450 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Tue, 24 May 2022 14:28:06 +0800 Subject: [PATCH 6/6] Fix can't start injected item problem Should set highlight Preference key after isDuplicateClick to ensure clicked Preference key & highlight Preference are different and then isDuplicateClick returns a correct value. Bug: 233553587 Test: make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.dashboard manual 1. Click all left pane items and see if there is any launch problem. 2. Check if duplicate click check works. Change-Id: Ic6394b96896fd3a0fb926707565f63beff74a27b --- .../settings/dashboard/DashboardFeatureProviderImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java index 09000bf785d..80c9ec652dd 100644 --- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java +++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java @@ -185,9 +185,9 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider { && ActivityEmbeddingUtils.isEmbeddingActivityEnabled(mContext)) { // Highlight the preference whenever it's clicked final TopLevelSettings topLevelSettings = (TopLevelSettings) fragment; - topLevelSettings.setHighlightPreferenceKey(key); highlightMixin = topLevelSettings.getHighlightMixin(); isDuplicateClick = topLevelSettings.isDuplicateClick(preference); + topLevelSettings.setHighlightPreferenceKey(key); } launchIntentOrSelectProfile(activity, tile, intent, sourceMetricsCategory, highlightMixin, isDuplicateClick);