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

Commit 381bfa01 authored by William Escande's avatar William Escande Committed by Gerrit Code Review
Browse files

Merge changes I1aef0faa,Ie08c7b47,Ia0aefd88,I2992e603

* changes:
  No longer bind to gatt from BluetoothManagerService
  Simplify StateChangeHandler
  Simplify bluetoothStateChange intent sent
  Remove impossible to reach code during user switch
parents 921d1c8c aa58f747
Loading
Loading
Loading
Loading
+123 −2
Original line number Original line Diff line number Diff line
@@ -65,6 +65,7 @@ import android.bluetooth.IBluetooth;
import android.bluetooth.IBluetoothActivityEnergyInfoListener;
import android.bluetooth.IBluetoothActivityEnergyInfoListener;
import android.bluetooth.IBluetoothCallback;
import android.bluetooth.IBluetoothCallback;
import android.bluetooth.IBluetoothConnectionCallback;
import android.bluetooth.IBluetoothConnectionCallback;
import android.bluetooth.IBluetoothGatt;
import android.bluetooth.IBluetoothMetadataListener;
import android.bluetooth.IBluetoothMetadataListener;
import android.bluetooth.IBluetoothOobDataCallback;
import android.bluetooth.IBluetoothOobDataCallback;
import android.bluetooth.IBluetoothPreferredAudioProfilesCallback;
import android.bluetooth.IBluetoothPreferredAudioProfilesCallback;
@@ -76,9 +77,11 @@ import android.bluetooth.UidTraffic;
import android.companion.CompanionDeviceManager;
import android.companion.CompanionDeviceManager;
import android.content.AttributionSource;
import android.content.AttributionSource;
import android.content.BroadcastReceiver;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.AsyncTask;
@@ -359,6 +362,7 @@ public class AdapterService extends Service {
    private BassClientService mBassClientService;
    private BassClientService mBassClientService;
    private BatteryService mBatteryService;
    private BatteryService mBatteryService;
    private BluetoothQualityReportNativeInterface mBluetoothQualityReportNativeInterface;
    private BluetoothQualityReportNativeInterface mBluetoothQualityReportNativeInterface;
    private IBluetoothGatt mBluetoothGatt;


    private volatile boolean mTestModeEnabled = false;
    private volatile boolean mTestModeEnabled = false;


@@ -412,6 +416,8 @@ public class AdapterService extends Service {
    private static final int MESSAGE_PROFILE_SERVICE_REGISTERED = 2;
    private static final int MESSAGE_PROFILE_SERVICE_REGISTERED = 2;
    private static final int MESSAGE_PROFILE_SERVICE_UNREGISTERED = 3;
    private static final int MESSAGE_PROFILE_SERVICE_UNREGISTERED = 3;
    private static final int MESSAGE_PREFERRED_AUDIO_PROFILES_AUDIO_FRAMEWORK_TIMEOUT = 4;
    private static final int MESSAGE_PREFERRED_AUDIO_PROFILES_AUDIO_FRAMEWORK_TIMEOUT = 4;
    private static final int MESSAGE_ON_PROFILE_SERVICE_BIND = 5;
    private static final int MESSAGE_ON_PROFILE_SERVICE_UNBIND = 6;


    class AdapterServiceHandler extends Handler {
    class AdapterServiceHandler extends Handler {
        @Override
        @Override
@@ -431,6 +437,14 @@ public class AdapterService extends Service {
                    verboseLog("handleMessage() - MESSAGE_PROFILE_SERVICE_UNREGISTERED");
                    verboseLog("handleMessage() - MESSAGE_PROFILE_SERVICE_UNREGISTERED");
                    unregisterProfileService((ProfileService) msg.obj);
                    unregisterProfileService((ProfileService) msg.obj);
                    break;
                    break;
                case MESSAGE_ON_PROFILE_SERVICE_BIND:
                    verboseLog("handleMessage() - MESSAGE_ON_PROFILE_SERVICE_BIND");
                    onGattBind((IBinder) msg.obj);
                    break;
                case MESSAGE_ON_PROFILE_SERVICE_UNBIND:
                    verboseLog("handleMessage() - MESSAGE_ON_PROFILE_SERVICE_UNBIND");
                    onGattUnbind();
                    break;
                case MESSAGE_PREFERRED_AUDIO_PROFILES_AUDIO_FRAMEWORK_TIMEOUT:
                case MESSAGE_PREFERRED_AUDIO_PROFILES_AUDIO_FRAMEWORK_TIMEOUT:
                    errorLog("handleMessage() - "
                    errorLog("handleMessage() - "
                            + "MESSAGE_PREFERRED_PROFILE_CHANGE_AUDIO_FRAMEWORK_TIMEOUT");
                            + "MESSAGE_PREFERRED_PROFILE_CHANGE_AUDIO_FRAMEWORK_TIMEOUT");
@@ -465,6 +479,22 @@ public class AdapterService extends Service {
            mRegisteredProfiles.remove(profile);
            mRegisteredProfiles.remove(profile);
        }
        }


        private void onGattBind(IBinder service) {
            mBluetoothGatt = IBluetoothGatt.Stub.asInterface(service);
            try {
                mBluetoothGatt.startService();
            } catch (RemoteException e) {
                Log.e(TAG, "onGattBind: RemoteException", e);
            }
        }

        private void onGattUnbind() {
            mBluetoothGatt = null;
            Log.e(
                    TAG,
                    "onGattUnbind: Gatt service has disconnected from AdapterService unexpectedly");
        }

        private void processProfileServiceStateChanged(ProfileService profile, int state) {
        private void processProfileServiceStateChanged(ProfileService profile, int state) {
            switch (state) {
            switch (state) {
                case BluetoothAdapter.STATE_ON:
                case BluetoothAdapter.STATE_ON:
@@ -842,7 +872,7 @@ public class AdapterService extends Service {
            Log.w(TAG,
            Log.w(TAG,
                    "GATT is configured off but the stack assumes it to be enabled. Start anyway.");
                    "GATT is configured off but the stack assumes it to be enabled. Start anyway.");
        }
        }
        setProfileServiceState(GattService.class, BluetoothAdapter.STATE_ON);
        startGattProfileService();
    }
    }


    void bringDownBle() {
    void bringDownBle() {
@@ -893,13 +923,66 @@ public class AdapterService extends Service {
        }
        }
    }
    }


    class GattServiceConnection implements ServiceConnection {
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            String name = componentName.getClassName();
            if (DBG) {
                Log.d(TAG, "GattServiceConnection.onServiceConnected: " + name);
            }
            if (!name.equals(GattService.class.getName())) {
                Log.e(TAG, "Unknown service connected: " + name);
                return;
            }
            mHandler.obtainMessage(MESSAGE_ON_PROFILE_SERVICE_BIND, service).sendToTarget();
        }

        public void onServiceDisconnected(ComponentName componentName) {
            // Called if we unexpectedly disconnect. This should never happen.
            String name = componentName.getClassName();
            Log.e(TAG, "GattServiceConnection.onServiceDisconnected: " + name);
            if (!name.equals(GattService.class.getName())) {
                Log.e(TAG, "Unknown service disconnected: " + name);
                return;
            }
            mHandler.sendEmptyMessage(MESSAGE_ON_PROFILE_SERVICE_UNBIND);
        }
    }

    private GattServiceConnection mGattConnection = new GattServiceConnection();

    private void startGattProfileService() {
        mStartedProfiles.add(GattService.class.getSimpleName());

        Intent intent = new Intent(this, GattService.class);
        if (!bindServiceAsUser(
                intent,
                mGattConnection,
                Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
                UserHandle.CURRENT)) {
            // This should never happen
            // unbindService will be called during stopGattProfileService triggered by AdapterState
            Log.e(TAG, "Error while binding to gatt. This Bluetooth session will timeout");
            unbindService(mGattConnection);
        }
    }

    private void stopGattProfileService() {
    private void stopGattProfileService() {
        mAdapterProperties.onBleDisable();
        mAdapterProperties.onBleDisable();
        if (mRunningProfiles.size() == 0) {
        if (mRunningProfiles.size() == 0) {
            debugLog("stopGattProfileService() - No profiles services to stop.");
            debugLog("stopGattProfileService() - No profiles services to stop.");
            mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED);
            mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED);
        }
        }
        setProfileServiceState(GattService.class, BluetoothAdapter.STATE_OFF);

        mStartedProfiles.remove(GattService.class.getSimpleName());

        try {
            if (mBluetoothGatt != null) {
                mBluetoothGatt.stopService();
            }
        } catch (RemoteException e) {
            Log.e(TAG, "stopGattProfileService: RemoteException", e);
        }
        unbindService(mGattConnection);
    }
    }


    private void invalidateBluetoothGetStateCache() {
    private void invalidateBluetoothGetStateCache() {
@@ -4715,6 +4798,30 @@ public class AdapterService extends Service {


            return service.getOffloadedTransportDiscoveryDataScanSupported();
            return service.getOffloadedTransportDiscoveryDataScanSupported();
        }
        }

        @Override
        public IBluetoothGatt getBluetoothGatt() {
            AdapterService service = getService();
            if (service == null) {
                return null;
            }
            return service.getBluetoothGatt();
        }

        @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
        @Override
        public void unregAllGattClient(
                AttributionSource source, SynchronousResultReceiver receiver) {
            try {
                AdapterService service = getService();
                if (service != null) {
                    service.unregAllGattClient(source);
                }
                receiver.send(null);
            } catch (RuntimeException e) {
                receiver.propagateException(e);
            }
        }
    }
    }


    /**
    /**
@@ -6237,6 +6344,20 @@ public class AdapterService extends Service {
        return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
        return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
    }
    }


    IBluetoothGatt getBluetoothGatt() {
        return mBluetoothGatt;
    }

    void unregAllGattClient(AttributionSource source) {
        if (mBluetoothGatt != null) {
            try {
                mBluetoothGatt.unregAll(source);
            } catch (RemoteException e) {
                Log.e(TAG, "Unable to disconnect all apps.", e);
            }
        }
    }

    /**
    /**
     * Notify the UID and package name of the app, and the address of associated active device
     * Notify the UID and package name of the app, and the address of associated active device
     *
     *
+10 −6
Original line number Original line Diff line number Diff line
@@ -280,6 +280,7 @@ public abstract class ProfileService extends Service {
    // Suppressed since this is called from framework
    // Suppressed since this is called from framework
    @SuppressLint("AndroidFrameworkRequiresPermission")
    @SuppressLint("AndroidFrameworkRequiresPermission")
    public void onDestroy() {
    public void onDestroy() {
        Log.v(mName, "onDestroy");
        cleanup();
        cleanup();
        if (mBinder != null) {
        if (mBinder != null) {
            mBinder.cleanup();
            mBinder.cleanup();
@@ -289,11 +290,13 @@ public abstract class ProfileService extends Service {
        super.onDestroy();
        super.onDestroy();
    }
    }


    @RequiresPermission(anyOf = {
    @RequiresPermission(
            anyOf = {
                android.Manifest.permission.MANAGE_USERS,
                android.Manifest.permission.MANAGE_USERS,
                android.Manifest.permission.INTERACT_ACROSS_USERS
                android.Manifest.permission.INTERACT_ACROSS_USERS
            })
            })
    private void doStart() {
    protected void doStart() {
        Log.v(mName, "doStart");
        if (mAdapter == null) {
        if (mAdapter == null) {
            Log.w(mName, "Can't start profile service: device does not have BT");
            Log.w(mName, "Can't start profile service: device does not have BT");
            return;
            return;
@@ -318,7 +321,8 @@ public abstract class ProfileService extends Service {
        mAdapterService.onProfileServiceStateChanged(this, BluetoothAdapter.STATE_ON);
        mAdapterService.onProfileServiceStateChanged(this, BluetoothAdapter.STATE_ON);
    }
    }


    private void doStop() {
    protected void doStop() {
        Log.v(mName, "doStop");
        if (mAdapterService == null || mAdapterService.isStartedProfile(mName)) {
        if (mAdapterService == null || mAdapterService.isStartedProfile(mName)) {
            Log.w(mName, "Unexpectedly do Stop, don't stop.");
            Log.w(mName, "Unexpectedly do Stop, don't stop.");
            return;
            return;
+30 −10
Original line number Original line Diff line number Diff line
@@ -84,8 +84,8 @@ import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AbstractionLayer;
import com.android.bluetooth.btservice.AbstractionLayer;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.BluetoothAdapterProxy;
import com.android.bluetooth.btservice.BluetoothAdapterProxy;
import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.btservice.CompanionManager;
import com.android.bluetooth.btservice.CompanionManager;
import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.util.NumberUtils;
import com.android.bluetooth.util.NumberUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
@@ -608,6 +608,34 @@ public class GattService extends ProfileService {
            return null;
            return null;
        }
        }


        @Override
        public void startService() {
            GattService service = mService;
            if (service == null) {
                Log.e(TAG, "startService: Service is null");
                return;
            }
            if (!Utils.checkConnectPermissionForDataDelivery(
                    service, null, "GattService startService")) {
                return;
            }
            service.doStart();
        }

        @Override
        public void stopService() {
            GattService service = mService;
            if (service == null) {
                Log.e(TAG, "stopService: Service is null");
                return;
            }
            if (!Utils.checkConnectPermissionForDataDelivery(
                    service, null, "GattService stopService")) {
                return;
            }
            service.doStop();
        }

        @Override
        @Override
        public void getDevicesMatchingConnectionStates(int[] states,
        public void getDevicesMatchingConnectionStates(int[] states,
                AttributionSource attributionSource, SynchronousResultReceiver receiver) {
                AttributionSource attributionSource, SynchronousResultReceiver receiver) {
@@ -1747,15 +1775,7 @@ public class GattService extends ProfileService {
        }
        }


        @Override
        @Override
        public void unregAll(AttributionSource source, SynchronousResultReceiver receiver) {
        public void unregAll(AttributionSource attributionSource) {
            try {
                unregAll(source);
                receiver.send(null);
            } catch (RuntimeException e) {
                receiver.propagateException(e);
            }
        }
        private void unregAll(AttributionSource attributionSource) {
            GattService service = getService();
            GattService service = getService();
            if (service == null) {
            if (service == null) {
                return;
                return;
+35 −30
Original line number Original line Diff line number Diff line
@@ -330,7 +330,7 @@ public class AdapterServiceFactoryResetTest {
        Log.e(TAG, "tearDown()");
        Log.e(TAG, "tearDown()");


        // Enable the stack to re-create the config. Next tests rely on it.
        // Enable the stack to re-create the config. Next tests rely on it.
        doEnable(0, false);
        doEnable();


        // Restores the foregroundUserId to the ID prior to the test setup
        // Restores the foregroundUserId to the ID prior to the test setup
        Utils.setForegroundUserId(mForegroundUserId);
        Utils.setForegroundUserId(mForegroundUserId);
@@ -353,55 +353,60 @@ public class AdapterServiceFactoryResetTest {
        }
        }
    }
    }


    private void doEnable(int invocationNumber, boolean onlyGatt) {
    private void doEnable() {
        Log.e(TAG, "doEnable() start");
        Log.e("AdapterServiceTest", "doEnable() start");
        Assert.assertFalse(mAdapterService.getState() == BluetoothAdapter.STATE_ON);
        Assert.assertFalse(mAdapterService.getState() == BluetoothAdapter.STATE_ON);


        int startServiceCalls;
        startServiceCalls = 2 * (onlyGatt ? 1 : 3); // Start and stop GATT + 2

        mAdapterService.enable(false);
        mAdapterService.enable(false);


        verifyStateChange(BluetoothAdapter.STATE_OFF, BluetoothAdapter.STATE_BLE_TURNING_ON,
        verifyStateChange(
                invocationNumber + 1, CONTEXT_SWITCH_MS);
                BluetoothAdapter.STATE_OFF,
                BluetoothAdapter.STATE_BLE_TURNING_ON,
                1,
                CONTEXT_SWITCH_MS);


        // Start GATT
        // Start GATT
        verify(mMockContext, timeout(GATT_START_TIME_MS).times(
        verify(mMockContext, timeout(GATT_START_TIME_MS).times(1))
                startServiceCalls * invocationNumber + 1)).startService(any());
                .bindServiceAsUser(any(), any(), anyInt(), any());
        mAdapterService.addProfile(mMockGattService);
        mAdapterService.addProfile(mMockGattService);
        mAdapterService.onProfileServiceStateChanged(mMockGattService, BluetoothAdapter.STATE_ON);
        mAdapterService.onProfileServiceStateChanged(mMockGattService, BluetoothAdapter.STATE_ON);


        verifyStateChange(BluetoothAdapter.STATE_BLE_TURNING_ON, BluetoothAdapter.STATE_BLE_ON,
        verifyStateChange(
                invocationNumber + 1, NATIVE_INIT_MS);
                BluetoothAdapter.STATE_BLE_TURNING_ON,
                BluetoothAdapter.STATE_BLE_ON,
                1,
                NATIVE_INIT_MS);


        mServiceBinder.startBrEdr(mAttributionSource);
        mServiceBinder.startBrEdr(mAttributionSource);


        verifyStateChange(BluetoothAdapter.STATE_BLE_ON, BluetoothAdapter.STATE_TURNING_ON,
        verifyStateChange(
                invocationNumber + 1, CONTEXT_SWITCH_MS);
                BluetoothAdapter.STATE_BLE_ON,
                BluetoothAdapter.STATE_TURNING_ON,
                1,
                CONTEXT_SWITCH_MS);


        if (!onlyGatt) {
        // Start Mock PBAP and PAN services
        // Start Mock PBAP and PAN services
            verify(mMockContext, timeout(ONE_SECOND_MS).times(
        verify(mMockContext, timeout(ONE_SECOND_MS).times(2)).startService(any());
                    startServiceCalls * invocationNumber + 3)).startService(any());


        mAdapterService.addProfile(mMockService);
        mAdapterService.addProfile(mMockService);
        mAdapterService.addProfile(mMockService2);
        mAdapterService.addProfile(mMockService2);
        mAdapterService.onProfileServiceStateChanged(mMockService, BluetoothAdapter.STATE_ON);
        mAdapterService.onProfileServiceStateChanged(mMockService, BluetoothAdapter.STATE_ON);
        mAdapterService.onProfileServiceStateChanged(mMockService2, BluetoothAdapter.STATE_ON);
        mAdapterService.onProfileServiceStateChanged(mMockService2, BluetoothAdapter.STATE_ON);
        }


        verifyStateChange(BluetoothAdapter.STATE_TURNING_ON, BluetoothAdapter.STATE_ON,
        verifyStateChange(
                invocationNumber + 1, PROFILE_SERVICE_TOGGLE_TIME_MS);
                BluetoothAdapter.STATE_TURNING_ON,
                BluetoothAdapter.STATE_ON,
                1,
                PROFILE_SERVICE_TOGGLE_TIME_MS);


        verify(mMockContext, timeout(CONTEXT_SWITCH_MS).times(2 * invocationNumber + 2))
        verify(mMockContext, timeout(CONTEXT_SWITCH_MS).times(2))
                .sendBroadcast(any(), eq(BLUETOOTH_SCAN),
                .sendBroadcast(any(), eq(BLUETOOTH_SCAN), any(Bundle.class));
                        any(Bundle.class));
        final int scanMode = mServiceBinder.getScanMode(mAttributionSource);
        final int scanMode = mServiceBinder.getScanMode(mAttributionSource);
        Assert.assertTrue(scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE
        Assert.assertTrue(scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE
                || scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
                || scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
        Assert.assertTrue(mAdapterService.getState() == BluetoothAdapter.STATE_ON);
        Assert.assertTrue(mAdapterService.getState() == BluetoothAdapter.STATE_ON);


        Log.e(TAG, "doEnable() complete success");
        Log.e("AdapterServiceTest", "doEnable() complete success");
    }
    }


    /**
    /**
@@ -434,7 +439,7 @@ public class AdapterServiceFactoryResetTest {
        Assert.assertFalse(AdapterServiceTest.isByteArrayAllZero(obfuscatedAddress2));
        Assert.assertFalse(AdapterServiceTest.isByteArrayAllZero(obfuscatedAddress2));
        Assert.assertFalse(Arrays.equals(obfuscatedAddress2,
        Assert.assertFalse(Arrays.equals(obfuscatedAddress2,
                obfuscatedAddress1));
                obfuscatedAddress1));
        doEnable(0, false);
        doEnable();
        byte[] obfuscatedAddress3 = mAdapterService.obfuscateAddress(device);
        byte[] obfuscatedAddress3 = mAdapterService.obfuscateAddress(device);
        Assert.assertTrue(obfuscatedAddress3.length > 0);
        Assert.assertTrue(obfuscatedAddress3.length > 0);
        Assert.assertFalse(AdapterServiceTest.isByteArrayAllZero(obfuscatedAddress3));
        Assert.assertFalse(AdapterServiceTest.isByteArrayAllZero(obfuscatedAddress3));
+74 −43

File changed.

Preview size limit exceeded, changes collapsed.

Loading