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

Commit 71b54554 authored by Lee Shombert's avatar Lee Shombert
Browse files

Binder cache for Bluetooth getState().

Bug: 140788621

Test: A special build that puts the PropertyInvalidatedCache in verification
mode was loaded on the device.  Then one iteration of MPTS was executed.  No
cache inconsistencies were found and no SELinux violations (associated with
the binder cache) were found.  The number of cache misses was approximately
3% of the total binder calls.  All binder calls went through the cache.
Repeated the test with a work profile installed (to provide a second user
ID).

Change-Id: I2f1d0b6d61dedc5d1badb06a20c5932eca415904
parent abf657ef
Loading
Loading
Loading
Loading
+34 −24
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.app.ActivityThread;
import android.app.PropertyInvalidatedCache;
import android.bluetooth.BluetoothProfile.ConnectionPolicy;
import android.bluetooth.le.BluetoothLeAdvertiser;
import android.bluetooth.le.BluetoothLeScanner;
@@ -994,6 +995,37 @@ public final class BluetoothAdapter {
        return false;
    }

    private static final String BLUETOOTH_GET_STATE_CACHE_PROPERTY = "cache_key.bluetooth.get_state";

    private final PropertyInvalidatedCache<Void, Integer> mBluetoothGetStateCache =
            new PropertyInvalidatedCache<Void, Integer>(
                8, BLUETOOTH_GET_STATE_CACHE_PROPERTY) {
                @Override
                protected Integer recompute(Void query) {
                    try {
                        mServiceLock.readLock().lock();
                        if (mService != null) {
                            return mService.getState();
                        }
                    } catch (RemoteException e) {
                        Log.e(TAG, "", e);
                    } finally {
                        mServiceLock.readLock().unlock();
                    }
                    return BluetoothAdapter.STATE_OFF;
                }
            };

    /** @hide */
    public void disableBluetoothGetStateCache() {
        mBluetoothGetStateCache.disableLocal();
    }

    /** @hide */
    public static void invalidateBluetoothGetStateCache() {
        PropertyInvalidatedCache.invalidateCache(BLUETOOTH_GET_STATE_CACHE_PROPERTY);
    }

    /**
     * Get the current state of the local Bluetooth adapter.
     * <p>Possible return values are
@@ -1007,18 +1039,7 @@ public final class BluetoothAdapter {
    @RequiresPermission(Manifest.permission.BLUETOOTH)
    @AdapterState
    public int getState() {
        int state = BluetoothAdapter.STATE_OFF;

        try {
            mServiceLock.readLock().lock();
            if (mService != null) {
                state = mService.getState();
            }
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
        } finally {
            mServiceLock.readLock().unlock();
        }
        int state = mBluetoothGetStateCache.query(null);

        // Consider all internal states as OFF
        if (state == BluetoothAdapter.STATE_BLE_ON || state == BluetoothAdapter.STATE_BLE_TURNING_ON
@@ -1056,18 +1077,7 @@ public final class BluetoothAdapter {
    @UnsupportedAppUsage(publicAlternatives = "Use {@link #getState()} instead to determine "
            + "whether you can use BLE & BT classic.")
    public int getLeState() {
        int state = BluetoothAdapter.STATE_OFF;

        try {
            mServiceLock.readLock().lock();
            if (mService != null) {
                state = mService.getState();
            }
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
        } finally {
            mServiceLock.readLock().unlock();
        }
        int state = mBluetoothGetStateCache.query(null);

        if (VDBG) {
            Log.d(TAG, "getLeState() returning " + BluetoothAdapter.nameForState(state));