Snap for 13033097 from 60c6d8ead5 to 25Q2-release

Change-Id: I49b6f959f5bc734783f87ce624b09b4f131da9ab
This commit is contained in:
Android Build Coastguard Worker
2025-02-07 19:22:12 -08:00
32 changed files with 802 additions and 253 deletions

View File

@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2025 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="@+id/autoclick_cursor_area_size_dialog_title"
android:text="@string/autoclick_cursor_area_size_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginHorizontal="26dp"
android:textSize="20sp"
android:textColor="?android:attr/textColorPrimary"
android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
/>
<TextView
android:id="@+id/autoclick_cursor_area_size_dialog_subtitle"
android:text="@string/autoclick_cursor_area_size_summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="26dp"
android:layout_marginTop="8dp"
android:textSize="16sp"
android:textColor="?android:attr/textColorSecondary"
/>
<RadioGroup
android:id="@+id/autoclick_cursor_area_size_value_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="16dp">
<RadioButton
android:id="@+id/autoclick_cursor_area_size_value_extra_small"
android:text="@string/autoclick_cursor_area_size_dialog_option_extra_small"
style="@style/AutoclickDialogRadioButton"/>
<RadioButton
android:id="@+id/autoclick_cursor_area_size_value_small"
android:text="@string/autoclick_cursor_area_size_dialog_option_small"
style="@style/AutoclickDialogRadioButton"/>
<RadioButton
android:id="@+id/autoclick_cursor_area_size_value_default"
android:text="@string/autoclick_cursor_area_size_dialog_option_default"
style="@style/AutoclickDialogRadioButton"/>
<RadioButton
android:id="@+id/autoclick_cursor_area_size_value_large"
android:text="@string/autoclick_cursor_area_size_dialog_option_large"
style="@style/AutoclickDialogRadioButton"/>
<RadioButton
android:id="@+id/autoclick_cursor_area_size_value_extra_large"
android:text="@string/autoclick_cursor_area_size_dialog_option_extra_large"
style="@style/AutoclickDialogRadioButton"/>
</RadioGroup>
</LinearLayout>

View File

@@ -1673,6 +1673,9 @@
<!-- Message shown in screen lock picker for setting up a work profile screen lock. [CHAR LIMIT=80] --> <!-- Message shown in screen lock picker for setting up a work profile screen lock. [CHAR LIMIT=80] -->
<string name="lock_settings_picker_profile_message">If you forget this lock, ask your IT admin to reset it</string> <string name="lock_settings_picker_profile_message">If you forget this lock, ask your IT admin to reset it</string>
<!-- Title for the category in screen lock settings page -->
<string name="lock_settings_screen_lock_settings_title">Screen lock settings</string>
<!-- Label for button in screen lock settings, allowing users to choose other types of screen locks. [CHAR LIMIT=40] --> <!-- Label for button in screen lock settings, allowing users to choose other types of screen locks. [CHAR LIMIT=40] -->
<string name="setup_lock_settings_options_button_label">Screen lock options</string> <string name="setup_lock_settings_options_button_label">Screen lock options</string>
@@ -3872,7 +3875,7 @@
<string name="ethernet_tether_checkbox_text">Ethernet tethering</string> <string name="ethernet_tether_checkbox_text">Ethernet tethering</string>
<!-- Tethering footer info [CHAR LIMIT=NONE]--> <!-- Tethering footer info [CHAR LIMIT=NONE]-->
<string name="tethering_footer_info">Use hotspot and tethering to provide internet to other devices through your mobile data connection. Apps can also create a hotspot to share content with nearby devices.</string> <string name="tethering_footer_info">Use hotspot and tethering to provide internet to other devices through your data connection. Apps can also create a hotspot to share content with nearby devices.</string>
<!-- Tethering footer info for the device which supports Wi-Fi and Wi-Fi tethering enabled at the same time [CHAR LIMIT=NONE]--> <!-- Tethering footer info for the device which supports Wi-Fi and Wi-Fi tethering enabled at the same time [CHAR LIMIT=NONE]-->
<string name="tethering_footer_info_sta_ap_concurrency">Use hotspot and tethering to provide internet to other devices through your Wi\u2011Fi or mobile data connection. Apps can also create a hotspot to share content with nearby devices.</string> <string name="tethering_footer_info_sta_ap_concurrency">Use hotspot and tethering to provide internet to other devices through your Wi\u2011Fi or mobile data connection. Apps can also create a hotspot to share content with nearby devices.</string>
@@ -4738,6 +4741,8 @@
<!-- Summary text for the 'Mouse reverse scrolling' preference switch indicating to users that when the setting is enabled that scrolling up with their mouse wheel will move the page content down. [CHAR LIMIT=NONE] --> <!-- Summary text for the 'Mouse reverse scrolling' preference switch indicating to users that when the setting is enabled that scrolling up with their mouse wheel will move the page content down. [CHAR LIMIT=NONE] -->
<string name="mouse_reverse_vertical_scrolling_summary">Content moves up when you scroll down</string> <string name="mouse_reverse_vertical_scrolling_summary">Content moves up when you scroll down</string>
<!-- TODO(b/383555305): finalize these strings and mark them translatable. --> <!-- TODO(b/383555305): finalize these strings and mark them translatable. -->
<!-- Title for the scrolling section of the mouse settings page. [CHAR LIMIT=60] -->
<string name="mouse_scrolling_category_title" translatable="false">Scrolling</string>
<!-- Title for the 'Mouse controlled scrolling' preference switch, which disables the mouse scrolling acceleration so that the scrolling speed becomes directly proportional to the speed at which the wheel is turned. [CHAR LIMIT=60]--> <!-- Title for the 'Mouse controlled scrolling' preference switch, which disables the mouse scrolling acceleration so that the scrolling speed becomes directly proportional to the speed at which the wheel is turned. [CHAR LIMIT=60]-->
<string name="mouse_scrolling_acceleration" translatable="false">Controlled scrolling</string> <string name="mouse_scrolling_acceleration" translatable="false">Controlled scrolling</string>
<!-- Title for the 'Scrolling speed' slider seekbar, which controls how fast content scrolls when the user moves the scroll wheel. [CHAR LIMIT=60]--> <!-- Title for the 'Scrolling speed' slider seekbar, which controls how fast content scrolls when the user moves the scroll wheel. [CHAR LIMIT=60]-->
@@ -5638,12 +5643,27 @@
<string name="accessibility_autoclick_longer_desc">Longer</string> <string name="accessibility_autoclick_longer_desc">Longer</string>
<!-- Description for the seekbar that adjust auto click time. [CHAR_LIMIT=NONE] --> <!-- Description for the seekbar that adjust auto click time. [CHAR_LIMIT=NONE] -->
<string name="accessibility_autoclick_seekbar_desc">Auto click time</string> <string name="accessibility_autoclick_seekbar_desc">Auto click time</string>
<!-- Title for the seekbar that adjust auto click cursor area size. [CHAR_LIMIT=NONE] --> <!-- Title for the alert dialog that adjust auto click cursor area size. [CHAR_LIMIT=NONE] -->
<!-- TODO(b/383901288): Update string to translatable once approved by UXW. --> <!-- TODO(b/394683600): Update string to translatable once approved by UXW. -->
<string name="autoclick_cursor_area_size_title" translatable="false">Cursor area size</string> <string name="autoclick_cursor_area_size_title" translatable="false">Click area</string>
<!-- Summary for the seekbar that adjust auto click cursor area size. [CHAR_LIMIT=NONE] --> <!-- Summary for the alert dialog that adjust auto click cursor area size. [CHAR_LIMIT=NONE] -->
<!-- TODO(b/383901288): Update string to translatable once approved by UXW. --> <!-- TODO(b/394683600): Update string to translatable once approved by UXW. -->
<string name="autoclick_cursor_area_size_summary" translatable="false">Adjust the autoclick ring indicator area size</string> <string name="autoclick_cursor_area_size_summary" translatable="false">The area where the cursor can move freely without canceling the click once the countdown starts</string>
<!-- Option for the autoclick area dialog that adjust auto click cursor area size to extra large. [CHAR_LIMIT=NONE] -->
<!-- TODO(b/394683600): Update string to translatable once approved by UXW. -->
<string name="autoclick_cursor_area_size_dialog_option_extra_large" translatable="false">Extra large</string>
<!-- Option for the autoclick area dialog that adjust auto click cursor area size to large. [CHAR_LIMIT=NONE] -->
<!-- TODO(b/394683600): Update string to translatable once approved by UXW. -->
<string name="autoclick_cursor_area_size_dialog_option_large" translatable="false">Large</string>
<!-- Option for the autoclick area dialog that adjust auto click cursor area size to Medium(Default). [CHAR_LIMIT=NONE] -->
<!-- TODO(b/394683600): Update string to translatable once approved by UXW. -->
<string name="autoclick_cursor_area_size_dialog_option_default" translatable="false">Default</string>
<!-- Option for the autoclick area dialog that adjust auto click cursor area size to small. [CHAR_LIMIT=NONE] -->
<!-- TODO(b/394683600): Update string to translatable once approved by UXW. -->
<string name="autoclick_cursor_area_size_dialog_option_small" translatable="false">Small</string>
<!-- Option for the autoclick area dialog that adjust auto click cursor area size to extra small. [CHAR_LIMIT=NONE] -->
<!-- TODO(b/394683600): Update string to translatable once approved by UXW. -->
<string name="autoclick_cursor_area_size_dialog_option_extra_small" translatable="false">Extra small</string>
<!-- Title for the toggle button that turns on/off the autoclick setting of ignoring minor cursor movement. [CHAR_LIMIT=NONE] --> <!-- Title for the toggle button that turns on/off the autoclick setting of ignoring minor cursor movement. [CHAR_LIMIT=NONE] -->
<!-- TODO(b/388845718): Update string to translatable once approved by UXW. --> <!-- TODO(b/388845718): Update string to translatable once approved by UXW. -->
<string name="autoclick_ignore_minor_cursor_movement_title" translatable="false">Ignore minor cursor movement</string> <string name="autoclick_ignore_minor_cursor_movement_title" translatable="false">Ignore minor cursor movement</string>

View File

@@ -710,6 +710,14 @@
<item name="android:textSize">14sp</item> <item name="android:textSize">14sp</item>
</style> </style>
<style name="AutoclickDialogRadioButton">
<item name="android:paddingStart">12dp</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">48dp</item>
<item name="android:layout_gravity">start|center_vertical</item>
<item name="android:background">@null</item>
</style>
<style name="Widget.PopupWindow.Settings" <style name="Widget.PopupWindow.Settings"
parent="@android:style/Widget.DeviceDefault.PopupWindow"> parent="@android:style/Widget.DeviceDefault.PopupWindow">
<item name="android:clipToPadding">true</item> <item name="android:clipToPadding">true</item>

View File

