diff options
5 files changed, 3 insertions, 1218 deletions
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index c6c64b034b60..9b37457c9907 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -3086,9 +3086,6 @@ public final class BluetoothAdapter {              BluetoothCsipSetCoordinator csipSetCoordinator =                      new BluetoothCsipSetCoordinator(context, listener, this);              return true; -        } else if (profile == BluetoothProfile.LE_CALL_CONTROL) { -            BluetoothLeCallControl tbs = new BluetoothLeCallControl(context, listener); -            return true;          } else {              return false;          } @@ -3191,10 +3188,6 @@ public final class BluetoothAdapter {                          (BluetoothCsipSetCoordinator) proxy;                  csipSetCoordinator.close();                  break; -            case BluetoothProfile.LE_CALL_CONTROL: -                BluetoothLeCallControl tbs = (BluetoothLeCallControl) proxy; -                tbs.close(); -                break;          }      } diff --git a/core/java/android/bluetooth/BluetoothLeCall.java b/core/java/android/bluetooth/BluetoothLeCall.java deleted file mode 100644 index fb7789db25c7..000000000000 --- a/core/java/android/bluetooth/BluetoothLeCall.java +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright 2021 HIMSA II K/S - www.himsa.com. - * Represented by EHIMA - www.ehima.com - * - * 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.annotation.IntDef; -import android.annotation.NonNull; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.ParcelUuid; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.Objects; -import java.util.UUID; - -/** - * Representation of Call - * - * @hide - */ -public final class BluetoothLeCall implements Parcelable { - -    /** @hide */ -    @IntDef(prefix = "STATE_", value = { -            STATE_INCOMING, -            STATE_DIALING, -            STATE_ALERTING, -            STATE_ACTIVE, -            STATE_LOCALLY_HELD, -            STATE_REMOTELY_HELD, -            STATE_LOCALLY_AND_REMOTELY_HELD -    }) -    @Retention(RetentionPolicy.SOURCE) -    public @interface State { -    } - -    /** -     * A remote party is calling (incoming call). -     * -     * @hide -     */ -    public static final int STATE_INCOMING = 0x00; - -    /** -     * The process to call the remote party has started but the remote party is not -     * being alerted (outgoing call). -     * -     * @hide -     */ -    public static final int STATE_DIALING = 0x01; - -    /** -     * A remote party is being alerted (outgoing call). -     * -     * @hide -     */ -    public static final int STATE_ALERTING = 0x02; - -    /** -     * The call is in an active conversation. -     * -     * @hide -     */ -    public static final int STATE_ACTIVE = 0x03; - -    /** -     * The call is connected but held locally. “Locally Held” implies that either -     * the server or the client can affect the state. -     * -     * @hide -     */ -    public static final int STATE_LOCALLY_HELD = 0x04; - -    /** -     * The call is connected but held remotely. “Remotely Held” means that the state -     * is controlled by the remote party of a call. -     * -     * @hide -     */ -    public static final int STATE_REMOTELY_HELD = 0x05; - -    /** -     * The call is connected but held both locally and remotely. -     * -     * @hide -     */ -    public static final int STATE_LOCALLY_AND_REMOTELY_HELD = 0x06; - -    /** -     * Whether the call direction is outgoing. -     * -     * @hide -     */ -    public static final int FLAG_OUTGOING_CALL = 0x00000001; - -    /** -     * Whether the call URI and Friendly Name are withheld by server. -     * -     * @hide -     */ -    public static final int FLAG_WITHHELD_BY_SERVER = 0x00000002; - -    /** -     * Whether the call URI and Friendly Name are withheld by network. -     * -     * @hide -     */ -    public static final int FLAG_WITHHELD_BY_NETWORK = 0x00000004; - -    /** Unique UUID that identifies this call */ -    private UUID mUuid; - -    /** Remote Caller URI */ -    private String mUri; - -    /** Caller friendly name */ -    private String mFriendlyName; - -    /** Call state */ -    private @State int mState; - -    /** Call flags */ -    private int mCallFlags; - -    /** @hide */ -    public BluetoothLeCall(@NonNull BluetoothLeCall that) { -        mUuid = new UUID(that.getUuid().getMostSignificantBits(), -                that.getUuid().getLeastSignificantBits()); -        mUri = that.mUri; -        mFriendlyName = that.mFriendlyName; -        mState = that.mState; -        mCallFlags = that.mCallFlags; -    } - -    /** @hide */ -    public BluetoothLeCall(@NonNull UUID uuid, @NonNull String uri, @NonNull String friendlyName, -            @State int state, int callFlags) { -        mUuid = uuid; -        mUri = uri; -        mFriendlyName = friendlyName; -        mState = state; -        mCallFlags = callFlags; -    } - -    @Override -    public boolean equals(Object o) { -        if (this == o) -            return true; -        if (o == null || getClass() != o.getClass()) -            return false; -        BluetoothLeCall that = (BluetoothLeCall) o; -        return mUuid.equals(that.mUuid) && mUri.equals(that.mUri) -                && mFriendlyName.equals(that.mFriendlyName) && mState == that.mState -                && mCallFlags == that.mCallFlags; -    } - -    @Override -    public int hashCode() { -        return Objects.hash(mUuid, mUri, mFriendlyName, mState, mCallFlags); -    } - -    /** -     * Returns a string representation of this BluetoothLeCall. -     * -     * <p> -     * Currently this is the UUID. -     * -     * @return string representation of this BluetoothLeCall -     */ -    @Override -    public String toString() { -        return mUuid.toString(); -    } - -    @Override -    public int describeContents() { -        return 0; -    } - -    @Override -    public void writeToParcel(@NonNull Parcel out, int flags) { -        out.writeParcelable(new ParcelUuid(mUuid), 0); -        out.writeString(mUri); -        out.writeString(mFriendlyName); -        out.writeInt(mState); -        out.writeInt(mCallFlags); -    } - -    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothLeCall> CREATOR = -    						    new Parcelable.Creator<BluetoothLeCall>() { -        public BluetoothLeCall createFromParcel(Parcel in) { -            return new BluetoothLeCall(in); -        } - -        public BluetoothLeCall[] newArray(int size) { -            return new BluetoothLeCall[size]; -        } -    }; - -    private BluetoothLeCall(Parcel in) { -        mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid(); -        mUri = in.readString(); -        mFriendlyName = in.readString(); -        mState = in.readInt(); -        mCallFlags = in.readInt(); -    } - -    /** -     * Returns an UUID of this BluetoothLeCall. -     * -     * <p> -     * An UUID is unique identifier of a BluetoothLeCall. -     * -     * @return UUID of this BluetoothLeCall -     * @hide -     */ -    public @NonNull UUID getUuid() { -        return mUuid; -    } - -    /** -     * Returns a URI of the remote party of this BluetoothLeCall. -     * -     * @return string representation of this BluetoothLeCall -     * @hide -     */ -    public @NonNull String getUri() { -        return mUri; -    } - -    /** -     * Returns a friendly name of the call. -     * -     * @return friendly name representation of this BluetoothLeCall -     * @hide -     */ -    public @NonNull String getFriendlyName() { -        return mFriendlyName; -    } - -    /** -     * Returns the call state. -     * -     * @return the state of this BluetoothLeCall -     * @hide -     */ -    public @State int getState() { -        return mState; -    } - -    /** -     * Returns the call flags. -     * -     * @return call flags -     * @hide -     */ -    public int getCallFlags() { -        return mCallFlags; -    } - -    /** -     * Whether the call direction is incoming. -     * -     * @return true if incoming call, false otherwise -     * @hide -     */ -    public boolean isIncomingCall() { -        return (mCallFlags & FLAG_OUTGOING_CALL) == 0; -    } -} diff --git a/core/java/android/bluetooth/BluetoothLeCallControl.java b/core/java/android/bluetooth/BluetoothLeCallControl.java deleted file mode 100644 index 5283e0804252..000000000000 --- a/core/java/android/bluetooth/BluetoothLeCallControl.java +++ /dev/null @@ -1,911 +0,0 @@ -/* - * Copyright 2019 HIMSA II K/S - www.himsa.com. - * Represented by EHIMA - www.ehima.com - * - * 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.Manifest; -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.RequiresPermission; -import android.bluetooth.annotations.RequiresBluetoothConnectPermission; -import android.content.ComponentName; -import android.content.Context; -import android.os.Binder; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; -import android.os.Message; -import android.os.ParcelUuid; -import android.os.RemoteException; -import android.util.Log; -import android.annotation.SuppressLint; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Executor; - -/** - * This class provides the APIs to control the Call Control profile. - * - * <p> - * This class provides Bluetooth Telephone Bearer Service functionality, - * allowing applications to expose a GATT Service based interface to control the - * state of the calls by remote devices such as LE audio devices. - * - * <p> - * BluetoothLeCallControl is a proxy object for controlling the Bluetooth Telephone Bearer - * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get the - * BluetoothLeCallControl proxy object. - * - * @hide - */ -public final class BluetoothLeCallControl implements BluetoothProfile { -    private static final String TAG = "BluetoothLeCallControl"; -    private static final boolean DBG = true; -    private static final boolean VDBG = false; - -    /** @hide */ -    @IntDef(prefix = "RESULT_", value = { -            RESULT_SUCCESS, -            RESULT_ERROR_UNKNOWN_CALL_ID, -            RESULT_ERROR_INVALID_URI, -            RESULT_ERROR_APPLICATION -    }) -    @Retention(RetentionPolicy.SOURCE) -    public @interface Result { -    } - -    /** -     * Opcode write was successful. -     * -     * @hide -     */ -    public static final int RESULT_SUCCESS = 0; - -    /** -     * Unknown call Id has been used in the operation. -     * -     * @hide -     */ -    public static final int RESULT_ERROR_UNKNOWN_CALL_ID = 1; - -    /** -     * The URI provided in {@link Callback#onPlaceCallRequest} is invalid. -     * -     * @hide -     */ -    public static final int RESULT_ERROR_INVALID_URI = 2; - -    /** -     * Application internal error. -     * -     * @hide -     */ -    public static final int RESULT_ERROR_APPLICATION = 3; - -    /** @hide */ -    @IntDef(prefix = "TERMINATION_REASON_", value = { -            TERMINATION_REASON_INVALID_URI, -            TERMINATION_REASON_FAIL, -            TERMINATION_REASON_REMOTE_HANGUP, -            TERMINATION_REASON_SERVER_HANGUP, -            TERMINATION_REASON_LINE_BUSY, -            TERMINATION_REASON_NETWORK_CONGESTION, -            TERMINATION_REASON_CLIENT_HANGUP, -            TERMINATION_REASON_NO_SERVICE, -            TERMINATION_REASON_NO_ANSWER -    }) -    @Retention(RetentionPolicy.SOURCE) -    public @interface TerminationReason { -    } - -    /** -     * Remote Caller ID value used to place a call was formed improperly. -     * -     * @hide -     */ -    public static final int TERMINATION_REASON_INVALID_URI = 0x00; - -    /** -     * Call fail. -     * -     * @hide -     */ -    public static final int TERMINATION_REASON_FAIL = 0x01; - -    /** -     * Remote party ended call. -     * -     * @hide -     */ -    public static final int TERMINATION_REASON_REMOTE_HANGUP = 0x02; - -    /** -     * Call ended from the server. -     * -     * @hide -     */ -    public static final int TERMINATION_REASON_SERVER_HANGUP = 0x03; - -    /** -     * Line busy. -     * -     * @hide -     */ -    public static final int TERMINATION_REASON_LINE_BUSY = 0x04; - -    /** -     * Network congestion. -     * -     * @hide -     */ -    public static final int TERMINATION_REASON_NETWORK_CONGESTION = 0x05; - -    /** -     * Client terminated. -     * -     * @hide -     */ -    public static final int TERMINATION_REASON_CLIENT_HANGUP = 0x06; - -    /** -     * No service. -     * -     * @hide -     */ -    public static final int TERMINATION_REASON_NO_SERVICE = 0x07; - -    /** -     * No answer. -     * -     * @hide -     */ -    public static final int TERMINATION_REASON_NO_ANSWER = 0x08; - -    /* -     * Flag indicating support for hold/unhold call feature. -     * -     * @hide -     */ -    public static final int CAPABILITY_HOLD_CALL = 0x00000001; - -    /** -     * Flag indicating support for joining calls feature. -     * -     * @hide -     */ -    public static final int CAPABILITY_JOIN_CALLS = 0x00000002; - -    private static final int MESSAGE_TBS_SERVICE_CONNECTED = 102; -    private static final int MESSAGE_TBS_SERVICE_DISCONNECTED = 103; - -    private static final int REG_TIMEOUT = 10000; - -    /** -     * The template class is used to call callback functions on events from the TBS -     * server. Callback functions are wrapped in this class and registered to the -     * Android system during app registration. -     * -     * @hide -     */ -    public abstract static class Callback { - -        private static final String TAG = "BluetoothLeCallControl.Callback"; - -        /** -         * Called when a remote client requested to accept the call. -         * -         * <p> -         * An application must call {@link BluetoothLeCallControl#requestResult} to complete the -         * request. -         * -         * @param requestId The Id of the request -         * @param callId    The call Id requested to be accepted -         * @hide -         */ -        public abstract void onAcceptCall(int requestId, @NonNull UUID callId); - -        /** -         * A remote client has requested to terminate the call. -         * -         * <p> -         * An application must call {@link BluetoothLeCallControl#requestResult} to complete the -         * request. -         * -         * @param requestId The Id of the request -         * @param callId    The call Id requested to terminate -         * @hide -         */ -        public abstract void onTerminateCall(int requestId, @NonNull UUID callId); - -        /** -         * A remote client has requested to hold the call. -         * -         * <p> -         * An application must call {@link BluetoothLeCallControl#requestResult} to complete the -         * request. -         * -         * @param requestId The Id of the request -         * @param callId    The call Id requested to be put on hold -         * @hide -         */ -        public void onHoldCall(int requestId, @NonNull UUID callId) { -            Log.e(TAG, "onHoldCall: unimplemented, however CAPABILITY_HOLD_CALL is set!"); -        } - -        /** -         * A remote client has requested to unhold the call. -         * -         * <p> -         * An application must call {@link BluetoothLeCallControl#requestResult} to complete the -         * request. -         * -         * @param requestId The Id of the request -         * @param callId    The call Id requested to unhold -         * @hide -         */ -        public void onUnholdCall(int requestId, @NonNull UUID callId) { -            Log.e(TAG, "onUnholdCall: unimplemented, however CAPABILITY_HOLD_CALL is set!"); -        } - -        /** -         * A remote client has requested to place a call. -         * -         * <p> -         * An application must call {@link BluetoothLeCallControl#requestResult} to complete the -         * request. -         * -         * @param requestId The Id of the request -         * @param callId    The Id to be assigned for the new call -         * @param uri       The caller URI requested -         * @hide -         */ -        public abstract void onPlaceCall(int requestId, @NonNull UUID callId, @NonNull String uri); - -        /** -         * A remote client has requested to join the calls. -         * -         * <p> -         * An application must call {@link BluetoothLeCallControl#requestResult} to complete the -         * request. -         * -         * @param requestId The Id of the request -         * @param callIds   The call Id list requested to join -         * @hide -         */ -        public void onJoinCalls(int requestId, @NonNull List<UUID> callIds) { -            Log.e(TAG, "onJoinCalls: unimplemented, however CAPABILITY_JOIN_CALLS is set!"); -        } -    } - -    private class CallbackWrapper extends IBluetoothLeCallControlCallback.Stub { - -        private final Executor mExecutor; -        private final Callback mCallback; - -        CallbackWrapper(Executor executor, Callback callback) { -            mExecutor = executor; -            mCallback = callback; -        } - -        @Override -        public void onBearerRegistered(int ccid) { -            synchronized (mServerIfLock) { -                if (mCallback != null) { -                    mCcid = ccid; -                    mServerIfLock.notifyAll(); -                } else { -                    // registration timeout -                    Log.e(TAG, "onBearerRegistered: mCallback is null"); -                } -            } -        } - -        @Override -        public void onAcceptCall(int requestId, ParcelUuid uuid) { -            final long identityToken = Binder.clearCallingIdentity(); -            try { -                mExecutor.execute(() -> mCallback.onAcceptCall(requestId, uuid.getUuid())); -            } finally { -                Binder.restoreCallingIdentity(identityToken); -            } -        } - -        @Override -        public void onTerminateCall(int requestId, ParcelUuid uuid) { -            final long identityToken = Binder.clearCallingIdentity(); -            try { -                mExecutor.execute(() -> mCallback.onTerminateCall(requestId, uuid.getUuid())); -            } finally { -                Binder.restoreCallingIdentity(identityToken); -            } -        } - -        @Override -        public void onHoldCall(int requestId, ParcelUuid uuid) { -            final long identityToken = Binder.clearCallingIdentity(); -            try { -                mExecutor.execute(() -> mCallback.onHoldCall(requestId, uuid.getUuid())); -            } finally { -                Binder.restoreCallingIdentity(identityToken); -            } -        } - -        @Override -        public void onUnholdCall(int requestId, ParcelUuid uuid) { -            final long identityToken = Binder.clearCallingIdentity(); -            try { -                mExecutor.execute(() -> mCallback.onUnholdCall(requestId, uuid.getUuid())); -            } finally { -                Binder.restoreCallingIdentity(identityToken); -            } -        } - -        @Override -        public void onPlaceCall(int requestId, ParcelUuid uuid, String uri) { -            final long identityToken = Binder.clearCallingIdentity(); -            try { -                mExecutor.execute(() -> mCallback.onPlaceCall(requestId, uuid.getUuid(), uri)); -            } finally { -                Binder.restoreCallingIdentity(identityToken); -            } -        } - -        @Override -        public void onJoinCalls(int requestId, List<ParcelUuid> parcelUuids) { -            List<UUID> uuids = new ArrayList<>(); -            for (ParcelUuid parcelUuid : parcelUuids) { -                uuids.add(parcelUuid.getUuid()); -            } - -            final long identityToken = Binder.clearCallingIdentity(); -            try { -                mExecutor.execute(() -> mCallback.onJoinCalls(requestId, uuids)); -            } finally { -                Binder.restoreCallingIdentity(identityToken); -            } -        } -    }; - -    private Context mContext; -    private ServiceListener mServiceListener; -    private volatile IBluetoothLeCallControl mService; -    private BluetoothAdapter mAdapter; -    private int mCcid = 0; -    private String mToken; -    private Callback mCallback = null; -    private Object mServerIfLock = new Object(); - -    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback = -        new IBluetoothStateChangeCallback.Stub() { -        public void onBluetoothStateChange(boolean up) { -            if (DBG) -                Log.d(TAG, "onBluetoothStateChange: up=" + up); -            if (!up) { -                doUnbind(); -            } else { -                doBind(); -            } -        } -    }; - -    /** -     * Create a BluetoothLeCallControl proxy object for interacting with the local Bluetooth -     * telephone bearer service. -     */ -    /* package */ BluetoothLeCallControl(Context context, ServiceListener listener) { -        mContext = context; -        mAdapter = BluetoothAdapter.getDefaultAdapter(); -        mServiceListener = listener; - -        IBluetoothManager mgr = mAdapter.getBluetoothManager(); -        if (mgr != null) { -            try { -                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); -            } catch (RemoteException e) { -                Log.e(TAG, "", e); -            } -        } - -        doBind(); -    } - -    private boolean doBind() { -        synchronized (mConnection) { -            if (mService == null) { -                if (VDBG) -                    Log.d(TAG, "Binding service..."); -                try { -                    return mAdapter.getBluetoothManager(). -                            bindBluetoothProfileService(BluetoothProfile.LE_CALL_CONTROL, -                            mConnection); -                } catch (RemoteException e) { -                    Log.e(TAG, "Unable to bind TelephoneBearerService", e); -                } -            } -        } -        return false; -    } - -    private void doUnbind() { -        synchronized (mConnection) { -            if (mService != null) { -                if (VDBG) -                    Log.d(TAG, "Unbinding service..."); -                try { -                    mAdapter.getBluetoothManager(). -                        unbindBluetoothProfileService(BluetoothProfile.LE_CALL_CONTROL, -                        mConnection); -                } catch (RemoteException e) { -                    Log.e(TAG, "Unable to unbind TelephoneBearerService", e); -                } finally { -                    mService = null; -                } -            } -        } -    } - -    /* package */ void close() { -        if (VDBG) -            log("close()"); -        unregisterBearer(); - -        IBluetoothManager mgr = mAdapter.getBluetoothManager(); -        if (mgr != null) { -            try { -                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback); -            } catch (RemoteException re) { -                Log.e(TAG, "", re); -            } -        } -        mServiceListener = null; -        doUnbind(); -    } - -    private IBluetoothLeCallControl getService() { -        return mService; -    } - -    /** -     * Not supported -     * -     * @throws UnsupportedOperationException -     */ -    @Override -    public int getConnectionState(@Nullable BluetoothDevice device) { -        throw new UnsupportedOperationException("not supported"); -    } - -    /** -     * Not supported -     * -     * @throws UnsupportedOperationException -     */ -    @Override -    public @NonNull List<BluetoothDevice> getConnectedDevices() { -        throw new UnsupportedOperationException("not supported"); -    } - -    /** -     * Not supported -     * -     * @throws UnsupportedOperationException -     */ -    @Override -    public @NonNull List<BluetoothDevice> getDevicesMatchingConnectionStates( -        @NonNull int[] states) { -        throw new UnsupportedOperationException("not supported"); -    } - -    /** -     * Register Telephone Bearer exposing the interface that allows remote devices -     * to track and control the call states. -     * -     * <p> -     * This is an asynchronous call. The callback is used to notify success or -     * failure if the function returns true. -     * -     * <p> -     * Requires {@link android.Manifest.permission#BLUETOOTH} permission. -     * -     * <!-- The UCI is a String identifier of the telephone bearer as defined at -     * https://www.bluetooth.com/specifications/assigned-numbers/uniform-caller-identifiers -     * (login required). --> -     * -     * <!-- The examples of common URI schemes can be found in -     * https://iana.org/assignments/uri-schemes/uri-schemes.xhtml --> -     * -     * <!-- The Technology is an integer value. The possible values are defined at -     * https://www.bluetooth.com/specifications/assigned-numbers (login required). -     * --> -     * -     * @param uci          Bearer Unique Client Identifier -     * @param uriSchemes   URI Schemes supported list -     * @param capabilities bearer capabilities -     * @param provider     Network provider name -     * @param technology   Network technology -     * @param executor     {@link Executor} object on which callback will be -     *                     executed. The Executor object is required. -     * @param callback     {@link Callback} object to which callback messages will -     *                     be sent. The Callback object is required. -     * @return true on success, false otherwise -     * @hide -     */ -    @SuppressLint("ExecutorRegistration") -    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) -    public boolean registerBearer(@Nullable String uci, -                    @NonNull List<String> uriSchemes, int capabilities, -                    @NonNull String provider, int technology, -                    @NonNull Executor executor, @NonNull Callback callback) { -        if (DBG) { -            Log.d(TAG, "registerBearer"); -        } -        if (callback == null) { -            throw new IllegalArgumentException("null parameter: " + callback); -        } -        if (mCcid != 0) { -            return false; -        } - -        mToken = uci; - -        final IBluetoothLeCallControl service = getService(); -        if (service != null) { -            synchronized (mServerIfLock) { -                if (mCallback != null) { -                    Log.e(TAG, "Bearer can be opened only once"); -                    return false; -                } - -                mCallback = callback; -                try { -                    CallbackWrapper callbackWrapper = new CallbackWrapper(executor, callback); -                    service.registerBearer(mToken, callbackWrapper, uci, uriSchemes, capabilities, -                                            provider, technology); -                } catch (RemoteException e) { -                    Log.e(TAG, "", e); -                    mCallback = null; -                    return false; -                } - -                try { -                    mServerIfLock.wait(REG_TIMEOUT); -                } catch (InterruptedException e) { -                    Log.e(TAG, "" + e); -                    mCallback = null; -                } - -                if (mCcid == 0) { -                    mCallback = null; -                    return false; -                } - -                return true; -            } -        } -        if (service == null) { -            Log.w(TAG, "Proxy not attached to service"); -        } - -        return false; -    } - -    /** -     * Unregister Telephone Bearer Service and destroy all the associated data. -     * -     * @hide -     */ -    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) -    public void unregisterBearer() { -        if (DBG) { -            Log.d(TAG, "unregisterBearer"); -        } -        if (mCcid == 0) { -            return; -        } - -        int ccid = mCcid; -        mCcid = 0; -        mCallback = null; - -        final IBluetoothLeCallControl service = getService(); -        if (service != null) { -            try { -                service.unregisterBearer(mToken); -            } catch (RemoteException e) { -                Log.e(TAG, "", e); -            } -        } -        if (service == null) { -            Log.w(TAG, "Proxy not attached to service"); -        } -    } - -    /** -     * Get the Content Control ID (CCID) value. -     * -     * @return ccid Content Control ID value -     * @hide -     */ -    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) -    public int getContentControlId() { -        return mCcid; -    } - -    /** -     * Notify about the newly added call. -     * -     * <p> -     * This shall be called as early as possible after the call has been added. -     * -     * <p> -     * Requires {@link android.Manifest.permission#BLUETOOTH} permission. -     * -     * @param call Newly added call -     * @hide -     */ -    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) -    public void onCallAdded(@NonNull BluetoothLeCall call) { -        if (DBG) { -            Log.d(TAG, "onCallAdded: call=" + call); -        } -        if (mCcid == 0) { -            return; -        } - -        final IBluetoothLeCallControl service = getService(); -        if (service != null) { -            try { -                service.callAdded(mCcid, call); -            } catch (RemoteException e) { -                Log.e(TAG, "", e); -            } -        } -        if (service == null) { -            Log.w(TAG, "Proxy not attached to service"); -        } -    } - -    /** -     * Notify about the removed call. -     * -     * <p> -     * This shall be called as early as possible after the call has been removed. -     * -     * <p> -     * Requires {@link android.Manifest.permission#BLUETOOTH} permission. -     * -     * @param callId The Id of a call that has been removed -     * @param reason Call termination reason -     * @hide -     */ -    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) -    public void onCallRemoved(@NonNull UUID callId, @TerminationReason int reason) { -        if (DBG) { -            Log.d(TAG, "callRemoved: callId=" + callId); -        } -        if (mCcid == 0) { -            return; -        } - -        final IBluetoothLeCallControl service = getService(); -        if (service != null) { -            try { -                service.callRemoved(mCcid, new ParcelUuid(callId), reason); -            } catch (RemoteException e) { -                Log.e(TAG, "", e); -            } -        } -        if (service == null) { -            Log.w(TAG, "Proxy not attached to service"); -        } -    } - -    /** -     * Notify the call state change -     * -     * <p> -     * This shall be called as early as possible after the state of the call has -     * changed. -     * -     * <p> -     * Requires {@link android.Manifest.permission#BLUETOOTH} permission. -     * -     * @param callId The call Id that state has been changed -     * @param state  Call state -     * @hide -     */ -    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) -    public void onCallStateChanged(@NonNull UUID callId, @BluetoothLeCall.State int state) { -        if (DBG) { -            Log.d(TAG, "callStateChanged: callId=" + callId + " state=" + state); -        } -        if (mCcid == 0) { -            return; -        } - -        final IBluetoothLeCallControl service = getService(); -        if (service != null) { -            try { -                service.callStateChanged(mCcid, new ParcelUuid(callId), state); -            } catch (RemoteException e) { -                Log.e(TAG, "", e); -            } -        } -        if (service == null) { -            Log.w(TAG, "Proxy not attached to service"); -        } -    } - -    /** -     * Provide the current calls list -     * -     * <p> -     * This function must be invoked after registration if application has any -     * calls. -     * -     * @param calls current calls list -     * @hide -     */ -    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) -     public void currentCallsList(@NonNull List<BluetoothLeCall> calls) { -        final IBluetoothLeCallControl service = getService(); -        if (service != null) { -            try { -                service.currentCallsList(mCcid, calls); -            } catch (RemoteException e) { -                Log.e(TAG, "", e); -            } -        } -    } - -    /** -     * Provide the network current status -     * -     * <p> -     * This function must be invoked on change of network state. -     * -     * <p> -     * Requires {@link android.Manifest.permission#BLUETOOTH} permission. -     * -     * <!-- The Technology is an integer value. The possible values are defined at -     * https://www.bluetooth.com/specifications/assigned-numbers (login required). -     * --> -     * -     * @param provider   Network provider name -     * @param technology Network technology -     * @hide -     */ -    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) -    public void networkStateChanged(@NonNull String provider, int technology) { -        if (DBG) { -            Log.d(TAG, "networkStateChanged: provider=" + provider + ", technology=" + technology); -        } -        if (mCcid == 0) { -            return; -        } - -        final IBluetoothLeCallControl service = getService(); -        if (service != null) { -            try { -                service.networkStateChanged(mCcid, provider, technology); -            } catch (RemoteException e) { -                Log.e(TAG, "", e); -            } -        } -        if (service == null) { -            Log.w(TAG, "Proxy not attached to service"); -        } -    } - -    /** -     * Send a response to a call control request to a remote device. -     * -     * <p> -     * This function must be invoked in when a request is received by one of these -     * callback methods: -     * -     * <ul> -     * <li>{@link Callback#onAcceptCall} -     * <li>{@link Callback#onTerminateCall} -     * <li>{@link Callback#onHoldCall} -     * <li>{@link Callback#onUnholdCall} -     * <li>{@link Callback#onPlaceCall} -     * <li>{@link Callback#onJoinCalls} -     * </ul> -     * -     * @param requestId The ID of the request that was received with the callback -     * @param result    The result of the request to be sent to the remote devices -     */ -    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) -    public void requestResult(int requestId, @Result int result) { -        if (DBG) { -            Log.d(TAG, "requestResult: requestId=" + requestId + " result=" + result); -        } -        if (mCcid == 0) { -            return; -        } - -        final IBluetoothLeCallControl service = getService(); -        if (service != null) { -            try { -                service.requestResult(mCcid, requestId, result); -            } catch (RemoteException e) { -                Log.e(TAG, "", e); -            } -        } -    } - -    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) -    private static boolean isValidDevice(@Nullable BluetoothDevice device) { -        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress()); -    } - -    private static void log(String msg) { -        Log.d(TAG, msg); -    } - -    private final IBluetoothProfileServiceConnection mConnection = -                                    new IBluetoothProfileServiceConnection.Stub() { -        @Override -        public void onServiceConnected(ComponentName className, IBinder service) { -            if (DBG) { -                Log.d(TAG, "Proxy object connected"); -            } -            mService = IBluetoothLeCallControl.Stub.asInterface(Binder.allowBlocking(service)); -            mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_TBS_SERVICE_CONNECTED)); -        } - -        @Override -        public void onServiceDisconnected(ComponentName className) { -            if (DBG) { -                Log.d(TAG, "Proxy object disconnected"); -            } -            doUnbind(); -            mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_TBS_SERVICE_DISCONNECTED)); -        } -    }; - -    private final Handler mHandler = new Handler(Looper.getMainLooper()) { -        @Override -        public void handleMessage(Message msg) { -            switch (msg.what) { -            case MESSAGE_TBS_SERVICE_CONNECTED: { -                if (mServiceListener != null) { -                    mServiceListener.onServiceConnected(BluetoothProfile.LE_CALL_CONTROL, -                        BluetoothLeCallControl.this); -                } -                break; -            } -            case MESSAGE_TBS_SERVICE_DISCONNECTED: { -                if (mServiceListener != null) { -                    mServiceListener.onServiceDisconnected(BluetoothProfile.LE_CALL_CONTROL); -                } -                break; -            } -            } -        } -    }; -} diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java index d0f74e985729..e047e5d81a9d 100644 --- a/core/java/android/bluetooth/BluetoothProfile.java +++ b/core/java/android/bluetooth/BluetoothProfile.java @@ -240,19 +240,12 @@ public interface BluetoothProfile {      int LE_AUDIO_BROADCAST = 26;      /** -     * @hide -     * Telephone Bearer Service from Call Control Profile -     * -     */ -    int LE_CALL_CONTROL = 27; - -    /**       * Max profile ID. This value should be updated whenever a new profile is added to match       * the largest value assigned to a profile.       *       * @hide       */ -    int MAX_PROFILE_ID = 27; +    int MAX_PROFILE_ID = 26;      /**       * Default priority for devices that we try to auto-connect to and diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index c8b4f1109b5e..450e9881bef2 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -46,7 +46,6 @@ import android.bluetooth.IBluetoothManager;  import android.bluetooth.IBluetoothManagerCallback;  import android.bluetooth.IBluetoothProfileServiceConnection;  import android.bluetooth.IBluetoothStateChangeCallback; -import android.bluetooth.IBluetoothLeCallControl;  import android.content.ActivityNotFoundException;  import android.content.AttributionSource;  import android.content.BroadcastReceiver; @@ -1329,15 +1328,11 @@ class BluetoothManagerService extends IBluetoothManager.Stub {                              + bluetoothProfile);                  } -                Intent intent; -                if (bluetoothProfile == BluetoothProfile.HEADSET) { -                    intent = new Intent(IBluetoothHeadset.class.getName()); -                } else if (bluetoothProfile== BluetoothProfile.LE_CALL_CONTROL) { -                    intent = new Intent(IBluetoothLeCallControl.class.getName()); -                } else { +                if (bluetoothProfile != BluetoothProfile.HEADSET) {                      return false;                  } +                Intent intent = new Intent(IBluetoothHeadset.class.getName());                  psc = new ProfileServiceConnections(intent);                  if (!psc.bindService()) {                      return false;  |