Snap for 11733120 from 660986353e to 24Q3-release

Change-Id: I4219aabaa0a9a14542a4464fac103e0e7ef563d3
This commit is contained in:
Android Build Coastguard Worker
2024-04-18 23:21:17 +00:00
20 changed files with 338 additions and 113 deletions

View File

@@ -28,3 +28,10 @@ flag {
description: "Feature flag to enable new settings homepage UX."
bug: "321612737"
}
flag {
name: "dynamic_injection_category"
namespace: "android_settings"
description: "Feature flag to enable injection into PreferenceCategory."
bug: "333547416"
}

View File

@@ -4814,6 +4814,8 @@
<!-- Summary for accessibility magnification preference when one finger panning feature is turned off.
The feature when disabled, allows user to move the magnification area by dragging two fingers instead of one. [CHAR LIMIT=60] -->
<string name="accessibility_magnification_one_finger_panning_summary_off">Move the magnification area by dragging two fingers.</string>
<!-- Summary for accessibility magnification preference when one finger panning feature is unavailable while partial-only capability. [CHAR LIMIT=none] -->
<string name="accessibility_magnification_one_finger_panning_summary_unavailable">Unavailable while only magnifying part of the screen</string>
<!-- Title for the accessibility preference screen to enable navigation bar screen magnification. [CHAR LIMIT=35] -->
<string name="accessibility_screen_magnification_navbar_title">Magnify with shortcut</string>
<!-- Summary for the accessibility magnification setting indicating both "Magnify with button" and "Magnify with triple-tap" are enabled [CHAR LIMIT=50] -->

View File

@@ -21,27 +21,43 @@ import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import android.content.Context;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.TwoStatePreference;
import com.android.server.accessibility.Flags;
import com.android.settings.R;
import com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.core.lifecycle.events.OnResume;
public class MagnificationOneFingerPanningPreferenceController
extends TogglePreferenceController {
extends TogglePreferenceController implements LifecycleObserver, OnResume, OnPause {
static final String PREF_KEY = Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED;
@Nullable
private TwoStatePreference mSwitchPreference;
@VisibleForTesting
final boolean mDefaultValue;
@VisibleForTesting
final ContentObserver mContentObserver = new ContentObserver(
new Handler(Looper.getMainLooper())) {
@Override
public void onChange(boolean selfChange, @Nullable Uri uri) {
updateState(mSwitchPreference);
}
};
public MagnificationOneFingerPanningPreferenceController(Context context) {
super(context, PREF_KEY);
boolean defaultValue;
@@ -54,10 +70,19 @@ public class MagnificationOneFingerPanningPreferenceController
mDefaultValue = defaultValue;
}
@Override
public void onResume() {
MagnificationCapabilities.registerObserver(mContext, mContentObserver);
}
@Override
public void onPause() {
MagnificationCapabilities.unregisterObserver(mContext, mContentObserver);
}
@Override
public int getAvailabilityStatus() {
return (Flags.enableMagnificationOneFingerPanningGesture())
? AVAILABLE : DISABLED_FOR_USER;
return AVAILABLE;
}
@Override
@@ -73,14 +98,17 @@ public class MagnificationOneFingerPanningPreferenceController
var toReturn = Settings.Secure.putInt(mContext.getContentResolver(),
PREF_KEY,
(isChecked ? ON : OFF));
if (mSwitchPreference != null) {
refreshSummary(mSwitchPreference);
}
refreshSummary(mSwitchPreference);
return toReturn;
}
@Override
public CharSequence getSummary() {
if (!mSwitchPreference.isEnabled()) {
return mContext.getString(
R.string.accessibility_magnification_one_finger_panning_summary_unavailable);
}
return (isChecked())
? mContext.getString(
R.string.accessibility_magnification_one_finger_panning_summary_on)
@@ -97,6 +125,20 @@ public class MagnificationOneFingerPanningPreferenceController
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mSwitchPreference = screen.findPreference(getPreferenceKey());
refreshSummary(mSwitchPreference);
updateState(mSwitchPreference);
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
if (preference == null) {
return;
}
@MagnificationMode int mode =
MagnificationCapabilities.getCapabilities(mContext);
preference.setEnabled(
mode == MagnificationMode.FULLSCREEN || mode == MagnificationMode.ALL);
refreshSummary(preference);
}
}

