Merge "Change resource id to the correct package name" into main
diff --git a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/AccessibilityInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/AccessibilityInteractor.kt
index bf0084d..52a3281 100644
--- a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/AccessibilityInteractor.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/AccessibilityInteractor.kt
@@ -54,7 +54,7 @@
.stateIn(
scope,
SharingStarted.WhileSubscribed(), // When no longer subscribed, we removeTheListener
- false,
+ accessibilityManager.isEnabled,
)
override val isEnabled: Boolean
diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBase.java b/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBase.java
index 36a14aa..33eba10 100644
--- a/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBase.java
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBase.java
@@ -48,6 +48,8 @@
import com.android.settingslib.bluetooth.HearingAidStatsLogUtils;
import com.android.settingslib.utils.ThreadUtils;
+import com.google.common.collect.ImmutableList;
+
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -58,8 +60,11 @@
* device pairing detail page.
*/
public abstract class BluetoothDevicePairingDetailBase extends DeviceListPreferenceFragment {
- private static final long AUTO_DISMISS_TIME_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(10);
+ private static final long AUTO_DISMISS_TIME_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(15);
private static final int AUTO_DISMISS_MESSAGE_ID = 1001;
+ private static final ImmutableList<Integer> AUDIO_SHARING_PROFILES = ImmutableList.of(
+ BluetoothProfile.LE_AUDIO,
+ BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, BluetoothProfile.VOLUME_CONTROL);
protected boolean mInitialScanStarted;
@VisibleForTesting
@@ -229,12 +234,13 @@
if (device != null
&& mSelectedList.contains(device)) {
if (BluetoothUtils.isAudioSharingUIAvailable(getContext())) {
- if (bluetoothProfile == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT
+ if (mShouldTriggerAudioSharingShareThenPairFlow
&& state == BluetoothAdapter.STATE_CONNECTED
&& device.equals(mJustBonded)
- && mShouldTriggerAudioSharingShareThenPairFlow) {
+ && AUDIO_SHARING_PROFILES.contains(bluetoothProfile)
+ && isReadyForAudioSharing(cachedDevice, bluetoothProfile)) {
Log.d(getLogTag(),
- "onProfileConnectionStateChanged, assistant profile connected");
+ "onProfileConnectionStateChanged, ready for audio sharing");
dismissConnectingDialog();
mHandler.removeMessages(AUTO_DISMISS_MESSAGE_ID);
finishFragmentWithResultForAudioSharing(device);
@@ -322,6 +328,35 @@
return false;
}
+ private boolean isReadyForAudioSharing(@NonNull CachedBluetoothDevice cachedDevice,
+ int justConnectedProfile) {
+ for (int profile : AUDIO_SHARING_PROFILES) {
+ // Skip checking connection state for just connected profile
+ if (profile == justConnectedProfile) continue;
+ switch (profile) {
+ case BluetoothProfile.LE_AUDIO -> {
+ if (!cachedDevice.isConnectedLeAudioDevice()) {
+ Log.d(getLogTag(), "isReadyForAudioSharing, LE_AUDIO not ready");
+ return false;
+ }
+ }
+ case BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT -> {
+ if (!cachedDevice.isConnectedLeAudioBroadcastAssistantDevice()) {
+ Log.d(getLogTag(), "isReadyForAudioSharing, ASSISTANT not ready");
+ return false;
+ }
+ }
+ case BluetoothProfile.VOLUME_CONTROL -> {
+ if (!cachedDevice.isConnectedVolumeControlDevice()) {
+ Log.d(getLogTag(), "isReadyForAudioSharing, VC not ready");
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
private void addOnMetadataChangedListener(@Nullable BluetoothDevice device) {
var unused = ThreadUtils.postOnBackgroundThread(() -> {
if (mBluetoothAdapter != null && device != null
diff --git a/src/com/android/settings/network/tether/TetherSettings.java b/src/com/android/settings/network/tether/TetherSettings.java
index 57715be..53de9f6 100644
--- a/src/com/android/settings/network/tether/TetherSettings.java
+++ b/src/com/android/settings/network/tether/TetherSettings.java
@@ -72,7 +72,6 @@
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
-// LINT.IfChange
/**
* Displays preferences for Tethering.
*/
@@ -209,19 +208,16 @@
mWifiTetherPreferenceController.displayPreference(getPreferenceScreen());
}
- if (!isCatalystEnabled()) {
- if (!bluetoothAvailable) {
- mBluetoothTether.setVisible(false);
+ if (!bluetoothAvailable) {
+ getPreferenceScreen().removePreference(mBluetoothTether);
+ } else {
+ BluetoothPan pan = mBluetoothPan.get();
+ if (pan != null && pan.isTetheringOn()) {
+ mBluetoothTether.setChecked(true);
} else {
- BluetoothPan pan = mBluetoothPan.get();
- if (pan != null && pan.isTetheringOn()) {
- mBluetoothTether.setChecked(true);
- } else {
- mBluetoothTether.setChecked(false);
- }
+ mBluetoothTether.setChecked(false);
}
}
-
if (!ethernetAvailable) getPreferenceScreen().removePreference(mEthernetTether);
// Set initial state based on Data Saver mode.
onDataSaverChanged(mDataSaverBackend.isDataSaverEnabled());
@@ -274,9 +270,7 @@
mWifiTetherPreferenceController.setDataSaverEnabled(mDataSaverEnabled);
}
mUsbTether.setEnabled(!mDataSaverEnabled);
- if (!isCatalystEnabled()) {
- mBluetoothTether.setEnabled(!mDataSaverEnabled);
- }
+ mBluetoothTether.setEnabled(!mDataSaverEnabled);
mEthernetTether.setEnabled(!mDataSaverEnabled);
mDataSaverFooter.setVisible(mDataSaverEnabled);
}
@@ -526,8 +520,6 @@
}
private void updateBluetoothState() {
- if (isCatalystEnabled()) return;
-
final int btState = getBluetoothState();
if (DEBUG) {
Log.d(TAG, "updateBluetoothState() btState : " + btState);
@@ -583,7 +575,7 @@
}
private void startTethering(int choice) {
- if (choice == TETHERING_BLUETOOTH && !isCatalystEnabled()) {
+ if (choice == TETHERING_BLUETOOTH) {
// Turn on Bluetooth first.
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter.getState() == BluetoothAdapter.STATE_OFF) {
@@ -605,7 +597,7 @@
} else {
mCm.stopTethering(TETHERING_USB);
}
- } else if (preference == mBluetoothTether && !isCatalystEnabled()) {
+ } else if (preference == mBluetoothTether) {
if (mBluetoothTether.isChecked()) {
startTethering(TETHERING_BLUETOOTH);
} else {
@@ -753,4 +745,3 @@
return TetherScreen.KEY;
}
}
-// LINT.ThenChange(BluetoothTetherSwitchPreference.kt)
diff --git a/src/com/android/settings/wifi/WepNetworksPreferenceController.kt b/src/com/android/settings/wifi/WepNetworksPreferenceController.kt
index bad7201..92716be 100644
--- a/src/com/android/settings/wifi/WepNetworksPreferenceController.kt
+++ b/src/com/android/settings/wifi/WepNetworksPreferenceController.kt
@@ -18,6 +18,9 @@
import android.content.Context
import android.net.wifi.WifiManager
+import android.security.advancedprotection.AdvancedProtectionManager
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -27,6 +30,7 @@
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.style.TextAlign
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settings.R
@@ -50,6 +54,9 @@
ComposePreferenceController(context, preferenceKey) {
var wifiManager = context.getSystemService(WifiManager::class.java)!!
+ var aapmManager = if (android.security.Flags.aapmApi() && Flags.wepDisabledInApm())
+ context.getSystemService(AdvancedProtectionManager::class.java)!!
+ else null
override fun getAvailabilityStatus() =
if (Flags.androidVWifiApi()) AVAILABLE else UNSUPPORTED_ON_DEVICE
@@ -60,27 +67,49 @@
isWepSupportedFlow.collectAsStateWithLifecycle(initialValue = null).value
val isWepAllowed: Boolean? =
wepAllowedFlow.flow.collectAsStateWithLifecycle(initialValue = null).value
- var openDialog by rememberSaveable { mutableStateOf(false) }
- SwitchPreference(
- object : SwitchPreferenceModel {
- override val title = stringResource(R.string.wifi_allow_wep_networks)
- override val summary = { getSummary(isWepSupported) }
- override val checked = {
- if (isWepSupported == true) isWepAllowed else isWepSupported
- }
- override val changeable: () -> Boolean
- get() = { isWepSupported == true }
+ val isAapmEnabled: Boolean? = if (android.security.Flags.aapmApi()
+ && Flags.wepDisabledInApm())
+ isAapmEnabledFlow.collectAsStateWithLifecycle(initialValue = null).value
+ else false
- override val onCheckedChange: (Boolean) -> Unit = { newChecked ->
- val wifiInfo = wifiManager.connectionInfo
- if (!newChecked && wifiInfo.currentSecurityType == WifiEntry.SECURITY_WEP) {
- openDialog = true
- } else {
- wifiManager.setWepAllowed(newChecked)
- wepAllowedFlow.override(newChecked)
+ var openDialog by rememberSaveable { mutableStateOf(false) }
+
+ RestrictionWrapper(
+ restricted = isAapmEnabled == true
+ ) {
+ SwitchPreference(
+ object : SwitchPreferenceModel {
+ override val title = stringResource(R.string.wifi_allow_wep_networks)
+ override val summary = { getSummary(isWepSupported) }
+ override val checked = {
+ when {
+ isWepSupported == false -> false
+ isAapmEnabled == true -> false
+ else -> isWepAllowed
+ }
}
+ override val changeable: () -> Boolean
+ get() = { isWepSupported == true && isAapmEnabled == false }
+
+ override val onCheckedChange: ((Boolean) -> Unit)? =
+ if (isAapmEnabled == true) {
+ null
+ } else {
+ { newChecked ->
+ val wifiInfo = wifiManager.connectionInfo
+ if (!newChecked &&
+ wifiInfo.currentSecurityType == WifiEntry.SECURITY_WEP
+ ) {
+ openDialog = true
+ } else {
+ wifiManager.setWepAllowed(newChecked)
+ wepAllowedFlow.override(newChecked)
+ }
+ }
+ }
}
- })
+ )
+ }
if (openDialog) {
SettingsAlertDialogWithIcon(
onDismissRequest = { openDialog = false },
@@ -103,6 +132,21 @@
}
}
+ @Composable
+ private fun RestrictionWrapper(restricted: Boolean, content: @Composable () -> Unit) {
+ if (restricted) {
+ Box(
+ Modifier.clickable(
+ enabled = true,
+ role = Role.Switch,
+ onClick = ::startSupportIntent
+ )
+ ) { content() }
+ } else {
+ content()
+ }
+ }
+
private fun getSummary(isWepSupported: Boolean?): String =
mContext.getString(
when (isWepSupported) {
@@ -114,6 +158,16 @@
private val isWepSupportedFlow =
flow { emit(wifiManager.isWepSupported) }.flowOn(Dispatchers.Default)
+ private val isAapmEnabledFlow = flow {
+ emit(aapmManager?.isAdvancedProtectionEnabled ?: false) }.flowOn(Dispatchers.Default)
+
+ private fun startSupportIntent() {
+ aapmManager?.createSupportIntent(
+ AdvancedProtectionManager.FEATURE_ID_DISALLOW_WEP,
+ AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_DISABLED_SETTING
+ )?.let { mContext.startActivity(it) }
+ }
+
val wepAllowedFlow =
OverridableFlow(
callbackFlow {
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBaseTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBaseTest.java
index 949b3d8..bd6ac4b 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBaseTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBaseTest.java
@@ -308,6 +308,9 @@
shadowOf(Looper.getMainLooper()).idle();
when(mCachedBluetoothDevice.isConnected()).thenReturn(true);
+ when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true);
+ when(mCachedBluetoothDevice.isConnectedLeAudioBroadcastAssistantDevice()).thenReturn(true);
+ when(mCachedBluetoothDevice.isConnectedVolumeControlDevice()).thenReturn(true);
mFragment.onProfileConnectionStateChanged(mCachedBluetoothDevice,
BluetoothAdapter.STATE_CONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT);
diff --git a/tests/spa_unit/src/com/android/settings/wifi/WepNetworksPreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/wifi/WepNetworksPreferenceControllerTest.kt
index 9183096..1f0a491 100644
--- a/tests/spa_unit/src/com/android/settings/wifi/WepNetworksPreferenceControllerTest.kt
+++ b/tests/spa_unit/src/com/android/settings/wifi/WepNetworksPreferenceControllerTest.kt
@@ -17,8 +17,10 @@
package com.android.settings.wifi
import android.content.Context
+import android.content.Intent
import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager
+import android.security.advancedprotection.AdvancedProtectionManager
import androidx.compose.ui.test.assertIsOff
import androidx.compose.ui.test.assertIsOn
import androidx.compose.ui.test.isDisplayed
@@ -43,9 +45,12 @@
import org.mockito.kotlin.any
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.doNothing
import org.mockito.kotlin.mock
import org.mockito.kotlin.spy
import org.mockito.kotlin.stub
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
@RunWith(AndroidJUnit4::class)
class WepNetworksPreferenceControllerTest {
@@ -71,9 +76,15 @@
on { connectionInfo } doReturn mockWifiInfo
}
+ private var mockAapmManager =
+ mock<AdvancedProtectionManager> {
+ on { isAdvancedProtectionEnabled } doReturn false
+ }
+
private var context: Context =
spy(ApplicationProvider.getApplicationContext()) {
on { getSystemService(WifiManager::class.java) } doReturn mockWifiManager
+ on { getSystemService(AdvancedProtectionManager::class.java) } doReturn mockAapmManager
}
private var controller = WepNetworksPreferenceController(context, TEST_KEY)
@@ -185,6 +196,23 @@
.isNotDisplayed()
}
+ @Test
+ fun whenClick_aapmEnabled_openDialog() {
+ mockAapmManager.stub {
+ on { isAdvancedProtectionEnabled } doReturn true
+ on { createSupportIntent(any(), any()) } doReturn Intent()
+ }
+ doNothing().whenever(context).startActivity(any())
+ composeTestRule.setContent { controller.Content() }
+
+ composeTestRule.onRoot().performClick()
+
+ composeTestRule
+ .onDialogText(context.getString(R.string.wifi_disconnect_button_text))
+ .isNotDisplayed()
+ verify(context).startActivity(any())
+ }
+
private companion object {
const val TEST_KEY = "test_key"
const val SSID = "ssid"