@@ -76,13 +76,12 @@
settings:searchable="false" settings:searchable="false"
settings:controller="com.android.settings.accessibility.ToggleAutoclickCustomSeekbarController"/> settings:controller="com.android.settings.accessibility.ToggleAutoclickCustomSeekbarController"/>
<com.android.settingslib.widget.SliderPreference <Preference
android:key="accessibility_control_autoclick_cursor_area_size" android:key="accessibility_control_autoclick_cursor_area_size"
android:title="@string/autoclick_cursor_area_size_title" android:persistent="false"
android:summary="@string/autoclick_cursor_area_size_summary"
android:selectable="false"
settings:searchable="false" settings:searchable="false"
settings:controller="com.android.settings.accessibility.ToggleAutoclickCursorAreaSizeController"/> android:title="@string/autoclick_cursor_area_size_title"
settings:controller="com.android.settings.accessibility.ToggleAutoclickCursorAreaSizeController" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:key="accessibility_control_autoclick_ignore_minor_cursor_movement" android:key="accessibility_control_autoclick_ignore_minor_cursor_movement"

View File

@@ -20,37 +20,27 @@
xmlns:settings="http://schemas.android.com/apk/res-auto" xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/mouse_settings"> android:title="@string/mouse_settings">
<SwitchPreferenceCompat
android:key="mouse_swap_primary_button"
android:title="@string/mouse_swap_primary_button"
android:summary="@string/mouse_swap_primary_button_summary"
settings:controller="com.android.settings.inputmethod.MouseSwapPrimaryButtonPreferenceController" />
<SwitchPreferenceCompat
android:key="mouse_reverse_vertical_scrolling"
android:title="@string/mouse_reverse_vertical_scrolling"
android:summary="@string/mouse_reverse_vertical_scrolling_summary"
settings:controller="com.android.settings.inputmethod.MouseReverseVerticalScrollingPreferenceController" />
<SwitchPreferenceCompat
android:key="mouse_swap_primary_button"
android:title="@string/mouse_swap_primary_button"
android:summary="@string/mouse_swap_primary_button_summary"
settings:controller="com.android.settings.inputmethod.MouseSwapPrimaryButtonPreferenceController" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:key="mouse_pointer_acceleration" android:key="mouse_pointer_acceleration"
android:title="@string/mouse_pointer_acceleration" android:title="@string/mouse_pointer_acceleration"
android:summary="@string/mouse_pointer_acceleration_summary" android:summary="@string/mouse_pointer_acceleration_summary"
android:order="10"
settings:controller="com.android.settings.inputmethod.MousePointerAccelerationPreferenceController" /> settings:controller="com.android.settings.inputmethod.MousePointerAccelerationPreferenceController" />
<com.android.settings.widget.SeekBarPreference <com.android.settings.widget.SeekBarPreference
android:key="trackpad_pointer_speed" android:key="trackpad_pointer_speed"
android:title="@string/trackpad_pointer_speed" android:title="@string/trackpad_pointer_speed"
android:order="40" android:order="20"
android:selectable="false" android:selectable="false"
settings:controller="com.android.settings.inputmethod.TouchpadPointerSpeedPreferenceController"/> settings:controller="com.android.settings.inputmethod.TouchpadPointerSpeedPreferenceController"/>
<SwitchPreferenceCompat
android:key="mouse_swap_primary_button"
android:title="@string/mouse_swap_primary_button"
android:summary="@string/mouse_swap_primary_button_summary"
android:order="30"
settings:controller="com.android.settings.inputmethod.MouseSwapPrimaryButtonPreferenceController" />
<Preference <Preference
android:fragment="com.android.settings.inputmethod.PointerTouchpadFragment" android:fragment="com.android.settings.inputmethod.PointerTouchpadFragment"
android:key="accessibility_pointer_and_touchpad" android:key="accessibility_pointer_and_touchpad"
@@ -60,10 +50,23 @@
android:summary="@string/accessibility_pointer_and_touchpad_summary" android:summary="@string/accessibility_pointer_and_touchpad_summary"
settings:searchable="true"/> settings:searchable="true"/>
<PreferenceCategory
android:key="pointer_category"
android:persistent="false"
android:order="51"
android:title="@string/mouse_scrolling_category_title">
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:key="mouse_reverse_vertical_scrolling"
android:order="52"
android:title="@string/mouse_reverse_vertical_scrolling"
android:summary="@string/mouse_reverse_vertical_scrolling_summary"
settings:controller="com.android.settings.inputmethod.MouseReverseVerticalScrollingPreferenceController" />
<SwitchPreferenceCompat
android:order="55"
android:key="mouse_scrolling_acceleration" android:key="mouse_scrolling_acceleration"
android:title="@string/mouse_scrolling_acceleration" android:title="@string/mouse_scrolling_acceleration"
android:order="55"
settings:controller="com.android.settings.inputmethod.MouseScrollingAccelerationPreferenceController" /> settings:controller="com.android.settings.inputmethod.MouseScrollingAccelerationPreferenceController" />
<com.android.settings.widget.SeekBarPreference <com.android.settings.widget.SeekBarPreference
@@ -73,4 +76,6 @@
android:selectable="false" android:selectable="false"
settings:controller="com.android.settings.inputmethod.MouseScrollingSpeedPreferenceController"/> settings:controller="com.android.settings.inputmethod.MouseScrollingSpeedPreferenceController"/>
</PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>

View File

@@ -69,7 +69,7 @@
<PreferenceCategory <PreferenceCategory
android:key="unlock_settings" android:key="unlock_settings"
android:title="@string/security_settings_fingerprint_settings_preferences_category" android:title="@string/lock_settings_screen_lock_settings_title"
settings:isPreferenceVisible="false"> settings:isPreferenceVisible="false">
<!-- available in pattern --> <!-- available in pattern -->

View File

