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

Commit 54017423 authored by Xin Li's avatar Xin Li
Browse files

Merge SP1A.210812.016

Merged-In: I8b62b9b9d7ae271bc623764d545db1320b4dc64f
Change-Id: I458ed7f2eb8603f5e89c1d73bc0f0d52b826973e
parents e9263ffd b2de95be
Loading
Loading
Loading
Loading
+124 −60
Original line number Original line Diff line number Diff line
@@ -64,6 +64,8 @@ import android.os.SystemProperties;
import android.util.Log;
import android.util.Log;
import android.util.Pair;
import android.util.Pair;


import com.android.internal.annotations.GuardedBy;

import java.io.IOException;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.RetentionPolicy;
@@ -78,6 +80,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Objects;
import java.util.Set;
import java.util.Set;
import java.util.UUID;
import java.util.UUID;
import java.util.WeakHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -715,10 +718,21 @@ public final class BluetoothAdapter {
    private final IBluetoothManager mManagerService;
    private final IBluetoothManager mManagerService;
    private final AttributionSource mAttributionSource;
    private final AttributionSource mAttributionSource;


    // Yeah, keeping both mService and sService isn't pretty, but it's too late
    // in the current release for a major refactoring, so we leave them both
    // intact until this can be cleaned up in a future release

    @UnsupportedAppUsage
    @UnsupportedAppUsage
    @GuardedBy("mServiceLock")
    private IBluetooth mService;
    private IBluetooth mService;
    private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock();
    private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock();


    @GuardedBy("sServiceLock")
    private static boolean sServiceRegistered;
    @GuardedBy("sServiceLock")
    private static IBluetooth sService;
    private static final Object sServiceLock = new Object();

    private final Object mLock = new Object();
    private final Object mLock = new Object();
    private final Map<LeScanCallback, ScanCallback> mLeScanClients;
    private final Map<LeScanCallback, ScanCallback> mLeScanClients;
    private final Map<BluetoothDevice, List<Pair<OnMetadataChangedListener, Executor>>>
    private final Map<BluetoothDevice, List<Pair<OnMetadataChangedListener, Executor>>>
@@ -792,19 +806,11 @@ public final class BluetoothAdapter {
     * Use {@link #getDefaultAdapter} to get the BluetoothAdapter instance.
     * Use {@link #getDefaultAdapter} to get the BluetoothAdapter instance.
     */
     */
    BluetoothAdapter(IBluetoothManager managerService, AttributionSource attributionSource) {
    BluetoothAdapter(IBluetoothManager managerService, AttributionSource attributionSource) {
        if (managerService == null) {
            throw new IllegalArgumentException("bluetooth manager service is null");
        }
        try {
            mServiceLock.writeLock().lock();
            mService = managerService.registerAdapter(mManagerCallback);
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
        } finally {
            mServiceLock.writeLock().unlock();
        }
        mManagerService = Objects.requireNonNull(managerService);
        mManagerService = Objects.requireNonNull(managerService);
        mAttributionSource = Objects.requireNonNull(attributionSource);
        mAttributionSource = Objects.requireNonNull(attributionSource);
        synchronized (mServiceLock.writeLock()) {
            mService = getBluetoothService(mManagerCallback);
        }
        mLeScanClients = new HashMap<LeScanCallback, ScanCallback>();
        mLeScanClients = new HashMap<LeScanCallback, ScanCallback>();
        mToken = new Binder(DESCRIPTOR);
        mToken = new Binder(DESCRIPTOR);
    }
    }
@@ -3171,21 +3177,16 @@ public final class BluetoothAdapter {
        }
        }
    }
    }


    @SuppressLint("AndroidFrameworkBluetoothPermission")
    private static final IBluetoothManagerCallback sManagerCallback =
    private final IBluetoothManagerCallback mManagerCallback =
            new IBluetoothManagerCallback.Stub() {
            new IBluetoothManagerCallback.Stub() {
                @SuppressLint("AndroidFrameworkRequiresPermission")
                public void onBluetoothServiceUp(IBluetooth bluetoothService) {
                public void onBluetoothServiceUp(IBluetooth bluetoothService) {
                    if (DBG) {
                    if (DBG) {
                        Log.d(TAG, "onBluetoothServiceUp: " + bluetoothService);
                        Log.d(TAG, "onBluetoothServiceUp: " + bluetoothService);
                    }
                    }


                    mServiceLock.writeLock().lock();
                    synchronized (sServiceLock) {
                    mService = bluetoothService;
                        sService = bluetoothService;
                    mServiceLock.writeLock().unlock();
                        for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) {

                    synchronized (mProxyServiceStateCallbacks) {
                        for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks) {
                            try {
                            try {
                                if (cb != null) {
                                if (cb != null) {
                                    cb.onBluetoothServiceUp(bluetoothService);
                                    cb.onBluetoothServiceUp(bluetoothService);
@@ -3197,6 +3198,56 @@ public final class BluetoothAdapter {
                            }
                            }
                        }
                        }
                    }
                    }
                }

                public void onBluetoothServiceDown() {
                    if (DBG) {
                        Log.d(TAG, "onBluetoothServiceDown");
                    }

                    synchronized (sServiceLock) {
                        sService = null;
                        for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) {
                            try {
                                if (cb != null) {
                                    cb.onBluetoothServiceDown();
                                } else {
                                    Log.d(TAG, "onBluetoothServiceDown: cb is null!");
                                }
                            } catch (Exception e) {
                                Log.e(TAG, "", e);
                            }
                        }
                    }
                }

                public void onBrEdrDown() {
                    if (VDBG) {
                        Log.i(TAG, "onBrEdrDown");
                    }

                    synchronized (sServiceLock) {
                        for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) {
                            try {
                                if (cb != null) {
                                    cb.onBrEdrDown();
                                } else {
                                    Log.d(TAG, "onBrEdrDown: cb is null!");
                                }
                            } catch (Exception e) {
                                Log.e(TAG, "", e);
                            }
                        }
                    }
                }
            };

    private final IBluetoothManagerCallback mManagerCallback =
            new IBluetoothManagerCallback.Stub() {
                public void onBluetoothServiceUp(IBluetooth bluetoothService) {
                    synchronized (mServiceLock.writeLock()) {
                        mService = bluetoothService;
                    }
                    synchronized (mMetadataListeners) {
                    synchronized (mMetadataListeners) {
                        mMetadataListeners.forEach((device, pair) -> {
                        mMetadataListeners.forEach((device, pair) -> {
                            try {
                            try {
@@ -3221,12 +3272,7 @@ public final class BluetoothAdapter {
                }
                }


                public void onBluetoothServiceDown() {
                public void onBluetoothServiceDown() {
                    if (DBG) {
                    synchronized (mServiceLock.writeLock()) {
                        Log.d(TAG, "onBluetoothServiceDown: " + mService);
                    }

                    try {
                        mServiceLock.writeLock().lock();
                        mService = null;
                        mService = null;
                        if (mLeScanClients != null) {
                        if (mLeScanClients != null) {
                            mLeScanClients.clear();
                            mLeScanClients.clear();
@@ -3237,29 +3283,10 @@ public final class BluetoothAdapter {
                        if (mBluetoothLeScanner != null) {
                        if (mBluetoothLeScanner != null) {
                            mBluetoothLeScanner.cleanup();
                            mBluetoothLeScanner.cleanup();
                        }
                        }
                    } finally {
                        mServiceLock.writeLock().unlock();
                    }

                    synchronized (mProxyServiceStateCallbacks) {
                        for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks) {
                            try {
                                if (cb != null) {
                                    cb.onBluetoothServiceDown();
                                } else {
                                    Log.d(TAG, "onBluetoothServiceDown: cb is null!");
                                }
                            } catch (Exception e) {
                                Log.e(TAG, "", e);
                            }
                        }
                    }
                    }
                }
                }


                public void onBrEdrDown() {
                public void onBrEdrDown() {
                    if (VDBG) {
                        Log.i(TAG, "onBrEdrDown: " + mService);
                    }
                }
                }
            };
            };


@@ -3494,15 +3521,12 @@ public final class BluetoothAdapter {


    protected void finalize() throws Throwable {
    protected void finalize() throws Throwable {
        try {
        try {
            mManagerService.unregisterAdapter(mManagerCallback);
            removeServiceStateCallback(mManagerCallback);
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
        } finally {
        } finally {
            super.finalize();
            super.finalize();
        }
        }
    }
    }



    /**
    /**
     * Validate a String Bluetooth address, such as "00:43:A8:23:10:F0"
     * Validate a String Bluetooth address, such as "00:43:A8:23:10:F0"
     * <p>Alphabetic characters must be uppercase to be valid.
     * <p>Alphabetic characters must be uppercase to be valid.
@@ -3566,24 +3590,64 @@ public final class BluetoothAdapter {
        return mAttributionSource;
        return mAttributionSource;
    }
    }


    private final ArrayList<IBluetoothManagerCallback> mProxyServiceStateCallbacks =
    @GuardedBy("sServiceLock")
            new ArrayList<IBluetoothManagerCallback>();
    private static final WeakHashMap<IBluetoothManagerCallback, Void> sProxyServiceStateCallbacks =
            new WeakHashMap<>();

    /*package*/ IBluetooth getBluetoothService() {
        synchronized (sServiceLock) {
            if (sProxyServiceStateCallbacks.isEmpty()) {
                throw new IllegalStateException(
                        "Anonymous service access requires at least one lifecycle in process");
            }
            return sService;
        }
    }


    @UnsupportedAppUsage
    @UnsupportedAppUsage
    /*package*/ IBluetooth getBluetoothService(IBluetoothManagerCallback cb) {
    /*package*/ IBluetooth getBluetoothService(IBluetoothManagerCallback cb) {
        synchronized (mProxyServiceStateCallbacks) {
        Objects.requireNonNull(cb);
            if (cb == null) {
        synchronized (sServiceLock) {
                Log.w(TAG, "getBluetoothService() called with no BluetoothManagerCallback");
            sProxyServiceStateCallbacks.put(cb, null);
            } else if (!mProxyServiceStateCallbacks.contains(cb)) {
            registerOrUnregisterAdapterLocked();
                mProxyServiceStateCallbacks.add(cb);
            return sService;
            }
        }
        }
        return mService;
    }
    }


    /*package*/ void removeServiceStateCallback(IBluetoothManagerCallback cb) {
    /*package*/ void removeServiceStateCallback(IBluetoothManagerCallback cb) {
        synchronized (mProxyServiceStateCallbacks) {
        Objects.requireNonNull(cb);
            mProxyServiceStateCallbacks.remove(cb);
        synchronized (sServiceLock) {
            sProxyServiceStateCallbacks.remove(cb);
            registerOrUnregisterAdapterLocked();
        }
    }

    /**
     * Handle registering (or unregistering) a single process-wide
     * {@link IBluetoothManagerCallback} based on the presence of local
     * {@link #sProxyServiceStateCallbacks} clients.
     */
    @GuardedBy("sServiceLock")
    private void registerOrUnregisterAdapterLocked() {
        final boolean isRegistered = sServiceRegistered;
        final boolean wantRegistered = !sProxyServiceStateCallbacks.isEmpty();

        if (isRegistered != wantRegistered) {
            if (wantRegistered) {
                try {
                    sService = mManagerService.registerAdapter(sManagerCallback);
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            } else {
                try {
                    mManagerService.unregisterAdapter(sManagerCallback);
                    sService = null;
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            }
            sServiceRegistered = wantRegistered;
        }
        }
    }
    }


+3 −3
Original line number Original line Diff line number Diff line
@@ -399,7 +399,7 @@ public final class BluetoothSocket implements Closeable {
        try {
        try {
            if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
            if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
            IBluetooth bluetoothProxy =
            IBluetooth bluetoothProxy =
                    BluetoothAdapter.getDefaultAdapter().getBluetoothService(null);
                    BluetoothAdapter.getDefaultAdapter().getBluetoothService();
            if (bluetoothProxy == null) throw new IOException("Bluetooth is off");
            if (bluetoothProxy == null) throw new IOException("Bluetooth is off");
            mPfd = bluetoothProxy.getSocketManager().connectSocket(mDevice, mType,
            mPfd = bluetoothProxy.getSocketManager().connectSocket(mDevice, mType,
                    mUuid, mPort, getSecurityFlags());
                    mUuid, mPort, getSecurityFlags());
@@ -438,7 +438,7 @@ public final class BluetoothSocket implements Closeable {
    /*package*/ int bindListen() {
    /*package*/ int bindListen() {
        int ret;
        int ret;
        if (mSocketState == SocketState.CLOSED) return EBADFD;
        if (mSocketState == SocketState.CLOSED) return EBADFD;
        IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(null);
        IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService();
        if (bluetoothProxy == null) {
        if (bluetoothProxy == null) {
            Log.e(TAG, "bindListen fail, reason: bluetooth is off");
            Log.e(TAG, "bindListen fail, reason: bluetooth is off");
            return -1;
            return -1;
@@ -706,7 +706,7 @@ public final class BluetoothSocket implements Closeable {
                throw new IOException("socket closed");
                throw new IOException("socket closed");
            }
            }
            IBluetooth bluetoothProxy =
            IBluetooth bluetoothProxy =
                    BluetoothAdapter.getDefaultAdapter().getBluetoothService(null);
                    BluetoothAdapter.getDefaultAdapter().getBluetoothService();
            if (bluetoothProxy == null) {
            if (bluetoothProxy == null) {
                throw new IOException("Bluetooth is off");
                throw new IOException("Bluetooth is off");
            }
            }