Snap for 12496712 from 6656d59ddf to 25Q1-release

Change-Id: I2e3612758c516c3ab88aba640208632e16e5fe46
This commit is contained in:
Android Build Coastguard Worker
2024-10-14 23:23:21 +00:00
30 changed files with 1035 additions and 229 deletions

View File

@@ -9,3 +9,11 @@ flag {
bug: "283239837"
}
flag {
name: "revamp_toggles"
# "location" is used by the Android System Time team for feature flags.
namespace: "location"
description: "Makes the use location toggle dependent on automatic time zone detection"
bug: "296835792"
}

View File

@@ -579,7 +579,7 @@
<!-- Date & time setting screen setting switch summary: whether the time zone should be determined automatically [CHAR LIMIT=100] -->
<string name="zone_auto_title_summary">Set automatically based on mobile networks near you</string>
<!-- Date & time setting screen setting switch summary for non-telephony devices [CHAR LIMIT=100] -->
<string name="auto_zone_requires_location_summary">Set automatically using your device location, if available. An active Wifi connection may also be required.</string>
<string name="auto_zone_requires_location_summary">Set automatically using your device location, if available</string>
<!-- Date & time setting screen setting option summary text for the automatic 24 hour setting checkbox [CHAR LIMIT=100] -->
<string name="date_time_24hour_auto">Use locale default</string>
<!-- Date & time setting screen setting check box title -->
@@ -4705,9 +4705,13 @@
<!-- Summary for the button to trigger the 'Physical keyboard accessibility' page. [CHAR LIMIT=NONE] -->
<string name="keyboard_a11y_settings_summary">Sticky keys, Bounce keys, Mouse keys</string>
<!-- Title for the keyboard repeat key option. [CHAR LIMIT=60] -->
<string name="keyboard_repeat_key_title">Repeat Keys</string>
<string name="keyboard_repeat_keys_title">Repeat Keys</string>
<!-- Title for the keyboard repeat key timeout option. [CHAR LIMIT=60] -->
<string name="keyboard_repeat_keys_timeout_title">Delay before repeat</string>
<!-- Title for the keyboard repeat key delay option. [CHAR LIMIT=60] -->
<string name="keyboard_repeat_keys_delay_title">Repeat Rate</string>
<!-- Summary for the keyboard repeat key option. [CHAR LIMIT=NONE] -->
<string name="keyboard_repeat_key_summary">Hold down a key to repeat its character until the key is released</string>
<string name="keyboard_repeat_keys_summary">Hold down a key to repeat its character until the key is released</string>
<!-- Title text for per IME subtype keyboard layout. [CHAR LIMIT=35] -->
<string name="ime_label_title"><xliff:g id="ime_label" example="Gboard">%s</xliff:g> layout</string>
@@ -6957,6 +6961,8 @@
<string name="vpn_disconnect">Disconnect</string>
<!-- Field label to show the version number for a VPN app. [CHAR LIMIT=40] -->
<string name="vpn_version">Version</string>
<!-- Field label to show the version number for a VPN app dialog. [CHAR LIMIT=40] -->
<string name="vpn_version_info">Version <xliff:g id="version" example="3.3.0">%s</xliff:g></string>
<!-- Button label to forget a VPN profile [CHAR LIMIT=40] -->
<string name="vpn_forget_long">Forget VPN</string>
<!-- Dialog message title to set another VPN app to be always-on [CHAR LIMIT=40] -->

View File

@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/date_and_time"
settings:keywords="@string/keywords_date_and_time">
<com.android.settingslib.RestrictedSwitchPreference
android:key="auto_time"
android:title="@string/date_time_auto"
android:summary="@string/summary_placeholder"
settings:userRestriction="no_config_date_time"
settings:controller="com.android.settings.datetime.AutoTimePreferenceController" />
<com.android.settingslib.RestrictedPreference
android:key="date"
android:title="@string/date_time_set_date_title"
android:summary="@string/summary_placeholder"
settings:userRestriction="no_config_date_time"
settings:controller="com.android.settings.datetime.DatePreferenceController" />
<com.android.settingslib.RestrictedPreference
android:key="time"
android:title="@string/date_time_set_time_title"
android:summary="@string/summary_placeholder"
settings:userRestriction="no_config_date_time"
settings:controller="com.android.settings.datetime.TimePreferenceController" />
<PreferenceCategory
android:key="timezone_preference_category"
android:title="@string/date_time_set_timezone_title">
<com.android.settingslib.RestrictedSwitchPreference
android:key="auto_zone"
android:title="@string/zone_auto_title"
android:summary="@string/summary_placeholder"
settings:userRestriction="no_config_date_time"
settings:controller="com.android.settings.datetime.AutoTimeZonePreferenceController" />
<com.android.settingslib.widget.BannerMessagePreference
android:key="location_time_zone_detection_status"
android:title="@string/location_time_zone_detection_status_title"
settings:controller="com.android.settings.datetime.LocationProviderStatusPreferenceController"/>
<!-- This preference gets removed if location-based time zone detection is not supported -->
<SwitchPreferenceCompat
android:key="location_time_zone_detection"
android:title="@string/location_time_zone_detection_toggle_title"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.datetime.LocationTimeZoneDetectionPreferenceController"/>
<com.android.settingslib.RestrictedPreference
android:key="timezone"
android:title="@string/date_time_set_timezone_title"
android:summary="@string/summary_placeholder"
android:fragment="com.android.settings.datetime.timezone.TimeZoneSettings"
settings:userRestriction="no_config_date_time"
settings:keywords="@string/keywords_time_zone"
settings:controller="com.android.settings.datetime.TimeZonePreferenceController" />
</PreferenceCategory>
<!-- An optional preference category for feedback. Only displayed up if enabled via flags and config. -->
<PreferenceCategory
android:key="time_feedback_preference_category"
android:title="@string/time_feedback_category_title"
settings:keywords="@string/keywords_time_feedback_category"
settings:controller="com.android.settings.datetime.TimeFeedbackPreferenceCategoryController">
<Preference
android:key="time_feedback"
android:title="@string/time_feedback_title"
settings:keywords="@string/keywords_time_feedback"
settings:controller="com.android.settings.datetime.TimeFeedbackPreferenceController" />
</PreferenceCategory>
<PreferenceCategory
android:key="time_format_preference_category"
android:title="@string/time_format_category_title"
settings:keywords="@string/keywords_time_format">
<SwitchPreferenceCompat
android:key="24 hour"
android:title="@string/date_time_24hour"
settings:controller="com.android.settings.datetime.TimeFormatPreferenceController" />
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -33,11 +33,12 @@
android:summary="@string/modifier_keys_settings_summary"
android:fragment="com.android.settings.inputmethod.ModifierKeysSettings" />
<SwitchPreferenceCompat
android:key="physical_keyboard_repeat_key"
android:title="@string/keyboard_repeat_key_title"
android:summary="@string/keyboard_repeat_key_summary"
<com.android.settingslib.PrimarySwitchPreference
android:key="physical_keyboard_repeat_keys"
android:title="@string/keyboard_repeat_keys_title"
android:summary="@string/keyboard_repeat_keys_summary"
android:defaultValue="false"
android:fragment="com.android.settings.inputmethod.KeyboardRepeatKeysMainFragment"
settings:controller="com.android.settings.inputmethod.KeyboardRepeatKeysController" />
<Preference

