Snap for 12173239 from f2d6fe9e32
to 24Q4-release
Change-Id: I993b777f5a9e84bf1aa9be97af904dcf8d42ba85
This commit is contained in:
@@ -51,6 +51,16 @@ flag {
|
|||||||
bug: "301198830"
|
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 {
|
flag {
|
||||||
name: "hide_magnification_always_on_toggle_when_window_mode_only"
|
name: "hide_magnification_always_on_toggle_when_window_mode_only"
|
||||||
namespace: "accessibility"
|
namespace: "accessibility"
|
||||||
|
@@ -26,7 +26,8 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minHeight="48dp"
|
android:minHeight="48dp"
|
||||||
android:textAlignment="viewStart"/>
|
android:textAlignment="viewStart"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"/>
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/broadcast_edit_text"
|
android:id="@+id/broadcast_edit_text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -34,11 +35,4 @@
|
|||||||
android:maxLength="16"
|
android:maxLength="16"
|
||||||
android:minHeight="48dp"
|
android:minHeight="48dp"
|
||||||
android:textAlignment="viewStart"/>
|
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>
|
</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] -->
|
<!-- 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>
|
<string name="enable_quick_setting">Show in Quick Settings</string>
|
||||||
<!-- Title shown for deuteranomaly (red-green color blindness) [CHAR LIMIT=45] -->
|
<!-- 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] -->
|
<!-- 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] -->
|
<!-- Title shown for tritanomaly (blue-yellow color blindness) [CHAR LIMIT=45] -->
|
||||||
<string name="daltonizer_mode_tritanomaly_title">Blue-yellow</string>
|
<string name="daltonizer_mode_tritanomaly_title">Blue-yellow</string>
|
||||||
<!-- Title shown for grayscale [CHAR LIMIT=45] -->
|
<!-- 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] -->
|
<!-- 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>
|
<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] -->
|
<!-- 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] -->
|
<!-- 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] -->
|
<!-- Summary shown for tritanomaly (blue-yellow color blindness) [CHAR LIMIT=45] -->
|
||||||
<string name="daltonizer_mode_tritanomaly_summary">Tritanomaly</string>
|
<string name="daltonizer_mode_tritanomaly_summary">Tritanomaly</string>
|
||||||
|
|
||||||
|
@@ -507,6 +507,11 @@
|
|||||||
android:title="@string/show_key_presses"
|
android:title="@string/show_key_presses"
|
||||||
android:summary="@string/show_key_presses_summary" />
|
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>
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
|
@@ -293,10 +293,10 @@
|
|||||||
settings:controller=
|
settings:controller=
|
||||||
"com.android.settings.network.telephony.NullAlgorithmsPreferenceController"/>
|
"com.android.settings.network.telephony.NullAlgorithmsPreferenceController"/>
|
||||||
|
|
||||||
|
<!-- Settings search is handled by NrAdvancedCallingSearchItem. -->
|
||||||
<com.android.settings.spa.preference.ComposePreference
|
<com.android.settings.spa.preference.ComposePreference
|
||||||
android:key="nr_advanced_calling"
|
android:key="nr_advanced_calling"
|
||||||
android:title="@string/nr_advanced_calling_title"
|
settings:searchable="false"
|
||||||
settings:keywords="@string/keywords_nr_advanced_calling"
|
|
||||||
settings:controller="com.android.settings.network.telephony.NrAdvancedCallingPreferenceController"/>
|
settings:controller="com.android.settings.network.telephony.NrAdvancedCallingPreferenceController"/>
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
@@ -613,7 +613,7 @@ public class AccessibilitySettings extends DashboardFragment implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAnyHardKeyboardsExist() {
|
static boolean isAnyHardKeyboardsExist() {
|
||||||
for (int deviceId : InputDevice.getDeviceIds()) {
|
for (int deviceId : InputDevice.getDeviceIds()) {
|
||||||
final InputDevice device = InputDevice.getDevice(deviceId);
|
final InputDevice device = InputDevice.getDevice(deviceId);
|
||||||
if (device != null && !device.isVirtual() && device.isFullKeyboard()) {
|
if (device != null && !device.isVirtual() && device.isFullKeyboard()) {
|
||||||
|
@@ -19,16 +19,21 @@ package com.android.settings.accessibility;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.hardware.input.InputSettings;
|
import android.hardware.input.InputSettings;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.core.TogglePreferenceController;
|
import com.android.settings.core.TogglePreferenceController;
|
||||||
import com.android.settings.inputmethod.PhysicalKeyboardFragment;
|
import com.android.settings.inputmethod.PhysicalKeyboardFragment;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A toggle preference controller for keyboard bounce key.
|
* A toggle preference controller for keyboard bounce key.
|
||||||
*/
|
*/
|
||||||
public class KeyboardBounceKeyPreferenceController extends TogglePreferenceController {
|
public class KeyboardBounceKeyPreferenceController extends TogglePreferenceController {
|
||||||
|
private static final String TAG = "BounceKeyPrefController";
|
||||||
static final String PREF_KEY = "toggle_keyboard_bounce_keys";
|
static final String PREF_KEY = "toggle_keyboard_bounce_keys";
|
||||||
|
|
||||||
public KeyboardBounceKeyPreferenceController(Context context, String preferenceKey) {
|
public KeyboardBounceKeyPreferenceController(Context context, String preferenceKey) {
|
||||||
@@ -58,4 +63,17 @@ public class KeyboardBounceKeyPreferenceController extends TogglePreferenceContr
|
|||||||
public int getSliceHighlightMenuRes() {
|
public int getSliceHighlightMenuRes() {
|
||||||
return R.string.menu_key_accessibility;
|
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.content.Context;
|
||||||
import android.hardware.input.InputSettings;
|
import android.hardware.input.InputSettings;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.core.TogglePreferenceController;
|
import com.android.settings.core.TogglePreferenceController;
|
||||||
import com.android.settings.inputmethod.PhysicalKeyboardFragment;
|
import com.android.settings.inputmethod.PhysicalKeyboardFragment;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A toggle preference controller for keyboard slow key.
|
* A toggle preference controller for keyboard slow key.
|
||||||
*/
|
*/
|
||||||
public class KeyboardSlowKeyPreferenceController extends TogglePreferenceController {
|
public class KeyboardSlowKeyPreferenceController extends TogglePreferenceController {
|
||||||
|
private static final String TAG = "SlowKeyPrefController";
|
||||||
|
|
||||||
static final String PREF_KEY = "toggle_keyboard_slow_keys";
|
static final String PREF_KEY = "toggle_keyboard_slow_keys";
|
||||||
|
|
||||||
@@ -58,4 +64,17 @@ public class KeyboardSlowKeyPreferenceController extends TogglePreferenceControl
|
|||||||
public int getSliceHighlightMenuRes() {
|
public int getSliceHighlightMenuRes() {
|
||||||
return R.string.menu_key_accessibility;
|
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.content.Context;
|
||||||
import android.hardware.input.InputSettings;
|
import android.hardware.input.InputSettings;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.core.TogglePreferenceController;
|
import com.android.settings.core.TogglePreferenceController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A toggle preference controller for keyboard sticky key.
|
* A toggle preference controller for keyboard sticky key.
|
||||||
*/
|
*/
|
||||||
public class KeyboardStickyKeyPreferenceController extends TogglePreferenceController {
|
public class KeyboardStickyKeyPreferenceController extends TogglePreferenceController {
|
||||||
|
private static final String TAG = "StickyKeyPrefController";
|
||||||
static final String PREF_KEY = "toggle_keyboard_sticky_keys";
|
static final String PREF_KEY = "toggle_keyboard_sticky_keys";
|
||||||
|
|
||||||
public KeyboardStickyKeyPreferenceController(Context context, String preferenceKey) {
|
public KeyboardStickyKeyPreferenceController(Context context, String preferenceKey) {
|
||||||
@@ -55,4 +60,17 @@ public class KeyboardStickyKeyPreferenceController extends TogglePreferenceContr
|
|||||||
public int getSliceHighlightMenuRes() {
|
public int getSliceHighlightMenuRes() {
|
||||||
return R.string.menu_key_accessibility;
|
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(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
mIsSatelliteOn.set(mSatelliteRepository.requestIsEnabled(
|
mIsSatelliteOn.set(mSatelliteRepository.requestIsSessionStarted(
|
||||||
Executors.newSingleThreadExecutor()).get(3000, TimeUnit.MILLISECONDS));
|
Executors.newSingleThreadExecutor()).get(3000, TimeUnit.MILLISECONDS));
|
||||||
} catch (InterruptedException | ExecutionException | TimeoutException e) {
|
} catch (InterruptedException | ExecutionException | TimeoutException e) {
|
||||||
Log.e(TAG, "Error to get satellite status : " + e);
|
Log.e(TAG, "Error to get satellite status : " + e);
|
||||||
|
@@ -79,7 +79,7 @@ public class BluetoothPairingDetail extends BluetoothDevicePairingDetailBase imp
|
|||||||
boolean isSatelliteOn = true;
|
boolean isSatelliteOn = true;
|
||||||
try {
|
try {
|
||||||
isSatelliteOn =
|
isSatelliteOn =
|
||||||
satelliteRepository.requestIsEnabled(
|
satelliteRepository.requestIsSessionStarted(
|
||||||
Executors.newSingleThreadExecutor()).get(3000, TimeUnit.MILLISECONDS);
|
Executors.newSingleThreadExecutor()).get(3000, TimeUnit.MILLISECONDS);
|
||||||
} catch (InterruptedException | ExecutionException | TimeoutException e) {
|
} catch (InterruptedException | ExecutionException | TimeoutException e) {
|
||||||
Log.e(TAG, "Error to get satellite status : " + 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.FeatureFlagUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
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;
|
||||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||||
|
|
||||||
@@ -284,6 +287,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
: mProfileManager.getLeAudioBroadcastAssistantProfile();
|
: mProfileManager.getLeAudioBroadcastAssistantProfile();
|
||||||
mExecutor = Executors.newSingleThreadExecutor();
|
mExecutor = Executors.newSingleThreadExecutor();
|
||||||
mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
|
mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
|
||||||
|
mSwitchBar.getRootView().setAccessibilityDelegate(new MainSwitchAccessibilityDelegate());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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
|
* Update preference UI based on connection status
|
||||||
*
|
*
|
||||||
* @param isConnected Is this stream connected
|
* @param isConnected Is this stream connected
|
||||||
* @param summary Summary text
|
|
||||||
* @param onPreferenceClickListener Click listener for the preference
|
|
||||||
*/
|
*/
|
||||||
void setIsConnected(
|
void setIsConnected(boolean isConnected) {
|
||||||
boolean isConnected,
|
if (mIsConnected != isConnected) {
|
||||||
String summary,
|
mIsConnected = isConnected;
|
||||||
@Nullable OnPreferenceClickListener onPreferenceClickListener) {
|
notifyChanged();
|
||||||
if (mIsConnected == isConnected
|
|
||||||
&& getSummary() == summary
|
|
||||||
&& getOnPreferenceClickListener() == onPreferenceClickListener) {
|
|
||||||
// Nothing to update.
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
mIsConnected = isConnected;
|
|
||||||
setSummary(summary);
|
|
||||||
setOnPreferenceClickListener(onPreferenceClickListener);
|
|
||||||
notifyChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@@ -16,8 +16,12 @@
|
|||||||
|
|
||||||
package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||||
|
|
||||||
|
import static android.text.Spanned.SPAN_EXCLUSIVE_INCLUSIVE;
|
||||||
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.text.SpannableString;
|
||||||
|
import android.text.style.ForegroundColorSpan;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@@ -26,6 +30,7 @@ import androidx.annotation.VisibleForTesting;
|
|||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
|
import com.android.settingslib.Utils;
|
||||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||||
import com.android.settingslib.utils.ThreadUtils;
|
import com.android.settingslib.utils.ThreadUtils;
|
||||||
@@ -68,15 +73,31 @@ class AudioStreamStateHandler {
|
|||||||
|
|
||||||
// Update UI
|
// Update UI
|
||||||
ThreadUtils.postOnMainThread(
|
ThreadUtils.postOnMainThread(
|
||||||
() ->
|
() -> {
|
||||||
preference.setIsConnected(
|
String summary =
|
||||||
newState
|
getSummary() != EMPTY_STRING_RES
|
||||||
== AudioStreamsProgressCategoryController.AudioStreamState
|
? preference.getContext().getString(getSummary())
|
||||||
.SOURCE_ADDED,
|
: "";
|
||||||
getSummary() != EMPTY_STRING_RES
|
if (newState
|
||||||
? preference.getContext().getString(getSummary())
|
== AudioStreamsProgressCategoryController.AudioStreamState
|
||||||
: "",
|
.ADD_SOURCE_BAD_CODE) {
|
||||||
getOnClickListener(controller)));
|
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;
|
package com.android.settings.development;
|
||||||
|
|
||||||
|
import static android.app.Activity.RESULT_OK;
|
||||||
import static android.provider.Settings.Global.DEVELOPMENT_SETTINGS_ENABLED;
|
import static android.provider.Settings.Global.DEVELOPMENT_SETTINGS_ENABLED;
|
||||||
import static android.service.quicksettings.TileService.ACTION_QS_TILE_PREFERENCES;
|
import static android.service.quicksettings.TileService.ACTION_QS_TILE_PREFERENCES;
|
||||||
import static android.view.flags.Flags.sensitiveContentAppProtectionApi;
|
import static android.view.flags.Flags.sensitiveContentAppProtectionApi;
|
||||||
@@ -100,11 +101,13 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
|||||||
NfcRebootDialog.OnNfcRebootDialogConfirmedListener, BluetoothSnoopLogHost {
|
NfcRebootDialog.OnNfcRebootDialogConfirmedListener, BluetoothSnoopLogHost {
|
||||||
|
|
||||||
private static final String TAG = "DevSettingsDashboard";
|
private static final String TAG = "DevSettingsDashboard";
|
||||||
|
@VisibleForTesting static final int REQUEST_BIOMETRIC_PROMPT = 100;
|
||||||
|
|
||||||
private final BluetoothA2dpConfigStore mBluetoothA2dpConfigStore =
|
private final BluetoothA2dpConfigStore mBluetoothA2dpConfigStore =
|
||||||
new BluetoothA2dpConfigStore();
|
new BluetoothA2dpConfigStore();
|
||||||
|
|
||||||
private boolean mIsAvailable = true;
|
private boolean mIsAvailable = true;
|
||||||
|
private boolean mIsBiometricsAuthenticated;
|
||||||
private SettingsMainSwitchBar mSwitchBar;
|
private SettingsMainSwitchBar mSwitchBar;
|
||||||
private DevelopmentSwitchBarController mSwitchBarController;
|
private DevelopmentSwitchBarController mSwitchBarController;
|
||||||
private List<AbstractPreferenceController> mPreferenceControllers = new ArrayList<>();
|
private List<AbstractPreferenceController> mPreferenceControllers = new ArrayList<>();
|
||||||
@@ -216,6 +219,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
|||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
final ContentResolver cr = getContext().getContentResolver();
|
final ContentResolver cr = getContext().getContentResolver();
|
||||||
|
mIsBiometricsAuthenticated = false;
|
||||||
cr.registerContentObserver(mDevelopEnabled, false, mDeveloperSettingsObserver);
|
cr.registerContentObserver(mDevelopEnabled, false, mDeveloperSettingsObserver);
|
||||||
|
|
||||||
// Restore UI state based on whether developer options is enabled
|
// Restore UI state based on whether developer options is enabled
|
||||||
@@ -360,7 +364,18 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
|||||||
DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext());
|
DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext());
|
||||||
if (isChecked != developmentEnabledState) {
|
if (isChecked != developmentEnabledState) {
|
||||||
if (isChecked) {
|
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 {
|
} else {
|
||||||
final BluetoothA2dpHwOffloadPreferenceController a2dpController =
|
final BluetoothA2dpHwOffloadPreferenceController a2dpController =
|
||||||
getDevelopmentOptionsController(
|
getDevelopmentOptionsController(
|
||||||
@@ -534,6 +549,12 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
|||||||
@Override
|
@Override
|
||||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
boolean handledResult = false;
|
boolean handledResult = false;
|
||||||
|
if (requestCode == REQUEST_BIOMETRIC_PROMPT) {
|
||||||
|
if (resultCode == RESULT_OK) {
|
||||||
|
mIsBiometricsAuthenticated = true;
|
||||||
|
mSwitchBar.setChecked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
for (AbstractPreferenceController controller : mPreferenceControllers) {
|
for (AbstractPreferenceController controller : mPreferenceControllers) {
|
||||||
if (controller instanceof OnActivityResultListener) {
|
if (controller instanceof OnActivityResultListener) {
|
||||||
// We do not break early because it is possible for multiple controllers to
|
// 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 ShowTapsPreferenceController(context));
|
||||||
controllers.add(new PointerLocationPreferenceController(context));
|
controllers.add(new PointerLocationPreferenceController(context));
|
||||||
controllers.add(new ShowKeyPressesPreferenceController(context));
|
controllers.add(new ShowKeyPressesPreferenceController(context));
|
||||||
|
controllers.add(new TouchpadVisualizerPreferenceController(context));
|
||||||
controllers.add(new ShowSurfaceUpdatesPreferenceController(context));
|
controllers.add(new ShowSurfaceUpdatesPreferenceController(context));
|
||||||
controllers.add(new ShowLayoutBoundsPreferenceController(context));
|
controllers.add(new ShowLayoutBoundsPreferenceController(context));
|
||||||
controllers.add(new ShowHdrSdrRatioPreferenceController(context));
|
controllers.add(new ShowHdrSdrRatioPreferenceController(context));
|
||||||
|
@@ -16,3 +16,6 @@ per-file DesktopModePreferenceController.java=file:platform/frameworks/base:/lib
|
|||||||
# ADB
|
# ADB
|
||||||
per-file Adb*=set noparent
|
per-file Adb*=set noparent
|
||||||
per-file Adb*=file:platform/packages/modules/adb:/OWNERS
|
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 TAPS_TO_BE_A_DEVELOPER = 7;
|
||||||
static final int REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF = 100;
|
static final int REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF = 100;
|
||||||
|
static final int REQUEST_IDENTITY_CHECK_FOR_DEV_PREF = 101;
|
||||||
|
|
||||||
private Activity mActivity;
|
private Activity mActivity;
|
||||||
private InstrumentedPreferenceFragment mFragment;
|
private InstrumentedPreferenceFragment mFragment;
|
||||||
@@ -217,10 +218,24 @@ public class BuildNumberPreferenceController extends BasePreferenceController im
|
|||||||
* @return if activity result is handled.
|
* @return if activity result is handled.
|
||||||
*/
|
*/
|
||||||
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
|
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;
|
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();
|
enableDevelopmentSettings();
|
||||||
}
|
}
|
||||||
mProcessingLastDevHit = false;
|
mProcessingLastDevHit = false;
|
||||||
|
@@ -162,7 +162,8 @@ public class AirplaneModePreferenceController extends TogglePreferenceController
|
|||||||
public void onResume() {
|
public void onResume() {
|
||||||
try {
|
try {
|
||||||
mIsSatelliteOn.set(
|
mIsSatelliteOn.set(
|
||||||
mSatelliteRepository.requestIsEnabled(Executors.newSingleThreadExecutor())
|
mSatelliteRepository
|
||||||
|
.requestIsSessionStarted(Executors.newSingleThreadExecutor())
|
||||||
.get(2000, TimeUnit.MILLISECONDS));
|
.get(2000, TimeUnit.MILLISECONDS));
|
||||||
} catch (ExecutionException | TimeoutException | InterruptedException e) {
|
} catch (ExecutionException | TimeoutException | InterruptedException e) {
|
||||||
Log.e(TAG, "Error to get satellite status : " + e);
|
Log.e(TAG, "Error to get satellite status : " + e);
|
||||||
|
@@ -25,6 +25,7 @@ import androidx.annotation.VisibleForTesting
|
|||||||
import androidx.concurrent.futures.CallbackToFutureAdapter
|
import androidx.concurrent.futures.CallbackToFutureAdapter
|
||||||
import com.google.common.util.concurrent.Futures.immediateFuture
|
import com.google.common.util.concurrent.Futures.immediateFuture
|
||||||
import com.google.common.util.concurrent.ListenableFuture
|
import com.google.common.util.concurrent.ListenableFuture
|
||||||
|
import java.util.concurrent.Executor
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.asExecutor
|
import kotlinx.coroutines.asExecutor
|
||||||
@@ -32,7 +33,6 @@ import kotlinx.coroutines.channels.awaitClose
|
|||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.callbackFlow
|
import kotlinx.coroutines.flow.callbackFlow
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import java.util.concurrent.Executor
|
|
||||||
import kotlinx.coroutines.flow.flowOn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,20 +58,26 @@ class SatelliteRepository(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return CallbackToFutureAdapter.getFuture { completer ->
|
return CallbackToFutureAdapter.getFuture { completer ->
|
||||||
satelliteManager.requestIsEnabled(executor,
|
try {
|
||||||
object : OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> {
|
satelliteManager.requestIsEnabled(executor,
|
||||||
override fun onResult(result: Boolean) {
|
object : OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> {
|
||||||
Log.i(TAG, "Satellite modem enabled status: $result")
|
override fun onResult(result: Boolean) {
|
||||||
completer.set(result)
|
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 {
|
val callback = object : SatelliteModemStateCallback {
|
||||||
override fun onSatelliteModemStateChanged(state: Int) {
|
override fun onSatelliteModemStateChanged(state: Int) {
|
||||||
val isSessionStarted = isSatelliteSessionStarted(state)
|
val isSessionStarted = isSatelliteSessionStarted(state)
|
||||||
Log.i(TAG, "Satellite modem state changed: state=$state"
|
Log.i(
|
||||||
+ ", isSessionStarted=$isSessionStarted")
|
TAG, "Satellite modem state changed: state=$state"
|
||||||
|
+ ", isSessionStarted=$isSessionStarted"
|
||||||
|
)
|
||||||
completer.set(isSessionStarted)
|
completer.set(isSessionStarted)
|
||||||
satelliteManager.unregisterForModemStateChanged(this)
|
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) {
|
if (registerResult != SatelliteManager.SATELLITE_RESULT_SUCCESS) {
|
||||||
Log.w(TAG, "Failed to register for satellite modem state change: $registerResult")
|
Log.w(TAG, "Failed to register for satellite modem state change: $registerResult")
|
||||||
completer.set(false)
|
completer.set(false)
|
||||||
@@ -132,15 +145,21 @@ class SatelliteRepository(
|
|||||||
return callbackFlow {
|
return callbackFlow {
|
||||||
val callback = SatelliteModemStateCallback { state ->
|
val callback = SatelliteModemStateCallback { state ->
|
||||||
val isSessionStarted = isSatelliteSessionStarted(state)
|
val isSessionStarted = isSatelliteSessionStarted(state)
|
||||||
Log.i(TAG, "Satellite modem state changed: state=$state"
|
Log.i(
|
||||||
+ ", isSessionStarted=$isSessionStarted")
|
TAG, "Satellite modem state changed: state=$state"
|
||||||
|
+ ", isSessionStarted=$isSessionStarted"
|
||||||
|
)
|
||||||
trySend(isSessionStarted)
|
trySend(isSessionStarted)
|
||||||
}
|
}
|
||||||
|
var registerResult: Int = SatelliteManager.SATELLITE_RESULT_ERROR
|
||||||
val registerResult = satelliteManager.registerForModemStateChanged(
|
try {
|
||||||
defaultDispatcher.asExecutor(),
|
registerResult = satelliteManager.registerForModemStateChanged(
|
||||||
callback
|
defaultDispatcher.asExecutor(),
|
||||||
)
|
callback
|
||||||
|
)
|
||||||
|
} catch (e: IllegalStateException) {
|
||||||
|
Log.w(TAG, "IllegalStateException $e")
|
||||||
|
}
|
||||||
|
|
||||||
if (registerResult != SatelliteManager.SATELLITE_RESULT_SUCCESS) {
|
if (registerResult != SatelliteManager.SATELLITE_RESULT_SUCCESS) {
|
||||||
// If the registration failed (e.g., device doesn't support satellite),
|
// If the registration failed (e.g., device doesn't support satellite),
|
||||||
@@ -150,7 +169,13 @@ class SatelliteRepository(
|
|||||||
trySend(false)
|
trySend(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
awaitClose { satelliteManager.unregisterForModemStateChanged(callback) }
|
awaitClose {
|
||||||
|
try {
|
||||||
|
satelliteManager.unregisterForModemStateChanged(callback)
|
||||||
|
} catch (e: IllegalStateException) {
|
||||||
|
Log.w(TAG, "IllegalStateException $e")
|
||||||
|
}
|
||||||
|
}
|
||||||
}.flowOn(Dispatchers.Default)
|
}.flowOn(Dispatchers.Default)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -22,6 +22,7 @@ import android.telephony.SubscriptionInfo
|
|||||||
import com.android.settings.R
|
import com.android.settings.R
|
||||||
import com.android.settings.network.SubscriptionUtil
|
import com.android.settings.network.SubscriptionUtil
|
||||||
import com.android.settings.network.telephony.MmsMessagePreferenceController.Companion.MmsMessageSearchItem
|
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.BundleValue
|
||||||
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingFragment
|
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingFragment
|
||||||
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingKey
|
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingKey
|
||||||
@@ -41,6 +42,9 @@ class MobileNetworkSettingsSearchIndex(
|
|||||||
|
|
||||||
val title: String
|
val title: String
|
||||||
|
|
||||||
|
val keywords: String?
|
||||||
|
get() = null
|
||||||
|
|
||||||
fun isAvailable(subId: Int): Boolean
|
fun isAvailable(subId: Int): Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,6 +93,7 @@ class MobileNetworkSettingsSearchIndex(
|
|||||||
context = context,
|
context = context,
|
||||||
spaSearchLandingKey = key,
|
spaSearchLandingKey = key,
|
||||||
itemTitle = searchItem.title,
|
itemTitle = searchItem.title,
|
||||||
|
keywords = searchItem.keywords,
|
||||||
indexableClass = MobileNetworkSettings::class.java,
|
indexableClass = MobileNetworkSettings::class.java,
|
||||||
pageTitle = "$simsTitle > ${subInfo.displayName}",
|
pageTitle = "$simsTitle > ${subInfo.displayName}",
|
||||||
)
|
)
|
||||||
@@ -107,6 +112,7 @@ class MobileNetworkSettingsSearchIndex(
|
|||||||
fun createSearchItems(context: Context): List<MobileNetworkSettingsSearchItem> =
|
fun createSearchItems(context: Context): List<MobileNetworkSettingsSearchItem> =
|
||||||
listOf(
|
listOf(
|
||||||
MmsMessageSearchItem(context),
|
MmsMessageSearchItem(context),
|
||||||
|
NrAdvancedCallingSearchItem(context),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,7 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.android.settings.R
|
import com.android.settings.R
|
||||||
|
import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem
|
||||||
import com.android.settings.spa.preference.ComposePreferenceController
|
import com.android.settings.spa.preference.ComposePreferenceController
|
||||||
import com.android.settingslib.spa.widget.preference.SwitchPreference
|
import com.android.settingslib.spa.widget.preference.SwitchPreference
|
||||||
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
|
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
|
||||||
@@ -41,6 +42,7 @@ class NrAdvancedCallingPreferenceController @JvmOverloads constructor(
|
|||||||
) : ComposePreferenceController(context, key) {
|
) : ComposePreferenceController(context, key) {
|
||||||
private var subId: Int = SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
private var subId: Int = SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
||||||
private var repository: VoNrRepository? = null
|
private var repository: VoNrRepository? = null
|
||||||
|
private val searchItem = NrAdvancedCallingSearchItem(context)
|
||||||
|
|
||||||
/** Initial this PreferenceController. */
|
/** Initial this PreferenceController. */
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
@@ -50,7 +52,7 @@ class NrAdvancedCallingPreferenceController @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getAvailabilityStatus() =
|
override fun getAvailabilityStatus() =
|
||||||
if (repository?.isVoNrAvailable() == true) AVAILABLE else CONDITIONALLY_UNAVAILABLE
|
if (searchItem.isAvailable(subId)) AVAILABLE else CONDITIONALLY_UNAVAILABLE
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
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,
|
itemTitle: String,
|
||||||
indexableClass: Class<*>,
|
indexableClass: Class<*>,
|
||||||
pageTitle: String,
|
pageTitle: String,
|
||||||
|
keywords: String? = null,
|
||||||
) =
|
) =
|
||||||
SearchIndexableRaw(context).apply {
|
SearchIndexableRaw(context).apply {
|
||||||
key = spaSearchLandingKey.toByteString().toStringUtf8()
|
key = spaSearchLandingKey.toByteString().toStringUtf8()
|
||||||
title = itemTitle
|
title = itemTitle
|
||||||
|
this.keywords = keywords
|
||||||
intentAction = SEARCH_LANDING_ACTION
|
intentAction = SEARCH_LANDING_ACTION
|
||||||
intentTargetClass = SpaSearchLandingActivity::class.qualifiedName
|
intentTargetClass = SpaSearchLandingActivity::class.qualifiedName
|
||||||
packageName = context.packageName
|
packageName = context.packageName
|
||||||
|
@@ -139,7 +139,8 @@ public class WifiEnabler implements SwitchWidgetController.OnSwitchChangeListene
|
|||||||
// Refresh satellite mode status.
|
// Refresh satellite mode status.
|
||||||
try {
|
try {
|
||||||
mIsSatelliteOn.set(
|
mIsSatelliteOn.set(
|
||||||
mSatelliteRepository.requestIsEnabled(Executors.newSingleThreadExecutor())
|
mSatelliteRepository
|
||||||
|
.requestIsSessionStarted(Executors.newSingleThreadExecutor())
|
||||||
.get(2000, TimeUnit.MILLISECONDS));
|
.get(2000, TimeUnit.MILLISECONDS));
|
||||||
} catch (ExecutionException | TimeoutException | InterruptedException e) {
|
} catch (ExecutionException | TimeoutException | InterruptedException e) {
|
||||||
Log.e(TAG, "Error to get satellite status : " + e);
|
Log.e(TAG, "Error to get satellite status : " + e);
|
||||||
|
@@ -431,7 +431,7 @@ public class WifiSlice implements CustomSliceable {
|
|||||||
boolean isSatelliteOn = false;
|
boolean isSatelliteOn = false;
|
||||||
try {
|
try {
|
||||||
isSatelliteOn =
|
isSatelliteOn =
|
||||||
satelliteRepository.requestIsEnabled(Executors.newSingleThreadExecutor())
|
satelliteRepository.requestIsSessionStarted(Executors.newSingleThreadExecutor())
|
||||||
.get(2000, TimeUnit.MILLISECONDS);
|
.get(2000, TimeUnit.MILLISECONDS);
|
||||||
} catch (ExecutionException | TimeoutException | InterruptedException e) {
|
} catch (ExecutionException | TimeoutException | InterruptedException e) {
|
||||||
Log.e(TAG, "Error to get satellite status : " + 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 static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.platform.test.annotations.EnableFlags;
|
||||||
|
import android.platform.test.flag.junit.SetFlagsRule;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
@@ -34,19 +36,24 @@ import androidx.test.core.app.ApplicationProvider;
|
|||||||
|
|
||||||
import com.android.settings.core.BasePreferenceController;
|
import com.android.settings.core.BasePreferenceController;
|
||||||
|
|
||||||
|
import org.junit.Assume;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class KeyboardBounceKeyPreferenceControllerTest {
|
public class KeyboardBounceKeyPreferenceControllerTest {
|
||||||
|
|
||||||
private static final String KEY_ACCESSIBILITY_BOUNCE_KEYS =
|
private static final String KEY_ACCESSIBILITY_BOUNCE_KEYS =
|
||||||
Settings.Secure.ACCESSIBILITY_BOUNCE_KEYS;
|
Settings.Secure.ACCESSIBILITY_BOUNCE_KEYS;
|
||||||
private static final int UNKNOWN = -1;
|
private static final int UNKNOWN = -1;
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final SetFlagsRule mSetFlagRule = new SetFlagsRule();
|
||||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||||
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
|
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
|
||||||
private final KeyboardBounceKeyPreferenceController mController =
|
private final KeyboardBounceKeyPreferenceController mController =
|
||||||
@@ -131,4 +138,26 @@ public class KeyboardBounceKeyPreferenceControllerTest {
|
|||||||
mContext.getContentResolver(), KEY_ACCESSIBILITY_BOUNCE_KEYS,
|
mContext.getContentResolver(), KEY_ACCESSIBILITY_BOUNCE_KEYS,
|
||||||
UNKNOWN)).isNotEqualTo(OFF);
|
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 static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.platform.test.annotations.EnableFlags;
|
||||||
|
import android.platform.test.flag.junit.SetFlagsRule;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
@@ -34,19 +36,24 @@ import androidx.test.core.app.ApplicationProvider;
|
|||||||
|
|
||||||
import com.android.settings.core.BasePreferenceController;
|
import com.android.settings.core.BasePreferenceController;
|
||||||
|
|
||||||
|
import org.junit.Assume;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class KeyboardSlowKeyPreferenceControllerTest {
|
public class KeyboardSlowKeyPreferenceControllerTest {
|
||||||
|
|
||||||
private static final String KEY_ACCESSIBILITY_SLOW_KEYS =
|
private static final String KEY_ACCESSIBILITY_SLOW_KEYS =
|
||||||
Settings.Secure.ACCESSIBILITY_SLOW_KEYS;
|
Settings.Secure.ACCESSIBILITY_SLOW_KEYS;
|
||||||
private static final int UNKNOWN = -1;
|
private static final int UNKNOWN = -1;
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final SetFlagsRule mSetFlagRule = new SetFlagsRule();
|
||||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||||
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
|
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
|
||||||
private final KeyboardSlowKeyPreferenceController mController =
|
private final KeyboardSlowKeyPreferenceController mController =
|
||||||
@@ -131,4 +138,26 @@ public class KeyboardSlowKeyPreferenceControllerTest {
|
|||||||
mContext.getContentResolver(), KEY_ACCESSIBILITY_SLOW_KEYS, UNKNOWN)).isNotEqualTo(
|
mContext.getContentResolver(), KEY_ACCESSIBILITY_SLOW_KEYS, UNKNOWN)).isNotEqualTo(
|
||||||
OFF);
|
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 static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.platform.test.annotations.EnableFlags;
|
||||||
|
import android.platform.test.flag.junit.SetFlagsRule;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
@@ -34,19 +36,24 @@ import androidx.test.core.app.ApplicationProvider;
|
|||||||
|
|
||||||
import com.android.settings.core.BasePreferenceController;
|
import com.android.settings.core.BasePreferenceController;
|
||||||
|
|
||||||
|
import org.junit.Assume;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class KeyboardStickyKeyPreferenceControllerTest {
|
public class KeyboardStickyKeyPreferenceControllerTest {
|
||||||
|
|
||||||
private static final String KEY_ACCESSIBILITY_STICKY_KEYS =
|
private static final String KEY_ACCESSIBILITY_STICKY_KEYS =
|
||||||
Settings.Secure.ACCESSIBILITY_STICKY_KEYS;
|
Settings.Secure.ACCESSIBILITY_STICKY_KEYS;
|
||||||
private static final int UNKNOWN = -1;
|
private static final int UNKNOWN = -1;
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final SetFlagsRule mSetFlagRule = new SetFlagsRule();
|
||||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||||
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
|
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
|
||||||
private final KeyboardStickyKeyPreferenceController mController =
|
private final KeyboardStickyKeyPreferenceController mController =
|
||||||
@@ -129,4 +136,26 @@ public class KeyboardStickyKeyPreferenceControllerTest {
|
|||||||
assertThat(Settings.Secure.getInt(
|
assertThat(Settings.Secure.getInt(
|
||||||
mContext.getContentResolver(), KEY_ACCESSIBILITY_STICKY_KEYS, UNKNOWN)).isEqualTo(ON);
|
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.doReturn;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
@@ -52,6 +54,7 @@ public class AudioSharingDashboardFragmentTest {
|
|||||||
|
|
||||||
@Mock private SettingsActivity mActivity;
|
@Mock private SettingsActivity mActivity;
|
||||||
@Mock private SettingsMainSwitchBar mSwitchBar;
|
@Mock private SettingsMainSwitchBar mSwitchBar;
|
||||||
|
@Mock private View mView;
|
||||||
@Mock private AudioSharingDeviceVolumeGroupController mVolumeGroupController;
|
@Mock private AudioSharingDeviceVolumeGroupController mVolumeGroupController;
|
||||||
@Mock private AudioSharingCallAudioPreferenceController mCallAudioController;
|
@Mock private AudioSharingCallAudioPreferenceController mCallAudioController;
|
||||||
@Mock private AudioSharingPlaySoundPreferenceController mPlaySoundController;
|
@Mock private AudioSharingPlaySoundPreferenceController mPlaySoundController;
|
||||||
@@ -61,6 +64,7 @@ public class AudioSharingDashboardFragmentTest {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
|
when(mSwitchBar.getRootView()).thenReturn(mView);
|
||||||
mFragment = new AudioSharingDashboardFragment();
|
mFragment = new AudioSharingDashboardFragment();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -51,6 +51,8 @@ import android.os.Looper;
|
|||||||
import android.platform.test.flag.junit.SetFlagsRule;
|
import android.platform.test.flag.junit.SetFlagsRule;
|
||||||
import android.util.FeatureFlagUtils;
|
import android.util.FeatureFlagUtils;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.accessibility.AccessibilityEvent;
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
|
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
@@ -590,4 +592,26 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
mController.mBroadcastAssistantCallback.onSourceLost(/* broadcastId= */ 1);
|
mController.mBroadcastAssistantCallback.onSourceLost(/* broadcastId= */ 1);
|
||||||
verifyNoMoreInteractions(mFeatureFactory.metricsFeatureProvider);
|
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.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.preference.Preference.OnPreferenceClickListener;
|
|
||||||
import androidx.preference.PreferenceViewHolder;
|
import androidx.preference.PreferenceViewHolder;
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
@@ -93,17 +92,6 @@ public class AudioStreamPreferenceTest {
|
|||||||
assertThat(divider.getVisibility()).isEqualTo(View.GONE);
|
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
|
@Test
|
||||||
public void setAudioStreamMetadata_shouldUpdateMetadata() {
|
public void setAudioStreamMetadata_shouldUpdateMetadata() {
|
||||||
AudioStreamPreference p =
|
AudioStreamPreference p =
|
||||||
@@ -147,7 +135,7 @@ public class AudioStreamPreferenceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldHideSecondTarget_connected() {
|
public void shouldHideSecondTarget_connected() {
|
||||||
mPreference.setIsConnected(true, "", null);
|
mPreference.setIsConnected(true);
|
||||||
assertThat(mPreference.shouldHideSecondTarget()).isTrue();
|
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.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
@@ -31,6 +30,7 @@ import static org.mockito.Mockito.verify;
|
|||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.text.SpannableString;
|
||||||
|
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
@@ -39,6 +39,7 @@ import org.junit.Before;
|
|||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.MockitoJUnit;
|
import org.mockito.junit.MockitoJUnit;
|
||||||
import org.mockito.junit.MockitoRule;
|
import org.mockito.junit.MockitoRule;
|
||||||
@@ -75,7 +76,9 @@ public class AudioStreamStateHandlerTest {
|
|||||||
|
|
||||||
verify(mPreference, never()).setAudioStreamState(any());
|
verify(mPreference, never()).setAudioStreamState(any());
|
||||||
verify(mHandler, never()).performAction(any(), any(), 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
|
@Test
|
||||||
@@ -93,7 +96,9 @@ public class AudioStreamStateHandlerTest {
|
|||||||
.setAudioStreamState(
|
.setAudioStreamState(
|
||||||
AudioStreamsProgressCategoryController.AudioStreamState.SOURCE_ADDED);
|
AudioStreamsProgressCategoryController.AudioStreamState.SOURCE_ADDED);
|
||||||
verify(mHandler).performAction(any(), any(), any());
|
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
|
@Test
|
||||||
@@ -119,7 +124,13 @@ public class AudioStreamStateHandlerTest {
|
|||||||
AudioStreamsProgressCategoryController.AudioStreamState
|
AudioStreamsProgressCategoryController.AudioStreamState
|
||||||
.ADD_SOURCE_BAD_CODE);
|
.ADD_SOURCE_BAD_CODE);
|
||||||
verify(mHandler).performAction(any(), any(), any());
|
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
|
@Test
|
||||||
|
@@ -18,13 +18,21 @@ package com.android.settings.development;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
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.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
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.SearchIndexableResource;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
@@ -42,6 +50,7 @@ import com.android.settingslib.development.DevelopmentSettingsEnabler;
|
|||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
@@ -51,6 +60,7 @@ import org.robolectric.annotation.Config;
|
|||||||
import org.robolectric.annotation.Implementation;
|
import org.robolectric.annotation.Implementation;
|
||||||
import org.robolectric.annotation.Implements;
|
import org.robolectric.annotation.Implements;
|
||||||
import org.robolectric.shadow.api.Shadow;
|
import org.robolectric.shadow.api.Shadow;
|
||||||
|
import org.robolectric.shadows.ShadowBiometricManager;
|
||||||
import org.robolectric.shadows.androidx.fragment.FragmentController;
|
import org.robolectric.shadows.androidx.fragment.FragmentController;
|
||||||
import org.robolectric.util.ReflectionHelpers;
|
import org.robolectric.util.ReflectionHelpers;
|
||||||
|
|
||||||
@@ -61,22 +71,34 @@ import java.util.List;
|
|||||||
ShadowAlertDialogCompat.class,
|
ShadowAlertDialogCompat.class,
|
||||||
ShadowUserManager.class,
|
ShadowUserManager.class,
|
||||||
ShadowUserManager.class,
|
ShadowUserManager.class,
|
||||||
|
ShadowBiometricManager.class,
|
||||||
})
|
})
|
||||||
public class DevelopmentSettingsDashboardFragmentTest {
|
public class DevelopmentSettingsDashboardFragmentTest {
|
||||||
|
@Rule
|
||||||
|
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private ShadowUserManager mShadowUserManager;
|
private ShadowUserManager mShadowUserManager;
|
||||||
|
private ShadowBiometricManager mShadowBiometricManager;
|
||||||
private DevelopmentSettingsDashboardFragment mDashboard;
|
private DevelopmentSettingsDashboardFragment mDashboard;
|
||||||
|
private SettingsMainSwitchBar mSwitchBar;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = RuntimeEnvironment.application;
|
mContext = RuntimeEnvironment.application;
|
||||||
SettingsMainSwitchBar switchBar = new SettingsMainSwitchBar(mContext);
|
mSwitchBar = new SettingsMainSwitchBar(mContext);
|
||||||
mDashboard = spy(new DevelopmentSettingsDashboardFragment());
|
mDashboard = spy(new DevelopmentSettingsDashboardFragment());
|
||||||
ReflectionHelpers.setField(mDashboard, "mSwitchBar", switchBar);
|
ReflectionHelpers.setField(mDashboard, "mSwitchBar", mSwitchBar);
|
||||||
mShadowUserManager = Shadow.extract(mContext.getSystemService(Context.USER_SERVICE));
|
mShadowUserManager = Shadow.extract(mContext.getSystemService(Context.USER_SERVICE));
|
||||||
mShadowUserManager.setIsAdminUser(true);
|
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
|
@After
|
||||||
@@ -176,6 +198,41 @@ public class DevelopmentSettingsDashboardFragmentTest {
|
|||||||
assertThat(ShadowEnableDevelopmentSettingWarningDialog.mShown).isTrue();
|
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
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
@Config(shadows = ShadowEnableDevelopmentSettingWarningDialog.class)
|
@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
|
@Test
|
||||||
fun requestIsSessionStarted_resultIsTrue() = runBlocking {
|
fun requestIsSessionStarted_resultIsTrue() = runBlocking {
|
||||||
`when`(mockSatelliteManager.registerForModemStateChanged(any(), any())
|
`when`(
|
||||||
|
mockSatelliteManager.registerForModemStateChanged(any(), any())
|
||||||
).thenAnswer { invocation ->
|
).thenAnswer { invocation ->
|
||||||
val callback = invocation.getArgument<SatelliteModemStateCallback>(1)
|
val callback = invocation.getArgument<SatelliteModemStateCallback>(1)
|
||||||
callback.onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED)
|
callback.onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED)
|
||||||
@@ -105,7 +106,8 @@ class SatelliteRepositoryTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun requestIsSessionStarted_resultIsFalse() = runBlocking {
|
fun requestIsSessionStarted_resultIsFalse() = runBlocking {
|
||||||
`when`(mockSatelliteManager.registerForModemStateChanged(any(), any())
|
`when`(
|
||||||
|
mockSatelliteManager.registerForModemStateChanged(any(), any())
|
||||||
).thenAnswer { invocation ->
|
).thenAnswer { invocation ->
|
||||||
val callback = invocation.getArgument<SatelliteModemStateCallback>(1)
|
val callback = invocation.getArgument<SatelliteModemStateCallback>(1)
|
||||||
callback.onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_OFF)
|
callback.onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_OFF)
|
||||||
@@ -119,7 +121,8 @@ class SatelliteRepositoryTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun requestIsSessionStarted_registerFailed() = runBlocking {
|
fun requestIsSessionStarted_registerFailed() = runBlocking {
|
||||||
`when`(mockSatelliteManager.registerForModemStateChanged(any(), any())
|
`when`(
|
||||||
|
mockSatelliteManager.registerForModemStateChanged(any(), any())
|
||||||
).thenAnswer {
|
).thenAnswer {
|
||||||
SatelliteManager.SATELLITE_RESULT_ERROR
|
SatelliteManager.SATELLITE_RESULT_ERROR
|
||||||
}
|
}
|
||||||
@@ -129,6 +132,17 @@ class SatelliteRepositoryTest {
|
|||||||
verify(mockSatelliteManager, never()).unregisterForModemStateChanged(any())
|
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
|
@Test
|
||||||
fun requestIsSessionStarted_nullSatelliteManager() = runBlocking {
|
fun requestIsSessionStarted_nullSatelliteManager() = runBlocking {
|
||||||
`when`(spyContext.getSystemService(SatelliteManager::class.java)).thenReturn(null)
|
`when`(spyContext.getSystemService(SatelliteManager::class.java)).thenReturn(null)
|
||||||
@@ -157,6 +171,17 @@ class SatelliteRepositoryTest {
|
|||||||
assertFalse(result.get())
|
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
|
@Test
|
||||||
fun requestIsEnabled_exceptionFailure() = runBlocking {
|
fun requestIsEnabled_exceptionFailure() = runBlocking {
|
||||||
@@ -232,7 +257,8 @@ class SatelliteRepositoryTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun getIsSessionStartedFlow_registerFailed() = runBlocking {
|
fun getIsSessionStartedFlow_registerFailed() = runBlocking {
|
||||||
`when`(mockSatelliteManager.registerForModemStateChanged(any(), any())
|
`when`(
|
||||||
|
mockSatelliteManager.registerForModemStateChanged(any(), any())
|
||||||
).thenAnswer {
|
).thenAnswer {
|
||||||
SatelliteManager.SATELLITE_RESULT_ERROR
|
SatelliteManager.SATELLITE_RESULT_ERROR
|
||||||
}
|
}
|
||||||
|
@@ -28,8 +28,13 @@ import static org.mockito.Mockito.when;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.hardware.biometrics.BiometricManager;
|
||||||
|
import android.hardware.biometrics.Flags;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.UserManager;
|
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 android.provider.Settings;
|
||||||
|
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
@@ -45,6 +50,7 @@ import com.android.settingslib.core.lifecycle.Lifecycle;
|
|||||||
import com.android.settingslib.development.DevelopmentSettingsEnabler;
|
import com.android.settingslib.development.DevelopmentSettingsEnabler;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Answers;
|
import org.mockito.Answers;
|
||||||
@@ -53,6 +59,9 @@ import org.mockito.MockitoAnnotations;
|
|||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public class BuildNumberPreferenceControllerTest {
|
public class BuildNumberPreferenceControllerTest {
|
||||||
|
@Rule
|
||||||
|
public final CheckFlagsRule mCheckFlagsRule =
|
||||||
|
DeviceFlagsValueProvider.createCheckFlagsRule();
|
||||||
|
|
||||||
private static final String KEY_BUILD_NUMBER = "build_number";
|
private static final String KEY_BUILD_NUMBER = "build_number";
|
||||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||||
@@ -60,6 +69,7 @@ public class BuildNumberPreferenceControllerTest {
|
|||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private UserManager mUserManager;
|
private UserManager mUserManager;
|
||||||
|
private BiometricManager mBiometricManager;
|
||||||
private LifecycleOwner mLifecycleOwner;
|
private LifecycleOwner mLifecycleOwner;
|
||||||
private Lifecycle mLifecycle;
|
private Lifecycle mLifecycle;
|
||||||
private FakeFeatureFactory mFactory;
|
private FakeFeatureFactory mFactory;
|
||||||
@@ -76,7 +86,13 @@ public class BuildNumberPreferenceControllerTest {
|
|||||||
|
|
||||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||||
mUserManager = (UserManager) spy(mContext.getSystemService(Context.USER_SERVICE));
|
mUserManager = (UserManager) spy(mContext.getSystemService(Context.USER_SERVICE));
|
||||||
|
mBiometricManager = spy(mContext.getSystemService(BiometricManager.class));
|
||||||
|
|
||||||
doReturn(mUserManager).when(mContext).getSystemService(Context.USER_SERVICE);
|
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();
|
mFactory = FakeFeatureFactory.setupForTest();
|
||||||
mLifecycleOwner = () -> mLifecycle;
|
mLifecycleOwner = () -> mLifecycle;
|
||||||
@@ -156,7 +172,7 @@ public class BuildNumberPreferenceControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void onActivityResult_notConfirmPasswordRequest_doNothing() {
|
public void onActivityResult_notConfirmPasswordRequest_doNothing() {
|
||||||
final boolean activityResultHandled = mController.onActivityResult(
|
final boolean activityResultHandled = mController.onActivityResult(
|
||||||
BuildNumberPreferenceController.REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF + 1,
|
BuildNumberPreferenceController.REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF + 2,
|
||||||
Activity.RESULT_OK,
|
Activity.RESULT_OK,
|
||||||
null);
|
null);
|
||||||
|
|
||||||
@@ -188,4 +204,38 @@ public class BuildNumberPreferenceControllerTest {
|
|||||||
assertThat(activityResultHandled).isTrue();
|
assertThat(activityResultHandled).isTrue();
|
||||||
assertThat(DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)).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