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

Commit b528b5f3 authored by Lee Shombert's avatar Lee Shombert Committed by Android (Google) Code Review
Browse files

Merge "Enable binder caches in Bluetooth module"

parents faf0df32 3e8fdcf3
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -200,7 +200,7 @@ class AdapterProperties {
    AdapterProperties(AdapterService service) {
        mService = service;
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        //invalidateBluetoothCaches();
        invalidateBluetoothCaches();
    }

    public void init(RemoteDevices remoteDevices) {
@@ -242,7 +242,7 @@ class AdapterProperties {
        filter.addAction(BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED);
        mService.registerReceiver(mReceiver, filter);
        mReceiverRegistered = true;
        //invalidateBluetoothCaches();
        invalidateBluetoothCaches();
    }

    public void cleanup() {
@@ -254,9 +254,9 @@ class AdapterProperties {
        }
        mService = null;
        mBondedDevices.clear();
        //invalidateBluetoothCaches();
        invalidateBluetoothCaches();
    }
    /*

    private static void invalidateGetProfileConnectionStateCache() {
        BluetoothAdapter.invalidateGetProfileConnectionStateCache();
    }
@@ -275,7 +275,6 @@ class AdapterProperties {
        invalidateGetConnectionStateCache();
        invalidateGetBondStateCache();
    }
     */

    @Override
    public Object clone() throws CloneNotSupportedException {
+2 −4
Original line number Diff line number Diff line
@@ -537,7 +537,7 @@ public class AdapterService extends Service {

        setAdapterService(this);

        //invalidateBluetoothCaches();
        invalidateBluetoothCaches();

        // First call to getSharedPreferences will result in a file read into
        // memory cache. Call it here asynchronously to avoid potential ANR
@@ -864,7 +864,7 @@ public class AdapterService extends Service {
        clearAdapterService(this);

        mCleaningUp = true;
        //invalidateBluetoothCaches();
        invalidateBluetoothCaches();

        unregisterReceiver(mAlarmBroadcastReceiver);

@@ -961,7 +961,6 @@ public class AdapterService extends Service {
        }
    }

    /*
    private void invalidateBluetoothCaches() {
        BluetoothAdapter.invalidateGetProfileConnectionStateCache();
        BluetoothAdapter.invalidateIsOffloadedFilteringSupportedCache();
@@ -969,7 +968,6 @@ public class AdapterService extends Service {
        BluetoothAdapter.invalidateBluetoothGetStateCache();
        BluetoothAdapter.invalidateGetAdapterConnectionStateCache();
    }
     */

    private void setProfileServiceState(Class service, int state) {
        if (state == BluetoothAdapter.STATE_ON) {
+112 −161
Original line number Diff line number Diff line
@@ -30,8 +30,9 @@ import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SuppressLint;
import android.annotation.SystemApi; //import android.app.PropertyInvalidatedCache;
import android.annotation.SystemApi;
import android.app.PendingIntent;
import android.app.PropertyInvalidatedCache;
import android.bluetooth.BluetoothDevice.AddressType;
import android.bluetooth.BluetoothDevice.Transport;
import android.bluetooth.BluetoothProfile.ConnectionPolicy;
@@ -1123,45 +1124,69 @@ public final class BluetoothAdapter {
        return false;
    }

    /*
    private static final String BLUETOOTH_GET_STATE_CACHE_PROPERTY = "cache_key.bluetooth.get_state";
    /**
     * There are several instances of PropertyInvalidatedCache used in this class.
     * BluetoothCache wraps up the common code.  All caches are created with a maximum of
     * eight entries, and the key is in the bluetooth module.  The name is set to the api.
     */
    private static class BluetoothCache<Q, R> extends PropertyInvalidatedCache<Q, R> {
        BluetoothCache(String api, PropertyInvalidatedCache.QueryHandler query) {
            super(8, PropertyInvalidatedCache.MODULE_BLUETOOTH, api, api, query);
        }};

    private final PropertyInvalidatedCache<Void, Integer> mBluetoothGetStateCache =
            new PropertyInvalidatedCache<Void, Integer>(
                8, BLUETOOTH_GET_STATE_CACHE_PROPERTY) {
    /**
     * Invalidate a bluetooth cache.  This method is just a short-hand wrapper that
     * enforces the bluetooth module.
     */
    private static void invalidateCache(@NonNull String api) {
        PropertyInvalidatedCache.invalidateCache(PropertyInvalidatedCache.MODULE_BLUETOOTH, api);
    }

    /**
     * The binder cache for getState().
     */
    private final static String GET_STATE_API = "getState";

    private final PropertyInvalidatedCache.QueryHandler<Void, Integer> mBluetoothGetStateQuery =
            new PropertyInvalidatedCache.QueryHandler<>() {
                @RequiresLegacyBluetoothPermission
                @RequiresNoPermission
                @AdapterState
                @Override
                @SuppressLint("AndroidFrameworkRequiresPermission")
                public Integer recompute(Void query) {
                public Integer apply(Void query) {
                    int state = BluetoothAdapter.STATE_OFF;
                    mServiceLock.readLock().lock();
                    try {
                        if (mService != null) {
                            final SynchronousResultReceiver<Integer> recv =
                                    new SynchronousResultReceiver();
                            mService.getState(recv);
                        return recv.awaitResultNoInterrupt(getSyncTimeout())
                            .getValue(BluetoothAdapter.STATE_OFF);
                            return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(state);
                        }
                    } catch (TimeoutException e) {
                        Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
                        return BluetoothAdapter.STATE_OFF;
                    } catch (RemoteException e) {
                        throw e.rethrowFromSystemServer();
                    }
                        Log.e(TAG, "", e);
                        e.rethrowFromSystemServer();
                    } finally {
                        mServiceLock.readLock().unlock();
                    }
            };
     */
                    return state;
                }};

    private final PropertyInvalidatedCache<Void, Integer> mBluetoothGetStateCache =
            new BluetoothCache<Void, Integer>(GET_STATE_API, mBluetoothGetStateQuery);

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

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

    /**
     * Fetch the current bluetooth state.  If the service is down, return
@@ -1169,25 +1194,7 @@ public final class BluetoothAdapter {
     */
    @AdapterState
    private int getStateInternal() {
        int state = BluetoothAdapter.STATE_OFF;
        try {
            mServiceLock.readLock().lock();
            if (mService != null) {
                //state = mBluetoothGetStateCache.query(null);
                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
                //return mBluetoothBondCache.query(this);
                mService.getState(recv);
                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(state);
            }
        } catch (TimeoutException e) {
            Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
            e.rethrowFromSystemServer();
        } finally {
            mServiceLock.readLock().unlock();
        }
        return state;
        return mBluetoothGetStateCache.query(null);
    }

    /**
@@ -2260,17 +2267,14 @@ public final class BluetoothAdapter {
        }
    }

    /*
    private static final String BLUETOOTH_FILTERING_CACHE_PROPERTY =
            "cache_key.bluetooth.is_offloaded_filtering_supported";
    private final PropertyInvalidatedCache<Void, Boolean> mBluetoothFilteringCache =
            new PropertyInvalidatedCache<Void, Boolean>(
                8, BLUETOOTH_FILTERING_CACHE_PROPERTY) {
    private final PropertyInvalidatedCache.QueryHandler<Void, Boolean> mBluetoothFilteringQuery =
            new PropertyInvalidatedCache.QueryHandler<>() {
                @RequiresLegacyBluetoothPermission
                @RequiresNoPermission
                @Override
                @SuppressLint("AndroidFrameworkRequiresPermission")
                public Boolean recompute(Void query) {
                    try {
                public Boolean apply(Void query) {
                    mServiceLock.readLock().lock();
                    try {
                        if (mService != null) {
                            final SynchronousResultReceiver<Boolean> recv =
                                    new SynchronousResultReceiver();
@@ -2283,25 +2287,23 @@ public final class BluetoothAdapter {
                        mServiceLock.readLock().unlock();
                    }
                    return false;
                }};

                }
            };
     */
    private static final String FILTERING_API = "isOffloadedFilteringSupported";

    private final PropertyInvalidatedCache<Void, Boolean> mBluetoothFilteringCache =
            new BluetoothCache<Void, Boolean>(FILTERING_API, mBluetoothFilteringQuery);

    /** @hide */
    /*
    @RequiresNoPermission
    public void disableIsOffloadedFilteringSupportedCache() {
        mBluetoothFilteringCache.disableLocal();
        mBluetoothFilteringCache.disableForCurrentProcess();
    }
     */

    /** @hide */
    /*
    public static void invalidateIsOffloadedFilteringSupportedCache() {
        PropertyInvalidatedCache.invalidateCache(BLUETOOTH_FILTERING_CACHE_PROPERTY);
        invalidateCache(FILTERING_API);
    }
     */

    /**
     * Return true if offloaded filters are supported
@@ -2314,22 +2316,7 @@ public final class BluetoothAdapter {
        if (!getLeAccess()) {
            return false;
        }
        //return mBluetoothFilteringCache.query(null);
        try {
            mServiceLock.readLock().lock();
            if (mService != null) {
                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
                mService.isOffloadedFilteringSupported(recv);
                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(false);
            }
        } catch (TimeoutException e) {
            Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
        } catch (RemoteException e) {
            Log.e(TAG, "failed to get isOffloadedFilteringSupported, error: ", e);
        } finally {
            mServiceLock.readLock().unlock();
        }
        return false;
        return mBluetoothFilteringCache.query(null);
    }

    /**
@@ -2812,47 +2799,46 @@ public final class BluetoothAdapter {
        return supportedProfiles;
    }

    /*
    private static final String BLUETOOTH_GET_ADAPTER_CONNECTION_STATE_CACHE_PROPERTY =
            "cache_key.bluetooth.get_adapter_connection_state";
    private final PropertyInvalidatedCache<Void, Integer>
            mBluetoothGetAdapterConnectionStateCache =
            new PropertyInvalidatedCache<Void, Integer> (
                8, BLUETOOTH_GET_ADAPTER_CONNECTION_STATE_CACHE_PROPERTY) {
   private final PropertyInvalidatedCache.QueryHandler<Void, Integer> mBluetoothGetAdapterQuery =
            new PropertyInvalidatedCache.QueryHandler<>() {
                @RequiresLegacyBluetoothPermission
                @RequiresNoPermission
                @Override
                @SuppressLint("AndroidFrameworkRequiresPermission")
                public Integer recompute(Void query) {
                public Integer apply(Void query) {
                    mServiceLock.readLock().lock();
                    try {
                        if (mService != null) {
                            final SynchronousResultReceiver<Integer> recv =
                                    new SynchronousResultReceiver();
                            mService.getAdapterConnectionState(recv);
                            return recv.awaitResultNoInterrupt(getSyncTimeout())
                            .getValue(BluetoothAdapter.STATE_DISCONNECTED);
                                    .getValue(STATE_DISCONNECTED);
                        }
                    } catch (TimeoutException e) {
                        Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
                    } catch (RemoteException e) {
                        throw e.rethrowAsRuntimeException();
                        Log.e(TAG, "failed to getConnectionState, error: ", e);
                    } finally {
                        mServiceLock.readLock().unlock();
                    }
                    return BluetoothAdapter.STATE_DISCONNECTED;
                }
            };
     */
                }};

    private static final String GET_CONNECTION_API = "getAdapterConnectionState";
    private final PropertyInvalidatedCache<Void, Integer>
            mBluetoothGetAdapterConnectionStateCache =
            new BluetoothCache<Void, Integer> (GET_CONNECTION_API, mBluetoothGetAdapterQuery);

    /** @hide */
    /*
    @RequiresNoPermission
    public void disableGetAdapterConnectionStateCache() {
        mBluetoothGetAdapterConnectionStateCache.disableLocal();
        mBluetoothGetAdapterConnectionStateCache.disableForCurrentProcess();
    }
     */

    /** @hide */
    /*
    public static void invalidateGetAdapterConnectionStateCache() {
        PropertyInvalidatedCache.invalidateCache(
            BLUETOOTH_GET_ADAPTER_CONNECTION_STATE_CACHE_PROPERTY);
        invalidateCache(GET_CONNECTION_API);
    }
     */

    /**
     * Get the current connection state of the local Bluetooth adapter.
@@ -2872,34 +2858,14 @@ public final class BluetoothAdapter {
        if (getState() != STATE_ON) {
            return BluetoothAdapter.STATE_DISCONNECTED;
        }
        try {
            mServiceLock.readLock().lock();
            if (mService != null) {
                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
                mService.getAdapterConnectionState(recv);
                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(STATE_DISCONNECTED);
            }
            //return mBluetoothGetAdapterConnectionStateCache.query(null);
        } catch (TimeoutException e) {
            Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
        } catch (RemoteException e) {
            Log.e(TAG, "failed to getConnectionState, error: ", e);
        } finally {
            mServiceLock.readLock().unlock();
        }
        return BluetoothAdapter.STATE_DISCONNECTED;
        return mBluetoothGetAdapterConnectionStateCache.query(null);
    }

    /*
    private static final String BLUETOOTH_PROFILE_CACHE_PROPERTY =
            "cache_key.bluetooth.get_profile_connection_state";
    private final PropertyInvalidatedCache<Integer, Integer>
            mGetProfileConnectionStateCache =
            new PropertyInvalidatedCache<Integer, Integer>(
                8, BLUETOOTH_PROFILE_CACHE_PROPERTY) {
    private final PropertyInvalidatedCache.QueryHandler<Integer, Integer> mBluetoothProfileQuery =
            new PropertyInvalidatedCache.QueryHandler<>() {
                @RequiresNoPermission
                @Override
                @SuppressLint("AndroidFrameworkRequiresPermission")
                public Integer recompute(Integer query) {
                public Integer apply(Integer query) {
                    try {
                        mServiceLock.readLock().lock();
                        if (mService != null) {
@@ -2907,37 +2873,37 @@ public final class BluetoothAdapter {
                                    new SynchronousResultReceiver();
                            mService.getProfileConnectionState(query, recv);
                            return recv.awaitResultNoInterrupt(getSyncTimeout())
                                .getValue(BluetoothProfile.STATE_DISCONNECTED);
                                    .getValue(STATE_DISCONNECTED);
                        }
                    } catch (RemoteException | TimeoutException e) {
                    } catch (TimeoutException e) {
                        Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
                    } catch (RemoteException e) {
                        Log.e(TAG, "failed to getProfileConnectionState, error: ", e);
                    } finally {
                        mServiceLock.readLock().unlock();
                    }
                    return BluetoothProfile.STATE_DISCONNECTED;
                }
                @Override
                public String queryToString(Integer query) {
                    return String.format("getProfileConnectionState(profile=\"%d\")",
                                         query);
                }
            };
     */
                }};

    /** @hide */
    /*
    private static final String PROFILE_API = "getProfileConnectionState";
    private final PropertyInvalidatedCache<Integer, Integer>
            mGetProfileConnectionStateCache =
            new BluetoothCache<Integer, Integer>(PROFILE_API, mBluetoothProfileQuery);

    /**
     * @hide
     */
    @RequiresNoPermission
    public void disableGetProfileConnectionStateCache() {
        mGetProfileConnectionStateCache.disableLocal();
        mGetProfileConnectionStateCache.disableForCurrentProcess();
    }
     */

    /** @hide */
    /*
    /**
     * @hide
     */
    public static void invalidateGetProfileConnectionStateCache() {
        PropertyInvalidatedCache.invalidateCache(BLUETOOTH_PROFILE_CACHE_PROPERTY);
        invalidateCache(PROFILE_API);
    }
     */

    /**
     * Get the current connection state of a profile.
@@ -2959,22 +2925,7 @@ public final class BluetoothAdapter {
        if (getState() != STATE_ON) {
            return BluetoothProfile.STATE_DISCONNECTED;
        }
        try {
            mServiceLock.readLock().lock();
            if (mService != null) {
                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
                mService.getProfileConnectionState(profile, recv);
                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(STATE_DISCONNECTED);
            }
            //return mGetProfileConnectionStateCache.query(new Integer(profile));
        } catch (TimeoutException e) {
            Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
        } catch (RemoteException e) {
            Log.e(TAG, "failed to getProfileConnectionState, error: ", e);
        } finally {
            mServiceLock.readLock().unlock();
        }
        return BluetoothProfile.STATE_DISCONNECTED;
        return mGetProfileConnectionStateCache.query(profile);
    }

    /**
+57 −45
Original line number Diff line number Diff line
@@ -25,7 +25,8 @@ import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SuppressLint;
import android.annotation.SystemApi; //import android.app.PropertyInvalidatedCache;
import android.annotation.SystemApi;
import android.app.PropertyInvalidatedCache;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresBluetoothLocationPermission;
import android.bluetooth.annotations.RequiresBluetoothScanPermission;
@@ -1810,42 +1811,71 @@ public final class BluetoothDevice implements Parcelable, Attributable {
        return defaultValue;
    }

    /*
    private static final String BLUETOOTH_BONDING_CACHE_PROPERTY =
            "cache_key.bluetooth.get_bond_state";
    private final PropertyInvalidatedCache<BluetoothDevice, Integer> mBluetoothBondCache =
            new PropertyInvalidatedCache<BluetoothDevice, Integer>(
                8, BLUETOOTH_BONDING_CACHE_PROPERTY) {
    /**
     * There are several instances of PropertyInvalidatedCache used in this class.
     * BluetoothCache wraps up the common code.  All caches are created with a maximum of
     * eight entries, and the key is in the bluetooth module.  The name is set to the api.
     */
    private static class BluetoothCache<Q, R> extends PropertyInvalidatedCache<Q, R> {
        BluetoothCache(String api, PropertyInvalidatedCache.QueryHandler query) {
            super(8, PropertyInvalidatedCache.MODULE_BLUETOOTH, api, api, query);
        }};

    /**
     * Invalidate a bluetooth cache.  This method is just a short-hand wrapper that
     * enforces the bluetooth module.
     */
    private static void invalidateCache(@NonNull String api) {
        PropertyInvalidatedCache.invalidateCache(PropertyInvalidatedCache.MODULE_BLUETOOTH, api);
    }

    private final
            PropertyInvalidatedCache.QueryHandler<BluetoothDevice, Integer> mBluetoothBondQuery =
            new PropertyInvalidatedCache.QueryHandler<>() {
                @RequiresLegacyBluetoothPermission
                @RequiresBluetoothConnectPermission
                @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
                @Override
                @SuppressLint("AndroidFrameworkRequiresPermission")
                public Integer recompute(BluetoothDevice query) {
                    final int defaultValue = BluetoothDevice.BOND_NONE;
                public Integer apply(BluetoothDevice query) {
                    if (DBG) log("getBondState() uncached");
                    final IBluetooth service = sService;
                    final int defaultValue = BOND_NONE;
                    if (service == null) {
                        Log.e(TAG, "BT not enabled. Cannot get bond state");
                        if (DBG) log(Log.getStackTraceString(new Throwable()));
                    } else {
                        try {
                            final SynchronousResultReceiver<Integer> recv =
                                    new SynchronousResultReceiver();
                        sService.getBondState(query, mAttributionSource, recv);
                        return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
                            service.getBondState(BluetoothDevice.this, mAttributionSource, recv);
                            return recv.awaitResultNoInterrupt(getSyncTimeout())
                                            .getValue(defaultValue);
                        } catch (TimeoutException e) {
                        Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
                            Log.e(TAG, e.toString() + "\n"
                                    + Log.getStackTraceString(new Throwable()));
                        } catch (RemoteException e) {
                        throw e.rethrowAsRuntimeException();
                            Log.e(TAG, "failed to ", e);
                            e.rethrowFromSystemServer();
                        }
                    }
                    return defaultValue;
                }
            };
     */

    private static final String GET_BOND_STATE_API = "getBondState";

    private final BluetoothCache<BluetoothDevice, Integer> mBluetoothBondCache =
        new BluetoothCache<BluetoothDevice, Integer>(GET_BOND_STATE_API, mBluetoothBondQuery);

    /** @hide */
    /* public void disableBluetoothGetBondStateCache() {
        mBluetoothBondCache.disableLocal();
    } */
    public void disableBluetoothGetBondStateCache() {
        mBluetoothBondCache.disableForCurrentProcess();
    }

    /** @hide */
    /*
    public static void invalidateBluetoothGetBondStateCache() {
        PropertyInvalidatedCache.invalidateCache(BLUETOOTH_BONDING_CACHE_PROPERTY);
        invalidateCache(GET_BOND_STATE_API);
    }
     */

    /**
     * Get the bond state of the remote device.
@@ -1862,25 +1892,7 @@ public final class BluetoothDevice implements Parcelable, Attributable {
    @SuppressLint("AndroidFrameworkRequiresPermission")
    public int getBondState() {
        if (DBG) log("getBondState()");
        final IBluetooth service = sService;
        final int defaultValue = BOND_NONE;
        if (service == null) {
            Log.e(TAG, "BT not enabled. Cannot get bond state");
            if (DBG) log(Log.getStackTraceString(new Throwable()));
        } else {
            try {
                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
                //return mBluetoothBondCache.query(this);
                service.getBondState(this, mAttributionSource, recv);
                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
            } catch (TimeoutException e) {
                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
            } catch (RemoteException e) {
                Log.e(TAG, "failed to ", e);
                e.rethrowFromSystemServer();
            }
        }
        return defaultValue;
        return mBluetoothBondCache.query(null);
    }

    /**