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

Commit 0e86ab19 authored by Android Build Merger (Role)'s avatar Android Build Merger (Role) Committed by Android (Google) Code Review
Browse files

Merge changes from topic "am-5116653c666040fb956f10b5cf4bfed7"

* changes:
  Merge changes from topic "bt-metadata-api-v2-qt-dev" into qt-dev am: 10093916 am: 98678381
  Refine Bluetooth Metadata API am: 4741a8bd am: e5e6ef1e
parents d0d60d06 29999d8a
Loading
Loading
Loading
Loading
+16 −17
Original line number Diff line number Diff line
@@ -1242,30 +1242,29 @@ package android.app.usage {
package android.bluetooth {
  public final class BluetoothAdapter {
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean addOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
    method public boolean disableBLE();
    method public boolean enableBLE();
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean enableNoAutoConnect();
    method public boolean isBleScanAlwaysAvailable();
    method public boolean isLeEnabled();
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean registerMetadataListener(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothAdapter.MetadataListener, android.os.Handler);
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean unregisterMetadataListener(android.bluetooth.BluetoothDevice);
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean removeOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
    field public static final String ACTION_BLE_STATE_CHANGED = "android.bluetooth.adapter.action.BLE_STATE_CHANGED";
    field public static final String ACTION_REQUEST_BLE_SCAN_ALWAYS_AVAILABLE = "android.bluetooth.adapter.action.REQUEST_BLE_SCAN_ALWAYS_AVAILABLE";
  }
  public abstract static class BluetoothAdapter.MetadataListener {
    ctor public BluetoothAdapter.MetadataListener();
    method public void onMetadataChanged(android.bluetooth.BluetoothDevice, int, String);
  public static interface BluetoothAdapter.OnMetadataChangedListener {
    method public void onMetadataChanged(@NonNull android.bluetooth.BluetoothDevice, int, @Nullable byte[]);
  }
  public final class BluetoothDevice implements android.os.Parcelable {
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean cancelBondProcess();
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public String getMetadata(int);
    method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public byte[] getMetadata(int);
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isConnected();
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isEncrypted();
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isInSilenceMode();
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean removeBond();
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setMetadata(int, String);
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setMetadata(int, @NonNull byte[]);
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPhonebookAccessPermission(int);
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setSilenceMode(boolean);
    field public static final int ACCESS_ALLOWED = 1; // 0x1
@@ -1275,21 +1274,21 @@ package android.bluetooth {
    field public static final int METADATA_COMPANION_APP = 4; // 0x4
    field public static final int METADATA_ENHANCED_SETTINGS_UI_URI = 16; // 0x10
    field public static final int METADATA_HARDWARE_VERSION = 3; // 0x3
    field public static final int METADATA_IS_UNTHETHERED_HEADSET = 6; // 0x6
    field public static final int METADATA_IS_UNTETHERED_HEADSET = 6; // 0x6
    field public static final int METADATA_MAIN_ICON = 5; // 0x5
    field public static final int METADATA_MANUFACTURER_NAME = 0; // 0x0
    field public static final int METADATA_MAX_LENGTH = 2048; // 0x800
    field public static final int METADATA_MODEL_NAME = 1; // 0x1
    field public static final int METADATA_SOFTWARE_VERSION = 2; // 0x2
    field public static final int METADATA_UNTHETHERED_CASE_BATTERY = 12; // 0xc
    field public static final int METADATA_UNTHETHERED_CASE_CHARGING = 15; // 0xf
    field public static final int METADATA_UNTHETHERED_CASE_ICON = 9; // 0x9
    field public static final int METADATA_UNTHETHERED_LEFT_BATTERY = 10; // 0xa
    field public static final int METADATA_UNTHETHERED_LEFT_CHARGING = 13; // 0xd
    field public static final int METADATA_UNTHETHERED_LEFT_ICON = 7; // 0x7
    field public static final int METADATA_UNTHETHERED_RIGHT_BATTERY = 11; // 0xb
    field public static final int METADATA_UNTHETHERED_RIGHT_CHARGING = 14; // 0xe
    field public static final int METADATA_UNTHETHERED_RIGHT_ICON = 8; // 0x8
    field public static final int METADATA_UNTETHERED_CASE_BATTERY = 12; // 0xc
    field public static final int METADATA_UNTETHERED_CASE_CHARGING = 15; // 0xf
    field public static final int METADATA_UNTETHERED_CASE_ICON = 9; // 0x9
    field public static final int METADATA_UNTETHERED_LEFT_BATTERY = 10; // 0xa
    field public static final int METADATA_UNTETHERED_LEFT_CHARGING = 13; // 0xd
    field public static final int METADATA_UNTETHERED_LEFT_ICON = 7; // 0x7
    field public static final int METADATA_UNTETHERED_RIGHT_BATTERY = 11; // 0xb
    field public static final int METADATA_UNTETHERED_RIGHT_CHARGING = 14; // 0xe
    field public static final int METADATA_UNTETHERED_RIGHT_ICON = 8; // 0x8
  }
  public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile {
+65 −51
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ package android.bluetooth;
import android.Manifest;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
@@ -37,7 +38,6 @@ import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.RemoteException;
@@ -61,6 +61,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.ReentrantReadWriteLock;

@@ -650,7 +651,7 @@ public final class BluetoothAdapter {

    private final Object mLock = new Object();
    private final Map<LeScanCallback, ScanCallback> mLeScanClients;
    private static final Map<BluetoothDevice, List<Pair<MetadataListener, Handler>>>
    private static final Map<BluetoothDevice, List<Pair<OnMetadataChangedListener, Executor>>>
                sMetadataListeners = new HashMap<>();

    /**
@@ -660,14 +661,15 @@ public final class BluetoothAdapter {
    private static final IBluetoothMetadataListener sBluetoothMetadataListener =
            new IBluetoothMetadataListener.Stub() {
        @Override
        public void onMetadataChanged(BluetoothDevice device, int key, String value) {
        public void onMetadataChanged(BluetoothDevice device, int key, byte[] value) {
            synchronized (sMetadataListeners) {
                if (sMetadataListeners.containsKey(device)) {
                    List<Pair<MetadataListener, Handler>> list = sMetadataListeners.get(device);
                    for (Pair<MetadataListener, Handler> pair : list) {
                        MetadataListener listener = pair.first;
                        Handler handler = pair.second;
                        handler.post(() -> {
                    List<Pair<OnMetadataChangedListener, Executor>> list =
                            sMetadataListeners.get(device);
                    for (Pair<OnMetadataChangedListener, Executor> pair : list) {
                        OnMetadataChangedListener listener = pair.first;
                        Executor executor = pair.second;
                        executor.execute(() -> {
                            listener.onMetadataChanged(device, key, value);
                        });
                    }
@@ -3153,30 +3155,30 @@ public final class BluetoothAdapter {
    }

    /**
     * Register a {@link #MetadataListener} to receive update about metadata
     * Register a {@link #OnMetadataChangedListener} to receive update about metadata
     * changes for this {@link BluetoothDevice}.
     * Registration must be done when Bluetooth is ON and will last until
     * {@link #unregisterMetadataListener(BluetoothDevice)} is called, even when Bluetooth
     * {@link #removeOnMetadataChangedListener(BluetoothDevice)} is called, even when Bluetooth
     * restarted in the middle.
     * All input parameters should not be null or {@link NullPointerException} will be triggered.
     * The same {@link BluetoothDevice} and {@link #MetadataListener} pair can only be registered
     * once, double registration would cause {@link IllegalArgumentException}.
     * The same {@link BluetoothDevice} and {@link #OnMetadataChangedListener} pair can only be
     * registered once, double registration would cause {@link IllegalArgumentException}.
     *
     * @param device {@link BluetoothDevice} that will be registered
     * @param listener {@link #MetadataListener} that will receive asynchronous callbacks
     * @param handler the handler for listener callback
     * @param executor the executor for listener callback
     * @param listener {@link #OnMetadataChangedListener} that will receive asynchronous callbacks
     * @return true on success, false on error
     * @throws NullPointerException If one of {@code listener}, {@code device} or {@code handler}
     * @throws NullPointerException If one of {@code listener}, {@code device} or {@code executor}
     * is null.
     * @throws IllegalArgumentException The same {@link #MetadataListener} and
     * @throws IllegalArgumentException The same {@link #OnMetadataChangedListener} and
     * {@link BluetoothDevice} are registered twice.
     * @hide
     */
    @SystemApi
    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
    public boolean registerMetadataListener(BluetoothDevice device, MetadataListener listener,
            Handler handler) {
        if (DBG) Log.d(TAG, "registerMetdataListener()");
    public boolean addOnMetadataChangedListener(@NonNull BluetoothDevice device,
            @NonNull Executor executor, @NonNull OnMetadataChangedListener listener) {
        if (DBG) Log.d(TAG, "addOnMetadataChangedListener()");

        final IBluetooth service = mService;
        if (service == null) {
@@ -3189,14 +3191,15 @@ public final class BluetoothAdapter {
        if (device == null) {
            throw new NullPointerException("device is null");
        }
        if (handler == null) {
            throw new NullPointerException("handler is null");
        if (executor == null) {
            throw new NullPointerException("executor is null");
        }

        synchronized (sMetadataListeners) {
            List<Pair<MetadataListener, Handler>> listenerList = sMetadataListeners.get(device);
            List<Pair<OnMetadataChangedListener, Executor>> listenerList =
                    sMetadataListeners.get(device);
            if (listenerList == null) {
                // Create new listener/handler list for registeration
                // Create new listener/executor list for registeration
                listenerList = new ArrayList<>();
                sMetadataListeners.put(device, listenerList);
            } else {
@@ -3207,7 +3210,7 @@ public final class BluetoothAdapter {
                }
            }

            Pair<MetadataListener, Handler> listenerPair = new Pair(listener, handler);
            Pair<OnMetadataChangedListener, Executor> listenerPair = new Pair(listener, executor);
            listenerList.add(listenerPair);

            boolean ret = false;
@@ -3230,34 +3233,43 @@ public final class BluetoothAdapter {
    }

    /**
     * Unregister all {@link MetadataListener} from this {@link BluetoothDevice}.
     * Unregister a {@link #OnMetadataChangedListener} from a registered {@link BluetoothDevice}.
     * Unregistration can be done when Bluetooth is either ON or OFF.
     * {@link #registerMetadataListener(MetadataListener, BluetoothDevice, Handler)} must
     * be called before unregisteration.
     * Unregistering a device that is not regestered would cause {@link IllegalArgumentException}.
     * {@link #addOnMetadataChangedListener(OnMetadataChangedListener, BluetoothDevice, Executor)}
     * must be called before unregisteration.
     *
     * @param device {@link BluetoothDevice} that will be unregistered. it
     * @param device {@link BluetoothDevice} that will be unregistered. It
     * should not be null or {@link NullPointerException} will be triggered.
     * @param listener {@link OnMetadataChangedListener} that will be unregistered. It
     * should not be null or {@link NullPointerException} will be triggered.
     * @return true on success, false on error
     * @throws NullPointerException If {@code device} is null.
     * @throws NullPointerException If {@code listener} or {@code device} is null.
     * @throws IllegalArgumentException If {@code device} has not been registered before.
     * @hide
     */
    @SystemApi
    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
    public boolean unregisterMetadataListener(BluetoothDevice device) {
        if (DBG) Log.d(TAG, "unregisterMetdataListener()");
    public boolean removeOnMetadataChangedListener(@NonNull BluetoothDevice device,
            @NonNull OnMetadataChangedListener listener) {
        if (DBG) Log.d(TAG, "removeOnMetadataChangedListener()");
        if (device == null) {
            throw new NullPointerException("device is null");
        }
        if (listener == null) {
            throw new NullPointerException("listener is null");
        }

        synchronized (sMetadataListeners) {
            if (sMetadataListeners.containsKey(device)) {
                sMetadataListeners.remove(device);
            } else {
            if (!sMetadataListeners.containsKey(device)) {
                throw new IllegalArgumentException("device was not registered");
            }
            // Remove issued listener from the registered device
            sMetadataListeners.get(device).removeIf((pair) -> (pair.first.equals(listener)));

            if (sMetadataListeners.get(device).isEmpty()) {
                // Unregister to Bluetooth service if all listeners are removed from
                // the registered device
                sMetadataListeners.remove(device);
                final IBluetooth service = mService;
                if (service == null) {
                    // Bluetooth is OFF, do nothing to Bluetooth service.
@@ -3271,22 +3283,24 @@ public final class BluetoothAdapter {
                }
            }
        }
        return true;
    }

    /**
     * This abstract class is used to implement {@link BluetoothAdapter} metadata listener.
     * This interface is used to implement {@link BluetoothAdapter} metadata listener.
     * @hide
     */
    @SystemApi
    public abstract static class MetadataListener {
    public interface OnMetadataChangedListener {
        /**
         * Callback triggered if the metadata of {@link BluetoothDevice} registered in
         * {@link #registerMetadataListener}.
         * {@link #addOnMetadataChangedListener}.
         *
         * @param device changed {@link BluetoothDevice}.
         * @param key changed metadata key, one of BluetoothDevice.METADATA_*.
         * @param value the new value of metadata.
         * @param value the new value of metadata as byte array.
         */
        public void onMetadataChanged(BluetoothDevice device, int key, String value) {
        }
        void onMetadataChanged(@NonNull BluetoothDevice device, int key,
                @Nullable byte[] value);
    }
}
+43 −24
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.bluetooth;

import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
@@ -351,6 +352,7 @@ public final class BluetoothDevice implements Parcelable {

    /**
     * Manufacturer name of this Bluetooth device
     * Data type should be {@String} as {@link Byte} array.
     * @hide
     */
    @SystemApi
@@ -358,6 +360,7 @@ public final class BluetoothDevice implements Parcelable {

    /**
     * Model name of this Bluetooth device
     * Data type should be {@String} as {@link Byte} array.
     * @hide
     */
    @SystemApi
@@ -365,6 +368,7 @@ public final class BluetoothDevice implements Parcelable {

    /**
     * Software version of this Bluetooth device
     * Data type should be {@String} as {@link Byte} array.
     * @hide
     */
    @SystemApi
@@ -372,6 +376,7 @@ public final class BluetoothDevice implements Parcelable {

    /**
     * Hardware version of this Bluetooth device
     * Data type should be {@String} as {@link Byte} array.
     * @hide
     */
    @SystemApi
@@ -379,6 +384,7 @@ public final class BluetoothDevice implements Parcelable {

    /**
     * Package name of the companion app, if any
     * Data type should be {@String} as {@link Byte} array.
     * @hide
     */
    @SystemApi
@@ -386,6 +392,7 @@ public final class BluetoothDevice implements Parcelable {

    /**
     * URI to the main icon shown on the settings UI
     * Data type should be {@link Byte} array.
     * @hide
     */
    @SystemApi
@@ -393,80 +400,91 @@ public final class BluetoothDevice implements Parcelable {

    /**
     * Whether this device is an untethered headset with left, right and case
     * Data type should be {@String} as {@link Byte} array.
     * @hide
     */
    @SystemApi
    public static final int METADATA_IS_UNTHETHERED_HEADSET = 6;
    public static final int METADATA_IS_UNTETHERED_HEADSET = 6;

    /**
     * URI to icon of the left headset
     * Data type should be {@link Byte} array.
     * @hide
     */
    @SystemApi
    public static final int METADATA_UNTHETHERED_LEFT_ICON = 7;
    public static final int METADATA_UNTETHERED_LEFT_ICON = 7;

    /**
     * URI to icon of the right headset
     * Data type should be {@link Byte} array.
     * @hide
     */
    @SystemApi
    public static final int METADATA_UNTHETHERED_RIGHT_ICON = 8;
    public static final int METADATA_UNTETHERED_RIGHT_ICON = 8;

    /**
     * URI to icon of the headset charging case
     * Data type should be {@link Byte} array.
     * @hide
     */
    @SystemApi
    public static final int METADATA_UNTHETHERED_CASE_ICON = 9;
    public static final int METADATA_UNTETHERED_CASE_ICON = 9;

    /**
     * Battery level (0-100), {@link BluetoothDevice#BATTERY_LEVEL_UNKNOWN}
     * is invalid, of the left headset
     * Battery level of left headset
     * Data type should be {@String} 0-100 as {@link Byte} array, otherwise
     * as invalid.
     * @hide
     */
    @SystemApi
    public static final int METADATA_UNTHETHERED_LEFT_BATTERY = 10;
    public static final int METADATA_UNTETHERED_LEFT_BATTERY = 10;

    /**
     * Battery level (0-100), {@link BluetoothDevice#BATTERY_LEVEL_UNKNOWN}
     * is invalid, of the right headset
     * Battery level of rigth headset
     * Data type should be {@String} 0-100 as {@link Byte} array, otherwise
     * as invalid.
     * @hide
     */
    @SystemApi
    public static final int METADATA_UNTHETHERED_RIGHT_BATTERY = 11;
    public static final int METADATA_UNTETHERED_RIGHT_BATTERY = 11;

    /**
     * Battery level (0-100), {@link BluetoothDevice#BATTERY_LEVEL_UNKNOWN}
     * is invalid, of the headset charging case
     * Battery level of the headset charging case
     * Data type should be {@String} 0-100 as {@link Byte} array, otherwise
     * as invalid.
     * @hide
     */
    @SystemApi
    public static final int METADATA_UNTHETHERED_CASE_BATTERY = 12;
    public static final int METADATA_UNTETHERED_CASE_BATTERY = 12;

    /**
     * Whether the left headset is charging
     * Data type should be {@String} as {@link Byte} array.
     * @hide
     */
    @SystemApi
    public static final int METADATA_UNTHETHERED_LEFT_CHARGING = 13;
    public static final int METADATA_UNTETHERED_LEFT_CHARGING = 13;

    /**
     * Whether the right headset is charging
     * Data type should be {@String} as {@link Byte} array.
     * @hide
     */
    @SystemApi
    public static final int METADATA_UNTHETHERED_RIGHT_CHARGING = 14;
    public static final int METADATA_UNTETHERED_RIGHT_CHARGING = 14;

    /**
     * Whether the headset charging case is charging
     * Data type should be {@String} as {@link Byte} array.
     * @hide
     */
    @SystemApi
    public static final int METADATA_UNTHETHERED_CASE_CHARGING = 15;
    public static final int METADATA_UNTETHERED_CASE_CHARGING = 15;

    /**
     * URI to the enhanced settings UI slice, null or empty String means
     * the UI does not exist
     * URI to the enhanced settings UI slice
     * Data type should be {@String} as {@link Byte} array, null means
     * the UI does not exist.
     * @hide
     */
    @SystemApi
@@ -2243,21 +2261,21 @@ public final class BluetoothDevice implements Parcelable {
     * {@link #BOND_NONE}.
     *
     * @param key must be within the list of BluetoothDevice.METADATA_*
     * @param value the string data to set for key. Must be less than
     * @param value a byte array data to set for key. Must be less than
     * {@link BluetoothAdapter#METADATA_MAX_LENGTH} characters in length
     * @return true on success, false on error
     * @hide
    */
    @SystemApi
    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
    public boolean setMetadata(int key, String value) {
    public boolean setMetadata(int key, @NonNull byte[] value) {
        final IBluetooth service = sService;
        if (service == null) {
            Log.e(TAG, "Bluetooth is not enabled. Cannot set metadata");
            return false;
        }
        if (value.length() > METADATA_MAX_LENGTH) {
            throw new IllegalArgumentException("value length is " + value.length()
        if (value.length > METADATA_MAX_LENGTH) {
            throw new IllegalArgumentException("value length is " + value.length
                    + ", should not over " + METADATA_MAX_LENGTH);
        }
        try {
@@ -2272,12 +2290,13 @@ public final class BluetoothDevice implements Parcelable {
     * Get a keyed metadata for this {@link BluetoothDevice} as {@link String}
     *
     * @param key must be within the list of BluetoothDevice.METADATA_*
     * @return Metadata of the key as string, null on error or not found
     * @return Metadata of the key as byte array, null on error or not found
     * @hide
     */
    @SystemApi
    @Nullable
    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
    public String getMetadata(int key) {
    public byte[] getMetadata(int key) {
        final IBluetooth service = sService;
        if (service == null) {
            Log.e(TAG, "Bluetooth is not enabled. Cannot get metadata");
+79 −8

File changed.

Preview size limit exceeded, changes collapsed.

+6 −10
Original line number Diff line number Diff line
@@ -881,16 +881,12 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
        //when profile is connected, information would be available
        if (profileConnected) {
            // Update Meta data for connected device
            if (Boolean.parseBoolean(
                    mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET))) {
                try {
                    leftBattery = Integer.parseInt(
                            mDevice.getMetadata(BluetoothDevice.METADATA_UNTHETHERED_LEFT_BATTERY));
                    rightBattery = Integer.parseInt(mDevice.getMetadata(
                                    BluetoothDevice.METADATA_UNTHETHERED_RIGHT_BATTERY));
                } catch (NumberFormatException e) {
                    Log.d(TAG, "Parse error for unthethered battery level.");
                }
            if (BluetoothUtils.getBooleanMetaData(
                    mDevice, BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) {
                leftBattery = BluetoothUtils.getIntMetaData(mDevice,
                        BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY);
                rightBattery = BluetoothUtils.getIntMetaData(mDevice,
                        BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY);
            }

            // Set default string with battery level in device connected situation.
Loading