View File

@@ -443,8 +443,7 @@ public class ToggleAccessibilityServicePreferenceFragment extends
final ApplicationInfo appInfo =
a11yServiceInfo.getResolveInfo().serviceInfo.applicationInfo;
final Uri packageUri = Uri.parse("package:" + appInfo.packageName);
final Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri)
.setPackage(getString(R.string.config_package_installer_package_name));
final Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri);
return uninstallIntent;
}

View File

@@ -202,7 +202,6 @@ public class ToggleScreenMagnificationPreferenceFragment extends
final PreferenceCategory generalCategory = findPreference(KEY_GENERAL_CATEGORY);
generalCategory.addPreference(mSettingsPreference);
addOneFingerPanningSetting(generalCategory);
final MagnificationModePreferenceController magnificationModePreferenceController =
new MagnificationModePreferenceController(getContext(),
MagnificationModePreferenceController.PREF_KEY);
@@ -212,6 +211,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends
addPreferenceController(magnificationModePreferenceController);
addFollowTypingSetting(generalCategory);
addOneFingerPanningSetting(generalCategory);
addAlwaysOnSetting(generalCategory);
addJoystickSetting(generalCategory);
}
@@ -302,6 +302,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends
var oneFingerPanningPreferenceController =
new MagnificationOneFingerPanningPreferenceController(getContext());
getSettingsLifecycle().addObserver(oneFingerPanningPreferenceController);
oneFingerPanningPreferenceController.displayPreference(getPreferenceScreen());
addPreferenceController(oneFingerPanningPreferenceController);
}

View File

@@ -539,8 +539,6 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp
// Create new intent to launch Uninstaller activity
Uri packageUri = Uri.parse("package:" + packageName);
Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri);
uninstallIntent.setPackage(mContext.getString(
R.string.config_package_installer_package_name));
uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, allUsers);
mMetricsFeatureProvider.action(mActivity, SettingsEnums.ACTION_SETTINGS_UNINSTALL_APP);
@@ -558,6 +556,11 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp
ActivityManager am = (ActivityManager) mActivity.getSystemService(
Context.ACTIVITY_SERVICE);
Log.d(TAG, "Stopping package " + pkgName);
if (android.app.Flags.appRestrictionsApi()) {
am.noteAppRestrictionEnabled(pkgName, mAppEntry.info.uid,
ActivityManager.RESTRICTION_LEVEL_FORCE_STOPPED, true,
ActivityManager.RESTRICTION_REASON_USER, "settings", 0L);
}
am.forceStopPackage(pkgName);
int userId = UserHandle.getUserId(mAppEntry.info.uid);
mState.invalidatePackage(pkgName, userId);

View File

@@ -642,7 +642,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
// Create new intent to launch Uninstaller activity
final Uri packageURI = Uri.parse("package:" + packageName);
final Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageURI);
uninstallIntent.setPackage(getString(R.string.config_package_installer_package_name));
uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, allUsers);
mMetricsFeatureProvider.action(
getContext(), SettingsEnums.ACTION_SETTINGS_UNINSTALL_APP);

View File

@@ -34,7 +34,6 @@ import android.util.Log;
import androidx.fragment.app.FragmentActivity;
import com.android.settings.R;
import com.android.settings.Utils;
import java.util.HashSet;
@@ -79,8 +78,6 @@ public class CloneBackend {
// Create new intent to launch Uninstaller activity.
Uri packageUri = Uri.parse("package:" + packageName);
Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri);
uninstallIntent.setPackage(mContext.getString(
R.string.config_package_installer_package_name));
uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, allUsers);
uninstallIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(mCloneUserId));
// Trigger uninstall as clone user.

View File

