Fix create bluetooth dialog repeatedly
When the screen rotates, currently the startActivityForResult() within RequestPermissionActivity could be called multiple times, so the multiple RequestPermissionHelperActivity will be created, which caused the issue. Replace RequestPermissionHelperActivity with AlertDialog (as an unfinished TODO of RequestPermissionHelperActivity) can fix this issue. Fix: 243601277 Test: Manually with adb shell commands Test: Unit test Change-Id: If1e2b2807b69a87bbcfffa543ee0da134d4c4312
This commit is contained in:
@@ -2955,13 +2955,6 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".bluetooth.RequestPermissionHelperActivity"
|
||||
android:label="@string/bluetooth_pairing_request"
|
||||
android:excludeFromRecents="true"
|
||||
android:permission="android.permission.BLUETOOTH_CONNECT"
|
||||
android:theme="@*android:style/Theme.DeviceDefault.Dialog.Alert.DayNight">
|
||||
</activity>
|
||||
|
||||
<service android:name=".bluetooth.BluetoothPairingService" />
|
||||
|
||||
<receiver android:name=".bluetooth.BluetoothPairingRequest"
|
||||
|
@@ -42,6 +42,8 @@ import androidx.appcompat.app.AlertDialog;
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.bluetooth.BluetoothDiscoverableTimeoutReceiver;
|
||||
|
||||
import kotlin.Unit;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
@@ -100,12 +102,15 @@ public class RequestPermissionActivity extends Activity implements
|
||||
|
||||
case BluetoothAdapter.STATE_ON:
|
||||
case BluetoothAdapter.STATE_TURNING_ON: {
|
||||
Intent intent = new Intent(this, RequestPermissionHelperActivity.class);
|
||||
intent.putExtra(RequestPermissionHelperActivity.EXTRA_APP_LABEL, mAppLabel);
|
||||
intent.setAction(RequestPermissionHelperActivity
|
||||
.ACTION_INTERNAL_REQUEST_BT_OFF);
|
||||
|
||||
startActivityForResult(intent, 0);
|
||||
RequestPermissionHelper.INSTANCE.requestDisable(this, mAppLabel,
|
||||
() -> {
|
||||
onDisableConfirmed();
|
||||
return Unit.INSTANCE;
|
||||
},
|
||||
() -> {
|
||||
cancelAndFinish();
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
} break;
|
||||
|
||||
default: {
|
||||
@@ -126,18 +131,17 @@ public class RequestPermissionActivity extends Activity implements
|
||||
* case via the broadcast receiver.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Start the helper activity to:
|
||||
* 1) ask the user about enabling bt AND discovery
|
||||
* 2) enable BT upon confirmation
|
||||
*/
|
||||
Intent intent = new Intent(this, RequestPermissionHelperActivity.class);
|
||||
intent.setAction(RequestPermissionHelperActivity.ACTION_INTERNAL_REQUEST_BT_ON);
|
||||
intent.putExtra(RequestPermissionHelperActivity.EXTRA_APP_LABEL, mAppLabel);
|
||||
if (mRequest == REQUEST_ENABLE_DISCOVERABLE) {
|
||||
intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, mTimeout);
|
||||
}
|
||||
startActivityForResult(intent, 0);
|
||||
// Start the helper activity to ask the user about enabling bt AND discovery
|
||||
RequestPermissionHelper.INSTANCE.requestEnable(this, mAppLabel,
|
||||
mRequest == REQUEST_ENABLE_DISCOVERABLE ? mTimeout : -1,
|
||||
() -> {
|
||||
onEnableConfirmed();
|
||||
return Unit.INSTANCE;
|
||||
},
|
||||
() -> {
|
||||
cancelAndFinish();
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
} break;
|
||||
|
||||
case BluetoothAdapter.STATE_ON: {
|
||||
@@ -202,42 +206,27 @@ public class RequestPermissionActivity extends Activity implements
|
||||
mDialog.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (resultCode != Activity.RESULT_OK) {
|
||||
cancelAndFinish();
|
||||
return;
|
||||
private void onEnableConfirmed() {
|
||||
mBluetoothAdapter.enable();
|
||||
if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
|
||||
proceedAndFinish();
|
||||
} else {
|
||||
// If BT is not up yet, show "Turning on Bluetooth..."
|
||||
mReceiver = new StateChangeReceiver();
|
||||
registerReceiver(mReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
|
||||
createDialog();
|
||||
}
|
||||
}
|
||||
|
||||
switch (mRequest) {
|
||||
case REQUEST_ENABLE:
|
||||
case REQUEST_ENABLE_DISCOVERABLE: {
|
||||
if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
|
||||
proceedAndFinish();
|
||||
} else {
|
||||
// If BT is not up yet, show "Turning on Bluetooth..."
|
||||
mReceiver = new StateChangeReceiver();
|
||||
registerReceiver(mReceiver, new IntentFilter(
|
||||
BluetoothAdapter.ACTION_STATE_CHANGED));
|
||||
createDialog();
|
||||
}
|
||||
} break;
|
||||
|
||||
case REQUEST_DISABLE: {
|
||||
if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_OFF) {
|
||||
proceedAndFinish();
|
||||
} else {
|
||||
// If BT is not up yet, show "Turning off Bluetooth..."
|
||||
mReceiver = new StateChangeReceiver();
|
||||
registerReceiver(mReceiver, new IntentFilter(
|
||||
BluetoothAdapter.ACTION_STATE_CHANGED));
|
||||
createDialog();
|
||||
}
|
||||
} break;
|
||||
|
||||
default: {
|
||||
cancelAndFinish();
|
||||
} break;
|
||||
private void onDisableConfirmed() {
|
||||
mBluetoothAdapter.disable();
|
||||
if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_OFF) {
|
||||
proceedAndFinish();
|
||||
} else {
|
||||
// If BT is not up yet, show "Turning off Bluetooth..."
|
||||
mReceiver = new StateChangeReceiver();
|
||||
registerReceiver(mReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
|
||||
createDialog();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.bluetooth
|
||||
|
||||
import android.content.Context
|
||||
import android.os.UserManager
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.android.settings.R
|
||||
import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager
|
||||
import com.android.settingslib.spaprivileged.framework.common.userManager
|
||||
|
||||
object RequestPermissionHelper {
|
||||
fun requestEnable(
|
||||
context: Context,
|
||||
appLabel: CharSequence?,
|
||||
timeout: Int,
|
||||
onAllow: () -> Unit,
|
||||
onDeny: () -> Unit,
|
||||
) {
|
||||
if (context.resources.getBoolean(R.bool.auto_confirm_bluetooth_activation_dialog)) {
|
||||
// Don't even show the dialog if configured this way
|
||||
onAllow()
|
||||
return
|
||||
}
|
||||
AlertDialog.Builder(context).apply {
|
||||
setMessage(context.getEnableMessage(timeout, appLabel))
|
||||
setPositiveButton(R.string.allow) { _, _ ->
|
||||
if (context.isDisallowBluetooth()) onDeny() else onAllow()
|
||||
}
|
||||
setNegativeButton(R.string.deny) { _, _ -> onDeny() }
|
||||
setOnCancelListener { onDeny() }
|
||||
}.show()
|
||||
}
|
||||
|
||||
fun requestDisable(
|
||||
context: Context,
|
||||
appLabel: CharSequence?,
|
||||
onAllow: () -> Unit,
|
||||
onDeny: () -> Unit,
|
||||
) {
|
||||
if (context.resources.getBoolean(R.bool.auto_confirm_bluetooth_activation_dialog)) {
|
||||
// Don't even show the dialog if configured this way
|
||||
onAllow()
|
||||
return
|
||||
}
|
||||
AlertDialog.Builder(context).apply {
|
||||
setMessage(context.getDisableMessage(appLabel))
|
||||
setPositiveButton(R.string.allow) { _, _ -> onAllow() }
|
||||
setNegativeButton(R.string.deny) { _, _ -> onDeny() }
|
||||
setOnCancelListener { onDeny() }
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
|
||||
// If Bluetooth is disallowed, don't try to enable it, show policy transparency message instead.
|
||||
private fun Context.isDisallowBluetooth() =
|
||||
if (userManager.hasUserRestriction(UserManager.DISALLOW_BLUETOOTH)) {
|
||||
devicePolicyManager.createAdminSupportIntent(UserManager.DISALLOW_BLUETOOTH)
|
||||
?.let { startActivity(it) }
|
||||
true
|
||||
} else false
|
||||
|
||||
private fun Context.getEnableMessage(timeout: Int, name: CharSequence?): String = when {
|
||||
timeout < 0 -> when (name) {
|
||||
null -> getString(R.string.bluetooth_ask_enablement_no_name)
|
||||
else -> getString(R.string.bluetooth_ask_enablement, name)
|
||||
}
|
||||
|
||||
timeout == BluetoothDiscoverableEnabler.DISCOVERABLE_TIMEOUT_NEVER -> when (name) {
|
||||
null -> getString(R.string.bluetooth_ask_enablement_and_lasting_discovery_no_name)
|
||||
else -> getString(R.string.bluetooth_ask_enablement_and_lasting_discovery, name)
|
||||
}
|
||||
|
||||
else -> when (name) {
|
||||
null -> getString(R.string.bluetooth_ask_enablement_and_discovery_no_name, timeout)
|
||||
else -> getString(R.string.bluetooth_ask_enablement_and_discovery, name, timeout)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Context.getDisableMessage(name: CharSequence?): String =
|
||||
when (name) {
|
||||
null -> getString(R.string.bluetooth_ask_disablement_no_name)
|
||||
else -> getString(R.string.bluetooth_ask_disablement, name)
|
||||
}
|
@@ -1,178 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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.bluetooth;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.app.AlertActivity;
|
||||
import com.android.internal.app.AlertController;
|
||||
import com.android.settings.R;
|
||||
|
||||
/**
|
||||
* RequestPermissionHelperActivity asks the user whether to toggle Bluetooth.
|
||||
*
|
||||
* TODO: This activity isn't needed - this should be folded in RequestPermissionActivity
|
||||
*/
|
||||
public class RequestPermissionHelperActivity extends AlertActivity implements
|
||||
DialogInterface.OnClickListener {
|
||||
private static final String TAG = "RequestPermissionHelperActivity";
|
||||
|
||||
public static final String ACTION_INTERNAL_REQUEST_BT_ON =
|
||||
"com.android.settings.bluetooth.ACTION_INTERNAL_REQUEST_BT_ON";
|
||||
|
||||
public static final String ACTION_INTERNAL_REQUEST_BT_OFF =
|
||||
"com.android.settings.bluetooth.ACTION_INTERNAL_REQUEST_BT_OFF";
|
||||
|
||||
public static final String EXTRA_APP_LABEL =
|
||||
"com.android.settings.bluetooth.extra.APP_LABEL";
|
||||
|
||||
private BluetoothAdapter mBluetoothAdapter;
|
||||
|
||||
private CharSequence mAppLabel;
|
||||
|
||||
private int mTimeout = -1;
|
||||
|
||||
private int mRequest;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setResult(RESULT_CANCELED);
|
||||
|
||||
// Note: initializes mBluetoothAdapter and returns true on error
|
||||
if (!parseIntent()) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
if (getResources().getBoolean(R.bool.auto_confirm_bluetooth_activation_dialog)) {
|
||||
// Don't even show the dialog if configured this way
|
||||
onClick(null, BUTTON_POSITIVE);
|
||||
dismiss();
|
||||
}
|
||||
|
||||
createDialog();
|
||||
}
|
||||
|
||||
void createDialog() {
|
||||
final AlertController.AlertParams p = mAlertParams;
|
||||
|
||||
switch (mRequest) {
|
||||
case RequestPermissionActivity.REQUEST_ENABLE: {
|
||||
if (mTimeout < 0) {
|
||||
p.mMessage = mAppLabel != null
|
||||
? getString(R.string.bluetooth_ask_enablement, mAppLabel)
|
||||
: getString(R.string.bluetooth_ask_enablement_no_name);
|
||||
} else if (mTimeout == BluetoothDiscoverableEnabler.DISCOVERABLE_TIMEOUT_NEVER) {
|
||||
p.mMessage = mAppLabel != null
|
||||
? getString(
|
||||
R.string.bluetooth_ask_enablement_and_lasting_discovery,
|
||||
mAppLabel)
|
||||
: getString(
|
||||
R.string.bluetooth_ask_enablement_and_lasting_discovery_no_name);
|
||||
} else {
|
||||
p.mMessage = mAppLabel != null
|
||||
? getString(R.string.bluetooth_ask_enablement_and_discovery,
|
||||
mAppLabel, mTimeout)
|
||||
: getString(R.string.bluetooth_ask_enablement_and_discovery_no_name,
|
||||
mTimeout);
|
||||
}
|
||||
} break;
|
||||
|
||||
case RequestPermissionActivity.REQUEST_DISABLE: {
|
||||
p.mMessage = mAppLabel != null
|
||||
? getString(R.string.bluetooth_ask_disablement, mAppLabel)
|
||||
: getString(R.string.bluetooth_ask_disablement_no_name);
|
||||
} break;
|
||||
}
|
||||
|
||||
p.mPositiveButtonText = getString(R.string.allow);
|
||||
p.mPositiveButtonListener = this;
|
||||
p.mNegativeButtonText = getString(R.string.deny);
|
||||
|
||||
setupAlert();
|
||||
}
|
||||
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
switch (mRequest) {
|
||||
case RequestPermissionActivity.REQUEST_ENABLE:
|
||||
case RequestPermissionActivity.REQUEST_ENABLE_DISCOVERABLE: {
|
||||
UserManager userManager = getSystemService(UserManager.class);
|
||||
if (userManager.hasUserRestriction(UserManager.DISALLOW_BLUETOOTH)) {
|
||||
// If Bluetooth is disallowed, don't try to enable it, show policy transparency
|
||||
// message instead.
|
||||
DevicePolicyManager dpm = getSystemService(DevicePolicyManager.class);
|
||||
Intent intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_BLUETOOTH);
|
||||
if (intent != null) {
|
||||
startActivity(intent);
|
||||
}
|
||||
} else {
|
||||
mBluetoothAdapter.enable();
|
||||
setResult(Activity.RESULT_OK);
|
||||
}
|
||||
} break;
|
||||
|
||||
case RequestPermissionActivity.REQUEST_DISABLE: {
|
||||
mBluetoothAdapter.disable();
|
||||
setResult(Activity.RESULT_OK);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the received Intent and initialize mBluetoothAdapter.
|
||||
* @return true if an error occurred; false otherwise
|
||||
*/
|
||||
private boolean parseIntent() {
|
||||
Intent intent = getIntent();
|
||||
if (intent == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String action = intent.getAction();
|
||||
if (ACTION_INTERNAL_REQUEST_BT_ON.equals(action)) {
|
||||
mRequest = RequestPermissionActivity.REQUEST_ENABLE;
|
||||
if (intent.hasExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION)) {
|
||||
// Value used for display purposes. Not range checking.
|
||||
mTimeout = intent.getIntExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,
|
||||
BluetoothDiscoverableEnabler.DEFAULT_DISCOVERABLE_TIMEOUT);
|
||||
}
|
||||
} else if (ACTION_INTERNAL_REQUEST_BT_OFF.equals(action)) {
|
||||
mRequest = RequestPermissionActivity.REQUEST_DISABLE;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
mAppLabel = getIntent().getCharSequenceExtra(EXTRA_APP_LABEL);
|
||||
|
||||
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
if (mBluetoothAdapter == null) {
|
||||
Log.e(TAG, "Error: there's a problem starting Bluetooth");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.bluetooth
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import com.android.settings.R
|
||||
import com.android.settings.testutils.shadow.ShadowAlertDialogCompat
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mockito.spy
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.android.controller.ActivityController
|
||||
import org.robolectric.annotation.Config
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(shadows = [ShadowAlertDialogCompat::class])
|
||||
class RequestPermissionHelperTest {
|
||||
private lateinit var activityController: ActivityController<ComponentActivity>
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
activityController =
|
||||
ActivityController.of(ComponentActivity()).create().start().postCreate(null).resume()
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
activityController.pause().stop().destroy()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun requestEnable_withAppLabelAndNoTimeout_hasCorrectMessage() {
|
||||
val activity = activityController.get()
|
||||
RequestPermissionHelper.requestEnable(
|
||||
context = activity,
|
||||
appLabel = "App Label",
|
||||
timeout = -1,
|
||||
onAllow = {},
|
||||
onDeny = {},
|
||||
)
|
||||
|
||||
assertLatestMessageIs("App Label wants to turn on Bluetooth")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun requestEnable_withAppLabelAndZeroTimeout_hasCorrectMessage() {
|
||||
val activity = activityController.get()
|
||||
RequestPermissionHelper.requestEnable(
|
||||
context = activity,
|
||||
appLabel = "App Label",
|
||||
timeout = 0,
|
||||
onAllow = {},
|
||||
onDeny = {},
|
||||
)
|
||||
|
||||
assertLatestMessageIs(
|
||||
"App Label wants to turn on Bluetooth and make your phone visible to other devices. " +
|
||||
"You can change this later in Bluetooth settings."
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun requestEnable_withAppLabelAndNormalTimeout_hasCorrectMessage() {
|
||||
val activity = activityController.get()
|
||||
RequestPermissionHelper.requestEnable(
|
||||
context = activity,
|
||||
appLabel = "App Label",
|
||||
timeout = 120,
|
||||
onAllow = {},
|
||||
onDeny = {},
|
||||
)
|
||||
|
||||
assertLatestMessageIs(
|
||||
"App Label wants to turn on Bluetooth and make your phone visible to other devices " +
|
||||
"for 120 seconds."
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun requestEnable_withNoAppLabelAndNoTimeout_hasCorrectMessage() {
|
||||
val activity = activityController.get()
|
||||
RequestPermissionHelper.requestEnable(
|
||||
context = activity,
|
||||
appLabel = null,
|
||||
timeout = -1,
|
||||
onAllow = {},
|
||||
onDeny = {},
|
||||
)
|
||||
|
||||
assertLatestMessageIs("An app wants to turn on Bluetooth")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun requestEnable_withNoAppLabelAndZeroTimeout_hasCorrectMessage() {
|
||||
val activity = activityController.get()
|
||||
RequestPermissionHelper.requestEnable(
|
||||
context = activity,
|
||||
appLabel = null,
|
||||
timeout = 0,
|
||||
onAllow = {},
|
||||
onDeny = {},
|
||||
)
|
||||
|
||||
assertLatestMessageIs(
|
||||
"An app wants to turn on Bluetooth and make your phone visible to other devices. " +
|
||||
"You can change this later in Bluetooth settings."
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun requestEnable_withNoAppLabelAndNormalTimeout_hasCorrectMessage() {
|
||||
val activity = activityController.get()
|
||||
RequestPermissionHelper.requestEnable(
|
||||
context = activity,
|
||||
appLabel = null,
|
||||
timeout = 120,
|
||||
onAllow = {},
|
||||
onDeny = {},
|
||||
)
|
||||
|
||||
assertLatestMessageIs(
|
||||
"An app wants to turn on Bluetooth and make your phone visible to other devices for " +
|
||||
"120 seconds."
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun requestEnable_whenAutoConfirm_onAllowIsCalled() {
|
||||
val activity = getActivityWith(autoConfirm = true)
|
||||
var onAllowCalled = false
|
||||
|
||||
RequestPermissionHelper.requestEnable(
|
||||
context = activity,
|
||||
appLabel = null,
|
||||
timeout = -1,
|
||||
onAllow = { onAllowCalled = true },
|
||||
onDeny = {},
|
||||
)
|
||||
|
||||
assertThat(onAllowCalled).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun requestEnable_whenNotAutoConfirm_onAllowIsNotCalledWhenRequest() {
|
||||
val activity = getActivityWith(autoConfirm = false)
|
||||
var onAllowCalled = false
|
||||
|
||||
RequestPermissionHelper.requestEnable(
|
||||
context = activity,
|
||||
appLabel = null,
|
||||
timeout = -1,
|
||||
onAllow = { onAllowCalled = true },
|
||||
onDeny = {},
|
||||
)
|
||||
|
||||
assertThat(onAllowCalled).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun requestDisable_withAppLabel_hasCorrectMessage() {
|
||||
val activity = activityController.get()
|
||||
RequestPermissionHelper.requestDisable(
|
||||
context = activity,
|
||||
appLabel = "App Label",
|
||||
onAllow = {},
|
||||
onDeny = {},
|
||||
)
|
||||
|
||||
assertLatestMessageIs("App Label wants to turn off Bluetooth")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun requestDisable_withNoAppLabel_hasCorrectMessage() {
|
||||
val activity = activityController.get()
|
||||
RequestPermissionHelper.requestDisable(
|
||||
context = activity,
|
||||
appLabel = null,
|
||||
onAllow = {},
|
||||
onDeny = {},
|
||||
)
|
||||
|
||||
assertLatestMessageIs("An app wants to turn off Bluetooth")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun requestDisable_whenAutoConfirm_onAllowIsCalled() {
|
||||
val activity = getActivityWith(autoConfirm = true)
|
||||
var onAllowCalled = false
|
||||
|
||||
RequestPermissionHelper.requestDisable(
|
||||
context = activity,
|
||||
appLabel = null,
|
||||
onAllow = { onAllowCalled = true },
|
||||
onDeny = {},
|
||||
)
|
||||
|
||||
assertThat(onAllowCalled).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun requestDisable_whenNotAutoConfirm_onAllowIsNotCalledWhenRequest() {
|
||||
val activity = getActivityWith(autoConfirm = false)
|
||||
var onAllowCalled = false
|
||||
|
||||
RequestPermissionHelper.requestDisable(
|
||||
context = activity,
|
||||
appLabel = null,
|
||||
onAllow = { onAllowCalled = true },
|
||||
onDeny = {},
|
||||
)
|
||||
|
||||
assertThat(onAllowCalled).isFalse()
|
||||
}
|
||||
|
||||
private fun getActivityWith(autoConfirm: Boolean): ComponentActivity {
|
||||
val activity = spy(activityController.get())
|
||||
val spyResources = spy(activity.resources)
|
||||
whenever(activity.resources).thenReturn(spyResources)
|
||||
whenever(spyResources.getBoolean(R.bool.auto_confirm_bluetooth_activation_dialog))
|
||||
.thenReturn(autoConfirm)
|
||||
return activity
|
||||
}
|
||||
|
||||
private fun assertLatestMessageIs(message: String) {
|
||||
val dialog = ShadowAlertDialogCompat.getLatestAlertDialog()
|
||||
val shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog)
|
||||
assertThat(shadowDialog.message.toString()).isEqualTo(message)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user