@@ -17,7 +17,6 @@
package com.android.settings.accessibility; package com.android.settings.accessibility;
import static android.content.Context.MODE_PRIVATE; import static android.content.Context.MODE_PRIVATE;
import static android.view.accessibility.AccessibilityManager.AUTOCLICK_CURSOR_AREA_INCREMENT_SIZE;
import static android.view.accessibility.AccessibilityManager.AUTOCLICK_CURSOR_AREA_SIZE_MAX; import static android.view.accessibility.AccessibilityManager.AUTOCLICK_CURSOR_AREA_SIZE_MAX;
import static android.view.accessibility.AccessibilityManager.AUTOCLICK_CURSOR_AREA_SIZE_MIN; import static android.view.accessibility.AccessibilityManager.AUTOCLICK_CURSOR_AREA_SIZE_MIN;
@@ -25,35 +24,51 @@ import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.provider.Settings; import android.provider.Settings;
import android.text.TextUtils;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
import android.widget.RadioGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.lifecycle.Lifecycle; import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent; import androidx.lifecycle.OnLifecycleEvent;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import com.android.server.accessibility.Flags; import com.android.server.accessibility.Flags;
import com.android.settings.core.SliderPreferenceController; import com.android.settings.R;
import com.android.settingslib.widget.SliderPreference; import com.android.settings.core.BasePreferenceController;
import com.google.common.collect.ImmutableBiMap;
/** Controller class that controls accessibility autoclick cursor area size settings. */ /** Controller class that controls accessibility autoclick cursor area size settings. */
public class ToggleAutoclickCursorAreaSizeController extends SliderPreferenceController public class ToggleAutoclickCursorAreaSizeController extends BasePreferenceController
implements LifecycleObserver, SharedPreferences.OnSharedPreferenceChangeListener { implements LifecycleObserver, SharedPreferences.OnSharedPreferenceChangeListener {
public static final String TAG = ToggleAutoclickCursorAreaSizeController.class.getSimpleName(); public static final String TAG = ToggleAutoclickCursorAreaSizeController.class.getSimpleName();
public final ImmutableBiMap<Integer, Integer> RADIO_BUTTON_ID_TO_CURSOR_SIZE =
new ImmutableBiMap.Builder<Integer, Integer>()
.put(R.id.autoclick_cursor_area_size_value_extra_large, 100)
.put(R.id.autoclick_cursor_area_size_value_large, 80)
.put(R.id.autoclick_cursor_area_size_value_default, 60)
.put(R.id.autoclick_cursor_area_size_value_small, 40)
.put(R.id.autoclick_cursor_area_size_value_extra_small, 20)
.buildOrThrow();
private final ContentResolver mContentResolver; private final ContentResolver mContentResolver;
private final SharedPreferences mSharedPreferences; private final SharedPreferences mSharedPreferences;
private SliderPreference mPreference; private Preference mPreference;
protected AlertDialog mAlertDialog;
public ToggleAutoclickCursorAreaSizeController(@NonNull Context context, public ToggleAutoclickCursorAreaSizeController(@NonNull Context context,
@NonNull String preferenceKey) { @NonNull String preferenceKey) {
super(context, preferenceKey); super(context, preferenceKey);
mContentResolver = context.getContentResolver(); mContentResolver = context.getContentResolver();
mSharedPreferences = context.getSharedPreferences(context.getPackageName(), MODE_PRIVATE); mSharedPreferences = context.getSharedPreferences(context.getPackageName(), MODE_PRIVATE);
constructDialog(context);
} }
@OnLifecycleEvent(Lifecycle.Event.ON_START) @OnLifecycleEvent(Lifecycle.Event.ON_START)
@@ -71,15 +86,55 @@ public class ToggleAutoclickCursorAreaSizeController extends SliderPreferenceCon
} }
@Override @Override
public void displayPreference(@NonNull PreferenceScreen screen) { public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen); super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey()); mPreference = screen.findPreference(getPreferenceKey());
if (mPreference != null) {
mPreference.setMin(getMin());
mPreference.setMax(getMax());
mPreference.setSliderIncrement(AUTOCLICK_CURSOR_AREA_INCREMENT_SIZE);
mPreference.setValue(getSliderPosition());
} }
protected void constructDialog(Context context) {
mAlertDialog = new AlertDialog.Builder(context)
.setView(R.layout.dialog_autoclick_cursor_area_size)
.setPositiveButton(android.R.string.ok,
(dialog, which) -> {
RadioGroup radioGroup =
mAlertDialog.findViewById(
R.id.autoclick_cursor_area_size_value_group);
int checkedRadioButtonId = radioGroup.getCheckedRadioButtonId();
int size = RADIO_BUTTON_ID_TO_CURSOR_SIZE.get(checkedRadioButtonId);
updateAutoclickCursorAreaSize(size);
})
.setNegativeButton(android.R.string.cancel, (dialog, which) -> dialog.dismiss())
.create();
mAlertDialog.setOnShowListener(dialog -> {
initStateBasedOnSize();
});
}
private void initStateBasedOnSize() {
RadioGroup cannedValueRadioGroup = mAlertDialog.findViewById(
R.id.autoclick_cursor_area_size_value_group);
int autoclickCursordefaultSize = validateSize(Settings.Secure.getInt(mContentResolver,
Settings.Secure.ACCESSIBILITY_AUTOCLICK_CURSOR_AREA_SIZE,
AccessibilityManager.AUTOCLICK_CURSOR_AREA_SIZE_DEFAULT));
int radioButtonId = RADIO_BUTTON_ID_TO_CURSOR_SIZE.inverse()
.get(autoclickCursordefaultSize);
cannedValueRadioGroup.check(radioButtonId);
}
@Override
public boolean handlePreferenceTreeClick(@NonNull Preference preference) {
if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
return false;
}
if (mAlertDialog != null) {
mAlertDialog.show();
}
return true;
} }
@Override @Override
@@ -94,29 +149,31 @@ public class ToggleAutoclickCursorAreaSizeController extends SliderPreferenceCon
} }
@Override @Override
public boolean setSliderPosition(int position) { public CharSequence getSummary() {
int size = validateSize(position); int autoclickCursorSize = validateSize(Settings.Secure.getInt(mContentResolver,
Settings.Secure.putInt(
mContentResolver, Settings.Secure.ACCESSIBILITY_AUTOCLICK_CURSOR_AREA_SIZE, size);
return true;
}
@Override
public int getSliderPosition() {
int size = Settings.Secure.getInt(mContentResolver,
Settings.Secure.ACCESSIBILITY_AUTOCLICK_CURSOR_AREA_SIZE, Settings.Secure.ACCESSIBILITY_AUTOCLICK_CURSOR_AREA_SIZE,
AccessibilityManager.AUTOCLICK_CURSOR_AREA_SIZE_DEFAULT); AccessibilityManager.AUTOCLICK_CURSOR_AREA_SIZE_DEFAULT));
return validateSize(size); int summaryStringId;
switch (autoclickCursorSize) {
case 100 -> summaryStringId =
R.string.autoclick_cursor_area_size_dialog_option_extra_large;
case 80 -> summaryStringId = R.string.autoclick_cursor_area_size_dialog_option_large;
case 40 -> summaryStringId = R.string.autoclick_cursor_area_size_dialog_option_small;
case 20 -> summaryStringId =
R.string.autoclick_cursor_area_size_dialog_option_extra_small;
default -> summaryStringId = R.string.autoclick_cursor_area_size_dialog_option_default;
} }
@Override return mContext.getString(summaryStringId);
public int getMax() {
return AUTOCLICK_CURSOR_AREA_SIZE_MAX;
} }
@Override /** Updates autoclick cursor area size. */
public int getMin() { public void updateAutoclickCursorAreaSize(int size) {
return AUTOCLICK_CURSOR_AREA_SIZE_MIN; Settings.Secure.putInt(
mContentResolver,
Settings.Secure.ACCESSIBILITY_AUTOCLICK_CURSOR_AREA_SIZE,
validateSize(size));
refreshSummary(mPreference);
} }
private int validateSize(int size) { private int validateSize(int size) {

View File

@@ -22,6 +22,7 @@ import static android.provider.Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED;
import static com.android.settings.biometrics.BiometricEnrollBase.BIOMETRIC_AUTH_REQUEST; import static com.android.settings.biometrics.BiometricEnrollBase.BIOMETRIC_AUTH_REQUEST;
import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_CONSENT_DENIED; import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_CONSENT_DENIED;
import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_CONSENT_GRANTED; import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_CONSENT_GRANTED;
import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_FINISHED;
import static com.google.android.setupdesign.transition.TransitionHelper.TRANSITION_FADE_THROUGH; import static com.google.android.setupdesign.transition.TransitionHelper.TRANSITION_FADE_THROUGH;
@@ -53,6 +54,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SetupWizardUtils; import com.android.settings.SetupWizardUtils;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settings.biometrics.combination.CombinedBiometricStatusUtils;
import com.android.settings.core.InstrumentedActivity; import com.android.settings.core.InstrumentedActivity;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.ChooseLockGeneric; import com.android.settings.password.ChooseLockGeneric;
@@ -131,6 +133,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
private Bundle mParentalOptions; private Bundle mParentalOptions;
@Nullable private Long mGkPwHandle; @Nullable private Long mGkPwHandle;
@Nullable private ParentalConsentHelper mParentalConsentHelper; @Nullable private ParentalConsentHelper mParentalConsentHelper;
private boolean mIsPreviousEnrollmentCanceled = false;
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
@@ -531,6 +534,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
} else { } else {
Log.d(TAG, "Unknown result for set/choose lock: " + resultCode); Log.d(TAG, "Unknown result for set/choose lock: " + resultCode);
setResult(resultCode, newResultIntent()); setResult(resultCode, newResultIntent());
notifySafetyIssueActionLaunchedIfNeeded(resultCode);
finish(); finish();
} }
break; break;
@@ -549,16 +553,21 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
// SetupFingerprintEnroll*/FingerprintEnrollmentActivity to // SetupFingerprintEnroll*/FingerprintEnrollmentActivity to
// SetupFaceEnrollIntroduction // SetupFaceEnrollIntroduction
TransitionHelper.applyForwardTransition(this, TRANSITION_FADE_THROUGH); TransitionHelper.applyForwardTransition(this, TRANSITION_FADE_THROUGH);
mIsPreviousEnrollmentCanceled =
resultCode != BiometricEnrollBase.RESULT_FINISHED;
launchFaceOnlyEnroll(); launchFaceOnlyEnroll();
} else { } else {
notifySafetyIssueActionLaunchedIfNeeded(resultCode);
finishOrLaunchHandToParent(resultCode); finishOrLaunchHandToParent(resultCode);
} }
break; break;
case REQUEST_SINGLE_ENROLL_FACE: case REQUEST_SINGLE_ENROLL_FACE:
mIsSingleEnrolling = false; mIsSingleEnrolling = false;
if (resultCode == Activity.RESULT_CANCELED && mIsFingerprintEnrollable) { if (resultCode == Activity.RESULT_CANCELED && mIsFingerprintEnrollable) {
mIsPreviousEnrollmentCanceled = true;
launchFingerprintOnlyEnroll(); launchFingerprintOnlyEnroll();
} else { } else {
notifySafetyIssueActionLaunchedIfNeeded(resultCode);
finishOrLaunchHandToParent(resultCode); finishOrLaunchHandToParent(resultCode);
} }
break; break;
@@ -742,6 +751,15 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
startActivityForResult(intent, REQUEST_HANDOFF_PARENT); startActivityForResult(intent, REQUEST_HANDOFF_PARENT);
} }
private void notifySafetyIssueActionLaunchedIfNeeded(int resultCode) {
if (getIntent().getBooleanExtra(
CombinedBiometricStatusUtils.EXTRA_LAUNCH_FROM_SAFETY_SOURCE_ISSUE, false)
&& (resultCode != RESULT_FINISHED || mIsPreviousEnrollmentCanceled)) {
FeatureFactory.getFeatureFactory().getBiometricsFeatureProvider()
.notifySafetyIssueActionLaunched();
}
}
@Override @Override
public int getMetricsCategory() { public int getMetricsCategory() {
return SettingsEnums.BIOMETRIC_ENROLL_ACTIVITY; return SettingsEnums.BIOMETRIC_ENROLL_ACTIVITY;

View File

@@ -3,7 +3,6 @@ set noparent
graciecheng@google.com graciecheng@google.com
ilyamaty@google.com ilyamaty@google.com
jaggies@google.com
jbolinger@google.com jbolinger@google.com
jeffpu@google.com jeffpu@google.com
joshmccloskey@google.com joshmccloskey@google.com

View File

@@ -36,6 +36,13 @@ import com.android.settingslib.utils.StringUtil;
*/ */
public class CombinedBiometricStatusUtils { public class CombinedBiometricStatusUtils {
/**
* An intent extra indicates that the enrollment process is launched from biometric
* SafetySourceIssue action.
*/
public static final String EXTRA_LAUNCH_FROM_SAFETY_SOURCE_ISSUE =
"launch_from_safety_source_issue";
private final int mUserId; private final int mUserId;
private final Context mContext; private final Context mContext;
@Nullable @Nullable

View File

@@ -16,10 +16,13 @@
package com.android.settings.biometrics.face package com.android.settings.biometrics.face
import android.app.ComponentCaller
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.android.settings.biometrics.BiometricEnrollBase.RESULT_FINISHED
import com.android.settings.biometrics.combination.CombinedBiometricStatusUtils
import com.android.settings.overlay.FeatureFactory.Companion.featureFactory import com.android.settings.overlay.FeatureFactory.Companion.featureFactory
@@ -46,9 +49,23 @@ class FaceEnroll: AppCompatActivity() {
*/ */
Log.d("FaceEnroll", "forward to $nextActivityClass") Log.d("FaceEnroll", "forward to $nextActivityClass")
val nextIntent = Intent(this, nextActivityClass) val nextIntent = Intent(this, nextActivityClass)
nextIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT)
nextIntent.putExtras(intent) nextIntent.putExtras(intent)
startActivity(nextIntent) startActivityForResult(nextIntent, 0)
}
override fun onActivityResult(
requestCode: Int,
resultCode: Int,
data: Intent?,
caller: ComponentCaller
) {
super.onActivityResult(requestCode, resultCode, data, caller)
if (intent.getBooleanExtra(
CombinedBiometricStatusUtils.EXTRA_LAUNCH_FROM_SAFETY_SOURCE_ISSUE, false)
&& resultCode != RESULT_FINISHED) {
featureFactory.biometricsFeatureProvider.notifySafetyIssueActionLaunched()
}
setResult(resultCode, data)
finish() finish()
} }
} }

View File

@@ -16,10 +16,13 @@
package com.android.settings.biometrics.fingerprint package com.android.settings.biometrics.fingerprint
import android.app.ComponentCaller
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.android.settings.biometrics.BiometricEnrollBase
import com.android.settings.biometrics.combination.CombinedBiometricStatusUtils
import com.android.settings.overlay.FeatureFactory.Companion.featureFactory import com.android.settings.overlay.FeatureFactory.Companion.featureFactory
/** /**
@@ -69,9 +72,24 @@ open class FingerprintEnroll: AppCompatActivity() {
*/ */
Log.d("FingerprintEnroll", "forward to $nextActivityClass") Log.d("FingerprintEnroll", "forward to $nextActivityClass")
val nextIntent = Intent(this, nextActivityClass) val nextIntent = Intent(this, nextActivityClass)
nextIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT)
nextIntent.putExtras(intent) nextIntent.putExtras(intent)
startActivity(nextIntent) startActivityForResult(nextIntent, 0)
}
override fun onActivityResult(
requestCode: Int,
resultCode: Int,
data: Intent?,
caller: ComponentCaller
) {
super.onActivityResult(requestCode, resultCode, data, caller)
if (intent.getBooleanExtra(
CombinedBiometricStatusUtils.EXTRA_LAUNCH_FROM_SAFETY_SOURCE_ISSUE, false)
&& resultCode != BiometricEnrollBase.RESULT_FINISHED
) {
featureFactory.biometricsFeatureProvider.notifySafetyIssueActionLaunched()
}
setResult(resultCode, data)
finish() finish()
} }
} }

