diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 70d0cca..97c97f2 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -3083,6 +3083,9 @@
             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;
         }
@@ -3181,6 +3184,10 @@
                         (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
new file mode 100644
index 0000000..fb7789d
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothLeCall.java
@@ -0,0 +1,285 @@
+/*
+ * 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
new file mode 100644
index 0000000..fb080c9
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothLeCallControl.java
@@ -0,0 +1,899 @@
+/*
+ * 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) {
+            if (mCallback != null) {
+                mCcid = ccid;
+            } 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 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) {
+            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;
+            }
+
+            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 e047e5d..d0f74e9 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -240,12 +240,19 @@
     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 = 26;
+    int MAX_PROFILE_ID = 27;
 
     /**
      * 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 7e270d1..4290e77 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -46,6 +46,7 @@
 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;
@@ -1324,11 +1325,15 @@
                             + bluetoothProfile);
                 }
 
-                if (bluetoothProfile != BluetoothProfile.HEADSET) {
+                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 {
                     return false;
                 }
 
-                Intent intent = new Intent(IBluetoothHeadset.class.getName());
                 psc = new ProfileServiceConnections(intent);
                 if (!psc.bindService()) {
                     return false;