View File

@@ -0,0 +1,42 @@
<?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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/keyboard_repeat_keys_title"
android:key="repeat_keys_main_page">
<com.android.settingslib.widget.MainSwitchPreference
android:key="repeat_keys_main_switch"
android:title="@string/keyboard_repeat_keys_title"
settings:controller="com.android.settings.inputmethod.KeyboardRepeatKeysController"/>
<com.android.settings.widget.LabeledSeekBarPreference
android:key="repeat_keys_timeout_preference"
android:title="@string/keyboard_repeat_keys_timeout_title"
android:min="0"
android:max="6"
settings:seekBarIncrement="1"
settings:controller= "com.android.settings.inputmethod.KeyboardRepeatKeysTimeOutPreferenceController" />
<com.android.settings.widget.LabeledSeekBarPreference
android:key="repeat_keys_delay_preference"
android:title="@string/keyboard_repeat_keys_delay_title"
android:min="0"
android:max="8"
settings:seekBarIncrement="1"
settings:controller= "com.android.settings.inputmethod.KeyboardRepeatKeysDelayPreferenceController" />
</PreferenceScreen>

View File

@@ -44,6 +44,7 @@ sealed interface DeviceSettingPreferenceModel {
val icon: DeviceSettingIcon? = null,
val checked: Boolean,
val onCheckedChange: ((Boolean) -> Unit),
val disabled: Boolean = false,
val action: DeviceSettingActionModel? = null,
) : DeviceSettingPreferenceModel

View File

@@ -139,7 +139,7 @@ class DeviceDetailsFragmentFormatterImpl(
viewModel
.getItems(fragmentType)
?.filterIsInstance<DeviceSettingConfigItemModel.BuiltinItem.BluetoothProfilesItem>()
?.first()
?.firstOrNull()
?.invisibleProfiles
}
@@ -306,6 +306,7 @@ class DeviceDetailsFragmentFormatterImpl(
override val onCheckedChange = { newChecked: Boolean ->
model.onCheckedChange(newChecked)
}
override val changeable = { !model.disabled }
override val icon: (@Composable () -> Unit)?
get() {
if (model.icon == null) {

View File

@@ -101,6 +101,7 @@ class BluetoothDeviceDetailsViewModel(
DeviceSettingStateModel.ActionSwitchPreferenceState(newState)
)
},
disabled = !isAllowedChangingState,
action = action,
)
} else {

View File

@@ -32,6 +32,7 @@ import androidx.preference.Preference;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.flags.Flags;
public class AutoTimeZonePreferenceController extends TogglePreferenceController {
@@ -46,7 +47,7 @@ public class AutoTimeZonePreferenceController extends TogglePreferenceController
// setTimeAndDateCallback() isn't called, e.g. for slices and other cases where the
// controller is instantiated outside of the context of the real Date & Time settings
// screen.
mCallback = (c) -> {};
mCallback = (c) -> {};
}
/**
@@ -103,10 +104,25 @@ public class AutoTimeZonePreferenceController extends TogglePreferenceController
@Override
public boolean setChecked(boolean isChecked) {
TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder()
.setAutoDetectionEnabled(isChecked)
.build();
boolean result = mTimeManager.updateTimeZoneConfiguration(configuration);
TimeZoneConfiguration.Builder configuration = new TimeZoneConfiguration.Builder()
.setAutoDetectionEnabled(isChecked);
if (Flags.revampToggles()) {
// "Use location for time zone" is only used if "Automatic time zone" is enabled. If
// the user toggles off automatic time zone, set the toggle off and disable the toggle.
int geoDetectionCapability = mTimeManager
.getTimeZoneCapabilitiesAndConfig()
.getCapabilities()
.getConfigureGeoDetectionEnabledCapability();
if (!isChecked
&& (geoDetectionCapability == CAPABILITY_NOT_APPLICABLE
|| geoDetectionCapability == CAPABILITY_POSSESSED)) {
configuration.setGeoDetectionEnabled(false);
}
}
boolean result = mTimeManager.updateTimeZoneConfiguration(configuration.build());
mCallback.updateTimeAndDateDisplay(mContext);
return result;
@@ -138,8 +154,10 @@ public class AutoTimeZonePreferenceController extends TogglePreferenceController
@VisibleForTesting
boolean isEnabled() {
TimeZoneConfiguration config = getTimeZoneCapabilitiesAndConfig().getConfiguration();
return config.isAutoDetectionEnabled();
return mTimeManager
.getTimeZoneCapabilitiesAndConfig()
.getConfiguration()
.isAutoDetectionEnabled();
}
private TimeZoneCapabilitiesAndConfig getTimeZoneCapabilitiesAndConfig() {

View File

@@ -23,6 +23,7 @@ import android.content.Context;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.flags.Flags;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable;
@@ -49,6 +50,9 @@ public class DateTimeSettings extends DashboardFragment implements
@Override
protected int getPreferenceScreenResId() {
if (Flags.revampToggles()) {
return R.xml.date_time_prefs_revamped;
}
return R.xml.date_time_prefs;
}
@@ -119,5 +123,6 @@ public class DateTimeSettings extends DashboardFragment implements
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.date_time_prefs);
new BaseSearchIndexProvider(
Flags.revampToggles() ? R.xml.date_time_prefs_revamped : R.xml.date_time_prefs);
}

View File

@@ -32,6 +32,7 @@ import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.flags.Flags;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -64,8 +65,10 @@ public class LocationTimeZoneDetectionPreferenceController
@Override
public boolean isChecked() {
// forceRefresh set to true as the location toggle may have been turned off by switching off
// automatic time zone
TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
getTimeZoneCapabilitiesAndConfig(/*forceRefresh=*/false);
getTimeZoneCapabilitiesAndConfig(/*forceRefresh=*/ Flags.revampToggles());
TimeZoneConfiguration configuration = capabilitiesAndConfig.getConfiguration();
return configuration.isGeoDetectionEnabled();
}
@@ -73,7 +76,7 @@ public class LocationTimeZoneDetectionPreferenceController
@Override
public boolean setChecked(boolean isChecked) {
TimeZoneCapabilitiesAndConfig timeZoneCapabilitiesAndConfig =
getTimeZoneCapabilitiesAndConfig(/*forceRefresh=*/false);
getTimeZoneCapabilitiesAndConfig(/*forceRefresh=*/ false);
boolean isLocationEnabled =
timeZoneCapabilitiesAndConfig.getCapabilities().isUseLocationEnabled();
if (isChecked && !isLocationEnabled) {
@@ -130,17 +133,30 @@ public class LocationTimeZoneDetectionPreferenceController
getTimeZoneCapabilitiesAndConfig(/* forceRefresh= */ false).getCapabilities();
int capability = timeZoneCapabilities.getConfigureGeoDetectionEnabledCapability();
// The preference only has two states: present and not present. The preference is never
// present but disabled.
// The preference can be present and enabled, present and disabled or not present.
if (capability == CAPABILITY_NOT_SUPPORTED || capability == CAPABILITY_NOT_ALLOWED) {
return UNSUPPORTED_ON_DEVICE;
} else if (capability == CAPABILITY_NOT_APPLICABLE || capability == CAPABILITY_POSSESSED) {
return AVAILABLE;
if (Flags.revampToggles()) {
return isAutoTimeZoneEnabled() ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
} else {
return AVAILABLE;
}
} else {
throw new IllegalStateException("Unknown capability=" + capability);
}
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
if (Flags.revampToggles()) {
// enable / disable the toggle based on automatic time zone being enabled or not
preference.setEnabled(isAutoTimeZoneEnabled());
}
}
@Override
public CharSequence getSummary() {
TimeZoneCapabilitiesAndConfig timeZoneCapabilitiesAndConfig =
@@ -212,4 +228,13 @@ public class LocationTimeZoneDetectionPreferenceController
}
return mTimeZoneCapabilitiesAndConfig;
}
/**
* Returns whether the user can select this preference or not, as it is a sub toggle of
* automatic time zone.
*/
private boolean isAutoTimeZoneEnabled() {
return mTimeManager.getTimeZoneCapabilitiesAndConfig().getConfiguration()
.isAutoDetectionEnabled();
}
}