View File

@@ -18,6 +18,7 @@ package com.android.settings.connecteddevice
import android.Manifest import android.Manifest
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.settings.SettingsEnums.ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE
import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothAdapter
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
@@ -27,8 +28,10 @@ import android.os.UserManager
import android.provider.Settings import android.provider.Settings
import android.widget.Toast import android.widget.Toast
import androidx.preference.Preference import androidx.preference.Preference
import com.android.settings.PreferenceActionMetricsProvider
import com.android.settings.PreferenceRestrictionMixin import com.android.settings.PreferenceRestrictionMixin
import com.android.settings.R import com.android.settings.R
import com.android.settings.contract.KEY_BLUETOOTH
import com.android.settings.network.SatelliteRepository.Companion.isSatelliteOn import com.android.settings.network.SatelliteRepository.Companion.isSatelliteOn
import com.android.settings.network.SatelliteWarningDialogActivity import com.android.settings.network.SatelliteWarningDialogActivity
import com.android.settings.widget.MainSwitchBarMetadata import com.android.settings.widget.MainSwitchBarMetadata
@@ -43,7 +46,10 @@ import com.android.settingslib.metadata.SensitivityLevel
@SuppressLint("MissingPermission") @SuppressLint("MissingPermission")
class BluetoothPreference(private val bluetoothDataStore: BluetoothDataStore) : class BluetoothPreference(private val bluetoothDataStore: BluetoothDataStore) :
MainSwitchBarMetadata, PreferenceRestrictionMixin, Preference.OnPreferenceChangeListener { MainSwitchBarMetadata,
PreferenceActionMetricsProvider,
PreferenceRestrictionMixin,
Preference.OnPreferenceChangeListener {
override val key override val key
get() = KEY get() = KEY
@@ -51,6 +57,11 @@ class BluetoothPreference(private val bluetoothDataStore: BluetoothDataStore) :
override val title override val title
get() = R.string.bluetooth_main_switch_title get() = R.string.bluetooth_main_switch_title
override val preferenceActionMetrics: Int
get() = ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE
override fun tags(context: Context) = arrayOf(KEY_BLUETOOTH)
override val restrictionKeys: Array<String> override val restrictionKeys: Array<String>
get() = arrayOf(UserManager.DISALLOW_BLUETOOTH, UserManager.DISALLOW_CONFIG_BLUETOOTH) get() = arrayOf(UserManager.DISALLOW_BLUETOOTH, UserManager.DISALLOW_CONFIG_BLUETOOTH)

View File

@@ -334,12 +334,15 @@ class DisplayTopologyPreference(context : Context)
* @param displayHeight height of display being dragged in actual (not View) coordinates * @param displayHeight height of display being dragged in actual (not View) coordinates
* @param dragOffsetX difference between event rawX coordinate and X of the display in the pane * @param dragOffsetX difference between event rawX coordinate and X of the display in the pane
* @param dragOffsetY difference between event rawY coordinate and Y of the display in the pane * @param dragOffsetY difference between event rawY coordinate and Y of the display in the pane
* @param didMove true if we have detected the user intentionally wanted to drag rather than
* just click
*/ */
private data class BlockDrag( private data class BlockDrag(
val stationaryDisps : List<Pair<Int, RectF>>, val stationaryDisps : List<Pair<Int, RectF>>,
val display: DisplayBlock, val displayId: Int, val display: DisplayBlock, val displayId: Int,
val displayWidth: Float, val displayHeight: Float, val displayWidth: Float, val displayHeight: Float,
val dragOffsetX: Float, val dragOffsetY: Float) val dragOffsetX: Float, val dragOffsetY: Float,
var didMove: Boolean = false)
private var mTopologyInfo : TopologyInfo? = null private var mTopologyInfo : TopologyInfo? = null
private var mDrag : BlockDrag? = null private var mDrag : BlockDrag? = null
@@ -369,7 +372,7 @@ class DisplayTopologyPreference(context : Context)
applyTopology(topology) applyTopology(topology)
} }
@VisibleForTesting var mTimesReceivedSameTopology = 0 @VisibleForTesting var mTimesRefreshedBlocks = 0
private fun applyTopology(topology: DisplayTopology) { private fun applyTopology(topology: DisplayTopology) {
mTopologyHint.text = context.getString(R.string.external_display_topology_hint) mTopologyHint.text = context.getString(R.string.external_display_topology_hint)
@@ -386,7 +389,6 @@ class DisplayTopologyPreference(context : Context)
oldBounds.zip(newBounds).all { (old, new) -> oldBounds.zip(newBounds).all { (old, new) ->
old.first == new.first && sameDisplayPosition(old.second, new.second) old.first == new.first && sameDisplayPosition(old.second, new.second)
}) { }) {
mTimesReceivedSameTopology++
return return
} }
@@ -438,6 +440,7 @@ class DisplayTopologyPreference(context : Context)
} }
} }
mPaneContent.removeViews(newBounds.size, recycleableBlocks.size) mPaneContent.removeViews(newBounds.size, recycleableBlocks.size)
mTimesRefreshedBlocks++
mTopologyInfo = TopologyInfo(topology, scaling, newBounds) mTopologyInfo = TopologyInfo(topology, scaling, newBounds)
@@ -481,6 +484,7 @@ class DisplayTopologyPreference(context : Context)
val snapRect = clampPosition(drag.stationaryDisps.map { it.second }, dispDragRect) val snapRect = clampPosition(drag.stationaryDisps.map { it.second }, dispDragRect)
drag.display.place(topology.scaling.displayToPaneCoor(snapRect.left, snapRect.top)) drag.display.place(topology.scaling.displayToPaneCoor(snapRect.left, snapRect.top))
drag.didMove = true
return true return true
} }
@@ -491,6 +495,15 @@ class DisplayTopologyPreference(context : Context)
mPaneContent.requestDisallowInterceptTouchEvent(false) mPaneContent.requestDisallowInterceptTouchEvent(false)
drag.display.setHighlighted(false) drag.display.setHighlighted(false)
mDrag = null
if (!drag.didMove) {
// If no move event occurred, ignore the drag completely.
// TODO(b/352648432): Responding to a single move event no matter how small may be too
// sensitive. It is easy to slide by a small amount just by force of pressing down the
// mouse button. Keep an eye on this.
return true
}
val newCoor = topology.scaling.paneToDisplayCoor( val newCoor = topology.scaling.paneToDisplayCoor(
drag.display.x, drag.display.y) drag.display.x, drag.display.y)
val newTopology = topology.topology.copy() val newTopology = topology.topology.copy()
@@ -499,9 +512,15 @@ class DisplayTopologyPreference(context : Context)
val arr = hashMapOf(*newPositions.toTypedArray()) val arr = hashMapOf(*newPositions.toTypedArray())
newTopology.rearrange(arr) newTopology.rearrange(arr)
// Setting mTopologyInfo to null forces applyTopology to skip the no-op drag check. This is
// necessary because we don't know if newTopology.rearrange has mutated the topology away
// from what the user has dragged into position.
mTopologyInfo = null
applyTopology(newTopology)
injector.displayTopology = newTopology injector.displayTopology = newTopology
refreshPane()
return true return true
} }
} }

View File

@@ -47,3 +47,42 @@ const val KEY_ADAPTIVE_BRIGHTNESS = "auto_brightness"
/** Contract key for the "Screen attention" setting. */ /** Contract key for the "Screen attention" setting. */
const val KEY_SCREEN_ATTENTION = "screen_attention" const val KEY_SCREEN_ATTENTION = "screen_attention"
/** Contract key for the "Use adaptive connectivity" setting. */
const val KEY_ADAPTIVE_CONNECTIVITY = "adaptive_connectivity"
/** Contract key for the "WiFi hotspot" setting. */
const val KEY_WIFI_HOTSPOT = "enable_wifi_ap"
/** Contract key for the "Battery Gauge Slider" setting. */
const val KEY_BATTERY_LEVEL = "battery_level"
/** Contract key for the "Battery Percentage" setting. */
const val KEY_BATTERY_PERCENTAGE = "battery_percentage"
/** Contract key for the "Brightness level" setting. */
const val KEY_BRIGHTNESS_LEVEL = "brightness_level"
/** Contract key for the "Smooth display" setting. */
const val KEY_SMOOTH_DISPLAY = "smooth_display"
/** Contract key for the "Dark theme" setting. */
const val KEY_DARK_THEME = "dark_theme"
/** Contract key for the "Always show time and info" setting. */
const val KEY_AMBIENT_DISPLAY_ALWAYS_ON = "ambient_display_always_on"
/** Contract key for the "Use vibration & haptics" setting. */
const val KEY_VIBRATION_HAPTICS = "vibration_haptics"
/** Contract key for the "Media volume" setting. */
const val KEY_MEDIA_VOLUME = "media_volume"
/** Contract key for the "Call volume" setting. */
const val KEY_CALL_VOLUME = "call_volume"
/** Contract key for the "Ring volume" setting. */
const val KEY_RING_VOLUME = "separate_ring_volume"
/** Contract key for the "Remove animation" setting. */
const val KEY_REMOVE_ANIMATION = "remove_animation"

View File

@@ -16,6 +16,7 @@
package com.android.settings.display package com.android.settings.display
import android.app.settings.SettingsEnums.ACTION_SCREEN_ATTENTION_CHANGED
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@@ -26,8 +27,10 @@ import android.hardware.SensorPrivacyManager.Sensors.CAMERA
import android.os.PowerManager import android.os.PowerManager
import android.os.UserManager import android.os.UserManager
import android.provider.Settings import android.provider.Settings
import com.android.settings.PreferenceActionMetricsProvider
import com.android.settings.PreferenceRestrictionMixin import com.android.settings.PreferenceRestrictionMixin
import com.android.settings.R import com.android.settings.R
import com.android.settings.contract.KEY_SCREEN_ATTENTION
import com.android.settingslib.RestrictedSwitchPreference import com.android.settingslib.RestrictedSwitchPreference
import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.KeyValueStore
import com.android.settingslib.datastore.KeyedObservableDelegate import com.android.settingslib.datastore.KeyedObservableDelegate
@@ -46,6 +49,7 @@ import com.android.settingslib.preference.SwitchPreferenceBinding
class AdaptiveSleepPreference : class AdaptiveSleepPreference :
BooleanValuePreference, BooleanValuePreference,
SwitchPreferenceBinding, SwitchPreferenceBinding,
PreferenceActionMetricsProvider,
PreferenceLifecycleProvider, PreferenceLifecycleProvider,
PreferenceBindingPlaceholder, // not needed once controller class is cleaned up PreferenceBindingPlaceholder, // not needed once controller class is cleaned up
PreferenceAvailabilityProvider, PreferenceAvailabilityProvider,
@@ -63,6 +67,11 @@ class AdaptiveSleepPreference :
override val summary: Int override val summary: Int
get() = R.string.adaptive_sleep_description get() = R.string.adaptive_sleep_description
override val preferenceActionMetrics: Int
get() = ACTION_SCREEN_ATTENTION_CHANGED
override fun tags(context: Context) = arrayOf(KEY_SCREEN_ATTENTION)
override fun isIndexable(context: Context) = false override fun isIndexable(context: Context) = false
override fun isEnabled(context: Context) = override fun isEnabled(context: Context) =