@@ -46,6 +46,7 @@ import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.CategoryMixin.CategoryHandler;
import com.android.settings.core.CategoryMixin.CategoryListener;
import com.android.settings.core.PreferenceControllerListHelper;
import com.android.settings.flags.Flags;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.PrimarySwitchPreference;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -543,13 +544,23 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
observers = mDashboardFeatureProvider.bindPreferenceToTileAndGetObservers(
getActivity(), this, forceRoundedIcons, pref, tile, key,
mPlaceholderPreferenceController.getOrder());
if (tile.hasGroupKey() && mDashboardTilePrefKeys.containsKey(tile.getGroupKey())) {
final Preference group = screen.findPreference(tile.getGroupKey());
if (group instanceof PreferenceCategory) {
if (Flags.dynamicInjectionCategory()) {
Preference group = screen.findPreference(tile.getGroupKey());
if (tile.hasGroupKey() && group instanceof PreferenceCategory) {
((PreferenceCategory) group).addPreference(pref);
} else {
screen.addPreference(pref);
}
} else {
screen.addPreference(pref);
if (tile.hasGroupKey()
&& mDashboardTilePrefKeys.containsKey(tile.getGroupKey())) {
Preference group = screen.findPreference(tile.getGroupKey());
if (group instanceof PreferenceCategory) {
((PreferenceCategory) group).addPreference(pref);
}
} else {
screen.addPreference(pref);
}
}
registerDynamicDataObservers(observers);
mDashboardTilePrefKeys.put(key, observers);
@@ -564,9 +575,13 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
for (Map.Entry<String, List<DynamicDataObserver>> entry : remove.entrySet()) {
final String key = entry.getKey();
mDashboardTilePrefKeys.remove(key);
final Preference preference = screen.findPreference(key);
if (preference != null) {
screen.removePreference(preference);
if (Flags.dynamicInjectionCategory()) {
screen.removePreferenceRecursively(key);
} else {
Preference preference = screen.findPreference(key);
if (preference != null) {
screen.removePreference(preference);
}
}
unregisterDynamicDataObservers(entry.getValue());
}

View File

@@ -345,9 +345,9 @@ public class BatteryOptimizeUtils {
try {
batteryUtils.setForceAppStandby(uid, packageName, appStandbyMode);
if (allowListed) {
powerAllowlistBackend.addApp(packageName);
powerAllowlistBackend.addApp(packageName, uid);
} else {
powerAllowlistBackend.removeApp(packageName);
powerAllowlistBackend.removeApp(packageName, uid);
}
} catch (Exception e) {
// Error cases, set standby mode as -1 for logging.

View File

@@ -15,6 +15,7 @@
*/
package com.android.settings.fuelgauge;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.Intent;
@@ -386,6 +387,14 @@ public class BatteryUtils {
// Control whether app could run in the background if it is pre O app
mAppOpsManager.setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName, mode);
}
// Notify system of reason for change
if (isForceAppStandbyEnabled(uid, packageName) != (mode == AppOpsManager.MODE_IGNORED)) {
mContext.getSystemService(ActivityManager.class).noteAppRestrictionEnabled(
packageName, uid, ActivityManager.RESTRICTION_LEVEL_BACKGROUND_RESTRICTED,
mode == AppOpsManager.MODE_IGNORED,
ActivityManager.RESTRICTION_REASON_USER,
"settings", 0);
}
// Control whether app could run jobs in the background
mAppOpsManager.setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName, mode);

View File

@@ -142,9 +142,9 @@ public class HighPowerDetail extends InstrumentedDialogFragment
if (newValue) {
mBatteryUtils.setForceAppStandby(
mPackageUid, mPackageName, AppOpsManager.MODE_ALLOWED);
mBackend.addApp(mPackageName);
mBackend.addApp(mPackageName, mPackageUid);
} else {
mBackend.removeApp(mPackageName);
mBackend.removeApp(mPackageName, mPackageUid);
}
}
}

View File

@@ -26,7 +26,7 @@ import androidx.preference.PreferenceScreen
import com.android.settings.R
import com.android.settings.core.BasePreferenceController
import com.android.settings.network.SubscriptionUtil
import com.android.settings.wifi.dpp.WifiDppUtils
import com.android.settings.network.telephony.MobileNetworkUtils
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
/** This controls a preference allowing the user to delete the profile for an eSIM. */
@@ -65,7 +65,7 @@ class DeleteSimProfilePreferenceController(context: Context, preferenceKey: Stri
override fun handlePreferenceTreeClick(preference: Preference): Boolean {
if (preference.key != preferenceKey) return false
WifiDppUtils.showLockScreen(mContext) { deleteSim() }
MobileNetworkUtils.showLockScreen(mContext) { deleteSim() }
return true
}

View File

@@ -31,6 +31,7 @@ import static com.android.settings.network.telephony.TelephonyConstants.Telephon
import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO;
import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA;
import android.app.KeyguardManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -41,13 +42,18 @@ import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.hardware.biometrics.BiometricPrompt;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.Looper;
import android.os.PersistableBundle;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.telecom.PhoneAccountHandle;
@@ -68,6 +74,7 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
@@ -1050,4 +1057,53 @@ public class MobileNetworkUtils {
.launch();
}
/**
* Shows authentication screen to confirm credentials (pin/pattern/password) for the current
* user of the device.
*
* <p>Similar to WifiDppUtils.showLockScreen(), but doesn't check for the existence of
* SIM PIN lock, only screen PIN lock.
*
* @param context The {@code Context} used to get {@link KeyguardManager} service
* @param onSuccess The {@code Runnable} which will be executed if the user does not setup
* device security or if lock screen is unlocked
*/
public static void showLockScreen(@NonNull Context context, @NonNull Runnable onSuccess) {
final KeyguardManager keyguardManager =
context.getSystemService(KeyguardManager.class);
if (keyguardManager.isDeviceSecure()) {
final BiometricPrompt.AuthenticationCallback authenticationCallback =
new BiometricPrompt.AuthenticationCallback() {
@Override
public void onAuthenticationSucceeded(
BiometricPrompt.AuthenticationResult result) {
onSuccess.run();
}
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
// Do nothing
}
};
final int userId = UserHandle.myUserId();
final BiometricPrompt biometricPrompt = new BiometricPrompt.Builder(context)
.setTitle(context.getText(R.string.wifi_dpp_lockscreen_title))
.setDeviceCredentialAllowed(true)
.setTextForDeviceCredential(
/* title= */ null,
Utils.getConfirmCredentialStringForUser(
context, userId, Utils.getCredentialType(context, userId)),
/* description= */ null)
.build();
final Handler handler = new Handler(Looper.getMainLooper());
biometricPrompt.authenticate(
new CancellationSignal(),
handler::post,
authenticationCallback);
} else {
onSuccess.run();
}
}
}

