Shows a warning dialog avoid using BT, Wifi and APM.
Flag: ACONFIG com.android.internal.telephony.flags.oem_enabled_satellite_flag
Fix: 329288009
Fix: 327039349
Test: Manual test
Test: atest passed
Change-Id: I0398dc3c8137219f7ab5723412566d5133f25790
diff --git a/packages/SettingsLib/src/com/android/settingslib/satellite/SatelliteDialogUtils.kt b/packages/SettingsLib/src/com/android/settingslib/satellite/SatelliteDialogUtils.kt
new file mode 100644
index 0000000..d69c87b
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/satellite/SatelliteDialogUtils.kt
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 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.settingslib.satellite
+
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.os.OutcomeReceiver
+import android.telephony.satellite.SatelliteManager
+import android.util.Log
+import android.view.WindowManager
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import com.android.settingslib.wifi.WifiUtils
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Dispatchers.Default
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.asExecutor
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.suspendCancellableCoroutine
+import kotlinx.coroutines.withContext
+import java.util.concurrent.ExecutionException
+import java.util.concurrent.TimeoutException
+import kotlin.coroutines.resume
+
+/** A util for Satellite dialog */
+object SatelliteDialogUtils {
+
+ /**
+ * Uses to start Satellite dialog to prevent users from using the BT, Airplane Mode, and
+ * Wifi during the satellite mode is on.
+ */
+ @JvmStatic
+ fun mayStartSatelliteWarningDialog(
+ context: Context,
+ lifecycleOwner: LifecycleOwner,
+ type: Int,
+ allowClick: (isAllowed: Boolean) -> Unit
+ ): Job {
+ return mayStartSatelliteWarningDialog(
+ context, lifecycleOwner.lifecycleScope, type, allowClick)
+ }
+
+ /**
+ * Uses to start Satellite dialog to prevent users from using the BT, Airplane Mode, and
+ * Wifi during the satellite mode is on.
+ */
+ @JvmStatic
+ fun mayStartSatelliteWarningDialog(
+ context: Context,
+ coroutineScope: CoroutineScope,
+ type: Int,
+ allowClick: (isAllowed: Boolean) -> Unit
+ ): Job =
+ coroutineScope.launch {
+ var isSatelliteModeOn = false
+ try {
+ isSatelliteModeOn = requestIsEnabled(context)
+ } catch (e: InterruptedException) {
+ Log.w(TAG, "Error to get satellite status : $e")
+ } catch (e: ExecutionException) {
+ Log.w(TAG, "Error to get satellite status : $e")
+ } catch (e: TimeoutException) {
+ Log.w(TAG, "Error to get satellite status : $e")
+ }
+
+ if (isSatelliteModeOn) {
+ startSatelliteWarningDialog(context, type)
+ }
+ withContext(Dispatchers.Main) {
+ allowClick(!isSatelliteModeOn)
+ }
+ }
+
+ private fun startSatelliteWarningDialog(context: Context, type: Int) {
+ context.startActivity(Intent(Intent.ACTION_MAIN).apply {
+ component = ComponentName(
+ "com.android.settings",
+ "com.android.settings.network.SatelliteWarningDialogActivity"
+ )
+ putExtra(WifiUtils.DIALOG_WINDOW_TYPE,
+ WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG)
+ putExtra(EXTRA_TYPE_OF_SATELLITE_WARNING_DIALOG, type)
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP)
+ })
+ }
+
+ /**
+ * Checks if the satellite modem is enabled.
+ *
+ * @param executor The executor to run the asynchronous operation on
+ * @return A ListenableFuture that will resolve to `true` if the satellite modem enabled,
+ * `false` otherwise.
+ */
+ private suspend fun requestIsEnabled(
+ context: Context,
+ ): Boolean = withContext(Default) {
+ val satelliteManager: SatelliteManager? =
+ context.getSystemService(SatelliteManager::class.java)
+ if (satelliteManager == null) {
+ Log.w(TAG, "SatelliteManager is null")
+ return@withContext false
+ }
+
+ suspendCancellableCoroutine {continuation ->
+ satelliteManager?.requestIsEnabled(Default.asExecutor(),
+ object : OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> {
+ override fun onResult(result: Boolean) {
+ Log.i(TAG, "Satellite modem enabled status: $result")
+ continuation.resume(result)
+ }
+
+ override fun onError(error: SatelliteManager.SatelliteException) {
+ super.onError(error)
+ Log.w(TAG, "Can't get satellite modem enabled status", error)
+ continuation.resume(false)
+ }
+ })
+ }
+ }
+
+ const val TAG = "SatelliteDialogUtils"
+
+ const val EXTRA_TYPE_OF_SATELLITE_WARNING_DIALOG: String =
+ "extra_type_of_satellite_warning_dialog"
+ const val TYPE_IS_UNKNOWN = -1
+ const val TYPE_IS_WIFI = 0
+ const val TYPE_IS_BLUETOOTH = 1
+ const val TYPE_IS_AIRPLANE_MODE = 2
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp
index f87b519..e125083 100644
--- a/packages/SettingsLib/tests/robotests/Android.bp
+++ b/packages/SettingsLib/tests/robotests/Android.bp
@@ -41,7 +41,10 @@
//###########################################################
android_robolectric_test {
name: "SettingsLibRoboTests",
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java",
+ "src/**/*.kt",
+ ],
static_libs: [
"Settings_robolectric_meta_service_file",
"Robolectric_shadows_androidx_fragment_upstream",
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/satellite/SatelliteDialogUtilsTest.kt b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/satellite/SatelliteDialogUtilsTest.kt
new file mode 100644
index 0000000..aeda1ed6
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/satellite/SatelliteDialogUtilsTest.kt
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 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.settingslib.satellite
+
+import android.content.Context
+import android.content.Intent
+import android.os.OutcomeReceiver
+import android.platform.test.annotations.RequiresFlagsEnabled
+import android.telephony.satellite.SatelliteManager
+import android.telephony.satellite.SatelliteManager.SatelliteException
+import android.util.AndroidRuntimeException
+import androidx.test.core.app.ApplicationProvider
+import com.android.internal.telephony.flags.Flags
+import com.android.settingslib.satellite.SatelliteDialogUtils.TYPE_IS_WIFI
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.any
+import org.mockito.Mockito.`when`
+import org.mockito.Spy
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+import org.mockito.Mockito.verify
+import org.mockito.internal.verification.Times
+import org.robolectric.RobolectricTestRunner
+
+@RunWith(RobolectricTestRunner::class)
+class SatelliteDialogUtilsTest {
+ @JvmField
+ @Rule
+ val mockitoRule: MockitoRule = MockitoJUnit.rule()
+
+ @Spy
+ var context: Context = ApplicationProvider.getApplicationContext()
+ @Mock
+ private lateinit var satelliteManager: SatelliteManager
+
+ private val coroutineScope = CoroutineScope(Dispatchers.Main)
+
+ @Before
+ fun setUp() {
+ `when`(context.getSystemService(SatelliteManager::class.java))
+ .thenReturn(satelliteManager)
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ fun mayStartSatelliteWarningDialog_satelliteIsOn_showWarningDialog() = runBlocking {
+ `when`(
+ satelliteManager.requestIsEnabled(
+ any(), any<OutcomeReceiver<Boolean, SatelliteManager.SatelliteException>>()
+ )
+ )
+ .thenAnswer { invocation ->
+ val receiver = invocation
+ .getArgument<
+ OutcomeReceiver<Boolean, SatelliteManager.SatelliteException>>(
+ 1
+ )
+ receiver.onResult(true)
+ null
+ }
+
+ try {
+ SatelliteDialogUtils.mayStartSatelliteWarningDialog(
+ context, coroutineScope, TYPE_IS_WIFI, allowClick = {
+ assertTrue(it)
+ })
+ } catch (e: AndroidRuntimeException) {
+ // Catch exception of starting activity .
+ }
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ fun mayStartSatelliteWarningDialog_satelliteIsOff_notShowWarningDialog() = runBlocking {
+ `when`(
+ satelliteManager.requestIsEnabled(
+ any(), any<OutcomeReceiver<Boolean, SatelliteManager.SatelliteException>>()
+ )
+ )
+ .thenAnswer { invocation ->
+ val receiver = invocation
+ .getArgument<
+ OutcomeReceiver<Boolean, SatelliteManager.SatelliteException>>(
+ 1
+ )
+ receiver.onResult(false)
+ null
+ }
+
+
+ SatelliteDialogUtils.mayStartSatelliteWarningDialog(
+ context, coroutineScope, TYPE_IS_WIFI, allowClick = {
+ assertFalse(it)
+ })
+
+ verify(context, Times(0)).startActivity(any<Intent>())
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ fun mayStartSatelliteWarningDialog_noSatelliteManager_notShowWarningDialog() = runBlocking {
+ `when`(context.getSystemService(SatelliteManager::class.java))
+ .thenReturn(null)
+
+ SatelliteDialogUtils.mayStartSatelliteWarningDialog(
+ context, coroutineScope, TYPE_IS_WIFI, allowClick = {
+ assertFalse(it)
+ })
+
+ verify(context, Times(0)).startActivity(any<Intent>())
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ fun mayStartSatelliteWarningDialog_satelliteErrorResult_notShowWarningDialog() = runBlocking {
+ `when`(
+ satelliteManager.requestIsEnabled(
+ any(), any<OutcomeReceiver<Boolean, SatelliteManager.SatelliteException>>()
+ )
+ )
+ .thenAnswer { invocation ->
+ val receiver = invocation
+ .getArgument<
+ OutcomeReceiver<Boolean, SatelliteManager.SatelliteException>>(
+ 1
+ )
+ receiver.onError(SatelliteException(SatelliteManager.SATELLITE_RESULT_ERROR))
+ null
+ }
+
+
+ SatelliteDialogUtils.mayStartSatelliteWarningDialog(
+ context, coroutineScope, TYPE_IS_WIFI, allowClick = {
+ assertFalse(it)
+ })
+
+ verify(context, Times(0)).startActivity(any<Intent>())
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index 2068799..71b69c9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -16,6 +16,8 @@
package com.android.systemui.qs.tiles;
+import static com.android.settingslib.satellite.SatelliteDialogUtils.TYPE_IS_AIRPLANE_MODE;
+
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -32,9 +34,12 @@
import android.widget.Switch;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.telephony.flags.Flags;
+import com.android.settingslib.satellite.SatelliteDialogUtils;
import com.android.systemui.animation.Expandable;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Background;
@@ -54,6 +59,8 @@
import dagger.Lazy;
+import kotlinx.coroutines.Job;
+
import javax.inject.Inject;
/** Quick settings tile: Airplane mode **/
@@ -66,6 +73,9 @@
private final Lazy<ConnectivityManager> mLazyConnectivityManager;
private boolean mListening;
+ @Nullable
+ @VisibleForTesting
+ Job mClickJob;
@Inject
public AirplaneModeTile(
@@ -111,6 +121,21 @@
new Intent(TelephonyManager.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS), 0);
return;
}
+
+ if (Flags.oemEnabledSatelliteFlag()) {
+ if (mClickJob != null && !mClickJob.isCompleted()) {
+ return;
+ }
+ mClickJob = SatelliteDialogUtils.mayStartSatelliteWarningDialog(
+ mContext, this, TYPE_IS_AIRPLANE_MODE, isAllowClick -> {
+ if (isAllowClick) {
+ setEnabled(!airplaneModeEnabled);
+ }
+ return null;
+ });
+ return;
+ }
+
setEnabled(!airplaneModeEnabled);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 9af34f6..9f41d98 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -16,6 +16,7 @@
package com.android.systemui.qs.tiles;
+import static com.android.settingslib.satellite.SatelliteDialogUtils.TYPE_IS_BLUETOOTH;
import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
import android.annotation.Nullable;
@@ -33,11 +34,14 @@
import android.util.Log;
import android.widget.Switch;
+import androidx.annotation.VisibleForTesting;
+
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.Utils;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.satellite.SatelliteDialogUtils;
import com.android.systemui.animation.Expandable;
import com.android.systemui.bluetooth.qsdialog.BluetoothTileDialogViewModel;
import com.android.systemui.dagger.qualifiers.Background;
@@ -55,6 +59,8 @@
import com.android.systemui.res.R;
import com.android.systemui.statusbar.policy.BluetoothController;
+import kotlinx.coroutines.Job;
+
import java.util.List;
import java.util.concurrent.Executor;
@@ -78,6 +84,9 @@
private final BluetoothTileDialogViewModel mDialogViewModel;
private final FeatureFlags mFeatureFlags;
+ @Nullable
+ @VisibleForTesting
+ Job mClickJob;
@Inject
public BluetoothTile(
@@ -110,6 +119,24 @@
@Override
protected void handleClick(@Nullable Expandable expandable) {
+ if (com.android.internal.telephony.flags.Flags.oemEnabledSatelliteFlag()) {
+ if (mClickJob != null && !mClickJob.isCompleted()) {
+ return;
+ }
+ mClickJob = SatelliteDialogUtils.mayStartSatelliteWarningDialog(
+ mContext, this, TYPE_IS_BLUETOOTH, isAllowClick -> {
+ if (!isAllowClick) {
+ return null;
+ }
+ handleClickEvent(expandable);
+ return null;
+ });
+ return;
+ }
+ handleClickEvent(expandable);
+ }
+
+ private void handleClickEvent(@Nullable Expandable expandable) {
if (mFeatureFlags.isEnabled(Flags.BLUETOOTH_QS_TILE_DIALOG)) {
mDialogViewModel.showDialog(expandable);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
index c9c4443..c971f54 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
@@ -15,6 +15,7 @@
*/
package com.android.systemui.qs.tiles.dialog;
+import static com.android.settingslib.satellite.SatelliteDialogUtils.TYPE_IS_WIFI;
import static com.android.systemui.Prefs.Key.QS_HAS_TURNED_OFF_MOBILE_DATA;
import static com.android.systemui.qs.tiles.dialog.InternetDialogController.MAX_WIFI_ENTRY_COUNT;
@@ -57,6 +58,8 @@
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
+import com.android.internal.telephony.flags.Flags;
+import com.android.settingslib.satellite.SatelliteDialogUtils;
import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
import com.android.systemui.Prefs;
import com.android.systemui.accessibility.floatingmenu.AnnotationLinkSpan;
@@ -73,6 +76,7 @@
import dagger.assisted.AssistedInject;
import kotlinx.coroutines.CoroutineScope;
+import kotlinx.coroutines.Job;
import java.util.List;
import java.util.concurrent.Executor;
@@ -161,6 +165,9 @@
// Wi-Fi scanning progress bar
protected boolean mIsProgressBarVisible;
private SystemUIDialog mDialog;
+ private final CoroutineScope mCoroutineScope;
+ @Nullable
+ private Job mClickJob;
@AssistedFactory
public interface Factory {
@@ -203,7 +210,7 @@
mCanConfigWifi = canConfigWifi;
mCanChangeWifiState = WifiEnterpriseRestrictionUtils.isChangeWifiStateAllowed(context);
mKeyguard = keyguardStateController;
-
+ mCoroutineScope = coroutineScope;
mUiEventLogger = uiEventLogger;
mDialogTransitionAnimator = dialogTransitionAnimator;
mAdapter = new InternetAdapter(mInternetDialogController, coroutineScope);
@@ -388,11 +395,9 @@
});
mConnectedWifListLayout.setOnClickListener(this::onClickConnectedWifi);
mSeeAllLayout.setOnClickListener(this::onClickSeeMoreButton);
- mWiFiToggle.setOnCheckedChangeListener(
- (buttonView, isChecked) -> {
- if (mInternetDialogController.isWifiEnabled() == isChecked) return;
- mInternetDialogController.setWifiEnabled(isChecked);
- });
+ mWiFiToggle.setOnClickListener(v -> {
+ handleWifiToggleClicked(mWiFiToggle.isChecked());
+ });
mDoneButton.setOnClickListener(v -> dialog.dismiss());
mShareWifiButton.setOnClickListener(v -> {
if (mInternetDialogController.mayLaunchShareWifiSettings(mConnectedWifiEntry, v)) {
@@ -404,6 +409,32 @@
});
}
+ private void handleWifiToggleClicked(boolean isChecked) {
+ if (Flags.oemEnabledSatelliteFlag()) {
+ if (mClickJob != null && !mClickJob.isCompleted()) {
+ return;
+ }
+ mClickJob = SatelliteDialogUtils.mayStartSatelliteWarningDialog(
+ mDialog.getContext(), mCoroutineScope, TYPE_IS_WIFI, isAllowClick -> {
+ if (isAllowClick) {
+ setWifiEnable(isChecked);
+ } else {
+ mWiFiToggle.setChecked(!isChecked);
+ }
+ return null;
+ });
+ return;
+ }
+ setWifiEnable(isChecked);
+ }
+
+ private void setWifiEnable(boolean isChecked) {
+ if (mInternetDialogController.isWifiEnabled() == isChecked) {
+ return;
+ }
+ mInternetDialogController.setWifiEnabled(isChecked);
+ }
+
@MainThread
private void updateEthernet() {
mEthernetLayout.setVisibility(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
index e2a3fac6..ad87315 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
@@ -22,7 +22,7 @@
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
-import com.android.systemui.res.R
+import com.android.internal.telephony.flags.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.classifier.FalsingManagerFake
@@ -33,10 +33,12 @@
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.res.R
import com.android.systemui.settings.UserTracker
import com.android.systemui.util.settings.GlobalSettings
import com.google.common.truth.Truth.assertThat
import dagger.Lazy
+import kotlinx.coroutines.Job
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -44,11 +46,15 @@
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
class AirplaneModeTileTest : SysuiTestCase() {
+
@Mock
private lateinit var mHost: QSHost
@Mock
@@ -62,7 +68,9 @@
@Mock
private lateinit var mBroadcastDispatcher: BroadcastDispatcher
@Mock
- private lateinit var mConnectivityManager: Lazy<ConnectivityManager>
+ private lateinit var mLazyConnectivityManager: Lazy<ConnectivityManager>
+ @Mock
+ private lateinit var mConnectivityManager: ConnectivityManager
@Mock
private lateinit var mGlobalSettings: GlobalSettings
@Mock
@@ -72,13 +80,15 @@
private lateinit var mTestableLooper: TestableLooper
private lateinit var mTile: AirplaneModeTile
+ @Mock
+ private lateinit var mClickJob: Job
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
mTestableLooper = TestableLooper.get(this)
Mockito.`when`(mHost.context).thenReturn(mContext)
Mockito.`when`(mHost.userContext).thenReturn(mContext)
-
+ Mockito.`when`(mLazyConnectivityManager.get()).thenReturn(mConnectivityManager)
mTile = AirplaneModeTile(
mHost,
mUiEventLogger,
@@ -90,7 +100,7 @@
mActivityStarter,
mQsLogger,
mBroadcastDispatcher,
- mConnectivityManager,
+ mLazyConnectivityManager,
mGlobalSettings,
mUserTracker)
}
@@ -120,4 +130,24 @@
assertThat(state.icon)
.isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_airplane_icon_on))
}
+
+ @Test
+ fun handleClick_noSatelliteFeature_directSetAirplaneMode() {
+ mSetFlagsRule.disableFlags(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+
+ mTile.handleClick(null)
+
+ verify(mConnectivityManager).setAirplaneMode(any())
+ }
+
+ @Test
+ fun handleClick_hasSatelliteFeatureButClickIsProcessing_doNothing() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ Mockito.`when`(mClickJob.isCompleted).thenReturn(false)
+ mTile.mClickJob = mClickJob
+
+ mTile.handleClick(null)
+
+ verify(mConnectivityManager, times(0)).setAirplaneMode(any())
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
index 830f08a..1ffbb7b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
@@ -9,10 +9,11 @@
import android.testing.TestableLooper.RunWithLooper
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
+import com.android.internal.telephony.flags.Flags
import com.android.settingslib.Utils
import com.android.settingslib.bluetooth.CachedBluetoothDevice
-import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.bluetooth.qsdialog.BluetoothTileDialogViewModel
import com.android.systemui.classifier.FalsingManagerFake
import com.android.systemui.flags.FeatureFlagsClassic
import com.android.systemui.plugins.ActivityStarter
@@ -23,13 +24,14 @@
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
-import com.android.systemui.bluetooth.qsdialog.BluetoothTileDialogViewModel
+import com.android.systemui.res.R
import com.android.systemui.statusbar.policy.BluetoothController
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.Job
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -37,6 +39,7 @@
import org.mockito.Mock
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
@@ -54,7 +57,7 @@
@Mock private lateinit var uiEventLogger: QsEventLogger
@Mock private lateinit var featureFlags: FeatureFlagsClassic
@Mock private lateinit var bluetoothTileDialogViewModel: BluetoothTileDialogViewModel
-
+ @Mock private lateinit var clickJob: Job
private lateinit var testableLooper: TestableLooper
private lateinit var tile: FakeBluetoothTile
@@ -191,6 +194,41 @@
}
@Test
+ fun handleClick_hasSatelliteFeatureButNoQsTileDialogAndClickIsProcessing_doNothing() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ `when`(featureFlags.isEnabled(com.android.systemui.flags.Flags.BLUETOOTH_QS_TILE_DIALOG))
+ .thenReturn(false)
+ `when`(clickJob.isCompleted).thenReturn(false)
+ tile.mClickJob = clickJob
+
+ tile.handleClick(null)
+
+ verify(bluetoothController, times(0)).setBluetoothEnabled(any())
+ }
+
+ @Test
+ fun handleClick_noSatelliteFeatureAndNoQsTileDialog_directSetBtEnable() {
+ mSetFlagsRule.disableFlags(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ `when`(featureFlags.isEnabled(com.android.systemui.flags.Flags.BLUETOOTH_QS_TILE_DIALOG))
+ .thenReturn(false)
+
+ tile.handleClick(null)
+
+ verify(bluetoothController).setBluetoothEnabled(any())
+ }
+
+ @Test
+ fun handleClick_noSatelliteFeatureButHasQsTileDialog_showDialog() {
+ mSetFlagsRule.disableFlags(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ `when`(featureFlags.isEnabled(com.android.systemui.flags.Flags.BLUETOOTH_QS_TILE_DIALOG))
+ .thenReturn(true)
+
+ tile.handleClick(null)
+
+ verify(bluetoothTileDialogViewModel).showDialog(null)
+ }
+
+ @Test
fun testMetadataListener_whenDisconnected_isUnregistered() {
val state = QSTile.BooleanState()
val cachedDevice = mock<CachedBluetoothDevice>()