View File

@@ -24,6 +24,7 @@ import android.os.UserManager
import android.provider.Settings.Secure.DOZE_ALWAYS_ON import android.provider.Settings.Secure.DOZE_ALWAYS_ON
import com.android.settings.PreferenceRestrictionMixin import com.android.settings.PreferenceRestrictionMixin
import com.android.settings.R import com.android.settings.R
import com.android.settings.contract.KEY_AMBIENT_DISPLAY_ALWAYS_ON
import com.android.settings.display.AmbientDisplayAlwaysOnPreferenceController.isAodSuppressedByBedtime import com.android.settings.display.AmbientDisplayAlwaysOnPreferenceController.isAodSuppressedByBedtime
import com.android.settingslib.datastore.AbstractKeyedDataObservable import com.android.settingslib.datastore.AbstractKeyedDataObservable
import com.android.settingslib.datastore.HandlerExecutor import com.android.settingslib.datastore.HandlerExecutor
@@ -123,7 +124,7 @@ class AmbientDisplayAlwaysOnPreference :
} }
companion object { companion object {
const val KEY = "ambient_display_always_on" const val KEY = KEY_AMBIENT_DISPLAY_ALWAYS_ON
private const val PROP_AWARE_AVAILABLE = "ro.vendor.aware_available" private const val PROP_AWARE_AVAILABLE = "ro.vendor.aware_available"
} }
} }

View File