View File

@@ -25,8 +25,8 @@ import android.telephony.RadioAccessSpecifier
import android.telephony.TelephonyManager
import android.telephony.TelephonyScanManager
import android.util.Log
import androidx.annotation.VisibleForTesting
import androidx.lifecycle.LifecycleOwner
import com.android.settings.R
import com.android.settings.network.telephony.CellInfoUtil
import com.android.settings.network.telephony.CellInfoUtil.getNetworkTitle
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
@@ -37,7 +37,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.flowOn
class NetworkScanRepository(context: Context, subId: Int) {
class NetworkScanRepository(private val context: Context, subId: Int) {
sealed interface NetworkScanResult
data class NetworkScanCellInfos(val cellInfos: List<CellInfo>) : NetworkScanResult
@@ -105,7 +105,7 @@ class NetworkScanRepository(context: Context, subId: Int) {
NetworkScanRequest.SCAN_TYPE_ONE_SHOT,
radioAccessSpecifiers,
NetworkScanRequest.MIN_SEARCH_PERIODICITY_SEC, // one shot, not used
MAX_SEARCH_TIME_SEC,
context.resources.getInteger(R.integer.config_network_scan_helper_max_search_time_sec),
true,
INCREMENTAL_RESULTS_PERIODICITY_SEC,
null,
@@ -158,10 +158,6 @@ class NetworkScanRepository(context: Context, subId: Int) {
companion object {
private const val TAG = "NetworkScanRepository"
@VisibleForTesting
val MAX_SEARCH_TIME_SEC = 300
@VisibleForTesting
val INCREMENTAL_RESULTS_PERIODICITY_SEC = 3
private const val INCREMENTAL_RESULTS_PERIODICITY_SEC = 3
}
}

View File

@@ -20,7 +20,6 @@ import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.UserHandle
import com.android.settings.R
/**
* Based on PackageManagerService design, and it looks like the suggested replacement in the
@@ -37,7 +36,6 @@ fun Context.startUninstallActivity(
val packageUri = Uri.parse("package:$packageName")
val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri).apply {
setPackage(getString(R.string.config_package_installer_package_name))
putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, forAllUsers)
}
startActivityAsUser(intent, userHandle)

View File

@@ -16,6 +16,7 @@
package com.android.settings.spa.app.appinfo
import android.app.ActivityManager
import android.app.settings.SettingsEnums
import android.content.Context
import android.content.Intent
@@ -154,6 +155,13 @@ class PackageInfoPresenter(
logAction(SettingsEnums.ACTION_APP_FORCE_STOP)
coroutineScope.launch(Dispatchers.Default) {
Log.d(TAG, "Stopping package $packageName")
if (android.app.Flags.appRestrictionsApi()) {
val uid = userPackageManager.getPackageUid(packageName, 0)
context.activityManager.noteAppRestrictionEnabled(
packageName, uid,
ActivityManager.RESTRICTION_LEVEL_FORCE_STOPPED, true,
ActivityManager.RESTRICTION_REASON_USER, "settings", 0)
}
context.activityManager.forceStopPackageAsUser(packageName, userId)
}
}

View File

@@ -18,19 +18,15 @@ package com.android.settings.accessibility;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER;
import static com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
import androidx.preference.PreferenceManager;
@@ -38,131 +34,137 @@ import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import com.android.server.accessibility.Flags;
import com.android.settings.R;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowContentResolver;
@RunWith(RobolectricTestRunner.class)
public class MagnificationOneFingerPanningPreferenceControllerTest {
private static final String ONE_FINGER_PANNING_KEY =
Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED;
@Rule
public final CheckFlagsRule mCheckFlagsRule =
DeviceFlagsValueProvider.createCheckFlagsRule();
private final Context mContext = ApplicationProvider.getApplicationContext();
private ShadowContentResolver mShadowContentResolver;
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
private final MagnificationOneFingerPanningPreferenceController mController =
new MagnificationOneFingerPanningPreferenceController(mContext);
private PreferenceScreen mScreen;
@Before
public void setUp() {
mShadowContentResolver = Shadow.extract(mContext.getContentResolver());
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
mScreen = preferenceManager.createPreferenceScreen(mContext);
final PreferenceScreen screen = preferenceManager.createPreferenceScreen(mContext);
mSwitchPreference.setKey(MagnificationOneFingerPanningPreferenceController.PREF_KEY);
mScreen.addPreference(mSwitchPreference);
mController.displayPreference(mScreen);
}
@After
public void cleanup() {
// Can't use resetToDefaults as it NPE with
// "Cannot invoke "android.content.IContentProvider.call"
Settings.Secure.putInt(
mContext.getContentResolver(),
MagnificationOneFingerPanningPreferenceController.PREF_KEY,
(mController.mDefaultValue) ? ON : OFF);
screen.addPreference(mSwitchPreference);
mController.displayPreference(screen);
}
@Test
public void displayPreference_defaultState_correctSummarySet() {
assertThat(mSwitchPreference.getSummary())
.isEqualTo(mContext.getString(
R.string.accessibility_magnification_one_finger_panning_summary_off));
public void onResume_verifyRegisterCapabilityObserver() {
mController.onResume();
assertThat(mShadowContentResolver.getContentObservers(
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY)))
.hasSize(1);
}
@Test
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
public void getAvailabilityStatus_flagDisabled_disabled() {
int status = mController.getAvailabilityStatus();
assertThat(status).isEqualTo(DISABLED_FOR_USER);
public void onPause_verifyUnregisterCapabilityObserver() {
mController.onResume();
mController.onPause();
assertThat(mShadowContentResolver.getContentObservers(
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY)))
.isEmpty();
}
@Test
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
public void getAvailabilityStatus_featureFlagEnabled_enabled() {
int status = mController.getAvailabilityStatus();
public void updateState_windowModeOnly_preferenceIsUnavailable() {
MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.WINDOW);
mController.updateState(mSwitchPreference);
assertThat(status).isEqualTo(AVAILABLE);
assertThat(mSwitchPreference.isEnabled()).isFalse();
}
@Test
public void updateState_fullscreenModeOnly_preferenceIsAvailable() {
MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.FULLSCREEN);
mController.updateState(mSwitchPreference);
assertThat(mSwitchPreference.isEnabled()).isTrue();
}
@Test
public void updateState_switchMode_preferenceIsAvailable() {
MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
mController.updateState(mSwitchPreference);
assertThat(mSwitchPreference.isEnabled()).isTrue();
}
@Test
public void isChecked_defaultState_returnFalse() {
mController.updateState(mSwitchPreference);
assertThat(mController.isChecked()).isFalse();
assertThat(mSwitchPreference.isChecked()).isFalse();
}
@Test
public void isChecked_settingsEnabled_returnTrue() {
public void isChecked_settingsOn_returnTrue() {
Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, ON);
mController.updateState(mSwitchPreference);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void isChecked_settingsDisabled_returnTrue() {
public void isChecked_settingsOff_returnFalse() {
Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, OFF);
mController.updateState(mSwitchPreference);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void setChecked_enabled_enabledSummarySet() {
mController.setChecked(true);
assertThat(mSwitchPreference.getSummary()).isEqualTo(enabledSummary());
assertThat(mController.isChecked()).isTrue();
}
@Test
public void setChecked_disabled_disabledSummarySet() {
mController.setChecked(false);
assertThat(mController.isChecked()).isFalse();
assertThat(mSwitchPreference.getSummary()).isEqualTo(disabledSummary());
}
@Test
public void getSummary_disable_disableSummaryTextUsed() {
public void getSummary_switchModeAndSettingsOff_disabledSummaryTextUsed() {
MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, OFF);
var summary = mController.getSummary();
mController.updateState(mSwitchPreference);
assertThat(summary).isEqualTo(disabledSummary());
assertThat(mController.getSummary()).isEqualTo(disabledSummary());
}
@Test
public void getSummary_enable_enabledSummaryTextUsed() {
public void getSummary_switchModeAndSettingsOn_enabledSummaryTextUsed() {
MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, ON);
var summary = mController.getSummary();
mController.updateState(mSwitchPreference);
assertThat(summary).isEqualTo(enabledSummary());
assertThat(mController.getSummary()).isEqualTo(enabledSummary());
}
@Test
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
public void performClick_switchDefaultState_shouldReturnTrue() {
public void getSummary_windowModeOnly_unavailableSummaryTextUsed() {
MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.WINDOW);
mController.updateState(mSwitchPreference);
assertThat(mController.getSummary()).isEqualTo(unavailableSummary());
}
@Test
public void performClick_defaultSettings_toggleOn() {
MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
mController.updateState(mSwitchPreference);
reset(mSwitchPreference);
mSwitchPreference.performClick();
verify(mSwitchPreference).setChecked(true);
@@ -170,6 +172,20 @@ public class MagnificationOneFingerPanningPreferenceControllerTest {
assertThat(mSwitchPreference.isChecked()).isTrue();
}
@Test
public void performClick_settingsOn_toggleOff() {
MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, ON);
mController.updateState(mSwitchPreference);
reset(mSwitchPreference);
mSwitchPreference.performClick();
verify(mSwitchPreference).setChecked(false);
assertThat(mController.isChecked()).isFalse();
assertThat(mSwitchPreference.isChecked()).isFalse();
}
private String enabledSummary() {
return mContext.getString(
R.string.accessibility_magnification_one_finger_panning_summary_on);
@@ -179,4 +195,9 @@ public class MagnificationOneFingerPanningPreferenceControllerTest {
return mContext.getString(
R.string.accessibility_magnification_one_finger_panning_summary_off);
}
private String unavailableSummary() {
return mContext.getString(
R.string.accessibility_magnification_one_finger_panning_summary_unavailable);
}
}

View File

@@ -122,6 +122,8 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
private static final String KEY_FOLLOW_TYPING =
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED;
private static final String KEY_SINGLE_FINGER_PANNING =
Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED;
private static final String KEY_ALWAYS_ON =
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED;
private static final String KEY_JOYSTICK =
@@ -215,6 +217,43 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
assertThat(switchPreference.isChecked()).isFalse();
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
public void onResume_defaultStateForOneFingerPan_switchPreferenceShouldReturnFalse() {
mFragController.create(R.id.main_content, /* bundle= */ null).start().resume();
final TwoStatePreference switchPreference = mFragController.get().findPreference(
MagnificationOneFingerPanningPreferenceController.PREF_KEY);
assertThat(switchPreference).isNotNull();
assertThat(switchPreference.isChecked()).isFalse();
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
public void onResume_enableOneFingerPan_switchPreferenceShouldReturnTrue() {
setKeyOneFingerPanEnabled(true);
mFragController.create(R.id.main_content, /* bundle= */ null).start().resume();
final TwoStatePreference switchPreference = mFragController.get().findPreference(
MagnificationOneFingerPanningPreferenceController.PREF_KEY);
assertThat(switchPreference).isNotNull();
assertThat(switchPreference.isChecked()).isTrue();
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
public void onResume_disableOneFingerPan_switchPreferenceShouldReturnFalse() {
setKeyOneFingerPanEnabled(false);
mFragController.create(R.id.main_content, /* bundle= */ null).start().resume();
final TwoStatePreference switchPreference = mFragController.get().findPreference(
MagnificationOneFingerPanningPreferenceController.PREF_KEY);
assertThat(switchPreference).isNotNull();
assertThat(switchPreference.isChecked()).isFalse();
}
@Test
public void onResume_defaultStateForAlwaysOn_switchPreferenceShouldReturnTrue() {
setAlwaysOnSupported(true);
@@ -777,6 +816,16 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
assertThat(mFragController.get().mSettingsPreference).isNull();
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
public void onCreateView_oneFingerPanNotSupported_settingsPreferenceIsNull() {
mFragController.create(R.id.main_content, /* bundle= */ null).start().resume();
final TwoStatePreference switchPreference = mFragController.get().findPreference(
MagnificationOneFingerPanningPreferenceController.PREF_KEY);
assertThat(switchPreference).isNull();
}
@Test
public void onCreateView_alwaysOnNotSupported_settingsPreferenceIsNull() {
setAlwaysOnSupported(false);
@@ -817,7 +866,25 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
}
@Test
public void onCreateView_addTheAlwaysOnControllerToLifeCycleObserver() {
@EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
public void onCreateView_oneFingerPanSupported_addControllerToLifeCycleObserver() {
Correspondence instanceOf = Correspondence.transforming(
observer -> (observer instanceof MagnificationOneFingerPanningPreferenceController),
"contains MagnificationOneFingerPanningPreferenceController");
ToggleScreenMagnificationPreferenceFragment fragment = mFragController.create(
R.id.main_content, /* bundle= */ null).start().resume().get();
List<LifecycleObserver> lifecycleObservers = ReflectionHelpers.getField(
fragment.getSettingsLifecycle(), "mObservers");
assertThat(lifecycleObservers).isNotNull();
assertThat(lifecycleObservers).comparingElementsUsing(instanceOf).contains(true);
}
@Test
public void onCreateView_alwaysOnSupported_addControllerToLifeCycleObserver() {
setAlwaysOnSupported(true);
Correspondence instanceOf = Correspondence.transforming(
observer -> (observer instanceof MagnificationAlwaysOnPreferenceController),
"contains MagnificationAlwaysOnPreferenceController");
@@ -984,6 +1051,11 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
enabled ? ON : OFF);
}
private void setKeyOneFingerPanEnabled(boolean enabled) {
Settings.Secure.putInt(mContext.getContentResolver(), KEY_SINGLE_FINGER_PANNING,
enabled ? ON : OFF);
}
private void setAlwaysOnSupported(boolean supported) {
ShadowDeviceConfig.setProperty(
DeviceConfig.NAMESPACE_WINDOW_MANAGER,

View File

@@ -206,8 +206,8 @@ public class BatteryOptimizeUtilsTest {
TimeUnit.SECONDS.sleep(1);
verify(mMockBatteryUtils, never()).setForceAppStandby(anyInt(), anyString(), anyInt());
verify(mMockBackend, never()).addApp(anyString());
verify(mMockBackend, never()).removeApp(anyString());
verify(mMockBackend, never()).addApp(anyString(), anyInt());
verify(mMockBackend, never()).removeApp(anyString(), anyInt());
verifyNoInteractions(mObserver);
}
@@ -358,9 +358,9 @@ public class BatteryOptimizeUtilsTest {
private void verifySetAppOptimizationMode(int appStandbyMode, boolean allowListed) {
verify(mMockBatteryUtils).setForceAppStandby(UID, PACKAGE_NAME, appStandbyMode);
if (allowListed) {
verify(mMockBackend).addApp(PACKAGE_NAME);
verify(mMockBackend).addApp(PACKAGE_NAME, UID);
} else {
verify(mMockBackend).removeApp(PACKAGE_NAME);
verify(mMockBackend).removeApp(PACKAGE_NAME, UID);
}
}
}