summaryrefslogtreecommitdiffstats
path: root/device
diff options
context:
space:
mode:
authorperja <perja@opera.com>2016-02-26 13:37:50 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-26 21:39:08 +0000
commit3a38a463d379e27cb72a3c0334f76ecf4f8de8c4 (patch)
tree22eece87bf34bdc0a6c143fa7068c2d701733760 /device
parent1369d7387a6e858a4be98e9dde29d2811fa95e31 (diff)
downloadchromium_src-3a38a463d379e27cb72a3c0334f76ecf4f8de8c4.zip
chromium_src-3a38a463d379e27cb72a3c0334f76ecf4f8de8c4.tar.gz
chromium_src-3a38a463d379e27cb72a3c0334f76ecf4f8de8c4.tar.bz2
bluetooth: android: register for adapter on/off events.
Register for BluetoothAdapter.ACTION_STATE_CHANGED and reflect the state changes in the device chooser dialog. BUG=543060 Review URL: https://codereview.chromium.org/1711393002 Cr-Commit-Position: refs/heads/master@{#377982}
Diffstat (limited to 'device')
-rw-r--r--device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java64
-rw-r--r--device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java11
-rw-r--r--device/bluetooth/bluetooth_adapter.cc5
-rw-r--r--device/bluetooth/bluetooth_adapter.h4
-rw-r--r--device/bluetooth/bluetooth_adapter_android.cc7
-rw-r--r--device/bluetooth/bluetooth_adapter_android.h5
-rw-r--r--device/bluetooth/bluetooth_adapter_unittest.cc10
-rw-r--r--device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java18
-rw-r--r--device/bluetooth/test/bluetooth_test_android.cc7
-rw-r--r--device/bluetooth/test/bluetooth_test_android.h6
10 files changed, 134 insertions, 3 deletions
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java
index 0a54a0b..54a8eb9 100644
--- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java
+++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java
@@ -8,6 +8,10 @@ import android.Manifest;
import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.le.ScanSettings;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.os.Build;
import android.os.ParcelUuid;
@@ -26,7 +30,7 @@ import java.util.List;
*/
@JNINamespace("device")
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
-final class ChromeBluetoothAdapter {
+final class ChromeBluetoothAdapter extends BroadcastReceiver {
private static final String TAG = "Bluetooth";
private long mNativeBluetoothAdapterAndroid;
@@ -49,6 +53,7 @@ final class ChromeBluetoothAdapter {
long nativeBluetoothAdapterAndroid, Wrappers.BluetoothAdapterWrapper adapterWrapper) {
mNativeBluetoothAdapterAndroid = nativeBluetoothAdapterAndroid;
mAdapter = adapterWrapper;
+ registerBroadcastReceiver();
if (adapterWrapper == null) {
Log.i(TAG, "ChromeBluetoothAdapter created with no adapterWrapper.");
} else {
@@ -63,6 +68,7 @@ final class ChromeBluetoothAdapter {
private void onBluetoothAdapterAndroidDestruction() {
stopScan();
mNativeBluetoothAdapterAndroid = 0;
+ unregisterBroadcastReceiver();
}
// ---------------------------------------------------------------------------------------------
@@ -187,6 +193,19 @@ final class ChromeBluetoothAdapter {
|| context.checkPermission(Manifest.permission.ACCESS_FINE_LOCATION);
}
+ private void registerBroadcastReceiver() {
+ if (mAdapter != null) {
+ mAdapter.getContext().registerReceiver(
+ this, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
+ }
+ }
+
+ private void unregisterBroadcastReceiver() {
+ if (mAdapter != null) {
+ mAdapter.getContext().unregisterReceiver(this);
+ }
+ }
+
/**
* Starts a Low Energy scan.
* @return True on success.
@@ -275,6 +294,45 @@ final class ChromeBluetoothAdapter {
}
}
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+
+ if (isPresent() && BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
+ int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
+
+ Log.w(TAG, "onReceive: BluetoothAdapter.ACTION_STATE_CHANGED: %s",
+ getBluetoothStateString(state));
+
+ switch (state) {
+ case BluetoothAdapter.STATE_ON:
+ nativeOnAdapterStateChanged(mNativeBluetoothAdapterAndroid, true);
+ break;
+ case BluetoothAdapter.STATE_OFF:
+ nativeOnAdapterStateChanged(mNativeBluetoothAdapterAndroid, false);
+ break;
+ default:
+ // do nothing
+ }
+ }
+ }
+
+ private String getBluetoothStateString(int state) {
+ switch (state) {
+ case BluetoothAdapter.STATE_OFF:
+ return "STATE_OFF";
+ case BluetoothAdapter.STATE_ON:
+ return "STATE_ON";
+ case BluetoothAdapter.STATE_TURNING_OFF:
+ return "STATE_TURNING_OFF";
+ case BluetoothAdapter.STATE_TURNING_ON:
+ return "STATE_TURNING_ON";
+ default:
+ assert false;
+ return "illegal state: " + state;
+ }
+ }
+
// ---------------------------------------------------------------------------------------------
// BluetoothAdapterAndroid C++ methods declared for access from java:
@@ -287,4 +345,8 @@ final class ChromeBluetoothAdapter {
// http://crbug.com/505554
private native void nativeCreateOrUpdateDeviceOnScan(long nativeBluetoothAdapterAndroid,
String address, Object bluetoothDeviceWrapper, List<ParcelUuid> advertisedUuids);
+
+ // Binds to BluetoothAdapterAndroid::nativeOnAdapterStateChanged
+ private native void nativeOnAdapterStateChanged(
+ long nativeBluetoothAdapterAndroid, boolean powered);
}
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java
index 9287f85..96634b3 100644
--- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java
+++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java
@@ -18,7 +18,10 @@ import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.ParcelUuid;
@@ -163,6 +166,14 @@ class Wrappers {
return mContext.checkPermission(permission, Process.myPid(), Process.myUid())
== PackageManager.PERMISSION_GRANTED;
}
+
+ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+ return mContext.registerReceiver(receiver, filter);
+ }
+
+ public void unregisterReceiver(BroadcastReceiver receiver) {
+ mContext.unregisterReceiver(receiver);
+ }
}
/**
diff --git a/device/bluetooth/bluetooth_adapter.cc b/device/bluetooth/bluetooth_adapter.cc
index 390bb93..dea3593 100644
--- a/device/bluetooth/bluetooth_adapter.cc
+++ b/device/bluetooth/bluetooth_adapter.cc
@@ -158,6 +158,11 @@ BluetoothDevice::PairingDelegate* BluetoothAdapter::DefaultPairingDelegate() {
return pairing_delegates_.front().first;
}
+void BluetoothAdapter::NotifyAdapterStateChanged(bool powered) {
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ AdapterPoweredChanged(this, powered));
+}
+
void BluetoothAdapter::NotifyGattServiceAdded(BluetoothGattService* service) {
DCHECK_EQ(service->GetDevice()->GetAdapter(), this);
diff --git a/device/bluetooth/bluetooth_adapter.h b/device/bluetooth/bluetooth_adapter.h
index e099e32..5dcf12f 100644
--- a/device/bluetooth/bluetooth_adapter.h
+++ b/device/bluetooth/bluetooth_adapter.h
@@ -398,8 +398,8 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapter
const CreateAdvertisementCallback& callback,
const CreateAdvertisementErrorCallback& error_callback) = 0;
- // The following methods are used to send various GATT observer events to
- // observers.
+ // The following methods are used to send various events to observers.
+ void NotifyAdapterStateChanged(bool powered);
void NotifyGattServiceAdded(BluetoothGattService* service);
void NotifyGattServiceRemoved(BluetoothGattService* service);
void NotifyGattServiceChanged(BluetoothGattService* service);
diff --git a/device/bluetooth/bluetooth_adapter_android.cc b/device/bluetooth/bluetooth_adapter_android.cc
index 00cead7..fc19a81 100644
--- a/device/bluetooth/bluetooth_adapter_android.cc
+++ b/device/bluetooth/bluetooth_adapter_android.cc
@@ -134,6 +134,13 @@ void BluetoothAdapterAndroid::RegisterAdvertisement(
error_callback.Run(BluetoothAdvertisement::ERROR_UNSUPPORTED_PLATFORM);
}
+void BluetoothAdapterAndroid::OnAdapterStateChanged(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& caller,
+ const bool powered) {
+ NotifyAdapterStateChanged(powered);
+}
+
void BluetoothAdapterAndroid::OnScanFailed(
JNIEnv* env,
const JavaParamRef<jobject>& caller) {
diff --git a/device/bluetooth/bluetooth_adapter_android.h b/device/bluetooth/bluetooth_adapter_android.h
index 3612602..8ebb49c 100644
--- a/device/bluetooth/bluetooth_adapter_android.h
+++ b/device/bluetooth/bluetooth_adapter_android.h
@@ -83,6 +83,11 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterAndroid final
const CreateAdvertisementCallback& callback,
const CreateAdvertisementErrorCallback& error_callback) override;
+ // Called when adapter state changes.
+ void OnAdapterStateChanged(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& caller,
+ const bool powered);
+
// Handles a scan error event by invalidating all discovery sessions.
void OnScanFailed(JNIEnv* env,
const base::android::JavaParamRef<jobject>& caller);
diff --git a/device/bluetooth/bluetooth_adapter_unittest.cc b/device/bluetooth/bluetooth_adapter_unittest.cc
index a40af0e..55bffb7 100644
--- a/device/bluetooth/bluetooth_adapter_unittest.cc
+++ b/device/bluetooth/bluetooth_adapter_unittest.cc
@@ -660,31 +660,40 @@ TEST_F(BluetoothTest, DiscoverMultipleLowEnergyDevices) {
#if defined(OS_ANDROID)
TEST_F(BluetoothTest, TogglePowerFakeAdapter) {
InitWithFakeAdapter();
+ TestBluetoothAdapterObserver observer(adapter_);
+
ASSERT_TRUE(adapter_->IsPresent());
ASSERT_TRUE(adapter_->IsPowered());
+ EXPECT_EQ(0, observer.powered_changed_count());
// Check if power can be turned off.
adapter_->SetPowered(false, GetCallback(Call::EXPECTED),
GetErrorCallback(Call::NOT_EXPECTED));
EXPECT_FALSE(adapter_->IsPowered());
+ EXPECT_EQ(1, observer.powered_changed_count());
// Check if power can be turned on again.
adapter_->SetPowered(true, GetCallback(Call::EXPECTED),
GetErrorCallback(Call::NOT_EXPECTED));
EXPECT_TRUE(adapter_->IsPowered());
+ EXPECT_EQ(2, observer.powered_changed_count());
}
#endif // defined(OS_ANDROID)
#if defined(OS_ANDROID)
TEST_F(BluetoothTest, TogglePowerBeforeScan) {
InitWithFakeAdapter();
+ TestBluetoothAdapterObserver observer(adapter_);
+
ASSERT_TRUE(adapter_->IsPresent());
ASSERT_TRUE(adapter_->IsPowered());
+ EXPECT_EQ(0, observer.powered_changed_count());
// Turn off adapter.
adapter_->SetPowered(false, GetCallback(Call::EXPECTED),
GetErrorCallback(Call::NOT_EXPECTED));
ASSERT_FALSE(adapter_->IsPowered());
+ EXPECT_EQ(1, observer.powered_changed_count());
// Try to perform a scan.
StartLowEnergyDiscoverySessionExpectedToFail();
@@ -693,6 +702,7 @@ TEST_F(BluetoothTest, TogglePowerBeforeScan) {
adapter_->SetPowered(true, GetCallback(Call::EXPECTED),
GetErrorCallback(Call::NOT_EXPECTED));
ASSERT_TRUE(adapter_->IsPowered());
+ EXPECT_EQ(2, observer.powered_changed_count());
// Try to perform a scan again.
ResetEventCounts();
diff --git a/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java b/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java
index 538f618..46f9c66 100644
--- a/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java
+++ b/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java
@@ -9,7 +9,11 @@ import android.annotation.TargetApi;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanSettings;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
import android.os.Build;
import android.os.ParcelUuid;
@@ -133,12 +137,14 @@ class Fakes {
@Override
public boolean disable() {
mPowered = false;
+ nativeOnFakeAdapterStateChanged(mNativeBluetoothTestAndroid, false);
return true;
}
@Override
public boolean enable() {
mPowered = true;
+ nativeOnFakeAdapterStateChanged(mNativeBluetoothTestAndroid, true);
return true;
}
@@ -191,6 +197,14 @@ class Fakes {
public boolean checkPermission(String permission) {
return mPermissions.contains(permission);
}
+
+ @Override
+ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+ return null;
+ }
+
+ @Override
+ public void unregisterReceiver(BroadcastReceiver receiver) {}
}
/**
@@ -715,6 +729,10 @@ class Fakes {
// ---------------------------------------------------------------------------------------------
// BluetoothTestAndroid C++ methods declared for access from java:
+ // Binds to BluetoothTestAndroid::OnFakeAdapterStateChanged.
+ private static native void nativeOnFakeAdapterStateChanged(
+ long nativeBluetoothTestAndroid, boolean powered);
+
// Binds to BluetoothTestAndroid::OnFakeBluetoothDeviceConnectGattCalled.
private static native void nativeOnFakeBluetoothDeviceConnectGattCalled(
long nativeBluetoothTestAndroid);
diff --git a/device/bluetooth/test/bluetooth_test_android.cc b/device/bluetooth/test/bluetooth_test_android.cc
index 43299bc..522cd61 100644
--- a/device/bluetooth/test/bluetooth_test_android.cc
+++ b/device/bluetooth/test/bluetooth_test_android.cc
@@ -356,4 +356,11 @@ void BluetoothTestAndroid::OnFakeBluetoothGattWriteDescriptor(
base::android::JavaByteArrayToByteVector(env, value, &last_write_value_);
}
+void BluetoothTestAndroid::OnFakeAdapterStateChanged(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& caller,
+ const bool powered) {
+ adapter_->NotifyAdapterStateChanged(powered);
+}
+
} // namespace device
diff --git a/device/bluetooth/test/bluetooth_test_android.h b/device/bluetooth/test/bluetooth_test_android.h
index 3fb3a33..b855eca 100644
--- a/device/bluetooth/test/bluetooth_test_android.h
+++ b/device/bluetooth/test/bluetooth_test_android.h
@@ -118,6 +118,12 @@ class BluetoothTestAndroid : public BluetoothTestBase {
const base::android::JavaParamRef<jobject>& caller,
const base::android::JavaParamRef<jbyteArray>& value);
+ // Records that Java FakeBluetoothAdapter onAdapterStateChanged was called.
+ void OnFakeAdapterStateChanged(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& caller,
+ const bool powered);
+
base::android::ScopedJavaGlobalRef<jobject> j_fake_bluetooth_adapter_;
int gatt_open_connections_ = 0;