@@ -15,6 +15,7 @@
*/ */
package com.android.settings.display package com.android.settings.display
import android.app.settings.SettingsEnums.ACTION_ADAPTIVE_BRIGHTNESS
import android.content.Context import android.content.Context
import android.os.UserManager import android.os.UserManager
import android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE import android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE
@@ -22,8 +23,10 @@ import android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
import android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL import android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceScreen import androidx.preference.PreferenceScreen
import com.android.settings.PreferenceActionMetricsProvider
import com.android.settings.PreferenceRestrictionMixin import com.android.settings.PreferenceRestrictionMixin
import com.android.settings.R import com.android.settings.R
import com.android.settings.contract.KEY_ADAPTIVE_BRIGHTNESS
import com.android.settings.flags.Flags import com.android.settings.flags.Flags
import com.android.settingslib.PrimarySwitchPreferenceBinding import com.android.settingslib.PrimarySwitchPreferenceBinding
import com.android.settingslib.datastore.AbstractKeyedDataObservable import com.android.settingslib.datastore.AbstractKeyedDataObservable
@@ -47,6 +50,7 @@ class AutoBrightnessScreen :
PreferenceScreenCreator, PreferenceScreenCreator,
PreferenceScreenBinding, // binding for screen page PreferenceScreenBinding, // binding for screen page
PrimarySwitchPreferenceBinding, // binding for screen entry point widget PrimarySwitchPreferenceBinding, // binding for screen entry point widget
PreferenceActionMetricsProvider,
PreferenceAvailabilityProvider, PreferenceAvailabilityProvider,
PreferenceRestrictionMixin, PreferenceRestrictionMixin,
BooleanValuePreference { BooleanValuePreference {
@@ -56,6 +60,11 @@ class AutoBrightnessScreen :
override val title: Int override val title: Int
get() = R.string.auto_brightness_title get() = R.string.auto_brightness_title
override val preferenceActionMetrics: Int
get() = ACTION_ADAPTIVE_BRIGHTNESS
override fun tags(context: Context) = arrayOf(KEY_ADAPTIVE_BRIGHTNESS)
override fun isFlagEnabled(context: Context) = Flags.catalystScreenBrightnessMode() override fun isFlagEnabled(context: Context) = Flags.catalystScreenBrightnessMode()
override fun fragmentClass() = AutoBrightnessSettings::class.java override fun fragmentClass() = AutoBrightnessSettings::class.java

View File

@@ -152,8 +152,8 @@ public class BatteryOptimizeUtils {
} }
/** Sets the {@link OptimizationMode} for associated app. */ /** Sets the {@link OptimizationMode} for associated app. */
public void setAppUsageState(@OptimizationMode int mode, Action action) { public void setAppUsageState(@OptimizationMode int mode, Action action, boolean forceMode) {
if (getAppOptimizationMode() == mode) { if (!forceMode && getAppOptimizationMode() == mode) {
Log.w(TAG, "set the same optimization mode for: " + mPackageName); Log.w(TAG, "set the same optimization mode for: " + mPackageName);
return; return;
} }
@@ -161,6 +161,11 @@ public class BatteryOptimizeUtils {
mContext, mode, mUid, mPackageName, mBatteryUtils, mPowerAllowListBackend, action); mContext, mode, mUid, mPackageName, mBatteryUtils, mPowerAllowListBackend, action);
} }
/** Sets the {@link OptimizationMode} for associated app. */
public void setAppUsageState(@OptimizationMode int mode, Action action) {
setAppUsageState(mode, action, /* forceMode= */ false);
}
/** Return {@code true} if it is disabled for default optimized mode only. */ /** Return {@code true} if it is disabled for default optimized mode only. */
public boolean isDisabledForOptimizeModeOnly() { public boolean isDisabledForOptimizeModeOnly() {
return getForceBatteryOptimizeModeList(mContext).contains(mPackageName) return getForceBatteryOptimizeModeList(mContext).contains(mPackageName)

View File

@@ -16,6 +16,8 @@
package com.android.settings.fuelgauge; package com.android.settings.fuelgauge;
import static com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_UNRESTRICTED;
import android.Manifest; import android.Manifest;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
@@ -24,20 +26,25 @@ import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.PowerManager; import android.os.PowerManager;
import android.os.PowerWhitelistManager; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import androidx.annotation.VisibleForTesting;
import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertActivity;
import com.android.internal.app.AlertController; import com.android.internal.app.AlertController;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action;
public class RequestIgnoreBatteryOptimizations extends AlertActivity public class RequestIgnoreBatteryOptimizations extends AlertActivity
implements DialogInterface.OnClickListener { implements DialogInterface.OnClickListener {
private static final String TAG = "RequestIgnoreBatteryOptimizations"; private static final String TAG = "RequestIgnoreBatteryOptimizations";
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
private PowerWhitelistManager mPowerWhitelistManager; @VisibleForTesting
private String mPackageName; static BatteryOptimizeUtils sTestBatteryOptimizeUtils = null;
private ApplicationInfo mApplicationInfo;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@@ -47,8 +54,6 @@ public class RequestIgnoreBatteryOptimizations extends AlertActivity
android.view.WindowManager.LayoutParams android.view.WindowManager.LayoutParams
.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); .SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
mPowerWhitelistManager = getSystemService(PowerWhitelistManager.class);
Uri data = getIntent().getData(); Uri data = getIntent().getData();
if (data == null) { if (data == null) {
debugLog( debugLog(
@@ -56,17 +61,18 @@ public class RequestIgnoreBatteryOptimizations extends AlertActivity
finish(); finish();
return; return;
} }
mPackageName = data.getSchemeSpecificPart(); final String packageName = data.getSchemeSpecificPart();
if (mPackageName == null) { if (TextUtils.isEmpty(packageName)) {
debugLog( debugLog(
"No data supplied for IGNORE_BATTERY_OPTIMIZATION_SETTINGS in: " + getIntent()); "No data supplied for IGNORE_BATTERY_OPTIMIZATION_SETTINGS in: " + getIntent());
finish(); finish();
return; return;
} }
// Package in Unrestricted mode already ignoring the battery optimizations.
PowerManager power = getSystemService(PowerManager.class); PowerManager power = getSystemService(PowerManager.class);
if (power.isIgnoringBatteryOptimizations(mPackageName)) { if (power.isIgnoringBatteryOptimizations(packageName)) {
debugLog("Not should prompt, already ignoring optimizations: " + mPackageName); debugLog("Not should prompt, already ignoring optimizations: " + packageName);
finish(); finish();
return; return;
} }
@@ -74,29 +80,28 @@ public class RequestIgnoreBatteryOptimizations extends AlertActivity
if (getPackageManager() if (getPackageManager()
.checkPermission( .checkPermission(
Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
mPackageName) packageName)
!= PackageManager.PERMISSION_GRANTED) { != PackageManager.PERMISSION_GRANTED) {
debugLog( debugLog(
"Requested package " "Requested package "
+ mPackageName + packageName
+ " does not hold permission " + " does not hold permission "
+ Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); + Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
finish(); finish();
return; return;
} }
ApplicationInfo ai;
try { try {
ai = getPackageManager().getApplicationInfo(mPackageName, 0); mApplicationInfo = getPackageManager().getApplicationInfo(packageName, 0);
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
debugLog("Requested package doesn't exist: " + mPackageName); debugLog("Requested package doesn't exist: " + packageName);
finish(); finish();
return; return;
} }
final AlertController.AlertParams p = mAlertParams; final AlertController.AlertParams p = mAlertParams;
final CharSequence appLabel = final CharSequence appLabel =
ai.loadSafeLabel( mApplicationInfo.loadSafeLabel(
getPackageManager(), getPackageManager(),
PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX, PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX,
PackageItemInfo.SAFE_LABEL_FLAG_TRIM PackageItemInfo.SAFE_LABEL_FLAG_TRIM
@@ -114,7 +119,15 @@ public class RequestIgnoreBatteryOptimizations extends AlertActivity
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
switch (which) { switch (which) {
case BUTTON_POSITIVE: case BUTTON_POSITIVE:
mPowerWhitelistManager.addToWhitelist(mPackageName); BatteryOptimizeUtils batteryOptimizeUtils =
sTestBatteryOptimizeUtils != null
? sTestBatteryOptimizeUtils
: new BatteryOptimizeUtils(
getApplicationContext(),
mApplicationInfo.uid,
mApplicationInfo.packageName);
batteryOptimizeUtils.setAppUsageState(
MODE_UNRESTRICTED, Action.APPLY, /* forceMode= */ true);
break; break;
case BUTTON_NEGATIVE: case BUTTON_NEGATIVE:
break; break;

View File

@@ -16,9 +16,12 @@
package com.android.settings.fuelgauge.batterysaver package com.android.settings.fuelgauge.batterysaver
import android.Manifest import android.Manifest
import android.app.settings.SettingsEnums.ACTION_BATTERY_SAVER
import android.content.Context import android.content.Context
import android.os.PowerManager import android.os.PowerManager
import com.android.settings.PreferenceActionMetricsProvider
import com.android.settings.R import com.android.settings.R
import com.android.settings.contract.KEY_BATTERY_SAVER
import com.android.settings.fuelgauge.BatterySaverReceiver import com.android.settings.fuelgauge.BatterySaverReceiver
import com.android.settings.fuelgauge.BatterySaverReceiver.BatterySaverListener import com.android.settings.fuelgauge.BatterySaverReceiver.BatterySaverListener
import com.android.settingslib.datastore.AbstractKeyedDataObservable import com.android.settingslib.datastore.AbstractKeyedDataObservable
@@ -40,7 +43,13 @@ import kotlinx.coroutines.launch
// LINT.IfChange // LINT.IfChange
class BatterySaverPreference : class BatterySaverPreference :
MainSwitchPreference(KEY, R.string.battery_saver_master_switch_title) { MainSwitchPreference(KEY, R.string.battery_saver_master_switch_title),
PreferenceActionMetricsProvider {
override val preferenceActionMetrics: Int
get() = ACTION_BATTERY_SAVER
override fun tags(context: Context) = arrayOf(KEY_BATTERY_SAVER)
override fun storage(context: Context) = BatterySaverStore(context) override fun storage(context: Context) = BatterySaverStore(context)

View File

@@ -2,7 +2,6 @@
asalo@google.com asalo@google.com
lifu@google.com lifu@google.com
mstogaitis@google.com mstogaitis@google.com
palanki@google.com
sooniln@google.com sooniln@google.com
weiwa@google.com weiwa@google.com
wyattriley@google.com wyattriley@google.com

View File

@@ -17,9 +17,12 @@
package com.android.settings.network package com.android.settings.network
import android.Manifest import android.Manifest
import android.app.settings.SettingsEnums.ACTION_MOBILE_DATA
import android.content.Context import android.content.Context
import android.telephony.SubscriptionManager import android.telephony.SubscriptionManager
import com.android.settings.PreferenceActionMetricsProvider
import com.android.settings.R import com.android.settings.R
import com.android.settings.contract.KEY_MOBILE_DATA
import com.android.settings.network.telephony.MobileDataRepository import com.android.settings.network.telephony.MobileDataRepository
import com.android.settings.network.telephony.SubscriptionRepository import com.android.settings.network.telephony.SubscriptionRepository
import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.KeyValueStore
@@ -38,8 +41,14 @@ class MobileDataPreference :
R.string.mobile_data_settings_title, R.string.mobile_data_settings_title,
R.string.mobile_data_settings_summary, R.string.mobile_data_settings_summary,
), ),
PreferenceActionMetricsProvider,
PreferenceAvailabilityProvider { PreferenceAvailabilityProvider {
override val preferenceActionMetrics: Int
get() = ACTION_MOBILE_DATA
override fun tags(context: Context) = arrayOf(KEY_MOBILE_DATA)
override fun isAvailable(context: Context) = override fun isAvailable(context: Context) =
SubscriptionRepository(context).getSelectableSubscriptionInfoList().any { SubscriptionRepository(context).getSelectableSubscriptionInfoList().any {
it.simSlotIndex > -1 it.simSlotIndex > -1
@@ -59,7 +68,7 @@ class MobileDataPreference :
override fun getWritePermissions(context: Context) = override fun getWritePermissions(context: Context) =
Permissions.allOf( Permissions.allOf(
// TelephonyManager.setDataEnabledForReason // TelephonyManager.setDataEnabledForReason
Manifest.permission.MODIFY_PHONE_STATE, Manifest.permission.MODIFY_PHONE_STATE
) )
override fun getReadPermit(context: Context, callingPid: Int, callingUid: Int) = override fun getReadPermit(context: Context, callingPid: Int, callingUid: Int) =

View File

@@ -171,7 +171,7 @@ public class CustomSliceRegistry {
.scheme(ContentResolver.SCHEME_CONTENT) .scheme(ContentResolver.SCHEME_CONTENT)
.authority(SettingsSliceProvider.SLICE_AUTHORITY) .authority(SettingsSliceProvider.SLICE_AUTHORITY)
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
.appendPath("call_volume") .appendPath(SettingsContractKt.KEY_CALL_VOLUME)
.build(); .build();
/** /**
* Full {@link Uri} for the Media Volume Slice. * Full {@link Uri} for the Media Volume Slice.
@@ -180,7 +180,7 @@ public class CustomSliceRegistry {
.scheme(ContentResolver.SCHEME_CONTENT) .scheme(ContentResolver.SCHEME_CONTENT)
.authority(SettingsSliceProvider.SLICE_AUTHORITY) .authority(SettingsSliceProvider.SLICE_AUTHORITY)
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
.appendPath("media_volume") .appendPath(SettingsContractKt.KEY_MEDIA_VOLUME)
.build(); .build();
/** /**
@@ -190,7 +190,7 @@ public class CustomSliceRegistry {
.scheme(ContentResolver.SCHEME_CONTENT) .scheme(ContentResolver.SCHEME_CONTENT)
.authority(SettingsSliceProvider.SLICE_AUTHORITY) .authority(SettingsSliceProvider.SLICE_AUTHORITY)
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
.appendPath("separate_ring_volume") .appendPath(SettingsContractKt.KEY_RING_VOLUME)
.build(); .build();
/** /**
@@ -268,7 +268,7 @@ public class CustomSliceRegistry {
.scheme(ContentResolver.SCHEME_CONTENT) .scheme(ContentResolver.SCHEME_CONTENT)
.authority(SettingsSliceProvider.SLICE_AUTHORITY) .authority(SettingsSliceProvider.SLICE_AUTHORITY)
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
.appendPath("dark_theme") .appendPath(SettingsContractKt.KEY_DARK_THEME)
.build(); .build();
/** /**

View File

@@ -17,6 +17,7 @@
package com.android.settings.wifi package com.android.settings.wifi
import android.Manifest import android.Manifest
import android.app.settings.SettingsEnums.ACTION_WIFI
import android.app.settings.SettingsEnums.ACTION_WIFI_OFF import android.app.settings.SettingsEnums.ACTION_WIFI_OFF
import android.app.settings.SettingsEnums.ACTION_WIFI_ON import android.app.settings.SettingsEnums.ACTION_WIFI_ON
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
@@ -29,8 +30,10 @@ import android.provider.Settings
import android.widget.Toast import android.widget.Toast
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.Preference.OnPreferenceChangeListener import androidx.preference.Preference.OnPreferenceChangeListener
import com.android.settings.PreferenceActionMetricsProvider
import com.android.settings.PreferenceRestrictionMixin import com.android.settings.PreferenceRestrictionMixin
import com.android.settings.R import com.android.settings.R
import com.android.settings.contract.KEY_WIFI
import com.android.settings.network.SatelliteRepository.Companion.isSatelliteOn import com.android.settings.network.SatelliteRepository.Companion.isSatelliteOn
import com.android.settings.network.SatelliteWarningDialogActivity import com.android.settings.network.SatelliteWarningDialogActivity
import com.android.settings.overlay.FeatureFactory.Companion.featureFactory import com.android.settings.overlay.FeatureFactory.Companion.featureFactory
@@ -54,6 +57,7 @@ import com.android.settingslib.preference.SwitchPreferenceBinding
class WifiSwitchPreference : class WifiSwitchPreference :
SwitchPreference(KEY, R.string.wifi), SwitchPreference(KEY, R.string.wifi),
SwitchPreferenceBinding, SwitchPreferenceBinding,
PreferenceActionMetricsProvider,
OnPreferenceChangeListener, OnPreferenceChangeListener,
PreferenceLifecycleProvider, PreferenceLifecycleProvider,
PreferenceRestrictionMixin { PreferenceRestrictionMixin {
@@ -61,6 +65,11 @@ class WifiSwitchPreference :
override val keywords: Int override val keywords: Int
get() = R.string.keywords_wifi get() = R.string.keywords_wifi
override val preferenceActionMetrics: Int
get() = ACTION_WIFI
override fun tags(context: Context) = arrayOf(KEY_WIFI)
override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context) override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context)
override val restrictionKeys override val restrictionKeys

View File

@@ -19,12 +19,15 @@ package com.android.settings.wifi.calling
import android.Manifest.permission.MODIFY_PHONE_STATE import android.Manifest.permission.MODIFY_PHONE_STATE
import android.Manifest.permission.READ_PRECISE_PHONE_STATE import android.Manifest.permission.READ_PRECISE_PHONE_STATE
import android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE import android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE
import android.app.settings.SettingsEnums.ACTION_WIFI_CALLING
import android.content.Context import android.content.Context
import android.telephony.SubscriptionManager import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager import android.telephony.TelephonyManager
import android.telephony.ims.ImsMmTelManager import android.telephony.ims.ImsMmTelManager
import android.util.Log import android.util.Log
import com.android.settings.PreferenceActionMetricsProvider
import com.android.settings.R import com.android.settings.R
import com.android.settings.contract.KEY_WIFI_CALLING
import com.android.settings.network.ims.WifiCallingQueryImsState import com.android.settings.network.ims.WifiCallingQueryImsState
import com.android.settings.network.telephony.wificalling.WifiCallingRepository import com.android.settings.network.telephony.wificalling.WifiCallingRepository
import com.android.settings.widget.SettingsMainSwitchPreference import com.android.settings.widget.SettingsMainSwitchPreference
@@ -47,7 +50,10 @@ import kotlinx.coroutines.runBlocking
* TODO(b/372732219): apply metadata to UI * TODO(b/372732219): apply metadata to UI
*/ */
class WifiCallingMainSwitchPreference(private val subId: Int) : class WifiCallingMainSwitchPreference(private val subId: Int) :
BooleanValuePreference, BooleanValuePreferenceBinding, PreferenceAvailabilityProvider { BooleanValuePreference,
BooleanValuePreferenceBinding,
PreferenceActionMetricsProvider,
PreferenceAvailabilityProvider {
override val key: String override val key: String
get() = KEY get() = KEY
@@ -55,6 +61,11 @@ class WifiCallingMainSwitchPreference(private val subId: Int) :
override val title: Int override val title: Int
get() = R.string.wifi_calling_main_switch_title get() = R.string.wifi_calling_main_switch_title
override val preferenceActionMetrics: Int
get() = ACTION_WIFI_CALLING
override fun tags(context: Context) = arrayOf(KEY_WIFI_CALLING)
override fun isEnabled(context: Context) = override fun isEnabled(context: Context) =
context.isCallStateIdle(subId) && context.isCallStateIdle(subId) &&
WifiCallingQueryImsState(context, subId).isAllowUserControl WifiCallingQueryImsState(context, subId).isAllowUserControl

View File

@@ -16,55 +16,60 @@
package com.android.settings.accessibility; package com.android.settings.accessibility;
import static android.view.accessibility.AccessibilityManager.AUTOCLICK_CURSOR_AREA_SIZE_MAX;
import static android.view.accessibility.AccessibilityManager.AUTOCLICK_CURSOR_AREA_SIZE_MIN;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.when;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.kotlin.VerificationKt.verify;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule; import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings; import android.provider.Settings;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
import android.widget.RadioGroup;
import androidx.preference.PreferenceScreen; import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController; import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.widget.SliderPreference; import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
import com.google.common.collect.ImmutableList;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule; import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowLooper;
/** Tests for {@link ToggleAutoclickCursorAreaSizeController}. */ /** Tests for {@link ToggleAutoclickCursorAreaSizeController}. */
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@Config(shadows = {
com.android.settings.testutils.shadow.ShadowFragment.class,
ShadowAlertDialogCompat.class,
})
public class ToggleAutoclickCursorAreaSizeControllerTest { public class ToggleAutoclickCursorAreaSizeControllerTest {
private static final String PREFERENCE_KEY = "accessibility_control_autoclick_cursor_area_size"; private static final String PREFERENCE_KEY = "accessibility_control_autoclick_cursor_area_size";
private static final String PACKAGE = "package";
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
private final Context mContext = ApplicationProvider.getApplicationContext(); @Mock
private Preference mPreference;
private Context mContext;
private ToggleAutoclickCursorAreaSizeController mController; private ToggleAutoclickCursorAreaSizeController mController;
@Before @Before
public void setUp() { public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
when(mPreference.getKey()).thenReturn(PREFERENCE_KEY);
mController = new ToggleAutoclickCursorAreaSizeController(mContext, PREFERENCE_KEY); mController = new ToggleAutoclickCursorAreaSizeController(mContext, PREFERENCE_KEY);
} }
@@ -75,6 +80,15 @@ public class ToggleAutoclickCursorAreaSizeControllerTest {
.isEqualTo(BasePreferenceController.AVAILABLE); .isEqualTo(BasePreferenceController.AVAILABLE);
} }
@Test
public void getSummary() {
mController.updateAutoclickCursorAreaSize(
mController.RADIO_BUTTON_ID_TO_CURSOR_SIZE.get(
R.id.autoclick_cursor_area_size_value_large));
assertThat(mController.getSummary()).isEqualTo(
mContext.getString(R.string.autoclick_cursor_area_size_dialog_option_large));
}
@Test @Test
@DisableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) @DisableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR)
public void getAvailabilityStatus_conditionallyUnavailableWhenFlagOn() { public void getAvailabilityStatus_conditionallyUnavailableWhenFlagOn() {
@@ -83,90 +97,48 @@ public class ToggleAutoclickCursorAreaSizeControllerTest {
} }
@Test @Test
public void onStart_registerOnSharedPreferenceChangeListener() { public void handlePreferenceTreeClick_dialogShows() {
final SharedPreferences prefs = mock(SharedPreferences.class); mController.handlePreferenceTreeClick(mPreference);
final Context context = mock(Context.class);
doReturn(PACKAGE).when(context).getPackageName();
doReturn(prefs).when(context).getSharedPreferences(anyString(), anyInt());
final ToggleAutoclickCursorAreaSizeController controller =
new ToggleAutoclickCursorAreaSizeController(context, PREFERENCE_KEY);
controller.onStart(); AlertDialog alertDialog = ShadowAlertDialogCompat.getLatestAlertDialog();
verify(prefs).registerOnSharedPreferenceChangeListener(controller); assertThat(alertDialog.isShowing()).isTrue();
}
@Test
public void onStop_unregisterOnSharedPreferenceChangeListener() {
final SharedPreferences prefs = mock(SharedPreferences.class);
final Context context = mock(Context.class);
doReturn(PACKAGE).when(context).getPackageName();
doReturn(prefs).when(context).getSharedPreferences(anyString(), anyInt());
final ToggleAutoclickCursorAreaSizeController controller =
new ToggleAutoclickCursorAreaSizeController(context, PREFERENCE_KEY);
controller.onStop();
verify(prefs).unregisterOnSharedPreferenceChangeListener(controller);
} }
@Test @Test
@EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR)
public void getProgress_matchesSetting_inRangeValue() { public void getProgress_matchesSetting_inRangeValue() {
// TODO(388844952): Use parameter testing. updateSetting(mController.RADIO_BUTTON_ID_TO_CURSOR_SIZE.get(
for (int size : ImmutableList.of(20, 40, 60, 80, 100)) { R.id.autoclick_cursor_area_size_value_extra_large));
updateSetting(size); ShadowLooper.idleMainLooper();
mController.handlePreferenceTreeClick(mPreference);
AlertDialog alertDialog = ShadowAlertDialogCompat.getLatestAlertDialog();
RadioGroup radioGroup = alertDialog.findViewById(
R.id.autoclick_cursor_area_size_value_group);
ShadowLooper.idleMainLooper();
assertThat(mController.getSliderPosition()).isEqualTo(size); assertThat(radioGroup.getCheckedRadioButtonId())
} .isEqualTo(R.id.autoclick_cursor_area_size_value_extra_large);
}
@Test
public void getProgress_matchesSetting_aboveMaxValue() {
updateSetting(120);
assertThat(mController.getSliderPosition()).isEqualTo(AUTOCLICK_CURSOR_AREA_SIZE_MAX);
}
@Test
public void getProgress_matchesSetting_belowMinValue() {
updateSetting(0);
assertThat(mController.getSliderPosition()).isEqualTo(AUTOCLICK_CURSOR_AREA_SIZE_MIN);
} }
@Test @Test
public void setProgress_updatesSetting_inRangeValue() { public void setProgress_updatesSetting_inRangeValue() {
// TODO(388844952): Use parameter testing. mController.handlePreferenceTreeClick(mPreference);
for (int position : ImmutableList.of(20, 40, 60, 80, 100)) { AlertDialog alertDialog = ShadowAlertDialogCompat.getLatestAlertDialog();
mController.setSliderPosition(position); RadioGroup radioGroup = alertDialog.findViewById(
R.id.autoclick_cursor_area_size_value_group);
ShadowLooper.idleMainLooper();
radioGroup.check(R.id.autoclick_cursor_area_size_value_extra_large);
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick();
ShadowLooper.idleMainLooper();
assertThat(readSetting()).isEqualTo(100);
assertThat(readSetting()).isEqualTo(position); mController.handlePreferenceTreeClick(mPreference);
} ShadowLooper.idleMainLooper();
} radioGroup.check(R.id.autoclick_cursor_area_size_value_extra_small);
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick();
@Test ShadowLooper.idleMainLooper();
public void setProgress_updatesSetting_aboveMaxValue() { assertThat(readSetting()).isEqualTo(20);
mController.setSliderPosition(120);
assertThat(readSetting()).isEqualTo(AUTOCLICK_CURSOR_AREA_SIZE_MAX);
}
@Test
public void setProgress_updatesSetting_belowMinValue() {
mController.setSliderPosition(0);
assertThat(readSetting()).isEqualTo(AUTOCLICK_CURSOR_AREA_SIZE_MIN);
}
@Test
public void sliderPreference_setCorrectInitialValue() {
SliderPreference preference = mock(SliderPreference.class);
PreferenceScreen screen = mock(PreferenceScreen.class);
doReturn(preference).when(screen).findPreference(anyString());
mController.displayPreference(screen);
verify(preference).setValue(mController.getSliderPosition());
} }
private int readSetting() { private int readSetting() {

View File

@@ -68,7 +68,6 @@ class FaceEnrollTest {
currentActivityInstance : FaceEnroll, currentActivityInstance : FaceEnroll,
nextActivityClass: Class<out Activity> nextActivityClass: Class<out Activity>
) { ) {
Truth.assertThat(currentActivityInstance.isFinishing).isTrue()
val nextActivityIntent = Shadows.shadowOf(currentActivityInstance).nextStartedActivity val nextActivityIntent = Shadows.shadowOf(currentActivityInstance).nextStartedActivity
assertThat(nextActivityIntent.component!!.className).isEqualTo(nextActivityClass.name) assertThat(nextActivityIntent.component!!.className).isEqualTo(nextActivityClass.name)
assertThat(nextActivityIntent.extras!!.size()).isEqualTo(1) assertThat(nextActivityIntent.extras!!.size()).isEqualTo(1)

View File

@@ -95,7 +95,6 @@ class FingerprintEnrollTest {
currentActivityInstance : FingerprintEnroll, currentActivityInstance : FingerprintEnroll,
nextActivityClass: Class<out Activity> nextActivityClass: Class<out Activity>
) { ) {
assertThat(currentActivityInstance.isFinishing).isTrue()
val nextActivityIntent = Shadows.shadowOf(currentActivityInstance).nextStartedActivity val nextActivityIntent = Shadows.shadowOf(currentActivityInstance).nextStartedActivity
assertThat(nextActivityIntent.component!!.className).isEqualTo(nextActivityClass.name) assertThat(nextActivityIntent.component!!.className).isEqualTo(nextActivityClass.name)
assertThat(nextActivityIntent.extras!!.size()).isEqualTo(1) assertThat(nextActivityIntent.extras!!.size()).isEqualTo(1)

View File

@@ -186,6 +186,8 @@ class DisplayTopologyPreferenceTest {
fun dragDisplayDownward() { fun dragDisplayDownward() {
val (leftBlock, _) = setupTwoDisplays() val (leftBlock, _) = setupTwoDisplays()
preference.mTimesRefreshedBlocks = 0
val downEvent = MotionEventBuilder.newBuilder() val downEvent = MotionEventBuilder.newBuilder()
.setPointer(0f, 0f) .setPointer(0f, 0f)
.setAction(MotionEvent.ACTION_DOWN) .setAction(MotionEvent.ACTION_DOWN)
@@ -208,12 +210,16 @@ class DisplayTopologyPreferenceTest {
val child = rootChildren[0] val child = rootChildren[0]
assertThat(child.position).isEqualTo(POSITION_LEFT) assertThat(child.position).isEqualTo(POSITION_LEFT)
assertThat(child.offset).isWithin(1f).of(82f) assertThat(child.offset).isWithin(1f).of(82f)
assertThat(preference.mTimesRefreshedBlocks).isEqualTo(1)
} }
@Test @Test
fun dragRootDisplayToNewSide() { fun dragRootDisplayToNewSide() {
val (leftBlock, rightBlock) = setupTwoDisplays() val (leftBlock, rightBlock) = setupTwoDisplays()
preference.mTimesRefreshedBlocks = 0
val downEvent = MotionEventBuilder.newBuilder() val downEvent = MotionEventBuilder.newBuilder()
.setAction(MotionEvent.ACTION_DOWN) .setAction(MotionEvent.ACTION_DOWN)
.setPointer(0f, 0f) .setPointer(0f, 0f)
@@ -251,6 +257,32 @@ class DisplayTopologyPreferenceTest {
assertThat(paneChildren[0].x) assertThat(paneChildren[0].x)
.isWithin(1f) .isWithin(1f)
.of(paneChildren[1].x) .of(paneChildren[1].x)
assertThat(preference.mTimesRefreshedBlocks).isEqualTo(1)
}
@Test
fun noRefreshForUnmovingDrag() {
val (leftBlock, rightBlock) = setupTwoDisplays()
preference.mTimesRefreshedBlocks = 0
val downEvent = MotionEventBuilder.newBuilder()
.setAction(MotionEvent.ACTION_DOWN)
.setPointer(0f, 0f)
.build()
val upEvent = MotionEventBuilder.newBuilder().setAction(MotionEvent.ACTION_UP).build()
rightBlock.dispatchTouchEvent(downEvent)
rightBlock.dispatchTouchEvent(upEvent)
// After drag, the original views should still be present.
val paneChildren = getPaneChildren()
assertThat(paneChildren.indexOf(leftBlock)).isNotEqualTo(-1)
assertThat(paneChildren.indexOf(rightBlock)).isNotEqualTo(-1)
assertThat(preference.mTimesRefreshedBlocks).isEqualTo(0)
} }
@Test @Test
@@ -269,13 +301,15 @@ class DisplayTopologyPreferenceTest {
@Test @Test
fun applyNewTopologyViaListenerUpdate() { fun applyNewTopologyViaListenerUpdate() {
setupTwoDisplays() setupTwoDisplays()
preference.mTimesRefreshedBlocks = 0
val newTopology = injector.topology!!.copy() val newTopology = injector.topology!!.copy()
newTopology.addDisplay(/* displayId= */ 8008, /* width= */ 300f, /* height= */ 320f) newTopology.addDisplay(/* displayId= */ 8008, /* width= */ 300f, /* height= */ 320f)
injector.topology = newTopology injector.topology = newTopology
injector.topologyListener!!.accept(newTopology) injector.topologyListener!!.accept(newTopology)
assertThat(preference.mTimesReceivedSameTopology).isEqualTo(0) assertThat(preference.mTimesRefreshedBlocks).isEqualTo(1)
val paneChildren = getPaneChildren() val paneChildren = getPaneChildren()
assertThat(paneChildren).hasSize(3) assertThat(paneChildren).hasSize(3)
@@ -293,11 +327,11 @@ class DisplayTopologyPreferenceTest {
injector.topology = twoDisplayTopology(POSITION_TOP, /* offset= */ 12.0f) injector.topology = twoDisplayTopology(POSITION_TOP, /* offset= */ 12.0f)
preparePane() preparePane()
assertThat(preference.mTimesReceivedSameTopology).isEqualTo(0) preference.mTimesRefreshedBlocks = 0
injector.topology = twoDisplayTopology(POSITION_TOP, /* offset= */ 12.1f) injector.topology = twoDisplayTopology(POSITION_TOP, /* offset= */ 12.1f)
injector.topologyListener!!.accept(injector.topology!!) injector.topologyListener!!.accept(injector.topology!!)
assertThat(preference.mTimesReceivedSameTopology).isEqualTo(1) assertThat(preference.mTimesRefreshedBlocks).isEqualTo(0)
} }
@Test @Test

View File

@@ -0,0 +1,224 @@
/*
* Copyright (C) 2025 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.fuelgauge;
import static com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_RESTRICTED;
import static com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_UNRESTRICTED;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
import android.Manifest;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.PowerManager;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowUtils.class})
public class RequestIgnoreBatteryOptimizationsTest {
private static final int UID = 12345;
private static final String PACKAGE_NAME = "com.android.app";
private static final String UNKNOWN_PACKAGE_NAME = "com.android.unknown";
private static final String PACKAGE_LABEL = "app";
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
private Context mContext;
private RequestIgnoreBatteryOptimizations mActivity;
private BatteryOptimizeUtils mBatteryOptimizeUtils;
private PowerAllowlistBackend mPowerAllowlistBackend;
@Mock private PowerManager mMockPowerManager;
@Mock private PackageManager mMockPackageManager;
@Mock private ApplicationInfo mMockApplicationInfo;
@Mock private BatteryUtils mMockBatteryUtils;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
mActivity = spy(Robolectric.setupActivity(RequestIgnoreBatteryOptimizations.class));
mBatteryOptimizeUtils = spy(new BatteryOptimizeUtils(mContext, UID, PACKAGE_NAME));
mPowerAllowlistBackend = spy(PowerAllowlistBackend.getInstance(mContext));
mBatteryOptimizeUtils.mPowerAllowListBackend = mPowerAllowlistBackend;
mBatteryOptimizeUtils.mBatteryUtils = mMockBatteryUtils;
RequestIgnoreBatteryOptimizations.sTestBatteryOptimizeUtils = mBatteryOptimizeUtils;
when(mActivity.getApplicationContext()).thenReturn(mContext);
doReturn(mMockPowerManager).when(mActivity).getSystemService(PowerManager.class);
doReturn(mMockPackageManager).when(mActivity).getPackageManager();
doReturn(mMockApplicationInfo)
.when(mMockPackageManager)
.getApplicationInfo(PACKAGE_NAME, 0);
doThrow(new PackageManager.NameNotFoundException(""))
.when(mMockPackageManager)
.getApplicationInfo(UNKNOWN_PACKAGE_NAME, 0);
doReturn(PACKAGE_LABEL)
.when(mMockApplicationInfo)
.loadSafeLabel(
mMockPackageManager,
PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX,
PackageItemInfo.SAFE_LABEL_FLAG_TRIM
| PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE);
doReturn(PackageManager.PERMISSION_GRANTED)
.when(mMockPackageManager)
.checkPermission(
eq(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS), anyString());
}
@After
public void tearDown() {
ShadowUtils.reset();
PowerAllowlistBackend.resetInstance();
}
@Test
public void onCreate_withIntent_shouldNotFinish() {
mActivity.setIntent(createIntent(PACKAGE_NAME));
mActivity.onCreate(new Bundle());
verify(mActivity, never()).finish();
}
@Test
public void onCreate_withNoDataIntent_shouldFinish() {
mActivity.setIntent(new Intent());
mActivity.onCreate(new Bundle());
verify(mActivity).finish();
}
@Test
public void onCreate_withEmptyPackageName_shouldFinish() {
mActivity.setIntent(createIntent(""));
mActivity.onCreate(new Bundle());
verify(mActivity).finish();
}
@Test
public void onCreate_withPkgAlreadyIgnoreOptimization_shouldFinish() {
mActivity.setIntent(createIntent(PACKAGE_NAME));
doReturn(true).when(mMockPowerManager).isIgnoringBatteryOptimizations(PACKAGE_NAME);
mActivity.onCreate(new Bundle());
verify(mActivity).finish();
}
@Test
public void onCreate_withPkgWithoutPermission_shouldFinish() {
mActivity.setIntent(createIntent(PACKAGE_NAME));
doReturn(PackageManager.PERMISSION_DENIED)
.when(mMockPackageManager)
.checkPermission(
Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, PACKAGE_NAME);
mActivity.onCreate(new Bundle());
verify(mActivity).finish();
}
@Test
public void onCreate_withPkgNameNotFound_shouldFinish() {
mActivity.setIntent(createIntent(UNKNOWN_PACKAGE_NAME));
mActivity.onCreate(new Bundle());
verify(mActivity).finish();
}
@Test
public void onClick_clickNegativeButton_doNothing() {
mActivity.onClick(null, DialogInterface.BUTTON_NEGATIVE);
verifyNoInteractions(mBatteryOptimizeUtils);
}
@Test
public void onClick_clickPositiveButtonWithUnrestrictedMode_addAllowlist() {
when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(MODE_UNRESTRICTED);
mActivity.onClick(null, DialogInterface.BUTTON_POSITIVE);
verify(mBatteryOptimizeUtils)
.setAppUsageState(
MODE_UNRESTRICTED,
BatteryOptimizeHistoricalLogEntry.Action.APPLY,
/* forceMode= */ true);
verify(mPowerAllowlistBackend).addApp(PACKAGE_NAME, UID);
verify(mMockBatteryUtils).setForceAppStandby(UID, PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
}
@Test
public void onClick_clickPositiveButtonWithRestrictedMode_addAllowlistAndSetStandby() {
when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(MODE_RESTRICTED);
doNothing().when(mMockBatteryUtils).setForceAppStandby(anyInt(), anyString(), anyInt());
mActivity.onClick(null, DialogInterface.BUTTON_POSITIVE);
verify(mBatteryOptimizeUtils)
.setAppUsageState(
MODE_UNRESTRICTED,
BatteryOptimizeHistoricalLogEntry.Action.APPLY,
/* forceMode= */ true);
verify(mPowerAllowlistBackend).addApp(PACKAGE_NAME, UID);
verify(mMockBatteryUtils).setForceAppStandby(UID, PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
}
private Intent createIntent(String packageName) {
final Intent intent = new Intent();
intent.setData(new Uri.Builder().scheme("package").opaquePart(packageName).build());
return intent;
}
}

View File

@@ -112,42 +112,6 @@ public class CellularSecurityNotificationsPreferenceControllerTest {
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
} }
@Test
public void setChecked_flagsDisabled_shouldReturnFalse() {
// Flags disabled
enableFlags(false);
// Hardware support is enabled
doNothing().when(mTelephonyManager).setNullCipherNotificationsEnabled(true);
doNothing().when(mTelephonyManager)
.setEnableCellularIdentifierDisclosureNotifications(true);
assertThat(mController.setChecked(false)).isFalse();
assertThat(mController.setChecked(true)).isFalse();
// Enable 1 flag, make sure it still fails
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY_UNSOL_EVENTS);
assertThat(mController.setChecked(false)).isFalse();
assertThat(mController.setChecked(true)).isFalse();
}
@Test
public void setChecked_hardwareDisabled_shouldReturnFalse() {
// Flags disabled
enableFlags(false);
// Hardware support is enabled
doNothing().when(mTelephonyManager).setNullCipherNotificationsEnabled(true);
doNothing().when(mTelephonyManager)
.setEnableCellularIdentifierDisclosureNotifications(true);
assertThat(mController.setChecked(true)).isFalse();
// Hardware support is enabled, called with false
doNothing().when(mTelephonyManager).setNullCipherNotificationsEnabled(false);
doNothing().when(mTelephonyManager)
.setEnableCellularIdentifierDisclosureNotifications(false);
assertThat(mController.setChecked(false)).isFalse();
}
@Test @Test
public void setChecked_shouldReturnTrue() { public void setChecked_shouldReturnTrue() {
enableFlags(true); enableFlags(true);
@@ -174,18 +138,6 @@ public class CellularSecurityNotificationsPreferenceControllerTest {
assertThat(mController.isChecked()).isTrue(); assertThat(mController.isChecked()).isTrue();
} }
@Test
public void isChecked_flagsDisabled_shouldReturnFalse() {
enableFlags(false);
// Hardware support is enabled
doReturn(true).when(mTelephonyManager).isNullCipherNotificationsEnabled();
doReturn(true).when(mTelephonyManager)
.isCellularIdentifierDisclosureNotificationsEnabled();
assertThat(mController.isChecked()).isFalse();
}
@Test @Test
public void isChecked_hardwareUnsupported_shouldReturnFalse() { public void isChecked_hardwareUnsupported_shouldReturnFalse() {
enableFlags(true); enableFlags(true);