Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4016e3d9 authored by Etienne Ruffieux's avatar Etienne Ruffieux Committed by Gerrit Code Review
Browse files

Merge changes from topic "api-review-result-receiver"

* changes:
  [API Review] Added error method to interface Bluetooth stats
  [API Review] BluetoothActivityenergyInfo doc + rename
  [API Review] Replace ResultReceiver by Executor
parents 87b8ffb4 a49e4e27
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -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;
@@ -84,7 +85,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;
@@ -218,8 +218,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),
@@ -3606,11 +3604,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.onBluetoothActivityEnergyInfoAvailable(info);
            } catch (RemoteException e) {
                Log.e(TAG, "onBluetoothActivityEnergyInfo: RemoteException", e);
            }
        }

        @Override
+6 −1
Original line number Diff line number Diff line
@@ -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.OnBluetoothActivityEnergyInfoCallback);
    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,11 @@ package android.bluetooth {
    method public void onDeviceDisconnected(@NonNull android.bluetooth.BluetoothDevice, int);
  }

  public static interface BluetoothAdapter.OnBluetoothActivityEnergyInfoCallback {
    method public void onBluetoothActivityEnergyInfoAvailable(@NonNull android.bluetooth.BluetoothActivityEnergyInfo);
    method public default void onBluetoothActivityEnergyInfoError(int);
  }

  public static interface BluetoothAdapter.OnMetadataChangedListener {
    method public void onMetadataChanged(@NonNull android.bluetooth.BluetoothDevice, int, @Nullable byte[]);
  }
+95 −12
Original line number Diff line number Diff line
@@ -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;
@@ -819,6 +818,82 @@ public final class BluetoothAdapter {
        }
    };

    /** @hide */
    @IntDef(value = {
            BluetoothStatusCodes.ERROR_UNKNOWN,
            BluetoothStatusCodes.FEATURE_NOT_SUPPORTED,
            BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface BluetoothActivityEnergyInfoCallbackError {}

    /**
     * Interface for Bluetooth activity energy info callback. Should be implemented by applications
     * and set when calling {@link #requestControllerActivityEnergyInfo}.
     *
     * @hide
     */
    @SystemApi
    public interface OnBluetoothActivityEnergyInfoCallback {
        /**
         * Called when Bluetooth activity energy info is available.
         * Note: this callback is triggered at most once for each call to
         * {@link #requestControllerActivityEnergyInfo}.
         *
         * @param info the latest {@link BluetoothActivityEnergyInfo}
         */
        void onBluetoothActivityEnergyInfoAvailable(
                @NonNull BluetoothActivityEnergyInfo info);

        /**
         * Called when the latest {@link BluetoothActivityEnergyInfo} can't be retrieved.
         * The reason of the failure is indicated by the {@link BluetoothStatusCodes}
         * passed as an argument to this method.
         * Note: this callback is triggered at most once for each call to
         * {@link #requestControllerActivityEnergyInfo}.
         *
         * @param error code indicating the reason for the failure
         */
        default void onBluetoothActivityEnergyInfoError(
                @BluetoothActivityEnergyInfoCallbackError int error) {}
    }

    private static class OnBluetoothActivityEnergyInfoProxy
            extends IBluetoothActivityEnergyInfoListener.Stub {
        private final Object mLock = new Object();
        @Nullable @GuardedBy("mLock") private Executor mExecutor;
        @Nullable @GuardedBy("mLock") private OnBluetoothActivityEnergyInfoCallback mCallback;

        OnBluetoothActivityEnergyInfoProxy(Executor executor,
                OnBluetoothActivityEnergyInfoCallback callback) {
            mExecutor = executor;
            mCallback = callback;
        }

        @Override
        public void onBluetoothActivityEnergyInfoAvailable(BluetoothActivityEnergyInfo info) {
            Executor executor;
            OnBluetoothActivityEnergyInfoCallback callback;
            synchronized (mLock) {
                if (mExecutor == null || mCallback == null) {
                    return;
                }
                executor = mExecutor;
                callback = mCallback;
                // null out to allow garbage collection, prevent triggering callback more than once
                mExecutor = null;
                mCallback = null;
            }
            Binder.clearCallingIdentity();
            if (info == null) {
                executor.execute(() -> callback.onBluetoothActivityEnergyInfoError(
                        BluetoothStatusCodes.FEATURE_NOT_SUPPORTED));
            } else {
                executor.execute(() -> callback.onBluetoothActivityEnergyInfoAvailable(info));
            }
        }
    }

    /**
     * Get a handle to the default local Bluetooth adapter.
     * <p>
@@ -2686,10 +2761,12 @@ public final class BluetoothAdapter {
     * has the activity and energy info. This can be used to ascertain what
     * the controller has been up to, since the last sample.
     *
     * A null value for the activity info object may be sent if the bluetooth service is
     * unreachable or the device does not support reporting such information.
     * The callback will be called only once, when the record is available.
     *
     * @param result The callback to which to send the activity info.
     * @param executor the executor that the callback will be invoked on
     * @param callback the callback that will be called with either the
     *                 {@link BluetoothActivityEnergyInfo} object, or the
     *                 error code if an error has occurred
     * @hide
     */
    @SystemApi
@@ -2698,22 +2775,28 @@ 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 OnBluetoothActivityEnergyInfoCallback callback) {
        requireNonNull(executor, "executor cannot be null");
        requireNonNull(callback, "callback cannot be null");
        try {
            mServiceLock.readLock().lock();
            if (mService != null) {
                mService.requestActivityInfo(result, mAttributionSource);
                result = null;
                mService.requestActivityInfo(
                        new OnBluetoothActivityEnergyInfoProxy(executor, callback),
                        mAttributionSource);
            } else {
                executor.execute(() -> callback.onBluetoothActivityEnergyInfoError(
                        BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND));
            }
        } catch (RemoteException e) {
            Log.e(TAG, "getControllerActivityEnergyInfoCallback: " + e);
            Binder.clearCallingIdentity();
            executor.execute(() -> callback.onBluetoothActivityEnergyInfoError(
                    BluetoothStatusCodes.ERROR_UNKNOWN));
        } finally {
            mServiceLock.readLock().unlock();
            if (result != null) {
                // Only send an immediate result if we failed.
                result.send(0, null);
            }
        }
    }

+1 −0
Original line number Diff line number Diff line
@@ -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",
+2 −1
Original line number Diff line number Diff line
@@ -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);
Loading