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] -->
|
<!-- 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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -76,12 +76,11 @@
|
|||||||
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"
|
||||||
|
android:title="@string/autoclick_cursor_area_size_title"
|
||||||
settings:controller="com.android.settings.accessibility.ToggleAutoclickCursorAreaSizeController" />
|
settings:controller="com.android.settings.accessibility.ToggleAutoclickCursorAreaSizeController" />
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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 -->
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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) =
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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) =
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
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);
|
||||||
|
|||||||
Reference in New Issue
Block a user