Snap for 12173239 from f2d6fe9e32
to 24Q4-release
Change-Id: I993b777f5a9e84bf1aa9be97af904dcf8d42ba85
This commit is contained in:
@@ -51,6 +51,16 @@ flag {
|
||||
bug: "301198830"
|
||||
}
|
||||
|
||||
flag {
|
||||
name: "fix_a11y_settings_search"
|
||||
namespace: "accessibility"
|
||||
description: "Fix the a11y related search items in Settings app"
|
||||
bug: "333437173"
|
||||
metadata {
|
||||
purpose: PURPOSE_BUGFIX
|
||||
}
|
||||
}
|
||||
|
||||
flag {
|
||||
name: "hide_magnification_always_on_toggle_when_window_mode_only"
|
||||
namespace: "accessibility"
|
||||
|
@@ -26,7 +26,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="48dp"
|
||||
android:textAlignment="viewStart"/>
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="?android:attr/textColorPrimary"/>
|
||||
<EditText
|
||||
android:id="@+id/broadcast_edit_text"
|
||||
android:layout_width="match_parent"
|
||||
@@ -34,11 +35,4 @@
|
||||
android:maxLength="16"
|
||||
android:minHeight="48dp"
|
||||
android:textAlignment="viewStart"/>
|
||||
<TextView
|
||||
android:id="@+id/broadcast_error_message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
style="@style/TextAppearance.ErrorText"
|
||||
android:visibility="invisible"/>
|
||||
</LinearLayout>
|
@@ -5456,9 +5456,9 @@
|
||||
<!-- Title for the preference to show a tile for a particular feature in the Quick Settings pane. [CHAR LIMIT=NONE] -->
|
||||
<string name="enable_quick_setting">Show in Quick Settings</string>
|
||||
<!-- Title shown for deuteranomaly (red-green color blindness) [CHAR LIMIT=45] -->
|
||||
<string name="daltonizer_mode_deuteranomaly_title">Red-green</string>
|
||||
<string name="daltonizer_mode_deuteranomaly_title">Red-green, green weak</string>
|
||||
<!-- Title shown for protanomaly (red-green color blindness) [CHAR LIMIT=45] -->
|
||||
<string name="daltonizer_mode_protanomaly_title">Red-green</string>
|
||||
<string name="daltonizer_mode_protanomaly_title">Red-green, red weak</string>
|
||||
<!-- Title shown for tritanomaly (blue-yellow color blindness) [CHAR LIMIT=45] -->
|
||||
<string name="daltonizer_mode_tritanomaly_title">Blue-yellow</string>
|
||||
<!-- Title shown for grayscale [CHAR LIMIT=45] -->
|
||||
@@ -5468,9 +5468,9 @@
|
||||
<!-- The summary shown for settings that controls color correction intensity/saturation level. It is shown when intensity slider is grayed out and is not usable and it explains why it's not usable to the user. [CHAR LIMIT=NONE] -->
|
||||
<string name="daltonizer_saturation_unavailable_summary">Unavailable for grayscale mode or when color correction is disabled</string>
|
||||
<!-- Summary shown for deuteranomaly (red-green color blindness) [CHAR LIMIT=45] -->
|
||||
<string name="daltonizer_mode_deuteranomaly_summary">Green weak, deuteranomaly</string>
|
||||
<string name="daltonizer_mode_deuteranomaly_summary">Deuteranomaly</string>
|
||||
<!-- Summary shown for protanomaly (red-green color blindness) [CHAR LIMIT=45] -->
|
||||
<string name="daltonizer_mode_protanomaly_summary">Red weak, protanomaly</string>
|
||||
<string name="daltonizer_mode_protanomaly_summary">Protanomaly</string>
|
||||
<!-- Summary shown for tritanomaly (blue-yellow color blindness) [CHAR LIMIT=45] -->
|
||||
<string name="daltonizer_mode_tritanomaly_summary">Tritanomaly</string>
|
||||
|
||||
|
@@ -507,6 +507,11 @@
|
||||
android:title="@string/show_key_presses"
|
||||
android:summary="@string/show_key_presses_summary" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="touchpad_visualizer"
|
||||
android:title="@string/touchpad_visualizer"
|
||||
android:summary="@string/touchpad_visualizer_summary" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
|
@@ -293,10 +293,10 @@
|
||||
settings:controller=
|
||||
"com.android.settings.network.telephony.NullAlgorithmsPreferenceController"/>
|
||||
|
||||
<!-- Settings search is handled by NrAdvancedCallingSearchItem. -->
|
||||
<com.android.settings.spa.preference.ComposePreference
|
||||
android:key="nr_advanced_calling"
|
||||
android:title="@string/nr_advanced_calling_title"
|
||||
settings:keywords="@string/keywords_nr_advanced_calling"
|
||||
settings:searchable="false"
|
||||
settings:controller="com.android.settings.network.telephony.NrAdvancedCallingPreferenceController"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
|
@@ -613,7 +613,7 @@ public class AccessibilitySettings extends DashboardFragment implements
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAnyHardKeyboardsExist() {
|
||||
static boolean isAnyHardKeyboardsExist() {
|
||||
for (int deviceId : InputDevice.getDeviceIds()) {
|
||||
final InputDevice device = InputDevice.getDevice(deviceId);
|
||||
if (device != null && !device.isVirtual() && device.isFullKeyboard()) {
|
||||
|
@@ -19,16 +19,21 @@ package com.android.settings.accessibility;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.input.InputSettings;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
import com.android.settings.inputmethod.PhysicalKeyboardFragment;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A toggle preference controller for keyboard bounce key.
|
||||
*/
|
||||
public class KeyboardBounceKeyPreferenceController extends TogglePreferenceController {
|
||||
|
||||
private static final String TAG = "BounceKeyPrefController";
|
||||
static final String PREF_KEY = "toggle_keyboard_bounce_keys";
|
||||
|
||||
public KeyboardBounceKeyPreferenceController(Context context, String preferenceKey) {
|
||||
@@ -58,4 +63,17 @@ public class KeyboardBounceKeyPreferenceController extends TogglePreferenceContr
|
||||
public int getSliceHighlightMenuRes() {
|
||||
return R.string.menu_key_accessibility;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNonIndexableKeys(@NonNull List<String> keys) {
|
||||
super.updateNonIndexableKeys(keys);
|
||||
|
||||
if (Flags.fixA11ySettingsSearch() && !AccessibilitySettings.isAnyHardKeyboardsExist()) {
|
||||
if (keys.contains(getPreferenceKey())) {
|
||||
Log.w(TAG, "Skipping updateNonIndexableKeys, key already in list.");
|
||||
return;
|
||||
}
|
||||
keys.add(getPreferenceKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -19,15 +19,21 @@ package com.android.settings.accessibility;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.input.InputSettings;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
import com.android.settings.inputmethod.PhysicalKeyboardFragment;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A toggle preference controller for keyboard slow key.
|
||||
*/
|
||||
public class KeyboardSlowKeyPreferenceController extends TogglePreferenceController {
|
||||
private static final String TAG = "SlowKeyPrefController";
|
||||
|
||||
static final String PREF_KEY = "toggle_keyboard_slow_keys";
|
||||
|
||||
@@ -58,4 +64,17 @@ public class KeyboardSlowKeyPreferenceController extends TogglePreferenceControl
|
||||
public int getSliceHighlightMenuRes() {
|
||||
return R.string.menu_key_accessibility;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNonIndexableKeys(@NonNull List<String> keys) {
|
||||
super.updateNonIndexableKeys(keys);
|
||||
|
||||
if (Flags.fixA11ySettingsSearch() && !AccessibilitySettings.isAnyHardKeyboardsExist()) {
|
||||
if (keys.contains(getPreferenceKey())) {
|
||||
Log.w(TAG, "Skipping updateNonIndexableKeys, key already in list.");
|
||||
return;
|
||||
}
|
||||
keys.add(getPreferenceKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -19,15 +19,20 @@ package com.android.settings.accessibility;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.input.InputSettings;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A toggle preference controller for keyboard sticky key.
|
||||
*/
|
||||
public class KeyboardStickyKeyPreferenceController extends TogglePreferenceController {
|
||||
|
||||
private static final String TAG = "StickyKeyPrefController";
|
||||
static final String PREF_KEY = "toggle_keyboard_sticky_keys";
|
||||
|
||||
public KeyboardStickyKeyPreferenceController(Context context, String preferenceKey) {
|
||||
@@ -55,4 +60,17 @@ public class KeyboardStickyKeyPreferenceController extends TogglePreferenceContr
|
||||
public int getSliceHighlightMenuRes() {
|
||||
return R.string.menu_key_accessibility;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNonIndexableKeys(@NonNull List<String> keys) {
|
||||
super.updateNonIndexableKeys(keys);
|
||||
|
||||
if (Flags.fixA11ySettingsSearch() && !AccessibilitySettings.isAnyHardKeyboardsExist()) {
|
||||
if (keys.contains(getPreferenceKey())) {
|
||||
Log.w(TAG, "Skipping updateNonIndexableKeys, key already in list.");
|
||||
return;
|
||||
}
|
||||
keys.add(getPreferenceKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -132,7 +132,7 @@ public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchCh
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
mIsSatelliteOn.set(mSatelliteRepository.requestIsEnabled(
|
||||
mIsSatelliteOn.set(mSatelliteRepository.requestIsSessionStarted(
|
||||
Executors.newSingleThreadExecutor()).get(3000, TimeUnit.MILLISECONDS));
|
||||
} catch (InterruptedException | ExecutionException | TimeoutException e) {
|
||||
Log.e(TAG, "Error to get satellite status : " + e);
|
||||
|
@@ -79,7 +79,7 @@ public class BluetoothPairingDetail extends BluetoothDevicePairingDetailBase imp
|
||||
boolean isSatelliteOn = true;
|
||||
try {
|
||||
isSatelliteOn =
|
||||
satelliteRepository.requestIsEnabled(
|
||||
satelliteRepository.requestIsSessionStarted(
|
||||
Executors.newSingleThreadExecutor()).get(3000, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException | ExecutionException | TimeoutException e) {
|
||||
Log.e(TAG, "Error to get satellite status : " + e);
|
||||
|
@@ -30,6 +30,9 @@ import android.content.IntentFilter;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
|
||||
@@ -284,6 +287,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
: mProfileManager.getLeAudioBroadcastAssistantProfile();
|
||||
mExecutor = Executors.newSingleThreadExecutor();
|
||||
mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
|
||||
mSwitchBar.getRootView().setAccessibilityDelegate(new MainSwitchAccessibilityDelegate());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -564,4 +568,19 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static final class MainSwitchAccessibilityDelegate extends View.AccessibilityDelegate {
|
||||
@Override
|
||||
public boolean onRequestSendAccessibilityEvent(
|
||||
@NonNull ViewGroup host, @NonNull View view, @NonNull AccessibilityEvent event) {
|
||||
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
|
||||
&& (event.getContentChangeTypes()
|
||||
& AccessibilityEvent.CONTENT_CHANGE_TYPE_ENABLED)
|
||||
!= 0) {
|
||||
Log.d(TAG, "Skip accessibility event for CONTENT_CHANGE_TYPE_ENABLED");
|
||||
return false;
|
||||
}
|
||||
return super.onRequestSendAccessibilityEvent(host, view, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -43,23 +43,12 @@ class AudioStreamPreference extends TwoTargetPreference {
|
||||
* Update preference UI based on connection status
|
||||
*
|
||||
* @param isConnected Is this stream connected
|
||||
* @param summary Summary text
|
||||
* @param onPreferenceClickListener Click listener for the preference
|
||||
*/
|
||||
void setIsConnected(
|
||||
boolean isConnected,
|
||||
String summary,
|
||||
@Nullable OnPreferenceClickListener onPreferenceClickListener) {
|
||||
if (mIsConnected == isConnected
|
||||
&& getSummary() == summary
|
||||
&& getOnPreferenceClickListener() == onPreferenceClickListener) {
|
||||
// Nothing to update.
|
||||
return;
|
||||
void setIsConnected(boolean isConnected) {
|
||||
if (mIsConnected != isConnected) {
|
||||
mIsConnected = isConnected;
|
||||
notifyChanged();
|
||||
}
|
||||
mIsConnected = isConnected;
|
||||
setSummary(summary);
|
||||
setOnPreferenceClickListener(onPreferenceClickListener);
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
@@ -16,8 +16,12 @@
|
||||
|
||||
package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
|
||||
import static android.text.Spanned.SPAN_EXCLUSIVE_INCLUSIVE;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -26,6 +30,7 @@ import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
@@ -68,15 +73,31 @@ class AudioStreamStateHandler {
|
||||
|
||||
// Update UI
|
||||
ThreadUtils.postOnMainThread(
|
||||
() ->
|
||||
preference.setIsConnected(
|
||||
newState
|
||||
== AudioStreamsProgressCategoryController.AudioStreamState
|
||||
.SOURCE_ADDED,
|
||||
getSummary() != EMPTY_STRING_RES
|
||||
? preference.getContext().getString(getSummary())
|
||||
: "",
|
||||
getOnClickListener(controller)));
|
||||
() -> {
|
||||
String summary =
|
||||
getSummary() != EMPTY_STRING_RES
|
||||
? preference.getContext().getString(getSummary())
|
||||
: "";
|
||||
if (newState
|
||||
== AudioStreamsProgressCategoryController.AudioStreamState
|
||||
.ADD_SOURCE_BAD_CODE) {
|
||||
SpannableString summarySpan = new SpannableString(summary);
|
||||
int colorError = Utils.getColorErrorDefaultColor(preference.getContext());
|
||||
summarySpan.setSpan(
|
||||
new ForegroundColorSpan(colorError),
|
||||
0,
|
||||
summary.length(),
|
||||
SPAN_EXCLUSIVE_INCLUSIVE);
|
||||
preference.setSummary(summarySpan);
|
||||
} else {
|
||||
preference.setSummary(summary);
|
||||
}
|
||||
preference.setIsConnected(
|
||||
newState
|
||||
== AudioStreamsProgressCategoryController.AudioStreamState
|
||||
.SOURCE_ADDED);
|
||||
preference.setOnPreferenceClickListener(getOnClickListener(controller));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.settings.development;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
import static android.provider.Settings.Global.DEVELOPMENT_SETTINGS_ENABLED;
|
||||
import static android.service.quicksettings.TileService.ACTION_QS_TILE_PREFERENCES;
|
||||
import static android.view.flags.Flags.sensitiveContentAppProtectionApi;
|
||||
@@ -100,11 +101,13 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
NfcRebootDialog.OnNfcRebootDialogConfirmedListener, BluetoothSnoopLogHost {
|
||||
|
||||
private static final String TAG = "DevSettingsDashboard";
|
||||
@VisibleForTesting static final int REQUEST_BIOMETRIC_PROMPT = 100;
|
||||
|
||||
private final BluetoothA2dpConfigStore mBluetoothA2dpConfigStore =
|
||||
new BluetoothA2dpConfigStore();
|
||||
|
||||
private boolean mIsAvailable = true;
|
||||
private boolean mIsBiometricsAuthenticated;
|
||||
private SettingsMainSwitchBar mSwitchBar;
|
||||
private DevelopmentSwitchBarController mSwitchBarController;
|
||||
private List<AbstractPreferenceController> mPreferenceControllers = new ArrayList<>();
|
||||
@@ -216,6 +219,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final ContentResolver cr = getContext().getContentResolver();
|
||||
mIsBiometricsAuthenticated = false;
|
||||
cr.registerContentObserver(mDevelopEnabled, false, mDeveloperSettingsObserver);
|
||||
|
||||
// Restore UI state based on whether developer options is enabled
|
||||
@@ -360,7 +364,18 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext());
|
||||
if (isChecked != developmentEnabledState) {
|
||||
if (isChecked) {
|
||||
EnableDevelopmentSettingWarningDialog.show(this /* host */);
|
||||
final int userId = getContext().getUserId();
|
||||
if (Utils.requestBiometricAuthenticationForMandatoryBiometrics(getContext(),
|
||||
mIsBiometricsAuthenticated,
|
||||
false /* biometricsAuthenticationRequested */, userId)) {
|
||||
mSwitchBar.setChecked(false);
|
||||
Utils.launchBiometricPromptForMandatoryBiometrics(this,
|
||||
REQUEST_BIOMETRIC_PROMPT, userId, false /* hideBackground */);
|
||||
} else {
|
||||
//Reset biometrics once enable dialog is shown
|
||||
mIsBiometricsAuthenticated = false;
|
||||
EnableDevelopmentSettingWarningDialog.show(this /* host */);
|
||||
}
|
||||
} else {
|
||||
final BluetoothA2dpHwOffloadPreferenceController a2dpController =
|
||||
getDevelopmentOptionsController(
|
||||
@@ -534,6 +549,12 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
boolean handledResult = false;
|
||||
if (requestCode == REQUEST_BIOMETRIC_PROMPT) {
|
||||
if (resultCode == RESULT_OK) {
|
||||
mIsBiometricsAuthenticated = true;
|
||||
mSwitchBar.setChecked(true);
|
||||
}
|
||||
}
|
||||
for (AbstractPreferenceController controller : mPreferenceControllers) {
|
||||
if (controller instanceof OnActivityResultListener) {
|
||||
// We do not break early because it is possible for multiple controllers to
|
||||
@@ -715,6 +736,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
controllers.add(new ShowTapsPreferenceController(context));
|
||||
controllers.add(new PointerLocationPreferenceController(context));
|
||||
controllers.add(new ShowKeyPressesPreferenceController(context));
|
||||
controllers.add(new TouchpadVisualizerPreferenceController(context));
|
||||
controllers.add(new ShowSurfaceUpdatesPreferenceController(context));
|
||||
controllers.add(new ShowLayoutBoundsPreferenceController(context));
|
||||
controllers.add(new ShowHdrSdrRatioPreferenceController(context));
|
||||
|
@@ -16,3 +16,6 @@ per-file DesktopModePreferenceController.java=file:platform/frameworks/base:/lib
|
||||
# ADB
|
||||
per-file Adb*=set noparent
|
||||
per-file Adb*=file:platform/packages/modules/adb:/OWNERS
|
||||
|
||||
#TouchpadVisualizerPreferenceController
|
||||
per-file TouchpadVisualizerPreferenceController.java=file:platform/frameworks/base:/INPUT_OWNERS
|
||||
|
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2024 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.development;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import android.hardware.input.InputSettings;
|
||||
|
||||
/** PreferenceController that controls the "Touchpad visualizer" developer option. */
|
||||
public class TouchpadVisualizerPreferenceController extends
|
||||
DeveloperOptionsPreferenceController implements
|
||||
Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
|
||||
|
||||
private static final String TOUCHPAD_VISUALIZER_KEY = "touchpad_visualizer";
|
||||
|
||||
@VisibleForTesting
|
||||
static final int SETTING_VALUE_ON = 1;
|
||||
@VisibleForTesting
|
||||
static final int SETTING_VALUE_OFF = 0;
|
||||
|
||||
public TouchpadVisualizerPreferenceController(@NonNull Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String getPreferenceKey() {
|
||||
return TOUCHPAD_VISUALIZER_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(){
|
||||
return InputSettings.isTouchpadVisualizerFeatureFlagEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(@NonNull Preference preference, @Nullable Object newValue) {
|
||||
final boolean isEnabled = newValue != null ? (Boolean) newValue : false;
|
||||
Settings.System.putInt(mContext.getContentResolver(),
|
||||
Settings.System.TOUCHPAD_VISUALIZER,
|
||||
isEnabled ? SETTING_VALUE_ON : SETTING_VALUE_OFF);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(@NonNull Preference preference) {
|
||||
int touchpadVisualizer = Settings.System.getInt(mContext.getContentResolver(),
|
||||
Settings.System.TOUCHPAD_VISUALIZER, SETTING_VALUE_OFF);
|
||||
((SwitchPreference) mPreference).setChecked(touchpadVisualizer != SETTING_VALUE_OFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeveloperOptionsSwitchDisabled() {
|
||||
super.onDeveloperOptionsSwitchDisabled();
|
||||
Settings.System.putInt(mContext.getContentResolver(), Settings.System.TOUCHPAD_VISUALIZER,
|
||||
SETTING_VALUE_OFF);
|
||||
((SwitchPreference) mPreference).setChecked(false);
|
||||
}
|
||||
}
|
@@ -55,6 +55,7 @@ public class BuildNumberPreferenceController extends BasePreferenceController im
|
||||
|
||||
static final int TAPS_TO_BE_A_DEVELOPER = 7;
|
||||
static final int REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF = 100;
|
||||
static final int REQUEST_IDENTITY_CHECK_FOR_DEV_PREF = 101;
|
||||
|
||||
private Activity mActivity;
|
||||
private InstrumentedPreferenceFragment mFragment;
|
||||
@@ -217,10 +218,24 @@ public class BuildNumberPreferenceController extends BasePreferenceController im
|
||||
* @return if activity result is handled.
|
||||
*/
|
||||
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode != REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF) {
|
||||
if (requestCode != REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF
|
||||
&& requestCode != REQUEST_IDENTITY_CHECK_FOR_DEV_PREF) {
|
||||
return false;
|
||||
}
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
if (requestCode == REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF
|
||||
&& resultCode == Activity.RESULT_OK) {
|
||||
final int userId = mContext.getUserId();
|
||||
if (Utils.requestBiometricAuthenticationForMandatoryBiometrics(mContext,
|
||||
false /* biometricsSuccessfullyAuthenticated */,
|
||||
false /* biometricsAuthenticationRequested */,
|
||||
userId)) {
|
||||
Utils.launchBiometricPromptForMandatoryBiometrics(mFragment,
|
||||
REQUEST_IDENTITY_CHECK_FOR_DEV_PREF, userId, false /* hideBackground */);
|
||||
} else {
|
||||
enableDevelopmentSettings();
|
||||
}
|
||||
} else if (requestCode == REQUEST_IDENTITY_CHECK_FOR_DEV_PREF
|
||||
&& resultCode == Activity.RESULT_OK) {
|
||||
enableDevelopmentSettings();
|
||||
}
|
||||
mProcessingLastDevHit = false;
|
||||
|
@@ -162,7 +162,8 @@ public class AirplaneModePreferenceController extends TogglePreferenceController
|
||||
public void onResume() {
|
||||
try {
|
||||
mIsSatelliteOn.set(
|
||||
mSatelliteRepository.requestIsEnabled(Executors.newSingleThreadExecutor())
|
||||
mSatelliteRepository
|
||||
.requestIsSessionStarted(Executors.newSingleThreadExecutor())
|
||||
.get(2000, TimeUnit.MILLISECONDS));
|
||||
} catch (ExecutionException | TimeoutException | InterruptedException e) {
|
||||
Log.e(TAG, "Error to get satellite status : " + e);
|
||||
|
@@ -25,6 +25,7 @@ import androidx.annotation.VisibleForTesting
|
||||
import androidx.concurrent.futures.CallbackToFutureAdapter
|
||||
import com.google.common.util.concurrent.Futures.immediateFuture
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import java.util.concurrent.Executor
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.asExecutor
|
||||
@@ -32,7 +33,6 @@ import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import java.util.concurrent.Executor
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
|
||||
/**
|
||||
@@ -58,20 +58,26 @@ class SatelliteRepository(
|
||||
}
|
||||
|
||||
return CallbackToFutureAdapter.getFuture { completer ->
|
||||
satelliteManager.requestIsEnabled(executor,
|
||||
object : OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> {
|
||||
override fun onResult(result: Boolean) {
|
||||
Log.i(TAG, "Satellite modem enabled status: $result")
|
||||
completer.set(result)
|
||||
}
|
||||
try {
|
||||
satelliteManager.requestIsEnabled(executor,
|
||||
object : OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> {
|
||||
override fun onResult(result: Boolean) {
|
||||
Log.i(TAG, "Satellite modem enabled status: $result")
|
||||
completer.set(result)
|
||||
}
|
||||
|
||||
override fun onError(error: SatelliteManager.SatelliteException) {
|
||||
super.onError(error)
|
||||
Log.w(TAG, "Can't get satellite modem enabled status", error)
|
||||
completer.set(false)
|
||||
}
|
||||
})
|
||||
"requestIsEnabled"
|
||||
} catch (e: IllegalStateException) {
|
||||
Log.w(TAG, "IllegalStateException $e")
|
||||
completer.set(false)
|
||||
}
|
||||
|
||||
override fun onError(error: SatelliteManager.SatelliteException) {
|
||||
super.onError(error)
|
||||
Log.w(TAG, "Can't get satellite modem enabled status", error)
|
||||
completer.set(false)
|
||||
}
|
||||
})
|
||||
"requestIsEnabled"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,14 +102,21 @@ class SatelliteRepository(
|
||||
val callback = object : SatelliteModemStateCallback {
|
||||
override fun onSatelliteModemStateChanged(state: Int) {
|
||||
val isSessionStarted = isSatelliteSessionStarted(state)
|
||||
Log.i(TAG, "Satellite modem state changed: state=$state"
|
||||
+ ", isSessionStarted=$isSessionStarted")
|
||||
Log.i(
|
||||
TAG, "Satellite modem state changed: state=$state"
|
||||
+ ", isSessionStarted=$isSessionStarted"
|
||||
)
|
||||
completer.set(isSessionStarted)
|
||||
satelliteManager.unregisterForModemStateChanged(this)
|
||||
}
|
||||
}
|
||||
|
||||
val registerResult = satelliteManager.registerForModemStateChanged(executor, callback)
|
||||
var registerResult = SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN
|
||||
try {
|
||||
registerResult = satelliteManager.registerForModemStateChanged(executor, callback)
|
||||
} catch (e: IllegalStateException) {
|
||||
Log.w(TAG, "IllegalStateException $e")
|
||||
}
|
||||
if (registerResult != SatelliteManager.SATELLITE_RESULT_SUCCESS) {
|
||||
Log.w(TAG, "Failed to register for satellite modem state change: $registerResult")
|
||||
completer.set(false)
|
||||
@@ -132,15 +145,21 @@ class SatelliteRepository(
|
||||
return callbackFlow {
|
||||
val callback = SatelliteModemStateCallback { state ->
|
||||
val isSessionStarted = isSatelliteSessionStarted(state)
|
||||
Log.i(TAG, "Satellite modem state changed: state=$state"
|
||||
+ ", isSessionStarted=$isSessionStarted")
|
||||
Log.i(
|
||||
TAG, "Satellite modem state changed: state=$state"
|
||||
+ ", isSessionStarted=$isSessionStarted"
|
||||
)
|
||||
trySend(isSessionStarted)
|
||||
}
|
||||
|
||||
val registerResult = satelliteManager.registerForModemStateChanged(
|
||||
defaultDispatcher.asExecutor(),
|
||||
callback
|
||||
)
|
||||
var registerResult: Int = SatelliteManager.SATELLITE_RESULT_ERROR
|
||||
try {
|
||||
registerResult = satelliteManager.registerForModemStateChanged(
|
||||
defaultDispatcher.asExecutor(),
|
||||
callback
|
||||
)
|
||||
} catch (e: IllegalStateException) {
|
||||
Log.w(TAG, "IllegalStateException $e")
|
||||
}
|
||||
|
||||
if (registerResult != SatelliteManager.SATELLITE_RESULT_SUCCESS) {
|
||||
// If the registration failed (e.g., device doesn't support satellite),
|
||||
@@ -150,7 +169,13 @@ class SatelliteRepository(
|
||||
trySend(false)
|
||||
}
|
||||
|
||||
awaitClose { satelliteManager.unregisterForModemStateChanged(callback) }
|
||||
awaitClose {
|
||||
try {
|
||||
satelliteManager.unregisterForModemStateChanged(callback)
|
||||
} catch (e: IllegalStateException) {
|
||||
Log.w(TAG, "IllegalStateException $e")
|
||||
}
|
||||
}
|
||||
}.flowOn(Dispatchers.Default)
|
||||
}
|
||||
|
||||
|
@@ -22,6 +22,7 @@ import android.telephony.SubscriptionInfo
|
||||
import com.android.settings.R
|
||||
import com.android.settings.network.SubscriptionUtil
|
||||
import com.android.settings.network.telephony.MmsMessagePreferenceController.Companion.MmsMessageSearchItem
|
||||
import com.android.settings.network.telephony.NrAdvancedCallingPreferenceController.Companion.NrAdvancedCallingSearchItem
|
||||
import com.android.settings.spa.SpaSearchLanding.BundleValue
|
||||
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingFragment
|
||||
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingKey
|
||||
@@ -41,6 +42,9 @@ class MobileNetworkSettingsSearchIndex(
|
||||
|
||||
val title: String
|
||||
|
||||
val keywords: String?
|
||||
get() = null
|
||||
|
||||
fun isAvailable(subId: Int): Boolean
|
||||
}
|
||||
|
||||
@@ -89,6 +93,7 @@ class MobileNetworkSettingsSearchIndex(
|
||||
context = context,
|
||||
spaSearchLandingKey = key,
|
||||
itemTitle = searchItem.title,
|
||||
keywords = searchItem.keywords,
|
||||
indexableClass = MobileNetworkSettings::class.java,
|
||||
pageTitle = "$simsTitle > ${subInfo.displayName}",
|
||||
)
|
||||
@@ -107,6 +112,7 @@ class MobileNetworkSettingsSearchIndex(
|
||||
fun createSearchItems(context: Context): List<MobileNetworkSettingsSearchItem> =
|
||||
listOf(
|
||||
MmsMessageSearchItem(context),
|
||||
NrAdvancedCallingSearchItem(context),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.android.settings.R
|
||||
import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem
|
||||
import com.android.settings.spa.preference.ComposePreferenceController
|
||||
import com.android.settingslib.spa.widget.preference.SwitchPreference
|
||||
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
|
||||
@@ -41,6 +42,7 @@ class NrAdvancedCallingPreferenceController @JvmOverloads constructor(
|
||||
) : ComposePreferenceController(context, key) {
|
||||
private var subId: Int = SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
||||
private var repository: VoNrRepository? = null
|
||||
private val searchItem = NrAdvancedCallingSearchItem(context)
|
||||
|
||||
/** Initial this PreferenceController. */
|
||||
@JvmOverloads
|
||||
@@ -50,7 +52,7 @@ class NrAdvancedCallingPreferenceController @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
override fun getAvailabilityStatus() =
|
||||
if (repository?.isVoNrAvailable() == true) AVAILABLE else CONDITIONALLY_UNAVAILABLE
|
||||
if (searchItem.isAvailable(subId)) AVAILABLE else CONDITIONALLY_UNAVAILABLE
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
@@ -73,4 +75,16 @@ class NrAdvancedCallingPreferenceController @JvmOverloads constructor(
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
companion object {
|
||||
class NrAdvancedCallingSearchItem(private val context: Context) :
|
||||
MobileNetworkSettingsSearchItem {
|
||||
override val key = "nr_advanced_calling"
|
||||
override val title: String = context.getString(R.string.nr_advanced_calling_title)
|
||||
override val keywords: String = context.getString(R.string.keywords_nr_advanced_calling)
|
||||
|
||||
override fun isAvailable(subId: Int): Boolean =
|
||||
VoNrRepository(context, subId).isVoNrAvailable()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -93,10 +93,12 @@ class SpaSearchRepository(
|
||||
itemTitle: String,
|
||||
indexableClass: Class<*>,
|
||||
pageTitle: String,
|
||||
keywords: String? = null,
|
||||
) =
|
||||
SearchIndexableRaw(context).apply {
|
||||
key = spaSearchLandingKey.toByteString().toStringUtf8()
|
||||
title = itemTitle
|
||||
this.keywords = keywords
|
||||
intentAction = SEARCH_LANDING_ACTION
|
||||
intentTargetClass = SpaSearchLandingActivity::class.qualifiedName
|
||||
packageName = context.packageName
|
||||
|
@@ -139,7 +139,8 @@ public class WifiEnabler implements SwitchWidgetController.OnSwitchChangeListene
|
||||
// Refresh satellite mode status.
|
||||
try {
|
||||
mIsSatelliteOn.set(
|
||||
mSatelliteRepository.requestIsEnabled(Executors.newSingleThreadExecutor())
|
||||
mSatelliteRepository
|
||||
.requestIsSessionStarted(Executors.newSingleThreadExecutor())
|
||||
.get(2000, TimeUnit.MILLISECONDS));
|
||||
} catch (ExecutionException | TimeoutException | InterruptedException e) {
|
||||
Log.e(TAG, "Error to get satellite status : " + e);
|
||||
|
@@ -431,7 +431,7 @@ public class WifiSlice implements CustomSliceable {
|
||||
boolean isSatelliteOn = false;
|
||||
try {
|
||||
isSatelliteOn =
|
||||
satelliteRepository.requestIsEnabled(Executors.newSingleThreadExecutor())
|
||||
satelliteRepository.requestIsSessionStarted(Executors.newSingleThreadExecutor())
|
||||
.get(2000, TimeUnit.MILLISECONDS);
|
||||
} catch (ExecutionException | TimeoutException | InterruptedException e) {
|
||||
Log.e(TAG, "Error to get satellite status : " + e);
|
||||
|
@@ -25,6 +25,8 @@ import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.platform.test.annotations.EnableFlags;
|
||||
import android.platform.test.flag.junit.SetFlagsRule;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
@@ -34,19 +36,24 @@ import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class KeyboardBounceKeyPreferenceControllerTest {
|
||||
|
||||
private static final String KEY_ACCESSIBILITY_BOUNCE_KEYS =
|
||||
Settings.Secure.ACCESSIBILITY_BOUNCE_KEYS;
|
||||
private static final int UNKNOWN = -1;
|
||||
|
||||
@Rule
|
||||
public final SetFlagsRule mSetFlagRule = new SetFlagsRule();
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
|
||||
private final KeyboardBounceKeyPreferenceController mController =
|
||||
@@ -131,4 +138,26 @@ public class KeyboardBounceKeyPreferenceControllerTest {
|
||||
mContext.getContentResolver(), KEY_ACCESSIBILITY_BOUNCE_KEYS,
|
||||
UNKNOWN)).isNotEqualTo(OFF);
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
|
||||
public void updateNonIndexableKeys_physicalKeyboardExists_returnEmptyList() {
|
||||
Assume.assumeTrue(AccessibilitySettings.isAnyHardKeyboardsExist());
|
||||
|
||||
List<String> nonIndexableKeys = new ArrayList<>();
|
||||
mController.updateNonIndexableKeys(nonIndexableKeys);
|
||||
|
||||
assertThat(nonIndexableKeys).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
|
||||
public void updateNonIndexableKeys_noPhysicalKeyboard_returnPreKey() {
|
||||
Assume.assumeFalse(AccessibilitySettings.isAnyHardKeyboardsExist());
|
||||
|
||||
List<String> nonIndexableKeys = new ArrayList<>();
|
||||
mController.updateNonIndexableKeys(nonIndexableKeys);
|
||||
|
||||
assertThat(nonIndexableKeys).contains(mController.getPreferenceKey());
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,8 @@ import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.platform.test.annotations.EnableFlags;
|
||||
import android.platform.test.flag.junit.SetFlagsRule;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
@@ -34,19 +36,24 @@ import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class KeyboardSlowKeyPreferenceControllerTest {
|
||||
|
||||
private static final String KEY_ACCESSIBILITY_SLOW_KEYS =
|
||||
Settings.Secure.ACCESSIBILITY_SLOW_KEYS;
|
||||
private static final int UNKNOWN = -1;
|
||||
|
||||
@Rule
|
||||
public final SetFlagsRule mSetFlagRule = new SetFlagsRule();
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
|
||||
private final KeyboardSlowKeyPreferenceController mController =
|
||||
@@ -131,4 +138,26 @@ public class KeyboardSlowKeyPreferenceControllerTest {
|
||||
mContext.getContentResolver(), KEY_ACCESSIBILITY_SLOW_KEYS, UNKNOWN)).isNotEqualTo(
|
||||
OFF);
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
|
||||
public void updateNonIndexableKeys_physicalKeyboardExists_returnEmptyList() {
|
||||
Assume.assumeTrue(AccessibilitySettings.isAnyHardKeyboardsExist());
|
||||
|
||||
List<String> nonIndexableKeys = new ArrayList<>();
|
||||
mController.updateNonIndexableKeys(nonIndexableKeys);
|
||||
|
||||
assertThat(nonIndexableKeys).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
|
||||
public void updateNonIndexableKeys_noPhysicalKeyboard_returnPreKey() {
|
||||
Assume.assumeFalse(AccessibilitySettings.isAnyHardKeyboardsExist());
|
||||
|
||||
List<String> nonIndexableKeys = new ArrayList<>();
|
||||
mController.updateNonIndexableKeys(nonIndexableKeys);
|
||||
|
||||
assertThat(nonIndexableKeys).contains(mController.getPreferenceKey());
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,8 @@ import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.platform.test.annotations.EnableFlags;
|
||||
import android.platform.test.flag.junit.SetFlagsRule;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
@@ -34,19 +36,24 @@ import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class KeyboardStickyKeyPreferenceControllerTest {
|
||||
|
||||
private static final String KEY_ACCESSIBILITY_STICKY_KEYS =
|
||||
Settings.Secure.ACCESSIBILITY_STICKY_KEYS;
|
||||
private static final int UNKNOWN = -1;
|
||||
|
||||
@Rule
|
||||
public final SetFlagsRule mSetFlagRule = new SetFlagsRule();
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
|
||||
private final KeyboardStickyKeyPreferenceController mController =
|
||||
@@ -129,4 +136,26 @@ public class KeyboardStickyKeyPreferenceControllerTest {
|
||||
assertThat(Settings.Secure.getInt(
|
||||
mContext.getContentResolver(), KEY_ACCESSIBILITY_STICKY_KEYS, UNKNOWN)).isEqualTo(ON);
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
|
||||
public void updateNonIndexableKeys_physicalKeyboardExists_returnEmptyList() {
|
||||
Assume.assumeTrue(AccessibilitySettings.isAnyHardKeyboardsExist());
|
||||
|
||||
List<String> nonIndexableKeys = new ArrayList<>();
|
||||
mController.updateNonIndexableKeys(nonIndexableKeys);
|
||||
|
||||
assertThat(nonIndexableKeys).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
|
||||
public void updateNonIndexableKeys_noPhysicalKeyboard_returnPreKey() {
|
||||
Assume.assumeFalse(AccessibilitySettings.isAnyHardKeyboardsExist());
|
||||
|
||||
List<String> nonIndexableKeys = new ArrayList<>();
|
||||
mController.updateNonIndexableKeys(nonIndexableKeys);
|
||||
|
||||
assertThat(nonIndexableKeys).contains(mController.getPreferenceKey());
|
||||
}
|
||||
}
|
||||
|
@@ -21,10 +21,12 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
@@ -52,6 +54,7 @@ public class AudioSharingDashboardFragmentTest {
|
||||
|
||||
@Mock private SettingsActivity mActivity;
|
||||
@Mock private SettingsMainSwitchBar mSwitchBar;
|
||||
@Mock private View mView;
|
||||
@Mock private AudioSharingDeviceVolumeGroupController mVolumeGroupController;
|
||||
@Mock private AudioSharingCallAudioPreferenceController mCallAudioController;
|
||||
@Mock private AudioSharingPlaySoundPreferenceController mPlaySoundController;
|
||||
@@ -61,6 +64,7 @@ public class AudioSharingDashboardFragmentTest {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
when(mSwitchBar.getRootView()).thenReturn(mView);
|
||||
mFragment = new AudioSharingDashboardFragment();
|
||||
}
|
||||
|
||||
|
@@ -51,6 +51,8 @@ import android.os.Looper;
|
||||
import android.platform.test.flag.junit.SetFlagsRule;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.util.Pair;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.widget.CompoundButton;
|
||||
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
@@ -590,4 +592,26 @@ public class AudioSharingSwitchBarControllerTest {
|
||||
mController.mBroadcastAssistantCallback.onSourceLost(/* broadcastId= */ 1);
|
||||
verifyNoMoreInteractions(mFeatureFactory.metricsFeatureProvider);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAccessibilityDelegate() {
|
||||
View view = new View(mContext);
|
||||
AccessibilityEvent event =
|
||||
new AccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
|
||||
event.setContentChangeTypes(AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
|
||||
assertThat(
|
||||
mSwitchBar
|
||||
.getRootView()
|
||||
.getAccessibilityDelegate()
|
||||
.onRequestSendAccessibilityEvent(mSwitchBar, view, event))
|
||||
.isTrue();
|
||||
|
||||
event.setContentChangeTypes(AccessibilityEvent.CONTENT_CHANGE_TYPE_ENABLED);
|
||||
assertThat(
|
||||
mSwitchBar
|
||||
.getRootView()
|
||||
.getAccessibilityDelegate()
|
||||
.onRequestSendAccessibilityEvent(mSwitchBar, view, event))
|
||||
.isFalse();
|
||||
}
|
||||
}
|
||||
|
@@ -28,7 +28,6 @@ import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.preference.Preference.OnPreferenceClickListener;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
@@ -93,17 +92,6 @@ public class AudioStreamPreferenceTest {
|
||||
assertThat(divider.getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setConnected_shouldUpdatePreferenceUI() {
|
||||
String summary = "Connected";
|
||||
OnPreferenceClickListener listener = mock(OnPreferenceClickListener.class);
|
||||
mPreference.setIsConnected(true, summary, listener);
|
||||
|
||||
assertThat(mPreference.getSummary()).isNotNull();
|
||||
assertThat(mPreference.getSummary().toString()).isEqualTo(summary);
|
||||
assertThat(mPreference.getOnPreferenceClickListener()).isEqualTo(listener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAudioStreamMetadata_shouldUpdateMetadata() {
|
||||
AudioStreamPreference p =
|
||||
@@ -147,7 +135,7 @@ public class AudioStreamPreferenceTest {
|
||||
|
||||
@Test
|
||||
public void shouldHideSecondTarget_connected() {
|
||||
mPreference.setIsConnected(true, "", null);
|
||||
mPreference.setIsConnected(true);
|
||||
assertThat(mPreference.shouldHideSecondTarget()).isTrue();
|
||||
}
|
||||
|
||||
|
@@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -31,6 +30,7 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.SpannableString;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
@@ -39,6 +39,7 @@ import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
@@ -75,7 +76,9 @@ public class AudioStreamStateHandlerTest {
|
||||
|
||||
verify(mPreference, never()).setAudioStreamState(any());
|
||||
verify(mHandler, never()).performAction(any(), any(), any());
|
||||
verify(mPreference, never()).setIsConnected(anyBoolean(), anyString(), any());
|
||||
verify(mPreference, never()).setIsConnected(anyBoolean());
|
||||
verify(mPreference, never()).setSummary(any());
|
||||
verify(mPreference, never()).setOnPreferenceClickListener(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -93,7 +96,9 @@ public class AudioStreamStateHandlerTest {
|
||||
.setAudioStreamState(
|
||||
AudioStreamsProgressCategoryController.AudioStreamState.SOURCE_ADDED);
|
||||
verify(mHandler).performAction(any(), any(), any());
|
||||
verify(mPreference).setIsConnected(eq(true), eq(""), eq(null));
|
||||
verify(mPreference).setIsConnected(eq(true));
|
||||
verify(mPreference).setSummary(eq(""));
|
||||
verify(mPreference).setOnPreferenceClickListener(eq(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -119,7 +124,13 @@ public class AudioStreamStateHandlerTest {
|
||||
AudioStreamsProgressCategoryController.AudioStreamState
|
||||
.ADD_SOURCE_BAD_CODE);
|
||||
verify(mHandler).performAction(any(), any(), any());
|
||||
verify(mPreference).setIsConnected(eq(false), eq(SUMMARY), eq(listener));
|
||||
verify(mPreference).setIsConnected(eq(false));
|
||||
ArgumentCaptor<SpannableString> argumentCaptor =
|
||||
ArgumentCaptor.forClass(SpannableString.class);
|
||||
verify(mPreference).setSummary(argumentCaptor.capture());
|
||||
assertThat(argumentCaptor.getValue()).isNotNull();
|
||||
assertThat(argumentCaptor.getValue().toString()).isEqualTo(SUMMARY);
|
||||
verify(mPreference).setOnPreferenceClickListener(eq(listener));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@@ -18,13 +18,21 @@ package com.android.settings.development;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricManager;
|
||||
import android.hardware.biometrics.Flags;
|
||||
import android.platform.test.annotations.EnableFlags;
|
||||
import android.platform.test.flag.junit.SetFlagsRule;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import android.provider.Settings;
|
||||
|
||||
@@ -42,6 +50,7 @@ import com.android.settingslib.development.DevelopmentSettingsEnabler;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
@@ -51,6 +60,7 @@ import org.robolectric.annotation.Config;
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowBiometricManager;
|
||||
import org.robolectric.shadows.androidx.fragment.FragmentController;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@@ -61,22 +71,34 @@ import java.util.List;
|
||||
ShadowAlertDialogCompat.class,
|
||||
ShadowUserManager.class,
|
||||
ShadowUserManager.class,
|
||||
ShadowBiometricManager.class,
|
||||
})
|
||||
public class DevelopmentSettingsDashboardFragmentTest {
|
||||
@Rule
|
||||
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
||||
|
||||
private Context mContext;
|
||||
private ShadowUserManager mShadowUserManager;
|
||||
private ShadowBiometricManager mShadowBiometricManager;
|
||||
private DevelopmentSettingsDashboardFragment mDashboard;
|
||||
private SettingsMainSwitchBar mSwitchBar;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
SettingsMainSwitchBar switchBar = new SettingsMainSwitchBar(mContext);
|
||||
mSwitchBar = new SettingsMainSwitchBar(mContext);
|
||||
mDashboard = spy(new DevelopmentSettingsDashboardFragment());
|
||||
ReflectionHelpers.setField(mDashboard, "mSwitchBar", switchBar);
|
||||
ReflectionHelpers.setField(mDashboard, "mSwitchBar", mSwitchBar);
|
||||
mShadowUserManager = Shadow.extract(mContext.getSystemService(Context.USER_SERVICE));
|
||||
mShadowUserManager.setIsAdminUser(true);
|
||||
mShadowBiometricManager = Shadow.extract(mContext.getSystemService(
|
||||
Context.BIOMETRIC_SERVICE));
|
||||
mShadowBiometricManager.setCanAuthenticate(false);
|
||||
//TODO(b/352603684): Should be Authenticators.MANDATORY_BIOMETRICS,
|
||||
// but it is not supported by ShadowBiometricManager
|
||||
mShadowBiometricManager.setAuthenticatorType(
|
||||
BiometricManager.Authenticators.BIOMETRIC_STRONG);
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -176,6 +198,41 @@ public class DevelopmentSettingsDashboardFragmentTest {
|
||||
assertThat(ShadowEnableDevelopmentSettingWarningDialog.mShown).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowEnableDevelopmentSettingWarningDialog.class)
|
||||
@EnableFlags(Flags.FLAG_MANDATORY_BIOMETRICS)
|
||||
public void onSwitchChanged_turnOn_shouldLaunchBiometricPromptIfMandatoryBiometricsEffective() {
|
||||
when(mDashboard.getContext()).thenReturn(mContext);
|
||||
doNothing().when(mDashboard).startActivityForResult(any(),
|
||||
eq(DevelopmentSettingsDashboardFragment.REQUEST_BIOMETRIC_PROMPT));
|
||||
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
|
||||
mShadowBiometricManager.setCanAuthenticate(true);
|
||||
mDashboard.onCheckedChanged(null, true /* isChecked */);
|
||||
|
||||
assertThat(mSwitchBar.isChecked()).isFalse();
|
||||
verify(mDashboard).startActivityForResult(any(),
|
||||
eq(DevelopmentSettingsDashboardFragment.REQUEST_BIOMETRIC_PROMPT));
|
||||
assertThat(ShadowEnableDevelopmentSettingWarningDialog.mShown).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowEnableDevelopmentSettingWarningDialog.class)
|
||||
@EnableFlags(Flags.FLAG_MANDATORY_BIOMETRICS)
|
||||
public void onActivityResult_requestBiometricPrompt_shouldShowWarningDialog() {
|
||||
when(mDashboard.getContext()).thenReturn(mContext);
|
||||
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
|
||||
mDashboard.onActivityResult(DevelopmentSettingsDashboardFragment.REQUEST_BIOMETRIC_PROMPT,
|
||||
Activity.RESULT_OK, null);
|
||||
mDashboard.onCheckedChanged(null, true /* isChecked */);
|
||||
|
||||
assertThat(mSwitchBar.isChecked()).isTrue();
|
||||
assertThat(ShadowEnableDevelopmentSettingWarningDialog.mShown).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
@Config(shadows = ShadowEnableDevelopmentSettingWarningDialog.class)
|
||||
|
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2024 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.development;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class TouchpadVisualizerPreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
@Mock
|
||||
private SwitchPreference mPreference;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private TouchpadVisualizerPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mController = new TouchpadVisualizerPreferenceController(mContext);
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
mController.displayPreference(mScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_touchpadVisualizerEnabled_shouldCheckedPreference() {
|
||||
Settings.System.putInt(mContext.getContentResolver(),
|
||||
Settings.System.TOUCHPAD_VISUALIZER, ShowTapsPreferenceController.SETTING_VALUE_ON);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setChecked(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_touchpadVisualizerDisabled_shouldUncheckedPreference() {
|
||||
Settings.System.putInt(mContext.getContentResolver(),
|
||||
Settings.System.TOUCHPAD_VISUALIZER,
|
||||
ShowTapsPreferenceController.SETTING_VALUE_OFF);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setChecked(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_preferenceChecked_shouldEnableTouchpadVisualizer() {
|
||||
mController.onPreferenceChange(mPreference, true /* new value */);
|
||||
|
||||
final int touchpadVisualizer = Settings.System.getInt(mContext.getContentResolver(),
|
||||
Settings.System.TOUCHPAD_VISUALIZER, -1 /* default */);
|
||||
|
||||
assertThat(touchpadVisualizer).isEqualTo(ShowTapsPreferenceController.SETTING_VALUE_ON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_preferenceUnchecked_shouldDisableTouchpadVisualizer() {
|
||||
mController.onPreferenceChange(mPreference, false /* new value */);
|
||||
|
||||
final int showTapsMode = Settings.System.getInt(mContext.getContentResolver(),
|
||||
Settings.System.TOUCHPAD_VISUALIZER, -1 /* default */);
|
||||
|
||||
assertThat(showTapsMode).isEqualTo(ShowTapsPreferenceController.SETTING_VALUE_OFF);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeveloperOptionsSwitchDisabled_preferenceShouldBeEnabled() {
|
||||
mController.onDeveloperOptionsSwitchDisabled();
|
||||
|
||||
final int showTapsMode = Settings.System.getInt(mContext.getContentResolver(),
|
||||
Settings.System.TOUCHPAD_VISUALIZER, -1 /* default */);
|
||||
|
||||
assertThat(showTapsMode).isEqualTo(ShowTapsPreferenceController.SETTING_VALUE_OFF);
|
||||
verify(mPreference).setEnabled(false);
|
||||
verify(mPreference).setChecked(false);
|
||||
}
|
||||
}
|
@@ -91,7 +91,8 @@ class SatelliteRepositoryTest {
|
||||
|
||||
@Test
|
||||
fun requestIsSessionStarted_resultIsTrue() = runBlocking {
|
||||
`when`(mockSatelliteManager.registerForModemStateChanged(any(), any())
|
||||
`when`(
|
||||
mockSatelliteManager.registerForModemStateChanged(any(), any())
|
||||
).thenAnswer { invocation ->
|
||||
val callback = invocation.getArgument<SatelliteModemStateCallback>(1)
|
||||
callback.onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED)
|
||||
@@ -105,7 +106,8 @@ class SatelliteRepositoryTest {
|
||||
|
||||
@Test
|
||||
fun requestIsSessionStarted_resultIsFalse() = runBlocking {
|
||||
`when`(mockSatelliteManager.registerForModemStateChanged(any(), any())
|
||||
`when`(
|
||||
mockSatelliteManager.registerForModemStateChanged(any(), any())
|
||||
).thenAnswer { invocation ->
|
||||
val callback = invocation.getArgument<SatelliteModemStateCallback>(1)
|
||||
callback.onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_OFF)
|
||||
@@ -119,7 +121,8 @@ class SatelliteRepositoryTest {
|
||||
|
||||
@Test
|
||||
fun requestIsSessionStarted_registerFailed() = runBlocking {
|
||||
`when`(mockSatelliteManager.registerForModemStateChanged(any(), any())
|
||||
`when`(
|
||||
mockSatelliteManager.registerForModemStateChanged(any(), any())
|
||||
).thenAnswer {
|
||||
SatelliteManager.SATELLITE_RESULT_ERROR
|
||||
}
|
||||
@@ -129,6 +132,17 @@ class SatelliteRepositoryTest {
|
||||
verify(mockSatelliteManager, never()).unregisterForModemStateChanged(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun requestIsSessionStarted_phoneCrash_registerFailed() = runBlocking {
|
||||
`when`(
|
||||
mockSatelliteManager.registerForModemStateChanged(any(), any())
|
||||
).thenThrow(IllegalStateException("Telephony is null"))
|
||||
|
||||
val result: ListenableFuture<Boolean> = repository.requestIsSessionStarted(mockExecutor)
|
||||
assertFalse(result.get())
|
||||
verify(mockSatelliteManager, never()).unregisterForModemStateChanged(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun requestIsSessionStarted_nullSatelliteManager() = runBlocking {
|
||||
`when`(spyContext.getSystemService(SatelliteManager::class.java)).thenReturn(null)
|
||||
@@ -157,6 +171,17 @@ class SatelliteRepositoryTest {
|
||||
assertFalse(result.get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun requestIsEnabled_phoneCrash_resultIsFalse() = runBlocking {
|
||||
`when`(
|
||||
mockSatelliteManager.requestIsEnabled(any(), any())
|
||||
).thenThrow(IllegalStateException("Telephony is null"))
|
||||
|
||||
val result: ListenableFuture<Boolean> =
|
||||
repository.requestIsEnabled(mockExecutor)
|
||||
assertFalse(result.get())
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun requestIsEnabled_exceptionFailure() = runBlocking {
|
||||
@@ -232,7 +257,8 @@ class SatelliteRepositoryTest {
|
||||
|
||||
@Test
|
||||
fun getIsSessionStartedFlow_registerFailed() = runBlocking {
|
||||
`when`(mockSatelliteManager.registerForModemStateChanged(any(), any())
|
||||
`when`(
|
||||
mockSatelliteManager.registerForModemStateChanged(any(), any())
|
||||
).thenAnswer {
|
||||
SatelliteManager.SATELLITE_RESULT_ERROR
|
||||
}
|
||||
|
@@ -28,8 +28,13 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricManager;
|
||||
import android.hardware.biometrics.Flags;
|
||||
import android.os.Looper;
|
||||
import android.os.UserManager;
|
||||
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.lifecycle.LifecycleOwner;
|
||||
@@ -45,6 +50,7 @@ import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.development.DevelopmentSettingsEnabler;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
@@ -53,6 +59,9 @@ import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class BuildNumberPreferenceControllerTest {
|
||||
@Rule
|
||||
public final CheckFlagsRule mCheckFlagsRule =
|
||||
DeviceFlagsValueProvider.createCheckFlagsRule();
|
||||
|
||||
private static final String KEY_BUILD_NUMBER = "build_number";
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
@@ -60,6 +69,7 @@ public class BuildNumberPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
private UserManager mUserManager;
|
||||
private BiometricManager mBiometricManager;
|
||||
private LifecycleOwner mLifecycleOwner;
|
||||
private Lifecycle mLifecycle;
|
||||
private FakeFeatureFactory mFactory;
|
||||
@@ -76,7 +86,13 @@ public class BuildNumberPreferenceControllerTest {
|
||||
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
mUserManager = (UserManager) spy(mContext.getSystemService(Context.USER_SERVICE));
|
||||
mBiometricManager = spy(mContext.getSystemService(BiometricManager.class));
|
||||
|
||||
doReturn(mUserManager).when(mContext).getSystemService(Context.USER_SERVICE);
|
||||
when(mContext.getSystemService(BiometricManager.class)).thenReturn(mBiometricManager);
|
||||
when(mBiometricManager.canAuthenticate(mContext.getUserId(),
|
||||
BiometricManager.Authenticators.MANDATORY_BIOMETRICS))
|
||||
.thenReturn(BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE);
|
||||
|
||||
mFactory = FakeFeatureFactory.setupForTest();
|
||||
mLifecycleOwner = () -> mLifecycle;
|
||||
@@ -156,7 +172,7 @@ public class BuildNumberPreferenceControllerTest {
|
||||
@Test
|
||||
public void onActivityResult_notConfirmPasswordRequest_doNothing() {
|
||||
final boolean activityResultHandled = mController.onActivityResult(
|
||||
BuildNumberPreferenceController.REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF + 1,
|
||||
BuildNumberPreferenceController.REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF + 2,
|
||||
Activity.RESULT_OK,
|
||||
null);
|
||||
|
||||
@@ -188,4 +204,38 @@ public class BuildNumberPreferenceControllerTest {
|
||||
assertThat(activityResultHandled).isTrue();
|
||||
assertThat(DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
@RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
|
||||
public void onActivityResult_confirmPasswordRequestCompleted_launchBiometricPrompt() {
|
||||
when(mUserManager.isAdminUser()).thenReturn(true);
|
||||
when(mBiometricManager.canAuthenticate(mContext.getUserId(),
|
||||
BiometricManager.Authenticators.MANDATORY_BIOMETRICS))
|
||||
.thenReturn(BiometricManager.BIOMETRIC_SUCCESS);
|
||||
|
||||
final boolean activityResultHandled = mController.onActivityResult(
|
||||
BuildNumberPreferenceController.REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF,
|
||||
Activity.RESULT_OK,
|
||||
null);
|
||||
|
||||
assertThat(activityResultHandled).isTrue();
|
||||
assertThat(DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)).isFalse();
|
||||
verify(mFragment).startActivityForResult(any(),
|
||||
eq(BuildNumberPreferenceController.REQUEST_IDENTITY_CHECK_FOR_DEV_PREF));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onActivityResult_confirmBiometricAuthentication_enableDevPref() {
|
||||
when(mUserManager.isAdminUser()).thenReturn(true);
|
||||
|
||||
Looper.prepare();
|
||||
final boolean activityResultHandled = mController.onActivityResult(
|
||||
BuildNumberPreferenceController.REQUEST_IDENTITY_CHECK_FOR_DEV_PREF,
|
||||
Activity.RESULT_OK,
|
||||
null);
|
||||
|
||||
assertThat(activityResultHandled).isTrue();
|
||||
assertThat(DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)).isTrue();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user