summaryrefslogtreecommitdiff
path: root/framework/java/android/bluetooth/BluetoothAdapter.java
diff options
context:
space:
mode:
authorWilliam Escande <wescande@google.com>2022-04-22 15:49:39 -0700
committerWilliam Escande <wescande@google.com>2022-04-29 22:39:43 +0000
commit25fc56ed6a3506d3c83cd01803a3b34e5ffff4ca (patch)
tree3664a30b0cee81565ed8ab3044e7650597f499b4 /framework/java/android/bluetooth/BluetoothAdapter.java
parent89f4da04fe1059d734c11247e0167f4685194c82 (diff)
Add caching for {Map,Sap}.getConnectionState
BluetoothMap and BluetoothSap are heavily using their getConnectionState method. By caching the value I intend to reduce drastically the number of binder calls generated. While performing a discovery, the caching is working on 80% of binder calls. This value should be bigger when we kepp asking the value for the same device. (currently everytime you ask the connection state of a new device, you refresh the cache, there is no caching for multiples devices). I don't have any Map/Sap setup to test it, asking to test team if they hit some issues Fixing cache on BluetoothDevice by passing the device as parameter Doing a refactoring of all cached method in bluetooth to keep code consistency: AKA we try to do the most of check outside of the cache query Bug: 217366135 Test: Put some log to see the value being cached sometimes - need more testing Ignore-AOSP-First: No caching api on AOSP Change-Id: Iababf9f9068a181e277b400e786a4a67d4447dc8
Diffstat (limited to 'framework/java/android/bluetooth/BluetoothAdapter.java')
-rw-r--r--framework/java/android/bluetooth/BluetoothAdapter.java218
1 files changed, 121 insertions, 97 deletions
diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java
index 51239f1236..eed12635c5 100644
--- a/framework/java/android/bluetooth/BluetoothAdapter.java
+++ b/framework/java/android/bluetooth/BluetoothAdapter.java
@@ -1269,36 +1269,27 @@ public final class BluetoothAdapter {
IpcDataCache.invalidateCache(IpcDataCache.MODULE_BLUETOOTH, api);
}
- /**
- * The binder cache for getState().
- */
- private static final String GET_STATE_API = "getState";
-
- private final IpcDataCache.QueryHandler<Void, Integer> mBluetoothGetStateQuery =
+ private final IpcDataCache.QueryHandler<IBluetooth, Integer> mBluetoothGetStateQuery =
new IpcDataCache.QueryHandler<>() {
- @RequiresLegacyBluetoothPermission
- @RequiresNoPermission
- @Override
- public @InternalAdapterState Integer apply(Void query) {
- int state = BluetoothAdapter.STATE_OFF;
- mServiceLock.readLock().lock();
- try {
- if (mService != null) {
- final SynchronousResultReceiver<Integer> recv =
- new SynchronousResultReceiver();
- mService.getState(recv);
- return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(state);
+ @RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
+ @Override
+ public @InternalAdapterState Integer apply(IBluetooth serviceQuery) {
+ try {
+ final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
+ serviceQuery.getState(recv);
+ return recv.awaitResultNoInterrupt(getSyncTimeout())
+ .getValue(BluetoothAdapter.STATE_OFF);
+ } catch (RemoteException | TimeoutException e) {
+ throw new RuntimeException(e);
}
- } catch (RemoteException | TimeoutException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
- } finally {
- mServiceLock.readLock().unlock();
}
- return state;
- }};
+ };
- private final IpcDataCache<Void, Integer> mBluetoothGetStateCache =
- new BluetoothCache<Void, Integer>(GET_STATE_API, mBluetoothGetStateQuery);
+ private static final String GET_STATE_API = "BluetoothAdapter_getState";
+
+ private final IpcDataCache<IBluetooth, Integer> mBluetoothGetStateCache =
+ new BluetoothCache<>(GET_STATE_API, mBluetoothGetStateQuery);
/** @hide */
@RequiresNoPermission
@@ -1316,7 +1307,21 @@ public final class BluetoothAdapter {
* OFF.
*/
private @InternalAdapterState int getStateInternal() {
- return mBluetoothGetStateCache.query(null);
+ mServiceLock.readLock().lock();
+ try {
+ if (mService != null) {
+ return mBluetoothGetStateCache.query(mService);
+ }
+ } catch (RuntimeException e) {
+ if (!(e.getCause() instanceof TimeoutException)
+ && !(e.getCause() instanceof RemoteException)) {
+ throw e;
+ }
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ return STATE_OFF;
}
/**
@@ -2417,31 +2422,25 @@ public final class BluetoothAdapter {
}
}
- private final IpcDataCache.QueryHandler<Void, Boolean> mBluetoothFilteringQuery =
+ private final IpcDataCache.QueryHandler<IBluetooth, Boolean> mBluetoothFilteringQuery =
new IpcDataCache.QueryHandler<>() {
@RequiresLegacyBluetoothPermission
@RequiresNoPermission
@Override
- public Boolean apply(Void query) {
- mServiceLock.readLock().lock();
+ public Boolean apply(IBluetooth serviceQuery) {
try {
- if (mService != null) {
- final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
- mService.isOffloadedFilteringSupported(recv);
- return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(false);
- }
+ final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
+ serviceQuery.isOffloadedFilteringSupported(recv);
+ return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(false);
} catch (RemoteException | TimeoutException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
- } finally {
- mServiceLock.readLock().unlock();
+ throw new RuntimeException(e);
}
- return false;
}};
- private static final String FILTERING_API = "isOffloadedFilteringSupported";
+ private static final String FILTERING_API = "BluetoothAdapter_isOffloadedFilteringSupported";
- private final IpcDataCache<Void, Boolean> mBluetoothFilteringCache =
- new BluetoothCache<Void, Boolean>(FILTERING_API, mBluetoothFilteringQuery);
+ private final IpcDataCache<IBluetooth, Boolean> mBluetoothFilteringCache =
+ new BluetoothCache<>(FILTERING_API, mBluetoothFilteringQuery);
/** @hide */
@RequiresNoPermission
@@ -2465,7 +2464,19 @@ public final class BluetoothAdapter {
if (!getLeAccess()) {
return false;
}
- return mBluetoothFilteringCache.query(null);
+ mServiceLock.readLock().lock();
+ try {
+ if (mService != null) return mBluetoothFilteringCache.query(mService);
+ } catch (RuntimeException e) {
+ if (!(e.getCause() instanceof TimeoutException)
+ && !(e.getCause() instanceof RemoteException)) {
+ throw e;
+ }
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ return false;
}
/**
@@ -2967,35 +2978,28 @@ public final class BluetoothAdapter {
return supportedProfiles;
}
- private final IpcDataCache.QueryHandler<Void, Integer> mBluetoothGetAdapterQuery =
- new IpcDataCache.QueryHandler<>() {
- @RequiresLegacyBluetoothPermission
- @RequiresNoPermission
- @Override
- public Integer apply(Void query) {
- mServiceLock.readLock().lock();
- try {
- if (mService != null) {
- final SynchronousResultReceiver<Integer> recv =
- new SynchronousResultReceiver();
- mService.getAdapterConnectionState(recv);
- return recv.awaitResultNoInterrupt(getSyncTimeout())
+ private final IpcDataCache.QueryHandler<IBluetooth, Integer>
+ mBluetoothGetAdapterConnectionStateQuery = new IpcDataCache.QueryHandler<>() {
+ @RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
+ @Override
+ public Integer apply(IBluetooth serviceQuery) {
+ try {
+ final SynchronousResultReceiver<Integer> recv =
+ new SynchronousResultReceiver();
+ serviceQuery.getAdapterConnectionState(recv);
+ return recv.awaitResultNoInterrupt(getSyncTimeout())
.getValue(STATE_DISCONNECTED);
+ } catch (RemoteException | TimeoutException e) {
+ throw new RuntimeException(e);
+ }
}
- } catch (TimeoutException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
- } catch (RemoteException e) {
- Log.e(TAG, "failed to getConnectionState, error: ", e);
- } finally {
- mServiceLock.readLock().unlock();
- }
- return BluetoothAdapter.STATE_DISCONNECTED;
- }};
+ };
+
+ private static final String GET_CONNECTION_API = "BluetoothAdapter_getConnectionState";
- private static final String GET_CONNECTION_API = "getAdapterConnectionState";
- private final IpcDataCache<Void, Integer>
- mBluetoothGetAdapterConnectionStateCache =
- new BluetoothCache<Void, Integer>(GET_CONNECTION_API, mBluetoothGetAdapterQuery);
+ private final IpcDataCache<IBluetooth, Integer> mBluetoothGetAdapterConnectionStateCache =
+ new BluetoothCache<>(GET_CONNECTION_API, mBluetoothGetAdapterConnectionStateQuery);
/** @hide */
@RequiresNoPermission
@@ -3025,36 +3029,42 @@ public final class BluetoothAdapter {
if (getState() != STATE_ON) {
return BluetoothAdapter.STATE_DISCONNECTED;
}
- return mBluetoothGetAdapterConnectionStateCache.query(null);
+ mServiceLock.readLock().lock();
+ try {
+ if (mService != null) return mBluetoothGetAdapterConnectionStateCache.query(mService);
+ } catch (RuntimeException e) {
+ if (!(e.getCause() instanceof TimeoutException)
+ && !(e.getCause() instanceof RemoteException)) {
+ throw e;
+ }
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ return STATE_DISCONNECTED;
}
- private final IpcDataCache.QueryHandler<Integer, Integer> mBluetoothProfileQuery =
- new IpcDataCache.QueryHandler<>() {
- @RequiresNoPermission
- @Override
- public Integer apply(Integer query) {
- try {
- mServiceLock.readLock().lock();
- if (mService != null) {
- final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
- mService.getProfileConnectionState(query, recv);
- return recv.awaitResultNoInterrupt(getSyncTimeout())
- .getValue(BluetoothProfile.STATE_DISCONNECTED);
+ private final IpcDataCache.QueryHandler<Pair<IBluetooth, Integer>, Integer>
+ mBluetoothProfileQuery = new IpcDataCache.QueryHandler<>() {
+ @RequiresNoPermission
+ @Override
+ public Integer apply(Pair<IBluetooth, Integer> pairQuery) {
+ final int defaultValue = STATE_DISCONNECTED;
+ try {
+ final SynchronousResultReceiver<Integer> recv =
+ new SynchronousResultReceiver();
+ pairQuery.first.getProfileConnectionState(pairQuery.second, recv);
+ return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
+ } catch (RemoteException | TimeoutException e) {
+ throw new RuntimeException(e);
+ }
}
- } catch (TimeoutException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
- } catch (RemoteException e) {
- Log.e(TAG, "failed to getProfileConnectionState, error: ", e);
- } finally {
- mServiceLock.readLock().unlock();
- }
- return BluetoothProfile.STATE_DISCONNECTED;
- }};
+ };
+
+ private static final String PROFILE_API = "BluetoothAdapter_getProfileConnectionState";
- private static final String PROFILE_API = "getProfileConnectionState";
- private final IpcDataCache<Integer, Integer>
- mGetProfileConnectionStateCache =
- new BluetoothCache<Integer, Integer>(PROFILE_API, mBluetoothProfileQuery);
+ private final IpcDataCache<Pair<IBluetooth, Integer>, Integer> mGetProfileConnectionStateCache =
+ new BluetoothCache<>(PROFILE_API, mBluetoothProfileQuery);
/**
* @hide
@@ -3085,9 +3095,23 @@ public final class BluetoothAdapter {
@SuppressLint("AndroidFrameworkRequiresPermission")
public @ConnectionState int getProfileConnectionState(int profile) {
if (getState() != STATE_ON) {
- return BluetoothProfile.STATE_DISCONNECTED;
+ return STATE_DISCONNECTED;
+ }
+ mServiceLock.readLock().lock();
+ try {
+ if (mService != null) {
+ return mGetProfileConnectionStateCache.query(new Pair<>(mService, profile));
+ }
+ } catch (RuntimeException e) {
+ if (!(e.getCause() instanceof TimeoutException)
+ && !(e.getCause() instanceof RemoteException)) {
+ throw e;
+ }
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } finally {
+ mServiceLock.readLock().unlock();
}
- return mGetProfileConnectionStateCache.query(profile);
+ return STATE_DISCONNECTED;
}
/**