Snap for 13033097 from 60c6d8ead5 to 25Q2-release
Change-Id: I49b6f959f5bc734783f87ce624b09b4f131da9ab
This commit is contained in:
78
res/layout/dialog_autoclick_cursor_area_size.xml
Normal file
78
res/layout/dialog_autoclick_cursor_area_size.xml
Normal 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>
|
||||
@@ -1673,6 +1673,9 @@
|
||||
<!-- 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>
|
||||
|
||||
<!-- 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] -->
|
||||
<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>
|
||||
|
||||
<!-- 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]-->
|
||||
<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] -->
|
||||
<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. -->
|
||||
<!-- 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]-->
|
||||
<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]-->
|
||||
@@ -5638,12 +5643,27 @@
|
||||
<string name="accessibility_autoclick_longer_desc">Longer</string>
|
||||
<!-- Description for the seekbar that adjust auto click time. [CHAR_LIMIT=NONE] -->
|
||||
<string name="accessibility_autoclick_seekbar_desc">Auto click time</string>
|
||||
<!-- Title for the seekbar that adjust auto click cursor area size. [CHAR_LIMIT=NONE] -->
|
||||
<!-- TODO(b/383901288): Update string to translatable once approved by UXW. -->
|
||||
<string name="autoclick_cursor_area_size_title" translatable="false">Cursor area size</string>
|
||||
<!-- Summary for the seekbar that adjust auto click cursor area size. [CHAR_LIMIT=NONE] -->
|
||||
<!-- TODO(b/383901288): 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>
|
||||
<!-- Title for the alert dialog that adjust auto click cursor area size. [CHAR_LIMIT=NONE] -->
|
||||
<!-- TODO(b/394683600): Update string to translatable once approved by UXW. -->
|
||||
<string name="autoclick_cursor_area_size_title" translatable="false">Click area</string>
|
||||
<!-- Summary for the alert dialog that adjust auto click cursor area size. [CHAR_LIMIT=NONE] -->
|
||||
<!-- TODO(b/394683600): Update string to translatable once approved by UXW. -->
|
||||
<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] -->
|
||||
<!-- 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>
|
||||
|
||||
@@ -710,6 +710,14 @@
|
||||
<item name="android:textSize">14sp</item>
|
||||
</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"
|
||||
parent="@android:style/Widget.DeviceDefault.PopupWindow">
|
||||
<item name="android:clipToPadding">true</item>
|
||||
|
||||
@@ -76,13 +76,12 @@
|
||||
settings:searchable="false"
|
||||
settings:controller="com.android.settings.accessibility.ToggleAutoclickCustomSeekbarController"/>
|
||||
|
||||
<com.android.settingslib.widget.SliderPreference
|
||||
<Preference
|
||||
android:key="accessibility_control_autoclick_cursor_area_size"
|
||||
android:title="@string/autoclick_cursor_area_size_title"
|
||||
android:summary="@string/autoclick_cursor_area_size_summary"
|
||||
android:selectable="false"
|
||||
android:persistent="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
|
||||
android:key="accessibility_control_autoclick_ignore_minor_cursor_movement"
|
||||
|
||||
@@ -20,37 +20,27 @@
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
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
|
||||
android:key="mouse_pointer_acceleration"
|
||||
android:title="@string/mouse_pointer_acceleration"
|
||||
android:summary="@string/mouse_pointer_acceleration_summary"
|
||||
android:order="10"
|
||||
settings:controller="com.android.settings.inputmethod.MousePointerAccelerationPreferenceController" />
|
||||
|
||||
<com.android.settings.widget.SeekBarPreference
|
||||
android:key="trackpad_pointer_speed"
|
||||
android:title="@string/trackpad_pointer_speed"
|
||||
android:order="40"
|
||||
android:order="20"
|
||||
android:selectable="false"
|
||||
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
|
||||
android:fragment="com.android.settings.inputmethod.PointerTouchpadFragment"
|
||||
android:key="accessibility_pointer_and_touchpad"
|
||||
@@ -60,17 +50,32 @@
|
||||
android:summary="@string/accessibility_pointer_and_touchpad_summary"
|
||||
settings:searchable="true"/>
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:key="mouse_scrolling_acceleration"
|
||||
android:title="@string/mouse_scrolling_acceleration"
|
||||
android:order="55"
|
||||
settings:controller="com.android.settings.inputmethod.MouseScrollingAccelerationPreferenceController" />
|
||||
<PreferenceCategory
|
||||
android:key="pointer_category"
|
||||
android:persistent="false"
|
||||
android:order="51"
|
||||
android:title="@string/mouse_scrolling_category_title">
|
||||
|
||||
<com.android.settings.widget.SeekBarPreference
|
||||
android:key="mouse_scrolling_speed"
|
||||
android:title="@string/mouse_scrolling_speed"
|
||||
android:order="60"
|
||||
android:selectable="false"
|
||||
settings:controller="com.android.settings.inputmethod.MouseScrollingSpeedPreferenceController"/>
|
||||
<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:title="@string/mouse_scrolling_acceleration"
|
||||
settings:controller="com.android.settings.inputmethod.MouseScrollingAccelerationPreferenceController" />
|
||||
|
||||
<com.android.settings.widget.SeekBarPreference
|
||||
android:key="mouse_scrolling_speed"
|
||||
android:title="@string/mouse_scrolling_speed"
|
||||
android:order="60"
|
||||
android:selectable="false"
|
||||
settings:controller="com.android.settings.inputmethod.MouseScrollingSpeedPreferenceController"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
|
||||
<PreferenceCategory
|
||||
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">
|
||||
|
||||
<!-- available in pattern -->
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
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_MIN;
|
||||
|
||||
@@ -25,35 +24,51 @@ import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.widget.RadioGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
import androidx.lifecycle.OnLifecycleEvent;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.server.accessibility.Flags;
|
||||
import com.android.settings.core.SliderPreferenceController;
|
||||
import com.android.settingslib.widget.SliderPreference;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
|
||||
/** Controller class that controls accessibility autoclick cursor area size settings. */
|
||||
public class ToggleAutoclickCursorAreaSizeController extends SliderPreferenceController
|
||||
public class ToggleAutoclickCursorAreaSizeController extends BasePreferenceController
|
||||
implements LifecycleObserver, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
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 SharedPreferences mSharedPreferences;
|
||||
private SliderPreference mPreference;
|
||||
private Preference mPreference;
|
||||
protected AlertDialog mAlertDialog;
|
||||
|
||||
public ToggleAutoclickCursorAreaSizeController(@NonNull Context context,
|
||||
@NonNull String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
|
||||
mContentResolver = context.getContentResolver();
|
||||
mSharedPreferences = context.getSharedPreferences(context.getPackageName(), MODE_PRIVATE);
|
||||
constructDialog(context);
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_START)
|
||||
@@ -71,15 +86,55 @@ public class ToggleAutoclickCursorAreaSizeController extends SliderPreferenceCon
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(@NonNull PreferenceScreen screen) {
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
|
||||
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
|
||||
@@ -94,29 +149,31 @@ public class ToggleAutoclickCursorAreaSizeController extends SliderPreferenceCon
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setSliderPosition(int position) {
|
||||
int size = validateSize(position);
|
||||
Settings.Secure.putInt(
|
||||
mContentResolver, Settings.Secure.ACCESSIBILITY_AUTOCLICK_CURSOR_AREA_SIZE, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSliderPosition() {
|
||||
int size = Settings.Secure.getInt(mContentResolver,
|
||||
public CharSequence getSummary() {
|
||||
int autoclickCursorSize = validateSize(Settings.Secure.getInt(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_AUTOCLICK_CURSOR_AREA_SIZE,
|
||||
AccessibilityManager.AUTOCLICK_CURSOR_AREA_SIZE_DEFAULT);
|
||||
return validateSize(size);
|
||||
AccessibilityManager.AUTOCLICK_CURSOR_AREA_SIZE_DEFAULT));
|
||||
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;
|
||||
}
|
||||
|
||||
return mContext.getString(summaryStringId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMax() {
|
||||
return AUTOCLICK_CURSOR_AREA_SIZE_MAX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMin() {
|
||||
return AUTOCLICK_CURSOR_AREA_SIZE_MIN;
|
||||
/** Updates autoclick cursor area size. */
|
||||
public void updateAutoclickCursorAreaSize(int size) {
|
||||
Settings.Secure.putInt(
|
||||
mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_AUTOCLICK_CURSOR_AREA_SIZE,
|
||||
validateSize(size));
|
||||
refreshSummary(mPreference);
|
||||
}
|
||||
|
||||
private int validateSize(int size) {
|
||||
|
||||
@@ -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.RESULT_CONSENT_DENIED;
|
||||
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;
|
||||
|
||||
@@ -53,6 +54,7 @@ import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SetupWizardUtils;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.biometrics.combination.CombinedBiometricStatusUtils;
|
||||
import com.android.settings.core.InstrumentedActivity;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.password.ChooseLockGeneric;
|
||||
@@ -131,6 +133,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
private Bundle mParentalOptions;
|
||||
@Nullable private Long mGkPwHandle;
|
||||
@Nullable private ParentalConsentHelper mParentalConsentHelper;
|
||||
private boolean mIsPreviousEnrollmentCanceled = false;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
@@ -531,6 +534,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
} else {
|
||||
Log.d(TAG, "Unknown result for set/choose lock: " + resultCode);
|
||||
setResult(resultCode, newResultIntent());
|
||||
notifySafetyIssueActionLaunchedIfNeeded(resultCode);
|
||||
finish();
|
||||
}
|
||||
break;
|
||||
@@ -549,16 +553,21 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
// SetupFingerprintEnroll*/FingerprintEnrollmentActivity to
|
||||
// SetupFaceEnrollIntroduction
|
||||
TransitionHelper.applyForwardTransition(this, TRANSITION_FADE_THROUGH);
|
||||
mIsPreviousEnrollmentCanceled =
|
||||
resultCode != BiometricEnrollBase.RESULT_FINISHED;
|
||||
launchFaceOnlyEnroll();
|
||||
} else {
|
||||
notifySafetyIssueActionLaunchedIfNeeded(resultCode);
|
||||
finishOrLaunchHandToParent(resultCode);
|
||||
}
|
||||
break;
|
||||
case REQUEST_SINGLE_ENROLL_FACE:
|
||||
mIsSingleEnrolling = false;
|
||||
if (resultCode == Activity.RESULT_CANCELED && mIsFingerprintEnrollable) {
|
||||
mIsPreviousEnrollmentCanceled = true;
|
||||
launchFingerprintOnlyEnroll();
|
||||
} else {
|
||||
notifySafetyIssueActionLaunchedIfNeeded(resultCode);
|
||||
finishOrLaunchHandToParent(resultCode);
|
||||
}
|
||||
break;
|
||||
@@ -742,6 +751,15 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
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
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.BIOMETRIC_ENROLL_ACTIVITY;
|
||||
|
||||
@@ -3,7 +3,6 @@ set noparent
|
||||
|
||||
graciecheng@google.com
|
||||
ilyamaty@google.com
|
||||
jaggies@google.com
|
||||
jbolinger@google.com
|
||||
jeffpu@google.com
|
||||
joshmccloskey@google.com
|
||||
|
||||
@@ -36,6 +36,13 @@ import com.android.settingslib.utils.StringUtil;
|
||||
*/
|
||||
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 Context mContext;
|
||||
@Nullable
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
|
||||
package com.android.settings.biometrics.face
|
||||
|
||||
import android.app.ComponentCaller
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
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
|
||||
|
||||
@@ -46,9 +49,23 @@ class FaceEnroll: AppCompatActivity() {
|
||||
*/
|
||||
Log.d("FaceEnroll", "forward to $nextActivityClass")
|
||||
val nextIntent = Intent(this, nextActivityClass)
|
||||
nextIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT)
|
||||
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()
|
||||
}
|
||||
}
|
||||
@@ -16,10 +16,13 @@
|
||||
|
||||
package com.android.settings.biometrics.fingerprint
|
||||
|
||||
import android.app.ComponentCaller
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
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
|
||||
|
||||
/**
|
||||
@@ -69,9 +72,24 @@ open class FingerprintEnroll: AppCompatActivity() {
|
||||
*/
|
||||
Log.d("FingerprintEnroll", "forward to $nextActivityClass")
|
||||
val nextIntent = Intent(this, nextActivityClass)
|
||||
nextIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT)
|
||||
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()
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package com.android.settings.connecteddevice
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.settings.SettingsEnums.ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE
|
||||
import android.bluetooth.BluetoothAdapter
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
@@ -27,8 +28,10 @@ import android.os.UserManager
|
||||
import android.provider.Settings
|
||||
import android.widget.Toast
|
||||
import androidx.preference.Preference
|
||||
import com.android.settings.PreferenceActionMetricsProvider
|
||||
import com.android.settings.PreferenceRestrictionMixin
|
||||
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.SatelliteWarningDialogActivity
|
||||
import com.android.settings.widget.MainSwitchBarMetadata
|
||||
@@ -43,7 +46,10 @@ import com.android.settingslib.metadata.SensitivityLevel
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
class BluetoothPreference(private val bluetoothDataStore: BluetoothDataStore) :
|
||||
MainSwitchBarMetadata, PreferenceRestrictionMixin, Preference.OnPreferenceChangeListener {
|
||||
MainSwitchBarMetadata,
|
||||
PreferenceActionMetricsProvider,
|
||||
PreferenceRestrictionMixin,
|
||||
Preference.OnPreferenceChangeListener {
|
||||
|
||||
override val key
|
||||
get() = KEY
|
||||
@@ -51,6 +57,11 @@ class BluetoothPreference(private val bluetoothDataStore: BluetoothDataStore) :
|
||||
override val 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>
|
||||
get() = arrayOf(UserManager.DISALLOW_BLUETOOTH, UserManager.DISALLOW_CONFIG_BLUETOOTH)
|
||||
|
||||
|
||||
@@ -334,12 +334,15 @@ class DisplayTopologyPreference(context : Context)
|
||||
* @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 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(
|
||||
val stationaryDisps : List<Pair<Int, RectF>>,
|
||||
val display: DisplayBlock, val displayId: Int,
|
||||
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 mDrag : BlockDrag? = null
|
||||
@@ -369,7 +372,7 @@ class DisplayTopologyPreference(context : Context)
|
||||
applyTopology(topology)
|
||||
}
|
||||
|
||||
@VisibleForTesting var mTimesReceivedSameTopology = 0
|
||||
@VisibleForTesting var mTimesRefreshedBlocks = 0
|
||||
|
||||
private fun applyTopology(topology: DisplayTopology) {
|
||||
mTopologyHint.text = context.getString(R.string.external_display_topology_hint)
|
||||
@@ -386,7 +389,6 @@ class DisplayTopologyPreference(context : Context)
|
||||
oldBounds.zip(newBounds).all { (old, new) ->
|
||||
old.first == new.first && sameDisplayPosition(old.second, new.second)
|
||||
}) {
|
||||
mTimesReceivedSameTopology++
|
||||
return
|
||||
}
|
||||
|
||||
@@ -438,6 +440,7 @@ class DisplayTopologyPreference(context : Context)
|
||||
}
|
||||
}
|
||||
mPaneContent.removeViews(newBounds.size, recycleableBlocks.size)
|
||||
mTimesRefreshedBlocks++
|
||||
|
||||
mTopologyInfo = TopologyInfo(topology, scaling, newBounds)
|
||||
|
||||
@@ -481,6 +484,7 @@ class DisplayTopologyPreference(context : Context)
|
||||
val snapRect = clampPosition(drag.stationaryDisps.map { it.second }, dispDragRect)
|
||||
|
||||
drag.display.place(topology.scaling.displayToPaneCoor(snapRect.left, snapRect.top))
|
||||
drag.didMove = true
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -491,6 +495,15 @@ class DisplayTopologyPreference(context : Context)
|
||||
mPaneContent.requestDisallowInterceptTouchEvent(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(
|
||||
drag.display.x, drag.display.y)
|
||||
val newTopology = topology.topology.copy()
|
||||
@@ -499,9 +512,15 @@ class DisplayTopologyPreference(context : Context)
|
||||
|
||||
val arr = hashMapOf(*newPositions.toTypedArray())
|
||||
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
|
||||
|
||||
refreshPane()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,3 +47,42 @@ const val KEY_ADAPTIVE_BRIGHTNESS = "auto_brightness"
|
||||
|
||||
/** Contract key for the "Screen attention" setting. */
|
||||
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"
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.settings.display
|
||||
|
||||
import android.app.settings.SettingsEnums.ACTION_SCREEN_ATTENTION_CHANGED
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
@@ -26,8 +27,10 @@ import android.hardware.SensorPrivacyManager.Sensors.CAMERA
|
||||
import android.os.PowerManager
|
||||
import android.os.UserManager
|
||||
import android.provider.Settings
|
||||
import com.android.settings.PreferenceActionMetricsProvider
|
||||
import com.android.settings.PreferenceRestrictionMixin
|
||||
import com.android.settings.R
|
||||
import com.android.settings.contract.KEY_SCREEN_ATTENTION
|
||||
import com.android.settingslib.RestrictedSwitchPreference
|
||||
import com.android.settingslib.datastore.KeyValueStore
|
||||
import com.android.settingslib.datastore.KeyedObservableDelegate
|
||||
@@ -46,6 +49,7 @@ import com.android.settingslib.preference.SwitchPreferenceBinding
|
||||
class AdaptiveSleepPreference :
|
||||
BooleanValuePreference,
|
||||
SwitchPreferenceBinding,
|
||||
PreferenceActionMetricsProvider,
|
||||
PreferenceLifecycleProvider,
|
||||
PreferenceBindingPlaceholder, // not needed once controller class is cleaned up
|
||||
PreferenceAvailabilityProvider,
|
||||
@@ -63,6 +67,11 @@ class AdaptiveSleepPreference :
|
||||
override val summary: Int
|
||||
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 isEnabled(context: Context) =
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.os.UserManager
|
||||
import android.provider.Settings.Secure.DOZE_ALWAYS_ON
|
||||
import com.android.settings.PreferenceRestrictionMixin
|
||||
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.settingslib.datastore.AbstractKeyedDataObservable
|
||||
import com.android.settingslib.datastore.HandlerExecutor
|
||||
@@ -123,7 +124,7 @@ class AmbientDisplayAlwaysOnPreference :
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.android.settings.display
|
||||
|
||||
import android.app.settings.SettingsEnums.ACTION_ADAPTIVE_BRIGHTNESS
|
||||
import android.content.Context
|
||||
import android.os.UserManager
|
||||
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 androidx.preference.Preference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import com.android.settings.PreferenceActionMetricsProvider
|
||||
import com.android.settings.PreferenceRestrictionMixin
|
||||
import com.android.settings.R
|
||||
import com.android.settings.contract.KEY_ADAPTIVE_BRIGHTNESS
|
||||
import com.android.settings.flags.Flags
|
||||
import com.android.settingslib.PrimarySwitchPreferenceBinding
|
||||
import com.android.settingslib.datastore.AbstractKeyedDataObservable
|
||||
@@ -47,6 +50,7 @@ class AutoBrightnessScreen :
|
||||
PreferenceScreenCreator,
|
||||
PreferenceScreenBinding, // binding for screen page
|
||||
PrimarySwitchPreferenceBinding, // binding for screen entry point widget
|
||||
PreferenceActionMetricsProvider,
|
||||
PreferenceAvailabilityProvider,
|
||||
PreferenceRestrictionMixin,
|
||||
BooleanValuePreference {
|
||||
@@ -56,6 +60,11 @@ class AutoBrightnessScreen :
|
||||
override val title: Int
|
||||
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 fragmentClass() = AutoBrightnessSettings::class.java
|
||||
|
||||
@@ -152,8 +152,8 @@ public class BatteryOptimizeUtils {
|
||||
}
|
||||
|
||||
/** Sets the {@link OptimizationMode} for associated app. */
|
||||
public void setAppUsageState(@OptimizationMode int mode, Action action) {
|
||||
if (getAppOptimizationMode() == mode) {
|
||||
public void setAppUsageState(@OptimizationMode int mode, Action action, boolean forceMode) {
|
||||
if (!forceMode && getAppOptimizationMode() == mode) {
|
||||
Log.w(TAG, "set the same optimization mode for: " + mPackageName);
|
||||
return;
|
||||
}
|
||||
@@ -161,6 +161,11 @@ public class BatteryOptimizeUtils {
|
||||
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. */
|
||||
public boolean isDisabledForOptimizeModeOnly() {
|
||||
return getForceBatteryOptimizeModeList(mContext).contains(mPackageName)
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settings.fuelgauge;
|
||||
|
||||
import static com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_UNRESTRICTED;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
@@ -24,20 +26,25 @@ import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.os.PowerWhitelistManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.app.AlertActivity;
|
||||
import com.android.internal.app.AlertController;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action;
|
||||
|
||||
public class RequestIgnoreBatteryOptimizations extends AlertActivity
|
||||
implements DialogInterface.OnClickListener {
|
||||
private static final String TAG = "RequestIgnoreBatteryOptimizations";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private PowerWhitelistManager mPowerWhitelistManager;
|
||||
private String mPackageName;
|
||||
@VisibleForTesting
|
||||
static BatteryOptimizeUtils sTestBatteryOptimizeUtils = null;
|
||||
|
||||
private ApplicationInfo mApplicationInfo;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
@@ -47,8 +54,6 @@ public class RequestIgnoreBatteryOptimizations extends AlertActivity
|
||||
android.view.WindowManager.LayoutParams
|
||||
.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
|
||||
|
||||
mPowerWhitelistManager = getSystemService(PowerWhitelistManager.class);
|
||||
|
||||
Uri data = getIntent().getData();
|
||||
if (data == null) {
|
||||
debugLog(
|
||||
@@ -56,17 +61,18 @@ public class RequestIgnoreBatteryOptimizations extends AlertActivity
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
mPackageName = data.getSchemeSpecificPart();
|
||||
if (mPackageName == null) {
|
||||
final String packageName = data.getSchemeSpecificPart();
|
||||
if (TextUtils.isEmpty(packageName)) {
|
||||
debugLog(
|
||||
"No data supplied for IGNORE_BATTERY_OPTIMIZATION_SETTINGS in: " + getIntent());
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// Package in Unrestricted mode already ignoring the battery optimizations.
|
||||
PowerManager power = getSystemService(PowerManager.class);
|
||||
if (power.isIgnoringBatteryOptimizations(mPackageName)) {
|
||||
debugLog("Not should prompt, already ignoring optimizations: " + mPackageName);
|
||||
if (power.isIgnoringBatteryOptimizations(packageName)) {
|
||||
debugLog("Not should prompt, already ignoring optimizations: " + packageName);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
@@ -74,29 +80,28 @@ public class RequestIgnoreBatteryOptimizations extends AlertActivity
|
||||
if (getPackageManager()
|
||||
.checkPermission(
|
||||
Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
|
||||
mPackageName)
|
||||
packageName)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
debugLog(
|
||||
"Requested package "
|
||||
+ mPackageName
|
||||
+ packageName
|
||||
+ " does not hold permission "
|
||||
+ Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
ApplicationInfo ai;
|
||||
try {
|
||||
ai = getPackageManager().getApplicationInfo(mPackageName, 0);
|
||||
mApplicationInfo = getPackageManager().getApplicationInfo(packageName, 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
debugLog("Requested package doesn't exist: " + mPackageName);
|
||||
debugLog("Requested package doesn't exist: " + packageName);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
final AlertController.AlertParams p = mAlertParams;
|
||||
final CharSequence appLabel =
|
||||
ai.loadSafeLabel(
|
||||
mApplicationInfo.loadSafeLabel(
|
||||
getPackageManager(),
|
||||
PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX,
|
||||
PackageItemInfo.SAFE_LABEL_FLAG_TRIM
|
||||
@@ -114,7 +119,15 @@ public class RequestIgnoreBatteryOptimizations extends AlertActivity
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
switch (which) {
|
||||
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;
|
||||
case BUTTON_NEGATIVE:
|
||||
break;
|
||||
|
||||
@@ -16,9 +16,12 @@
|
||||
package com.android.settings.fuelgauge.batterysaver
|
||||
|
||||
import android.Manifest
|
||||
import android.app.settings.SettingsEnums.ACTION_BATTERY_SAVER
|
||||
import android.content.Context
|
||||
import android.os.PowerManager
|
||||
import com.android.settings.PreferenceActionMetricsProvider
|
||||
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.BatterySaverListener
|
||||
import com.android.settingslib.datastore.AbstractKeyedDataObservable
|
||||
@@ -40,7 +43,13 @@ import kotlinx.coroutines.launch
|
||||
|
||||
// LINT.IfChange
|
||||
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)
|
||||
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
asalo@google.com
|
||||
lifu@google.com
|
||||
mstogaitis@google.com
|
||||
palanki@google.com
|
||||
sooniln@google.com
|
||||
weiwa@google.com
|
||||
wyattriley@google.com
|
||||
|
||||
# Emergency approvers in case the above are not available
|
||||
# Emergency approvers in case the above are not available
|
||||
|
||||
@@ -17,9 +17,12 @@
|
||||
package com.android.settings.network
|
||||
|
||||
import android.Manifest
|
||||
import android.app.settings.SettingsEnums.ACTION_MOBILE_DATA
|
||||
import android.content.Context
|
||||
import android.telephony.SubscriptionManager
|
||||
import com.android.settings.PreferenceActionMetricsProvider
|
||||
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.SubscriptionRepository
|
||||
import com.android.settingslib.datastore.KeyValueStore
|
||||
@@ -38,8 +41,14 @@ class MobileDataPreference :
|
||||
R.string.mobile_data_settings_title,
|
||||
R.string.mobile_data_settings_summary,
|
||||
),
|
||||
PreferenceActionMetricsProvider,
|
||||
PreferenceAvailabilityProvider {
|
||||
|
||||
override val preferenceActionMetrics: Int
|
||||
get() = ACTION_MOBILE_DATA
|
||||
|
||||
override fun tags(context: Context) = arrayOf(KEY_MOBILE_DATA)
|
||||
|
||||
override fun isAvailable(context: Context) =
|
||||
SubscriptionRepository(context).getSelectableSubscriptionInfoList().any {
|
||||
it.simSlotIndex > -1
|
||||
@@ -59,7 +68,7 @@ class MobileDataPreference :
|
||||
override fun getWritePermissions(context: Context) =
|
||||
Permissions.allOf(
|
||||
// TelephonyManager.setDataEnabledForReason
|
||||
Manifest.permission.MODIFY_PHONE_STATE,
|
||||
Manifest.permission.MODIFY_PHONE_STATE
|
||||
)
|
||||
|
||||
override fun getReadPermit(context: Context, callingPid: Int, callingUid: Int) =
|
||||
|
||||
@@ -171,7 +171,7 @@ public class CustomSliceRegistry {
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.appendPath("call_volume")
|
||||
.appendPath(SettingsContractKt.KEY_CALL_VOLUME)
|
||||
.build();
|
||||
/**
|
||||
* Full {@link Uri} for the Media Volume Slice.
|
||||
@@ -180,7 +180,7 @@ public class CustomSliceRegistry {
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.appendPath("media_volume")
|
||||
.appendPath(SettingsContractKt.KEY_MEDIA_VOLUME)
|
||||
.build();
|
||||
|
||||
/**
|
||||
@@ -190,7 +190,7 @@ public class CustomSliceRegistry {
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.appendPath("separate_ring_volume")
|
||||
.appendPath(SettingsContractKt.KEY_RING_VOLUME)
|
||||
.build();
|
||||
|
||||
/**
|
||||
@@ -268,7 +268,7 @@ public class CustomSliceRegistry {
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.appendPath("dark_theme")
|
||||
.appendPath(SettingsContractKt.KEY_DARK_THEME)
|
||||
.build();
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.wifi
|
||||
|
||||
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_ON
|
||||
import android.content.BroadcastReceiver
|
||||
@@ -29,8 +30,10 @@ import android.provider.Settings
|
||||
import android.widget.Toast
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.Preference.OnPreferenceChangeListener
|
||||
import com.android.settings.PreferenceActionMetricsProvider
|
||||
import com.android.settings.PreferenceRestrictionMixin
|
||||
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.SatelliteWarningDialogActivity
|
||||
import com.android.settings.overlay.FeatureFactory.Companion.featureFactory
|
||||
@@ -54,6 +57,7 @@ import com.android.settingslib.preference.SwitchPreferenceBinding
|
||||
class WifiSwitchPreference :
|
||||
SwitchPreference(KEY, R.string.wifi),
|
||||
SwitchPreferenceBinding,
|
||||
PreferenceActionMetricsProvider,
|
||||
OnPreferenceChangeListener,
|
||||
PreferenceLifecycleProvider,
|
||||
PreferenceRestrictionMixin {
|
||||
@@ -61,6 +65,11 @@ class WifiSwitchPreference :
|
||||
override val keywords: Int
|
||||
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 val restrictionKeys
|
||||
|
||||
@@ -19,12 +19,15 @@ package com.android.settings.wifi.calling
|
||||
import android.Manifest.permission.MODIFY_PHONE_STATE
|
||||
import android.Manifest.permission.READ_PRECISE_PHONE_STATE
|
||||
import android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE
|
||||
import android.app.settings.SettingsEnums.ACTION_WIFI_CALLING
|
||||
import android.content.Context
|
||||
import android.telephony.SubscriptionManager
|
||||
import android.telephony.TelephonyManager
|
||||
import android.telephony.ims.ImsMmTelManager
|
||||
import android.util.Log
|
||||
import com.android.settings.PreferenceActionMetricsProvider
|
||||
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.telephony.wificalling.WifiCallingRepository
|
||||
import com.android.settings.widget.SettingsMainSwitchPreference
|
||||
@@ -47,7 +50,10 @@ import kotlinx.coroutines.runBlocking
|
||||
* TODO(b/372732219): apply metadata to UI
|
||||
*/
|
||||
class WifiCallingMainSwitchPreference(private val subId: Int) :
|
||||
BooleanValuePreference, BooleanValuePreferenceBinding, PreferenceAvailabilityProvider {
|
||||
BooleanValuePreference,
|
||||
BooleanValuePreferenceBinding,
|
||||
PreferenceActionMetricsProvider,
|
||||
PreferenceAvailabilityProvider {
|
||||
|
||||
override val key: String
|
||||
get() = KEY
|
||||
@@ -55,6 +61,11 @@ class WifiCallingMainSwitchPreference(private val subId: Int) :
|
||||
override val title: Int
|
||||
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) =
|
||||
context.isCallStateIdle(subId) &&
|
||||
WifiCallingQueryImsState(context, subId).isAllowUserControl
|
||||
|
||||
@@ -16,55 +16,60 @@
|
||||
|
||||
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 org.mockito.ArgumentMatchers.anyInt;
|
||||
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 static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.platform.test.annotations.DisableFlags;
|
||||
import android.platform.test.annotations.EnableFlags;
|
||||
import android.platform.test.flag.junit.SetFlagsRule;
|
||||
import android.provider.Settings;
|
||||
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 com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settingslib.widget.SliderPreference;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowLooper;
|
||||
|
||||
/** Tests for {@link ToggleAutoclickCursorAreaSizeController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
com.android.settings.testutils.shadow.ShadowFragment.class,
|
||||
ShadowAlertDialogCompat.class,
|
||||
})
|
||||
public class ToggleAutoclickCursorAreaSizeControllerTest {
|
||||
|
||||
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 MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Mock
|
||||
private Preference mPreference;
|
||||
private Context mContext;
|
||||
private ToggleAutoclickCursorAreaSizeController mController;
|
||||
|
||||
@Before
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -75,6 +80,15 @@ public class ToggleAutoclickCursorAreaSizeControllerTest {
|
||||
.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
|
||||
@DisableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR)
|
||||
public void getAvailabilityStatus_conditionallyUnavailableWhenFlagOn() {
|
||||
@@ -83,90 +97,48 @@ public class ToggleAutoclickCursorAreaSizeControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStart_registerOnSharedPreferenceChangeListener() {
|
||||
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);
|
||||
public void handlePreferenceTreeClick_dialogShows() {
|
||||
mController.handlePreferenceTreeClick(mPreference);
|
||||
|
||||
controller.onStart();
|
||||
AlertDialog alertDialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
|
||||
verify(prefs).registerOnSharedPreferenceChangeListener(controller);
|
||||
}
|
||||
|
||||
@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);
|
||||
assertThat(alertDialog.isShowing()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR)
|
||||
public void getProgress_matchesSetting_inRangeValue() {
|
||||
// TODO(388844952): Use parameter testing.
|
||||
for (int size : ImmutableList.of(20, 40, 60, 80, 100)) {
|
||||
updateSetting(size);
|
||||
updateSetting(mController.RADIO_BUTTON_ID_TO_CURSOR_SIZE.get(
|
||||
R.id.autoclick_cursor_area_size_value_extra_large));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
assertThat(radioGroup.getCheckedRadioButtonId())
|
||||
.isEqualTo(R.id.autoclick_cursor_area_size_value_extra_large);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setProgress_updatesSetting_inRangeValue() {
|
||||
// TODO(388844952): Use parameter testing.
|
||||
for (int position : ImmutableList.of(20, 40, 60, 80, 100)) {
|
||||
mController.setSliderPosition(position);
|
||||
mController.handlePreferenceTreeClick(mPreference);
|
||||
AlertDialog alertDialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setProgress_updatesSetting_aboveMaxValue() {
|
||||
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());
|
||||
mController.handlePreferenceTreeClick(mPreference);
|
||||
ShadowLooper.idleMainLooper();
|
||||
radioGroup.check(R.id.autoclick_cursor_area_size_value_extra_small);
|
||||
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick();
|
||||
ShadowLooper.idleMainLooper();
|
||||
assertThat(readSetting()).isEqualTo(20);
|
||||
}
|
||||
|
||||
private int readSetting() {
|
||||
|
||||
@@ -68,7 +68,6 @@ class FaceEnrollTest {
|
||||
currentActivityInstance : FaceEnroll,
|
||||
nextActivityClass: Class<out Activity>
|
||||
) {
|
||||
Truth.assertThat(currentActivityInstance.isFinishing).isTrue()
|
||||
val nextActivityIntent = Shadows.shadowOf(currentActivityInstance).nextStartedActivity
|
||||
assertThat(nextActivityIntent.component!!.className).isEqualTo(nextActivityClass.name)
|
||||
assertThat(nextActivityIntent.extras!!.size()).isEqualTo(1)
|
||||
|
||||
@@ -95,7 +95,6 @@ class FingerprintEnrollTest {
|
||||
currentActivityInstance : FingerprintEnroll,
|
||||
nextActivityClass: Class<out Activity>
|
||||
) {
|
||||
assertThat(currentActivityInstance.isFinishing).isTrue()
|
||||
val nextActivityIntent = Shadows.shadowOf(currentActivityInstance).nextStartedActivity
|
||||
assertThat(nextActivityIntent.component!!.className).isEqualTo(nextActivityClass.name)
|
||||
assertThat(nextActivityIntent.extras!!.size()).isEqualTo(1)
|
||||
|
||||
@@ -186,6 +186,8 @@ class DisplayTopologyPreferenceTest {
|
||||
fun dragDisplayDownward() {
|
||||
val (leftBlock, _) = setupTwoDisplays()
|
||||
|
||||
preference.mTimesRefreshedBlocks = 0
|
||||
|
||||
val downEvent = MotionEventBuilder.newBuilder()
|
||||
.setPointer(0f, 0f)
|
||||
.setAction(MotionEvent.ACTION_DOWN)
|
||||
@@ -208,12 +210,16 @@ class DisplayTopologyPreferenceTest {
|
||||
val child = rootChildren[0]
|
||||
assertThat(child.position).isEqualTo(POSITION_LEFT)
|
||||
assertThat(child.offset).isWithin(1f).of(82f)
|
||||
|
||||
assertThat(preference.mTimesRefreshedBlocks).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dragRootDisplayToNewSide() {
|
||||
val (leftBlock, rightBlock) = setupTwoDisplays()
|
||||
|
||||
preference.mTimesRefreshedBlocks = 0
|
||||
|
||||
val downEvent = MotionEventBuilder.newBuilder()
|
||||
.setAction(MotionEvent.ACTION_DOWN)
|
||||
.setPointer(0f, 0f)
|
||||
@@ -251,6 +257,32 @@ class DisplayTopologyPreferenceTest {
|
||||
assertThat(paneChildren[0].x)
|
||||
.isWithin(1f)
|
||||
.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
|
||||
@@ -269,13 +301,15 @@ class DisplayTopologyPreferenceTest {
|
||||
@Test
|
||||
fun applyNewTopologyViaListenerUpdate() {
|
||||
setupTwoDisplays()
|
||||
|
||||
preference.mTimesRefreshedBlocks = 0
|
||||
val newTopology = injector.topology!!.copy()
|
||||
newTopology.addDisplay(/* displayId= */ 8008, /* width= */ 300f, /* height= */ 320f)
|
||||
|
||||
injector.topology = newTopology
|
||||
injector.topologyListener!!.accept(newTopology)
|
||||
|
||||
assertThat(preference.mTimesReceivedSameTopology).isEqualTo(0)
|
||||
assertThat(preference.mTimesRefreshedBlocks).isEqualTo(1)
|
||||
val paneChildren = getPaneChildren()
|
||||
assertThat(paneChildren).hasSize(3)
|
||||
|
||||
@@ -293,11 +327,11 @@ class DisplayTopologyPreferenceTest {
|
||||
injector.topology = twoDisplayTopology(POSITION_TOP, /* offset= */ 12.0f)
|
||||
preparePane()
|
||||
|
||||
assertThat(preference.mTimesReceivedSameTopology).isEqualTo(0)
|
||||
preference.mTimesRefreshedBlocks = 0
|
||||
injector.topology = twoDisplayTopology(POSITION_TOP, /* offset= */ 12.1f)
|
||||
injector.topologyListener!!.accept(injector.topology!!)
|
||||
|
||||
assertThat(preference.mTimesReceivedSameTopology).isEqualTo(1)
|
||||
assertThat(preference.mTimesRefreshedBlocks).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -112,42 +112,6 @@ public class CellularSecurityNotificationsPreferenceControllerTest {
|
||||
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
|
||||
public void setChecked_shouldReturnTrue() {
|
||||
enableFlags(true);
|
||||
@@ -174,18 +138,6 @@ public class CellularSecurityNotificationsPreferenceControllerTest {
|
||||
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
|
||||
public void isChecked_hardwareUnsupported_shouldReturnFalse() {
|
||||
enableFlags(true);
|
||||
|
||||
Reference in New Issue
Block a user