Snap for 13033097 from 60c6d8ead5 to 25Q2-release

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

View File

@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2025 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="@+id/autoclick_cursor_area_size_dialog_title"
android:text="@string/autoclick_cursor_area_size_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginHorizontal="26dp"
android:textSize="20sp"
android:textColor="?android:attr/textColorPrimary"
android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
/>
<TextView
android:id="@+id/autoclick_cursor_area_size_dialog_subtitle"
android:text="@string/autoclick_cursor_area_size_summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="26dp"
android:layout_marginTop="8dp"
android:textSize="16sp"
android:textColor="?android:attr/textColorSecondary"
/>
<RadioGroup
android:id="@+id/autoclick_cursor_area_size_value_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="16dp">
<RadioButton
android:id="@+id/autoclick_cursor_area_size_value_extra_small"
android:text="@string/autoclick_cursor_area_size_dialog_option_extra_small"
style="@style/AutoclickDialogRadioButton"/>
<RadioButton
android:id="@+id/autoclick_cursor_area_size_value_small"
android:text="@string/autoclick_cursor_area_size_dialog_option_small"
style="@style/AutoclickDialogRadioButton"/>
<RadioButton
android:id="@+id/autoclick_cursor_area_size_value_default"
android:text="@string/autoclick_cursor_area_size_dialog_option_default"
style="@style/AutoclickDialogRadioButton"/>
<RadioButton
android:id="@+id/autoclick_cursor_area_size_value_large"
android:text="@string/autoclick_cursor_area_size_dialog_option_large"
style="@style/AutoclickDialogRadioButton"/>
<RadioButton
android:id="@+id/autoclick_cursor_area_size_value_extra_large"
android:text="@string/autoclick_cursor_area_size_dialog_option_extra_large"
style="@style/AutoclickDialogRadioButton"/>
</RadioGroup>
</LinearLayout>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,224 @@
/*
* Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.fuelgauge;
import static com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_RESTRICTED;
import static com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_UNRESTRICTED;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
import android.Manifest;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.PowerManager;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowUtils.class})
public class RequestIgnoreBatteryOptimizationsTest {
private static final int UID = 12345;
private static final String PACKAGE_NAME = "com.android.app";
private static final String UNKNOWN_PACKAGE_NAME = "com.android.unknown";
private static final String PACKAGE_LABEL = "app";
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
private Context mContext;
private RequestIgnoreBatteryOptimizations mActivity;
private BatteryOptimizeUtils mBatteryOptimizeUtils;
private PowerAllowlistBackend mPowerAllowlistBackend;
@Mock private PowerManager mMockPowerManager;
@Mock private PackageManager mMockPackageManager;
@Mock private ApplicationInfo mMockApplicationInfo;
@Mock private BatteryUtils mMockBatteryUtils;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
mActivity = spy(Robolectric.setupActivity(RequestIgnoreBatteryOptimizations.class));
mBatteryOptimizeUtils = spy(new BatteryOptimizeUtils(mContext, UID, PACKAGE_NAME));
mPowerAllowlistBackend = spy(PowerAllowlistBackend.getInstance(mContext));
mBatteryOptimizeUtils.mPowerAllowListBackend = mPowerAllowlistBackend;
mBatteryOptimizeUtils.mBatteryUtils = mMockBatteryUtils;
RequestIgnoreBatteryOptimizations.sTestBatteryOptimizeUtils = mBatteryOptimizeUtils;
when(mActivity.getApplicationContext()).thenReturn(mContext);
doReturn(mMockPowerManager).when(mActivity).getSystemService(PowerManager.class);
doReturn(mMockPackageManager).when(mActivity).getPackageManager();
doReturn(mMockApplicationInfo)
.when(mMockPackageManager)
.getApplicationInfo(PACKAGE_NAME, 0);
doThrow(new PackageManager.NameNotFoundException(""))
.when(mMockPackageManager)
.getApplicationInfo(UNKNOWN_PACKAGE_NAME, 0);
doReturn(PACKAGE_LABEL)
.when(mMockApplicationInfo)
.loadSafeLabel(
mMockPackageManager,
PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX,
PackageItemInfo.SAFE_LABEL_FLAG_TRIM
| PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE);
doReturn(PackageManager.PERMISSION_GRANTED)
.when(mMockPackageManager)
.checkPermission(
eq(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS), anyString());
}
@After
public void tearDown() {
ShadowUtils.reset();
PowerAllowlistBackend.resetInstance();
}
@Test
public void onCreate_withIntent_shouldNotFinish() {
mActivity.setIntent(createIntent(PACKAGE_NAME));
mActivity.onCreate(new Bundle());
verify(mActivity, never()).finish();
}
@Test
public void onCreate_withNoDataIntent_shouldFinish() {
mActivity.setIntent(new Intent());
mActivity.onCreate(new Bundle());
verify(mActivity).finish();
}
@Test
public void onCreate_withEmptyPackageName_shouldFinish() {
mActivity.setIntent(createIntent(""));
mActivity.onCreate(new Bundle());
verify(mActivity).finish();
}
@Test
public void onCreate_withPkgAlreadyIgnoreOptimization_shouldFinish() {
mActivity.setIntent(createIntent(PACKAGE_NAME));
doReturn(true).when(mMockPowerManager).isIgnoringBatteryOptimizations(PACKAGE_NAME);
mActivity.onCreate(new Bundle());
verify(mActivity).finish();
}
@Test
public void onCreate_withPkgWithoutPermission_shouldFinish() {
mActivity.setIntent(createIntent(PACKAGE_NAME));
doReturn(PackageManager.PERMISSION_DENIED)
.when(mMockPackageManager)
.checkPermission(
Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, PACKAGE_NAME);
mActivity.onCreate(new Bundle());
verify(mActivity).finish();
}
@Test
public void onCreate_withPkgNameNotFound_shouldFinish() {
mActivity.setIntent(createIntent(UNKNOWN_PACKAGE_NAME));
mActivity.onCreate(new Bundle());
verify(mActivity).finish();
}
@Test
public void onClick_clickNegativeButton_doNothing() {
mActivity.onClick(null, DialogInterface.BUTTON_NEGATIVE);
verifyNoInteractions(mBatteryOptimizeUtils);
}
@Test
public void onClick_clickPositiveButtonWithUnrestrictedMode_addAllowlist() {
when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(MODE_UNRESTRICTED);
mActivity.onClick(null, DialogInterface.BUTTON_POSITIVE);
verify(mBatteryOptimizeUtils)
.setAppUsageState(
MODE_UNRESTRICTED,
BatteryOptimizeHistoricalLogEntry.Action.APPLY,
/* forceMode= */ true);
verify(mPowerAllowlistBackend).addApp(PACKAGE_NAME, UID);
verify(mMockBatteryUtils).setForceAppStandby(UID, PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
}
@Test
public void onClick_clickPositiveButtonWithRestrictedMode_addAllowlistAndSetStandby() {
when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(MODE_RESTRICTED);
doNothing().when(mMockBatteryUtils).setForceAppStandby(anyInt(), anyString(), anyInt());
mActivity.onClick(null, DialogInterface.BUTTON_POSITIVE);
verify(mBatteryOptimizeUtils)
.setAppUsageState(
MODE_UNRESTRICTED,
BatteryOptimizeHistoricalLogEntry.Action.APPLY,
/* forceMode= */ true);
verify(mPowerAllowlistBackend).addApp(PACKAGE_NAME, UID);
verify(mMockBatteryUtils).setForceAppStandby(UID, PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
}
private Intent createIntent(String packageName) {
final Intent intent = new Intent();
intent.setData(new Uri.Builder().scheme("package").opaquePart(packageName).build());
return intent;
}
}

View File

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