diff options
6 files changed, 108 insertions, 19 deletions
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java index 3ba407327d..54851897c4 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java @@ -54,6 +54,7 @@ import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.BluetoothUuid; import android.bluetooth.BufferConstraints; import android.bluetooth.IBluetooth; +import android.bluetooth.IBluetoothActivityEnergyInfoListener; import android.bluetooth.IBluetoothCallback; import android.bluetooth.IBluetoothConnectionCallback; import android.bluetooth.IBluetoothMetadataListener; @@ -83,7 +84,6 @@ import android.os.ParcelUuid; import android.os.PowerManager; import android.os.RemoteCallbackList; import android.os.RemoteException; -import android.os.ResultReceiver; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; @@ -217,8 +217,6 @@ public class AdapterService extends Service { public static final String ACTIVITY_ATTRIBUTION_NO_ACTIVE_DEVICE_ADDRESS = "no_active_device_address"; - public static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity"; - // Report ID definition public enum BqrQualityReportId { QUALITY_REPORT_ID_MONITOR_MODE(0x01), @@ -3594,11 +3592,14 @@ public class AdapterService extends Service { } @Override - public void requestActivityInfo(ResultReceiver result, AttributionSource source) { - Bundle bundle = new Bundle(); - bundle.putParcelable(RESULT_RECEIVER_CONTROLLER_KEY, - reportActivityInfo(source)); - result.send(0, bundle); + public void requestActivityInfo(IBluetoothActivityEnergyInfoListener listener, + AttributionSource source) { + BluetoothActivityEnergyInfo info = reportActivityInfo(source); + try { + listener.onBluetoothActivityEnergyInfo(info); + } catch (RemoteException e) { + Log.e(TAG, "onBluetoothActivityEnergyInfo: RemoteException", e); + } } @Override diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt index 282b7eed19..d401b89c8a 100644 --- a/framework/api/system-current.txt +++ b/framework/api/system-current.txt @@ -73,7 +73,7 @@ package android.bluetooth { method public boolean registerServiceLifecycleCallback(@NonNull android.bluetooth.BluetoothAdapter.ServiceLifecycleCallback); method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean removeActiveDevice(int); method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean removeOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener); - method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void requestControllerActivityEnergyInfo(@NonNull android.os.ResultReceiver); + method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void requestControllerActivityEnergyInfo(@NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OnBluetoothActivityEnergyInfoListener); method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.bluetooth.BluetoothSocket retrieveConnectedRfcommSocket(@NonNull java.util.UUID); method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean setActiveDevice(@NonNull android.bluetooth.BluetoothDevice, int); method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int startRfcommServer(@NonNull String, @NonNull java.util.UUID, @NonNull android.app.PendingIntent); @@ -97,6 +97,10 @@ package android.bluetooth { method public void onDeviceDisconnected(@NonNull android.bluetooth.BluetoothDevice, int); } + public static interface BluetoothAdapter.OnBluetoothActivityEnergyInfoListener { + method public void onBluetoothActivityEnergyInfo(@Nullable android.bluetooth.BluetoothActivityEnergyInfo); + } + public static interface BluetoothAdapter.OnMetadataChangedListener { method public void onMetadataChanged(@NonNull android.bluetooth.BluetoothDevice, int, @Nullable byte[]); } diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java index aedd85d156..cccc7d43f5 100644 --- a/framework/java/android/bluetooth/BluetoothAdapter.java +++ b/framework/java/android/bluetooth/BluetoothAdapter.java @@ -57,7 +57,6 @@ import android.os.Build; import android.os.IBinder; import android.os.ParcelUuid; import android.os.RemoteException; -import android.os.ResultReceiver; import android.os.ServiceManager; import android.sysprop.BluetoothProperties; import android.util.Log; @@ -820,6 +819,55 @@ public final class BluetoothAdapter { }; /** + * Interface for Bluetooth activity energy info listener. Should be implemented by applications + * and set when calling {@link BluetoothAdapter#requestControllerActivityEnergyInfo}. + * + * @hide + */ + @SystemApi + public interface OnBluetoothActivityEnergyInfoListener { + /** + * Called when Bluetooth activity energy info is available. + * Note: this listener is triggered at most once for each call to + * {@link #requestControllerActivityEnergyInfo}. + * + * @param info the latest {@link BluetoothActivityEnergyInfo}, or null if unavailable. + */ + void onBluetoothActivityEnergyInfo(@Nullable BluetoothActivityEnergyInfo info); + } + + private static class OnBluetoothActivityEnergyInfoProxy + extends IBluetoothActivityEnergyInfoListener.Stub { + private final Object mLock = new Object(); + @Nullable @GuardedBy("mLock") private Executor mExecutor; + @Nullable @GuardedBy("mLock") private OnBluetoothActivityEnergyInfoListener mListener; + + OnBluetoothActivityEnergyInfoProxy(Executor executor, + OnBluetoothActivityEnergyInfoListener listener) { + mExecutor = executor; + mListener = listener; + } + + @Override + public void onBluetoothActivityEnergyInfo(BluetoothActivityEnergyInfo info) { + Executor executor; + OnBluetoothActivityEnergyInfoListener listener; + synchronized (mLock) { + if (mExecutor == null || mListener == null) { + return; + } + executor = mExecutor; + listener = mListener; + // null out to allow garbage collection, prevent triggering listener more than once + mExecutor = null; + mListener = null; + } + Binder.clearCallingIdentity(); + executor.execute(() -> listener.onBluetoothActivityEnergyInfo(info)); + } + } + + /** * Get a handle to the default local Bluetooth adapter. * <p> * Currently Android only supports one Bluetooth adapter, but the API could @@ -2698,22 +2746,22 @@ public final class BluetoothAdapter { android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, }) - public void requestControllerActivityEnergyInfo(@NonNull ResultReceiver result) { - requireNonNull(result, "ResultReceiver cannot be null"); + public void requestControllerActivityEnergyInfo( + @NonNull @CallbackExecutor Executor executor, + @NonNull OnBluetoothActivityEnergyInfoListener listener) { + requireNonNull(executor, "executor cannot be null"); + requireNonNull(listener, "listener cannot be null"); try { mServiceLock.readLock().lock(); if (mService != null) { - mService.requestActivityInfo(result, mAttributionSource); - result = null; + mService.requestActivityInfo( + new OnBluetoothActivityEnergyInfoProxy(executor, listener), + mAttributionSource); } } catch (RemoteException e) { Log.e(TAG, "getControllerActivityEnergyInfoCallback: " + e); } finally { mServiceLock.readLock().unlock(); - if (result != null) { - // Only send an immediate result if we failed. - result.send(0, null); - } } } diff --git a/system/binder/Android.bp b/system/binder/Android.bp index 4a6fe65bc7..70b97f39b4 100644 --- a/system/binder/Android.bp +++ b/system/binder/Android.bp @@ -16,6 +16,7 @@ filegroup { "android/bluetooth/IBluetooth.aidl", "android/bluetooth/IBluetoothA2dp.aidl", "android/bluetooth/IBluetoothA2dpSink.aidl", + "android/bluetooth/IBluetoothActivityEnergyInfoListener.aidl", "android/bluetooth/IBluetoothAvrcpController.aidl", "android/bluetooth/IBluetoothAvrcpTarget.aidl", "android/bluetooth/IBluetoothBattery.aidl", diff --git a/system/binder/android/bluetooth/IBluetooth.aidl b/system/binder/android/bluetooth/IBluetooth.aidl index 04a0a0a7eb..fe462ea06e 100644 --- a/system/binder/android/bluetooth/IBluetooth.aidl +++ b/system/binder/android/bluetooth/IBluetooth.aidl @@ -17,6 +17,7 @@ package android.bluetooth; import android.app.PendingIntent; +import android.bluetooth.IBluetoothActivityEnergyInfoListener; import android.bluetooth.IBluetoothCallback; import android.bluetooth.IBluetoothConnectionCallback; import android.bluetooth.IBluetoothMetadataListener; @@ -231,7 +232,7 @@ interface IBluetooth * The result code is ignored. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") - oneway void requestActivityInfo(in ResultReceiver result, in AttributionSource attributionSource); + oneway void requestActivityInfo(in IBluetoothActivityEnergyInfoListener listener, in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") oneway void onLeServiceUp(in AttributionSource attributionSource, in SynchronousResultReceiver receiver); diff --git a/system/binder/android/bluetooth/IBluetoothActivityEnergyInfoListener.aidl b/system/binder/android/bluetooth/IBluetoothActivityEnergyInfoListener.aidl new file mode 100644 index 0000000000..24ae14adb9 --- /dev/null +++ b/system/binder/android/bluetooth/IBluetoothActivityEnergyInfoListener.aidl @@ -0,0 +1,34 @@ +/* + * 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 android.bluetooth; + +import android.bluetooth.BluetoothActivityEnergyInfo; + +/** + * Interface for Bluetooth activity energy info listener. + * + * {@hide} + */ +oneway interface IBluetoothActivityEnergyInfoListener +{ + /** + * AdapterService to BluetoothAdapter callback providing current Bluetooth + * activity energy info. + * @param info the Bluetooth activity energy info + */ + void onBluetoothActivityEnergyInfo(in BluetoothActivityEnergyInfo info); +}
\ No newline at end of file |