View File

@@ -25,6 +25,7 @@ import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.flags.Flags;
import java.util.Calendar;
import java.util.Date;
@@ -72,8 +73,10 @@ public class TimeFormatPreferenceController extends TogglePreferenceController {
if (mIsFromSUW) {
return DISABLED_DEPENDENT_SETTING;
}
if (AutoTimeFormatPreferenceController.isAutoTimeFormatSelection(mContext)) {
return DISABLED_DEPENDENT_SETTING;
if (!Flags.revampToggles()) {
if (AutoTimeFormatPreferenceController.isAutoTimeFormatSelection(mContext)) {
return DISABLED_DEPENDENT_SETTING;
}
}
return AVAILABLE;
}
@@ -130,7 +133,7 @@ public class TimeFormatPreferenceController extends TogglePreferenceController {
timeFormatPreference = Intent.EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT;
} else {
timeFormatPreference = is24Hour ? Intent.EXTRA_TIME_PREF_VALUE_USE_24_HOUR
: Intent.EXTRA_TIME_PREF_VALUE_USE_12_HOUR;
: Intent.EXTRA_TIME_PREF_VALUE_USE_12_HOUR;
}
timeChanged.putExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, timeFormatPreference);
context.sendBroadcast(timeChanged);
@@ -138,7 +141,7 @@ public class TimeFormatPreferenceController extends TogglePreferenceController {
static void set24Hour(Context context, Boolean is24Hour) {
String value = is24Hour == null ? null :
is24Hour ? HOURS_24 : HOURS_12;
is24Hour ? HOURS_24 : HOURS_12;
Settings.System.putString(context.getContentResolver(),
Settings.System.TIME_12_24, value);
}

View File

@@ -72,25 +72,22 @@ public final class BatterySettingsMigrateChecker extends BroadcastReceiver {
Context context,
@BatteryOptimizeUtils.OptimizationMode int optimizationMode,
List<String> allowList) {
allowList.forEach(
packageName -> {
final BatteryOptimizeUtils batteryOptimizeUtils =
BatteryBackupHelper.newBatteryOptimizeUtils(
context,
packageName,
/* testOptimizeUtils */ sBatteryOptimizeUtils);
if (batteryOptimizeUtils == null) {
return;
}
if (batteryOptimizeUtils.getAppOptimizationMode() != optimizationMode) {
Log.w(
TAG,
"Reset " + packageName + " battery mode into " + optimizationMode);
batteryOptimizeUtils.setAppUsageState(
optimizationMode,
BatteryOptimizeHistoricalLogEntry.Action.FORCE_RESET);
}
});
for (String packageName : allowList) {
final BatteryOptimizeUtils batteryOptimizeUtils =
BatteryBackupHelper.newBatteryOptimizeUtils(
context,
packageName,
/* testOptimizeUtils */ sBatteryOptimizeUtils);
if (batteryOptimizeUtils == null) {
continue;
}
if (batteryOptimizeUtils.getAppOptimizationMode() != optimizationMode) {
Log.w(TAG, "Reset " + packageName + " mode into " + optimizationMode);
batteryOptimizeUtils.setAppUsageState(
optimizationMode,
BatteryOptimizeHistoricalLogEntry.Action.FORCE_RESET);
}
}
}
static void verifySaverConfiguration(Context context) {

View File

@@ -25,14 +25,20 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.LifecycleObserver;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreferenceCompat;
import com.android.settingslib.PrimarySwitchPreference;
import com.android.settingslib.widget.MainSwitchPreference;
public class KeyboardRepeatKeysController extends
InputSettingPreferenceController implements
LifecycleObserver {
private static final String KEY_REPEAT_KEY = "physical_keyboard_repeat_keys";
private static final String KEY_REPEAT_KEY_MAIN_PAGE = "repeat_key_main_switch";
@Nullable
private SwitchPreferenceCompat mSwitchPreferenceCompat;
private PrimarySwitchPreference mPrimarySwitchPreference;
@Nullable
private MainSwitchPreference mMainSwitchPreference;
public KeyboardRepeatKeysController(@NonNull Context context,
@NonNull String key) {
@@ -42,7 +48,11 @@ public class KeyboardRepeatKeysController extends
@Override
public void displayPreference(@NonNull PreferenceScreen screen) {
super.displayPreference(screen);
mSwitchPreferenceCompat = screen.findPreference(getPreferenceKey());
if (KEY_REPEAT_KEY.equals(getPreferenceKey())) {
mPrimarySwitchPreference = screen.findPreference(getPreferenceKey());
} else if (KEY_REPEAT_KEY_MAIN_PAGE.equals(getPreferenceKey())) {
mMainSwitchPreference = screen.findPreference(getPreferenceKey());
}
}
@Override
@@ -63,8 +73,10 @@ public class KeyboardRepeatKeysController extends
@Override
protected void onInputSettingUpdated() {
if (mSwitchPreferenceCompat != null) {
mSwitchPreferenceCompat.setChecked(InputSettings.isRepeatKeysEnabled(mContext));
if (mPrimarySwitchPreference != null) {
mPrimarySwitchPreference.setChecked(InputSettings.isRepeatKeysEnabled(mContext));
} else if (mMainSwitchPreference != null) {
mMainSwitchPreference.setChecked(InputSettings.isRepeatKeysEnabled(mContext));
}
}

View File

@@ -0,0 +1,65 @@
/*
* 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.
*/
package com.android.settings.inputmethod;
import android.content.Context;
import android.hardware.input.InputSettings;
import androidx.annotation.NonNull;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.core.SliderPreferenceController;
import com.google.common.collect.ImmutableList;
public class KeyboardRepeatKeysDelayPreferenceController extends SliderPreferenceController {
@VisibleForTesting
static final ImmutableList<Integer> REPEAT_KEY_DELAY_VALUE_LIST = ImmutableList.of(2000, 1000,
500, 300, 200, 100, 50, 30, 20);
public KeyboardRepeatKeysDelayPreferenceController(@NonNull Context context,
@NonNull String preferenceKey) {
super(context, preferenceKey);
}
@Override
public int getSliderPosition() {
return REPEAT_KEY_DELAY_VALUE_LIST.indexOf(InputSettings.getRepeatKeysDelay(mContext));
}
@Override
public boolean setSliderPosition(int position) {
InputSettings.setRepeatKeysDelay(mContext, REPEAT_KEY_DELAY_VALUE_LIST.get(position));
return true;
}
@Override
public int getMax() {
return REPEAT_KEY_DELAY_VALUE_LIST.size() - 1;
}
@Override
public int getMin() {
return 0;
}
@Override
public int getAvailabilityStatus() {
return InputSettings.isRepeatKeysFeatureFlagEnabled()
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
}

View File

@@ -0,0 +1,170 @@
/*
* 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.
*/
package com.android.settings.inputmethod;
import static com.android.settings.inputmethod.PhysicalKeyboardFragment.getHardKeyboards;
import android.app.settings.SettingsEnums;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.hardware.input.InputManager;
import android.hardware.input.InputSettings;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.util.Preconditions;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.keyboard.Flags;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.LabeledSeekBarPreference;
import com.android.settingslib.utils.ThreadUtils;
import java.util.List;
public class KeyboardRepeatKeysMainFragment extends DashboardFragment
implements InputManager.InputDeviceListener {
private static final String TAG = "RepeatKeysMainFragment";
private static final String TIME_OUT_KEY = "repeat_keys_timeout_preference";
private static final String DELAY_KEY = "repeat_keys_delay_preference";
private final Uri mRepeatKeyUri = Settings.Secure.getUriFor(
Settings.Secure.KEY_REPEAT_ENABLED);
private final ContentObserver mContentObserver = new ContentObserver(new Handler(true)) {
@Override
public void onChange(boolean selfChange, Uri uri) {
if (mRepeatKeyUri.equals(uri)) {
updatePreferencesState();
}
}
};
private InputManager mInputManager;
private ContentResolver mContentResolver;
@Nullable
private LabeledSeekBarPreference mRepeatTimeoutPreference;
@Nullable
private LabeledSeekBarPreference mRepeatDelayPreference;
@Override
public int getMetricsCategory() {
return SettingsEnums.PHYSICAL_KEYBOARD_A11Y;
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
mInputManager = Preconditions.checkNotNull(getActivity()
.getSystemService(InputManager.class));
mContentResolver = context.getContentResolver();
}
@Override
public void onCreatePreferences(Bundle bundle, String s) {
super.onCreatePreferences(bundle, s);
mRepeatTimeoutPreference = findPreference(TIME_OUT_KEY);
mRepeatDelayPreference = findPreference(DELAY_KEY);
updatePreferencesState();
}
@Override
public void onResume() {
super.onResume();
finishEarlyIfNeeded();
mInputManager.registerInputDeviceListener(this, null);
registerSettingsObserver();
}
@Override
public void onPause() {
super.onPause();
mInputManager.unregisterInputDeviceListener(this);
unregisterSettingsObserver();
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.repeat_key_main_page;
}
private void updatePreferencesState() {
boolean isRepeatKeyEnabled = InputSettings.isRepeatKeysEnabled(getContext());
if (mRepeatTimeoutPreference != null && mRepeatDelayPreference != null) {
mRepeatTimeoutPreference.setEnabled(isRepeatKeyEnabled);
mRepeatDelayPreference.setEnabled(isRepeatKeyEnabled);
}
}
private void registerSettingsObserver() {
unregisterSettingsObserver();
mContentResolver.registerContentObserver(
mRepeatKeyUri,
false,
mContentObserver,
UserHandle.myUserId());
}
private void unregisterSettingsObserver() {
mContentResolver.unregisterContentObserver(mContentObserver);
}
@Override
public void onInputDeviceAdded(int deviceId) {
finishEarlyIfNeeded();
}
@Override
public void onInputDeviceRemoved(int deviceId) {
finishEarlyIfNeeded();
}
@Override
public void onInputDeviceChanged(int deviceId) {
finishEarlyIfNeeded();
}
private void finishEarlyIfNeeded() {
final Context context = getContext();
ThreadUtils.postOnBackgroundThread(() -> {
final List<PhysicalKeyboardFragment.HardKeyboardDeviceInfo> newHardKeyboards =
getHardKeyboards(context);
if (newHardKeyboards.isEmpty()) {
getActivity().finish();
}
});
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.repeat_key_main_page) {
@Override
protected boolean isPageSearchEnabled(Context context) {
return Flags.keyboardAndTouchpadA11yNewPageEnabled()
&& !getHardKeyboards(context).isEmpty();
}
};
}

View File

@@ -0,0 +1,66 @@
/*
* 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.
*/
package com.android.settings.inputmethod;
import android.content.Context;
import android.hardware.input.InputSettings;
import androidx.annotation.NonNull;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.core.SliderPreferenceController;
import com.google.common.collect.ImmutableList;
public class KeyboardRepeatKeysTimeOutPreferenceController extends SliderPreferenceController {
@VisibleForTesting
static final ImmutableList<Integer> REPEAT_KEY_TIMEOUT_VALUE_LIST = ImmutableList.of(2000, 1500,
1000, 400, 300, 200, 150);
public KeyboardRepeatKeysTimeOutPreferenceController(
@NonNull Context context,
@NonNull String preferenceKey) {
super(context, preferenceKey);
}
@Override
public int getSliderPosition() {
return REPEAT_KEY_TIMEOUT_VALUE_LIST.indexOf(InputSettings.getRepeatKeysTimeout(mContext));
}
@Override
public boolean setSliderPosition(int position) {
InputSettings.setRepeatKeysTimeout(mContext, REPEAT_KEY_TIMEOUT_VALUE_LIST.get(position));
return true;
}
@Override
public int getMax() {
return REPEAT_KEY_TIMEOUT_VALUE_LIST.size() - 1;
}
@Override
public int getMin() {
return 0;
}
@Override
public int getAvailabilityStatus() {
return InputSettings.isRepeatKeysFeatureFlagEnabled()
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
}

View File

@@ -19,7 +19,6 @@ package com.android.settings.privacy;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
import android.text.TextUtils;
@@ -33,7 +32,6 @@ import com.android.settings.core.TogglePreferenceController;
import com.android.settings.dashboard.profileselector.ProfileSelectDialog;
import com.android.settings.utils.ContentCaptureUtils;
import java.util.ArrayList;
import java.util.List;
public final class EnableContentCaptureWithServiceSettingsPreferenceController
@@ -94,11 +92,7 @@ public final class EnableContentCaptureWithServiceSettingsPreferenceController
private void show(Preference preference) {
final UserManager userManager = UserManager.get(mContext);
final List<UserInfo> userInfos = userManager.getUsers();
final ArrayList<UserHandle> userHandles = new ArrayList<>(userInfos.size());
for (UserInfo info : userInfos) {
userHandles.add(info.getUserHandle());
}
final List<UserHandle> userHandles = userManager.getEnabledProfiles();
final Intent intent = preference.getIntent().addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
if (userHandles.size() == 1) {
mContext.startActivityAsUser(intent, userHandles.get(0));

View File

@@ -56,7 +56,7 @@ class AppDialog extends AlertDialog implements DialogInterface.OnClickListener {
@Override
protected void onCreate(Bundle savedState) {
setTitle(mLabel);
setMessage(getContext().getString(R.string.vpn_version, mPackageInfo.versionName));
setMessage(getContext().getString(R.string.vpn_version_info, mPackageInfo.versionName));
createButtons();
super.onCreate(savedState);

View File

@@ -262,16 +262,9 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
continue;
}
canFindNetwork = true;
final int security =
WifiDppUtils.getSecurityTypeFromWifiConfiguration(wifiConfiguration);
if (security == wifiEntry.getSecurity()) {
return REACHABLE_WIFI_NETWORK;
}
// Default security type of PSK/SAE transition mode WifiEntry is SECURITY_PSK and
// there is no way to know if a WifiEntry is of transition mode. Give it a chance.
if (security == WifiEntry.SECURITY_SAE
&& wifiEntry.getSecurity() == WifiEntry.SECURITY_PSK) {
int security = WifiDppUtils.getSecurityTypeFromWifiConfiguration(wifiConfiguration);
if (isSecurityMatched(security, wifiEntry.getSecurity())) {
Log.d(TAG, "WiFi DPP detects connection security for a matching WiFi network.");
return REACHABLE_WIFI_NETWORK;
}
}
@@ -283,6 +276,24 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
return R.string.wifi_dpp_check_connection_no_matched_ssid;
}
@VisibleForTesting
boolean isSecurityMatched(int qrSecurity, int entrySecurity) {
if (qrSecurity == entrySecurity) {
return true;
}
// Default security type of PSK/SAE transition mode WifiEntry is SECURITY_PSK and
// there is no way to know if a WifiEntry is of transition mode. Give it a chance.
if (qrSecurity == WifiEntry.SECURITY_SAE && entrySecurity == WifiEntry.SECURITY_PSK) {
return true;
}
// If configured is no password, the Wi-Fi framework will attempt OPEN and OWE security.
return isNoPasswordSecurity(qrSecurity) && isNoPasswordSecurity(entrySecurity);
}
private boolean isNoPasswordSecurity(int security) {
return security == WifiEntry.SECURITY_NONE || security == WifiEntry.SECURITY_OWE;
}
@VisibleForTesting
boolean canConnectWifi(String ssid) {
final List<WifiEntry> wifiEntries = mWifiPickerTracker.getWifiEntries();

View File

@@ -40,12 +40,17 @@ import android.app.time.TimeZoneConfiguration;
import android.app.time.TimeZoneDetectorStatus;
import android.content.Context;
import android.os.UserHandle;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.flags.Flags;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -57,6 +62,9 @@ import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class AutoTimeZonePreferenceControllerTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@Mock
private UpdateTimeAndDateCallback mCallback;
private Context mContext;
@@ -238,8 +246,53 @@ public class AutoTimeZonePreferenceControllerTest {
mContext.getString(R.string.auto_zone_requires_location_summary));
}
@Test
@EnableFlags({Flags.FLAG_REVAMP_TOGGLES})
public void toggleOff_revampFlagOn_shouldToggleOffUseLocation() {
TimeZoneCapabilitiesAndConfig capabilitiesAndConfig = createCapabilitiesAndConfig(
/* autoSupported= */ true,
/* autoEnabled= */ true,
/* telephonySupported= */ true,
/* locationSupported= */ true);
when(mTimeManager.getTimeZoneCapabilitiesAndConfig()).thenReturn(capabilitiesAndConfig);
mController.setChecked(false);
TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder()
.setAutoDetectionEnabled(false)
.setGeoDetectionEnabled(false)
.build();
verify(mTimeManager).updateTimeZoneConfiguration(configuration);
}
@Test
@DisableFlags({Flags.FLAG_REVAMP_TOGGLES})
public void toggleOff_revampFlagOff_shouldToggleOffUseLocation() {
TimeZoneCapabilitiesAndConfig capabilitiesAndConfig = createCapabilitiesAndConfig(
/* autoSupported= */ true,
/* autoEnabled= */ true,
/* telephonySupported= */ true,
/* locationSupported= */ true);
when(mTimeManager.getTimeZoneCapabilitiesAndConfig()).thenReturn(capabilitiesAndConfig);
mController.setChecked(false);
TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder()
.setAutoDetectionEnabled(false)
.build();
verify(mTimeManager).updateTimeZoneConfiguration(configuration);
}
private static TimeZoneCapabilitiesAndConfig createCapabilitiesAndConfig(
boolean autoSupported, boolean autoEnabled, boolean telephonySupported) {
return createCapabilitiesAndConfig(autoSupported, autoEnabled, telephonySupported, false);
}
private static TimeZoneCapabilitiesAndConfig createCapabilitiesAndConfig(
boolean autoSupported, boolean autoEnabled, boolean telephonySupported,
boolean locationSupported) {
TimeZoneDetectorStatus status = new TimeZoneDetectorStatus(DETECTOR_STATUS_RUNNING,
new TelephonyTimeZoneAlgorithmStatus(
telephonySupported ? DETECTION_ALGORITHM_STATUS_RUNNING
@@ -253,12 +306,14 @@ public class AutoTimeZonePreferenceControllerTest {
TimeZoneCapabilities capabilities = new TimeZoneCapabilities.Builder(UserHandle.SYSTEM)
.setConfigureAutoDetectionEnabledCapability(configureAutoDetectionEnabledCapability)
.setUseLocationEnabled(true)
.setConfigureGeoDetectionEnabledCapability(Capabilities.CAPABILITY_NOT_SUPPORTED)
.setConfigureGeoDetectionEnabledCapability(
locationSupported ? Capabilities.CAPABILITY_POSSESSED
: Capabilities.CAPABILITY_NOT_SUPPORTED)
.setSetManualTimeZoneCapability(Capabilities.CAPABILITY_POSSESSED)
.build();
TimeZoneConfiguration config = new TimeZoneConfiguration.Builder()
.setAutoDetectionEnabled(autoEnabled)
.setGeoDetectionEnabled(false)
.setGeoDetectionEnabled(locationSupported)
.build();
return new TimeZoneCapabilitiesAndConfig(status, capabilities, config);
}

View File

@@ -25,6 +25,8 @@ import static android.app.time.DetectorStatusTypes.DETECTOR_STATUS_RUNNING;
import static android.app.time.LocationTimeZoneAlgorithmStatus.PROVIDER_STATUS_NOT_PRESENT;
import static android.app.time.LocationTimeZoneAlgorithmStatus.PROVIDER_STATUS_NOT_READY;
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -43,11 +45,17 @@ import android.app.time.TimeZoneConfiguration;
import android.app.time.TimeZoneDetectorStatus;
import android.content.Context;
import android.os.UserHandle;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import androidx.preference.SwitchPreference;
import com.android.settings.R;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.flags.Flags;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
@@ -62,9 +70,14 @@ import org.robolectric.annotation.Config;
com.android.settings.testutils.shadow.ShadowFragment.class,
})
public class LocationTimeZoneDetectionPreferenceControllerTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@Mock
private TimeManager mTimeManager;
private Context mContext;
private SwitchPreference mPreference;
private LocationTimeZoneDetectionPreferenceController mController;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private InstrumentedPreferenceFragment mFragment;
@@ -76,6 +89,9 @@ public class LocationTimeZoneDetectionPreferenceControllerTest {
when(mContext.getSystemService(TimeManager.class)).thenReturn(mTimeManager);
mController = new LocationTimeZoneDetectionPreferenceController(mContext);
mController.setFragment(mFragment);
mPreference = new SwitchPreference(mContext);
mPreference.setKey("location_time_zone_detection");
}
@Test
@@ -114,6 +130,17 @@ public class LocationTimeZoneDetectionPreferenceControllerTest {
verify(mTimeManager, never()).updateTimeZoneConfiguration(any());
}
@Test
@EnableFlags({Flags.FLAG_REVAMP_TOGGLES})
public void flagRevampTogglesOn_toggleOff_automaticTimeZone_disablesLocationToggle() {
TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
createTimeZoneCapabilitiesAndConfig(/* useLocationEnabled= */ true,
CAPABILITY_POSSESSED, /* setAutoDetectionEnabled= */ false);
when(mTimeManager.getTimeZoneCapabilitiesAndConfig()).thenReturn(capabilitiesAndConfig);
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
}
@Test
public void setChecked_withFalse_shouldUpdateSetting() {
boolean useLocationEnabled = false;
@@ -181,7 +208,14 @@ public class LocationTimeZoneDetectionPreferenceControllerTest {
private static TimeZoneCapabilitiesAndConfig createTimeZoneCapabilitiesAndConfig(
boolean useLocationEnabled,
@CapabilityState int configureGeoDetectionEnabledCapability) {
return createTimeZoneCapabilitiesAndConfig(useLocationEnabled,
configureGeoDetectionEnabledCapability, /* setAutoDetectionEnabled= */ true);
}
private static TimeZoneCapabilitiesAndConfig createTimeZoneCapabilitiesAndConfig(
boolean useLocationEnabled,
@CapabilityState int configureGeoDetectionEnabledCapability,
boolean setAutoDetectionEnabled) {
// Create a status that matches the user's capability state.
LocationTimeZoneAlgorithmStatus locationAlgorithmStatus;
switch (configureGeoDetectionEnabledCapability) {
@@ -213,7 +247,7 @@ public class LocationTimeZoneDetectionPreferenceControllerTest {
.build();
TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder()
.setAutoDetectionEnabled(true)
.setAutoDetectionEnabled(setAutoDetectionEnabled)
.setGeoDetectionEnabled(true)
.build();

View File

@@ -23,11 +23,16 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.content.Intent;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import com.android.settings.flags.Flags;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -41,6 +46,9 @@ import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class TimeFormatPreferenceControllerTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@Mock
private UpdateTimeAndDateCallback mCallback;
@@ -97,6 +105,7 @@ public class TimeFormatPreferenceControllerTest {
}
@Test
@DisableFlags({Flags.FLAG_REVAMP_TOGGLES})
public void updateState_autoSet_shouldNotEnablePreference() {
Settings.System.putString(mContext.getContentResolver(), Settings.System.TIME_12_24, null);

View File

@@ -23,6 +23,7 @@ import com.android.settings.flags.Flags
import com.android.settings.testutils.FakeFeatureFactory
import com.android.settingslib.preference.CatalystScreenTestCase
import com.google.common.truth.Truth.assertThat
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
@@ -65,6 +66,7 @@ class DisplayScreenTest : CatalystScreenTestCase() {
assertThat(preferenceScreenCreator.isAvailable(contextWrapper)).isFalse()
}
@Ignore("robolectric.createActivityContexts cause other test failure")
override fun migration() {
// avoid UnsupportedOperationException when getDisplay from context
System.setProperty("robolectric.createActivityContexts", "true")

View File

@@ -51,7 +51,7 @@ public class KeyboardRepeatKeysControllerTest {
public void setUp() {
mContext = RuntimeEnvironment.application;
mKeyboardRepeatKeysController = new KeyboardRepeatKeysController(mContext,
"physical_keyboard_repeat_key");
"physical_keyboard_repeat_keys");
}
@Test

View File

@@ -0,0 +1,86 @@
/*
* 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.
*/
package com.android.settings.inputmethod;
import static com.android.input.flags.Flags.FLAG_KEYBOARD_REPEAT_KEYS;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.hardware.input.InputSettings;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {
com.android.settings.testutils.shadow.ShadowFragment.class,
})
public class KeyboardRepeatKeysDelayPreferenceControllerTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private Context mContext;
private KeyboardRepeatKeysDelayPreferenceController mRepeatKeysDelayPreferenceController;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mRepeatKeysDelayPreferenceController = new KeyboardRepeatKeysDelayPreferenceController(
mContext, "repeat_keys_delay_preference");
}
@Test
@EnableFlags(FLAG_KEYBOARD_REPEAT_KEYS)
public void getAvailabilityStatus_flagIsEnabled_isAvailable() {
assertThat(mRepeatKeysDelayPreferenceController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
@DisableFlags(FLAG_KEYBOARD_REPEAT_KEYS)
public void getAvailabilityStatus_flagIsDisabled_notSupport() {
assertThat(mRepeatKeysDelayPreferenceController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
}
@Test
public void setSliderPosition_updatesInputSettingValue() {
int sliderPosition = 1;
mRepeatKeysDelayPreferenceController.setSliderPosition(sliderPosition);
assertThat(InputSettings.getRepeatKeysDelay(mContext)).isEqualTo(
KeyboardRepeatKeysDelayPreferenceController.REPEAT_KEY_DELAY_VALUE_LIST.get(
sliderPosition));
}
@Test
public void getSliderPosition_matchesWithDelayValue() {
int timeout = InputSettings.getRepeatKeysDelay(mContext);
assertThat(mRepeatKeysDelayPreferenceController.getSliderPosition()).isEqualTo(
KeyboardRepeatKeysDelayPreferenceController.REPEAT_KEY_DELAY_VALUE_LIST.indexOf(
timeout));
}
}

View File

@@ -0,0 +1,88 @@
/*
* 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.
*/
package com.android.settings.inputmethod;
import static com.android.input.flags.Flags.FLAG_KEYBOARD_REPEAT_KEYS;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.hardware.input.InputSettings;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {
com.android.settings.testutils.shadow.ShadowFragment.class,
})
public class KeyboardRepeatKeysTimeOutPreferenceControllerTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private Context mContext;
private KeyboardRepeatKeysTimeOutPreferenceController
mKeyboardRepeatKeysTimeOutPreferenceController;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mKeyboardRepeatKeysTimeOutPreferenceController =
new KeyboardRepeatKeysTimeOutPreferenceController(mContext,
"repeat_keys_timeout_preference");
}
@Test
@EnableFlags(FLAG_KEYBOARD_REPEAT_KEYS)
public void getAvailabilityStatus_flagIsEnabled_isAvailable() {
assertThat(mKeyboardRepeatKeysTimeOutPreferenceController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
@DisableFlags(FLAG_KEYBOARD_REPEAT_KEYS)
public void getAvailabilityStatus_flagIsDisabled_notSupport() {
assertThat(mKeyboardRepeatKeysTimeOutPreferenceController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
}
@Test
public void setSliderPosition_updatesInputSettingValue() {
int sliderPosition = 1;
mKeyboardRepeatKeysTimeOutPreferenceController.setSliderPosition(sliderPosition);
assertThat(InputSettings.getRepeatKeysTimeout(mContext)).isEqualTo(
KeyboardRepeatKeysTimeOutPreferenceController.REPEAT_KEY_TIMEOUT_VALUE_LIST.get(
sliderPosition));
}
@Test
public void getSliderPosition_matchesWithTimeoutValue() {
int timeout = InputSettings.getRepeatKeysTimeout(mContext);
assertThat(mKeyboardRepeatKeysTimeOutPreferenceController.getSliderPosition()).isEqualTo(
KeyboardRepeatKeysTimeOutPreferenceController.REPEAT_KEY_TIMEOUT_VALUE_LIST.indexOf(
timeout));
}
}

View File

@@ -16,6 +16,11 @@
package com.android.settings.wifi.dpp;
import static com.android.wifitrackerlib.WifiEntry.SECURITY_NONE;
import static com.android.wifitrackerlib.WifiEntry.SECURITY_OWE;
import static com.android.wifitrackerlib.WifiEntry.SECURITY_PSK;
import static com.android.wifitrackerlib.WifiEntry.SECURITY_SAE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -148,4 +153,24 @@ public class WifiDppQrCodeScannerFragmentTest {
verify(mActivity).setResult(eq(Activity.RESULT_OK), any());
verify(mActivity).finish();
}
@Test
public void isSecurityMatched_securityNotMatch_returnFalse() {
assertThat(mFragment.isSecurityMatched(SECURITY_NONE, SECURITY_PSK)).isFalse();
}
@Test
public void isSecurityMatched_securityMatch_returnTrue() {
assertThat(mFragment.isSecurityMatched(SECURITY_PSK, SECURITY_PSK)).isTrue();
}
@Test
public void isSecurityMatched_tryPskSaeTransition_returnTrue() {
assertThat(mFragment.isSecurityMatched(SECURITY_SAE, SECURITY_PSK)).isTrue();
}
@Test
public void isSecurityMatched_noPasswordSecurity_returnTrue() {
assertThat(mFragment.isSecurityMatched(SECURITY_NONE, SECURITY_OWE)).isTrue();
}
}

View File

@@ -0,0 +1,135 @@
/*
* Copyright (C) 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.
*/
package com.android.settings.deviceinfo
import android.content.Context
import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceManager
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.R
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.spy
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
@RunWith(AndroidJUnit4::class)
class PhoneNumberPreferenceControllerTest {
private val mockTelephonyManager = mock<TelephonyManager>()
private val mockSubscriptionManager = mock<SubscriptionManager>()
private val context: Context =
spy(ApplicationProvider.getApplicationContext()) {
on { getSystemService(SubscriptionManager::class.java) } doReturn
mockSubscriptionManager
on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager
}
private val subscriptionInfo = mock<SubscriptionInfo>()
private val preference = spy(Preference(context))
private val secondPreference = mock<Preference>()
private var category = PreferenceCategory(context)
private var preferenceScreen = PreferenceManager(context).createPreferenceScreen(context)
private var controller = spy(PhoneNumberPreferenceController(context, "phone_number"))
@Before
fun setup() {
preference.setKey(controller.preferenceKey)
preference.isVisible = true
preferenceScreen.addPreference(preference)
category.key = "basic_info_category"
preferenceScreen.addPreference(category)
doReturn(secondPreference).whenever(controller).createNewPreference(context)
}
@Test
fun displayPreference_multiSim_shouldAddSecondPreference() {
whenever(mockTelephonyManager.phoneCount).thenReturn(2)
val sim1Preference = Preference(context)
category.addItemFromInflater(sim1Preference)
controller.displayPreference(preferenceScreen)
assertThat(category.preferenceCount).isEqualTo(2)
}
@Test
fun updateState_singleSim_shouldUpdateTitleAndPhoneNumber() {
val phoneNumber = "1111111111"
doReturn(subscriptionInfo).whenever(controller).getSubscriptionInfo(any())
doReturn(phoneNumber).whenever(controller).getFormattedPhoneNumber(subscriptionInfo)
whenever(mockTelephonyManager.phoneCount).thenReturn(1)
controller.displayPreference(preferenceScreen)
controller.updateState(preference)
verify(preference).title = context.getString(R.string.status_number)
verify(preference).summary = phoneNumber
}
@Test
fun updateState_multiSim_shouldUpdateTitleAndPhoneNumberOfMultiplePreferences() {
val phoneNumber = "1111111111"
doReturn(subscriptionInfo).whenever(controller).getSubscriptionInfo(any())
doReturn(phoneNumber).whenever(controller).getFormattedPhoneNumber(subscriptionInfo)
whenever(mockTelephonyManager.phoneCount).thenReturn(2)
controller.displayPreference(preferenceScreen)
controller.updateState(preference)
verify(preference).title =
context.getString(R.string.status_number_sim_slot, 1 /* sim slot */)
verify(preference).summary = phoneNumber
verify(secondPreference).title =
context.getString(R.string.status_number_sim_slot, 2 /* sim slot */)
verify(secondPreference).summary = phoneNumber
}
@Test
fun getSummary_cannotGetActiveSubscriptionInfo_shouldShowNotAvailable() {
whenever(mockSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(null)
controller.displayPreference(preferenceScreen)
controller.updateState(preference)
verify(preference).summary = context.getString(R.string.device_info_not_available)
}
@Test
fun getSummary_getEmptySubscriptionInfo_shouldShowNotAvailable() {
whenever(mockSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(emptyList())
controller.displayPreference(preferenceScreen)
controller.updateState(preference)
verify(preference).summary = context.getString(R.string.device_info_not_available)
}
}

View File

@@ -1,158 +0,0 @@
/*
* Copyright (C) 2017 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.deviceinfo;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.Looper;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.R;
import com.android.settings.testutils.ResourcesUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.List;
@RunWith(AndroidJUnit4.class)
public class PhoneNumberPreferenceControllerTest {
private Preference mPreference;
@Mock
private Preference mSecondPreference;
@Mock
private TelephonyManager mTelephonyManager;
@Mock
private SubscriptionInfo mSubscriptionInfo;
@Mock
private SubscriptionManager mSubscriptionManager;
private PreferenceCategory mCategory;
private PreferenceScreen mScreen;
private Context mContext;
private PhoneNumberPreferenceController mController;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mContext = spy(ApplicationProvider.getApplicationContext());
when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
mController = spy(new PhoneNumberPreferenceController(mContext, "phone_number"));
if (Looper.myLooper() == null) {
Looper.prepare();
}
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
mScreen = preferenceManager.createPreferenceScreen(mContext);
mPreference = spy(new Preference(mContext));
mPreference.setKey(mController.getPreferenceKey());
mPreference.setVisible(true);
mScreen.addPreference(mPreference);
final String categoryKey = "basic_info_category";
mCategory = new PreferenceCategory(mContext);
mCategory.setKey(categoryKey);
mScreen.addPreference(mCategory);
doReturn(mSecondPreference).when(mController).createNewPreference(mContext);
}
@Test
public void displayPreference_multiSim_shouldAddSecondPreference() {
when(mTelephonyManager.getPhoneCount()).thenReturn(2);
final Preference sim1Preference = new Preference(mContext);
mCategory.addItemFromInflater(sim1Preference);
mController.displayPreference(mScreen);
assertThat(mCategory.getPreferenceCount()).isEqualTo(2);
}
@Test
public void updateState_singleSim_shouldUpdateTitleAndPhoneNumber() {
final String phoneNumber = "1111111111";
doReturn(mSubscriptionInfo).when(mController).getSubscriptionInfo(anyInt());
doReturn(phoneNumber).when(mController).getFormattedPhoneNumber(mSubscriptionInfo);
when(mTelephonyManager.getPhoneCount()).thenReturn(1);
mController.displayPreference(mScreen);
mController.updateState(mPreference);
verify(mPreference).setTitle(ResourcesUtils.getResourcesString(mContext, "status_number"));
verify(mPreference).setSummary(phoneNumber);
}
@Test
public void updateState_multiSim_shouldUpdateTitleAndPhoneNumberOfMultiplePreferences() {
final String phoneNumber = "1111111111";
doReturn(mSubscriptionInfo).when(mController).getSubscriptionInfo(anyInt());
doReturn(phoneNumber).when(mController).getFormattedPhoneNumber(mSubscriptionInfo);
when(mTelephonyManager.getPhoneCount()).thenReturn(2);
mController.displayPreference(mScreen);
mController.updateState(mPreference);
verify(mPreference).setTitle(ResourcesUtils.getResourcesString(
mContext, "status_number_sim_slot", 1 /* sim slot */));
verify(mPreference).setSummary(phoneNumber);
verify(mSecondPreference).setTitle(ResourcesUtils.getResourcesString(
mContext, "status_number_sim_slot", 2 /* sim slot */));
verify(mSecondPreference).setSummary(phoneNumber);
}
@Test
public void getSummary_cannotGetActiveSubscriptionInfo_shouldShowNotAvailable() {
when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(null);
mController.displayPreference(mScreen);
mController.updateState(mPreference);
verify(mPreference).setSummary(mContext.getString(R.string.device_info_not_available));
}
@Test
public void getSummary_getEmptySubscriptionInfo_shouldShowNotAvailable() {
List<SubscriptionInfo> infos = new ArrayList<>();
when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(infos);
mController.displayPreference(mScreen);
mController.updateState(mPreference);
verify(mPreference).setSummary(mContext.getString(R.string.device_info_not_available));
}
}