| /* |
| * Copyright (C) 2022 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.bedstead.nene.bluetooth; |
| |
| import static android.os.Build.VERSION_CODES.R; |
| |
| import static com.android.bedstead.nene.permissions.CommonPermissions.BLUETOOTH; |
| import static com.android.bedstead.nene.permissions.CommonPermissions.BLUETOOTH_CONNECT; |
| import static com.android.bedstead.nene.permissions.CommonPermissions.INTERACT_ACROSS_USERS_FULL; |
| import static com.android.bedstead.nene.permissions.CommonPermissions.NETWORK_SETTINGS; |
| import static com.android.bedstead.nene.utils.Versions.T; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| |
| import android.bluetooth.BluetoothAdapter; |
| import android.bluetooth.BluetoothManager; |
| import android.content.Context; |
| import android.content.Intent; |
| |
| import com.android.bedstead.nene.TestApis; |
| import com.android.bedstead.nene.logging.Logger; |
| import com.android.bedstead.nene.permissions.PermissionContext; |
| import com.android.bedstead.nene.utils.Poll; |
| import com.android.compatibility.common.util.BlockingBroadcastReceiver; |
| |
| /** Test APIs related to bluetooth. */ |
| public final class Bluetooth { |
| |
| public static final Bluetooth sInstance = new Bluetooth(); |
| |
| private static final Context sContext = TestApis.context().instrumentedContext(); |
| private static final BluetoothManager sBluetoothManager = |
| sContext.getSystemService(BluetoothManager.class); |
| private static final BluetoothAdapter sBluetoothAdapter = sBluetoothManager.getAdapter(); |
| |
| private final Logger mLogger = Logger.forInstance(this); |
| |
| private Bluetooth() { |
| mLogger.constructor(); |
| } |
| |
| /** Enable or disable bluetooth on the device. */ |
| public void setEnabled(boolean enabled) { |
| mLogger.method("setEnabled", enabled, () -> { |
| if (isEnabled() == enabled) { |
| return; |
| } |
| |
| if (enabled) { |
| enable(); |
| } else { |
| disable(); |
| } |
| }); |
| } |
| |
| private void enable() { |
| mLogger.method("enable", () -> { |
| try (PermissionContext p = |
| TestApis.permissions() |
| .withPermission(BLUETOOTH_CONNECT, INTERACT_ACROSS_USERS_FULL) |
| .withPermissionOnVersionAtLeast(T, NETWORK_SETTINGS)) { |
| BlockingBroadcastReceiver r = BlockingBroadcastReceiver.create( |
| sContext, |
| BluetoothAdapter.ACTION_STATE_CHANGED, |
| this::isStateEnabled).register(); |
| |
| try { |
| assertThat(sBluetoothAdapter.enable()).isTrue(); |
| |
| r.awaitForBroadcast(); |
| Poll.forValue("Bluetooth Enabled", this::isEnabled) |
| .toBeEqualTo(true) |
| .errorOnFail() |
| .await(); |
| } finally { |
| r.unregisterQuietly(); |
| } |
| } |
| }); |
| } |
| |
| private void disable() { |
| mLogger.method("disable", () -> { |
| try (PermissionContext p = |
| TestApis.permissions() |
| .withPermission(BLUETOOTH_CONNECT, INTERACT_ACROSS_USERS_FULL) |
| .withPermissionOnVersionAtLeast(T, NETWORK_SETTINGS)) { |
| BlockingBroadcastReceiver r = BlockingBroadcastReceiver.create( |
| sContext, |
| BluetoothAdapter.ACTION_STATE_CHANGED, |
| this::isStateDisabled).register(); |
| |
| try { |
| assertThat(sBluetoothAdapter.disable()).isTrue(); |
| |
| r.awaitForBroadcast(); |
| Poll.forValue("Bluetooth Enabled", this::isEnabled) |
| .toBeEqualTo(false) |
| .errorOnFail() |
| .await(); |
| } finally { |
| r.unregisterQuietly(); |
| } |
| } |
| }); |
| } |
| |
| /** {@code true} if bluetooth is enabled. */ |
| public boolean isEnabled() { |
| return mLogger.method("isEnabled", () -> { |
| try (PermissionContext p = |
| TestApis.permissions().withPermissionOnVersionAtMost(R, BLUETOOTH)) { |
| return sBluetoothAdapter.isEnabled(); |
| } |
| }); |
| } |
| |
| private boolean isStateEnabled(Intent intent) { |
| return mLogger.method("isStateEnabled", intent, () -> |
| intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1) |
| == BluetoothAdapter.STATE_ON); |
| } |
| |
| private boolean isStateDisabled(Intent intent) { |
| return mLogger.method("isStateDisabled", intent, () -> |
| intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1) |
| == BluetoothAdapter.STATE_OFF); |
| } |
| } |