Loading services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +4 −4 Original line number Diff line number Diff line Loading @@ -103,10 +103,10 @@ import com.android.server.companion.datatransfer.SystemDataTransferRequestStore; import com.android.server.companion.datatransfer.contextsync.CrossDeviceCall; import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncController; import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncControllerCallback; import com.android.server.companion.presence.CompanionAppBinder; import com.android.server.companion.presence.DevicePresenceProcessor; import com.android.server.companion.presence.ObservableUuid; import com.android.server.companion.presence.ObservableUuidStore; import com.android.server.companion.devicepresence.CompanionAppBinder; import com.android.server.companion.devicepresence.DevicePresenceProcessor; import com.android.server.companion.devicepresence.ObservableUuid; import com.android.server.companion.devicepresence.ObservableUuidStore; import com.android.server.companion.transport.CompanionTransportManager; import com.android.server.pm.UserManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal; Loading services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java +2 −2 Original line number Diff line number Diff line Loading @@ -36,8 +36,8 @@ import com.android.server.companion.association.DisassociationProcessor; import com.android.server.companion.datatransfer.SystemDataTransferProcessor; import com.android.server.companion.datatransfer.contextsync.BitmapUtils; import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncController; import com.android.server.companion.presence.DevicePresenceProcessor; import com.android.server.companion.presence.ObservableUuid; import com.android.server.companion.devicepresence.DevicePresenceProcessor; import com.android.server.companion.devicepresence.ObservableUuid; import com.android.server.companion.transport.CompanionTransportManager; import java.io.PrintWriter; Loading services/companion/java/com/android/server/companion/association/DisassociationProcessor.java +2 −2 Original line number Diff line number Diff line Loading @@ -37,8 +37,8 @@ import android.os.UserHandle; import android.util.Slog; import com.android.server.companion.datatransfer.SystemDataTransferRequestStore; import com.android.server.companion.presence.CompanionAppBinder; import com.android.server.companion.presence.DevicePresenceProcessor; import com.android.server.companion.devicepresence.CompanionAppBinder; import com.android.server.companion.devicepresence.DevicePresenceProcessor; import com.android.server.companion.transport.CompanionTransportManager; /** Loading services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java→services/companion/java/com/android/server/companion/devicepresence/BleDeviceProcessor.java +22 −122 Original line number Diff line number Diff line Loading @@ -15,27 +15,15 @@ */ package com.android.server.companion.presence; package com.android.server.companion.devicepresence; import static android.bluetooth.BluetoothAdapter.ACTION_BLE_STATE_CHANGED; import static android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED; import static android.bluetooth.BluetoothAdapter.EXTRA_PREVIOUS_STATE; import static android.bluetooth.BluetoothAdapter.EXTRA_STATE; import static android.bluetooth.BluetoothAdapter.nameForState; import static android.bluetooth.le.ScanCallback.SCAN_FAILED_ALREADY_STARTED; import static android.bluetooth.le.ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED; import static android.bluetooth.le.ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED; import static android.bluetooth.le.ScanCallback.SCAN_FAILED_INTERNAL_ERROR; import static android.bluetooth.le.ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES; import static android.bluetooth.le.ScanCallback.SCAN_FAILED_SCANNING_TOO_FREQUENTLY; import static android.bluetooth.le.ScanSettings.CALLBACK_TYPE_ALL_MATCHES; import static android.bluetooth.le.ScanSettings.CALLBACK_TYPE_FIRST_MATCH; import static android.bluetooth.le.ScanSettings.CALLBACK_TYPE_MATCH_LOST; import static android.bluetooth.le.ScanSettings.SCAN_MODE_LOW_POWER; import static com.android.server.companion.presence.DevicePresenceProcessor.DEBUG; import static com.android.server.companion.utils.Utils.btDeviceToString; import static java.util.Objects.requireNonNull; import android.annotation.MainThread; Loading @@ -56,21 +44,19 @@ import android.content.Intent; import android.content.IntentFilter; import android.os.Handler; import android.os.Looper; import android.util.Log; import android.util.Slog; import com.android.server.companion.association.AssociationStore; import com.android.server.companion.association.AssociationStore.ChangeType; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; @SuppressLint("LongLogTag") class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { private static final String TAG = "CDM_BleCompanionDeviceScanner"; class BleDeviceProcessor implements AssociationStore.OnChangeListener { private static final String TAG = "CDM_BleDeviceProcessor"; interface Callback { void onBleCompanionDeviceFound(int associationId, int userId); Loading @@ -78,26 +64,27 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { void onBleCompanionDeviceLost(int associationId, int userId); } private final @NonNull AssociationStore mAssociationStore; private final @NonNull Callback mCallback; @NonNull private final AssociationStore mAssociationStore; @NonNull private final Callback mCallback; // Non-null after init(). private @Nullable BluetoothAdapter mBtAdapter; @Nullable private BluetoothAdapter mBtAdapter; // Non-null after init() and when BLE is available. Otherwise - null. private @Nullable BluetoothLeScanner mBleScanner; @Nullable private BluetoothLeScanner mBleScanner; // Only accessed from the Main thread. private boolean mScanning = false; BleCompanionDeviceScanner( @NonNull AssociationStore associationStore, @NonNull Callback callback) { BleDeviceProcessor(@NonNull AssociationStore associationStore, @NonNull Callback callback) { mAssociationStore = associationStore; mCallback = callback; } @MainThread void init(@NonNull Context context, @NonNull BluetoothAdapter btAdapter) { if (DEBUG) Log.i(TAG, "init()"); if (mBtAdapter != null) { throw new IllegalStateException(getClass().getSimpleName() + " is already initialized"); } Loading @@ -113,9 +100,7 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { final void restartScan() { enforceInitialized(); if (DEBUG) Log.i(TAG , "restartScan()"); if (mBleScanner == null) { if (DEBUG) Log.d(TAG, " > BLE is not available"); return; } Loading @@ -138,12 +123,8 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { enforceInitialized(); final boolean bleAvailable = mBtAdapter.isLeEnabled(); if (DEBUG) { Log.i(TAG, "checkBleState() bleAvailable=" + bleAvailable); } if ((bleAvailable && mBleScanner != null) || (!bleAvailable && mBleScanner == null)) { // Nothing changed. if (DEBUG) Log.i(TAG, " > BLE status did not change"); return; } Loading @@ -153,12 +134,9 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { // Oops, that's a race condition. Can return. return; } if (DEBUG) Log.i(TAG, " > BLE is now available"); startScan(); } else { if (DEBUG) Log.i(TAG, " > BLE is now unavailable"); stopScanIfNeeded(); mBleScanner = null; } Loading Loading @@ -194,13 +172,7 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { } } if (macAddresses.isEmpty()) { if (DEBUG) Log.i(TAG, " > there are no (associated) devices to Scan for."); return; } else { if (DEBUG) { Log.d(TAG, " > addresses=(n=" + macAddresses.size() + ")" + "[" + String.join(", ", macAddresses) + "]"); } } final List<ScanFilter> filters = new ArrayList<>(macAddresses.size()); Loading Loading @@ -230,7 +202,6 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { Slog.i(TAG, "stopBleScan()"); if (!mScanning) { if (DEBUG) Log.d(TAG, " > not scanning."); return; } // mScanCallback is non-null here - it cannot be null when mScanning is true. Loading @@ -252,26 +223,16 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { @MainThread private void notifyDeviceFound(@NonNull BluetoothDevice device) { if (DEBUG) Log.i(TAG, "notifyDevice_Found()" + btDeviceToString(device)); final List<AssociationInfo> associations = mAssociationStore.getActiveAssociationsByAddress(device.getAddress()); if (DEBUG) Log.d(TAG, " > associations=" + Arrays.toString(associations.toArray())); for (AssociationInfo association : associations) { for (AssociationInfo association : mAssociationStore.getActiveAssociationsByAddress( device.getAddress())) { mCallback.onBleCompanionDeviceFound(association.getId(), association.getUserId()); } } @MainThread private void notifyDeviceLost(@NonNull BluetoothDevice device) { if (DEBUG) Log.i(TAG, "notifyDevice_Lost()" + btDeviceToString(device)); final List<AssociationInfo> associations = mAssociationStore.getActiveAssociationsByAddress(device.getAddress()); if (DEBUG) Log.d(TAG, " > associations=" + Arrays.toString(associations.toArray())); for (AssociationInfo association : associations) { for (AssociationInfo association : mAssociationStore.getActiveAssociationsByAddress( device.getAddress())) { mCallback.onBleCompanionDeviceLost(association.getId(), association.getUserId()); } } Loading @@ -280,17 +241,6 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { final BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final int prevState = intent.getIntExtra(EXTRA_PREVIOUS_STATE, -1); final int state = intent.getIntExtra(EXTRA_STATE, -1); if (DEBUG) { // The action is either STATE_CHANGED or BLE_STATE_CHANGED. final String action = intent.getAction().replace("android.bluetooth.adapter.", "bt."); Log.d(TAG, "on(Broadcast)Receive() " + action + ": " + nameForBtState(prevState) + "->" + nameForBtState(state)); } checkBleState(); } }; Loading @@ -313,16 +263,6 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { public void onScanResult(int callbackType, ScanResult result) { final BluetoothDevice device = result.getDevice(); if (DEBUG) { Log.d(TAG, "onScanResult() " + nameForBleScanCallbackType(callbackType) + " device=" + btDeviceToString(device)); Log.v(TAG, " > scanResult=" + result); final List<AssociationInfo> associations = mAssociationStore.getActiveAssociationsByAddress(device.getAddress()); Log.v(TAG, " > associations=" + Arrays.toString(associations.toArray())); } switch (callbackType) { case CALLBACK_TYPE_FIRST_MATCH: notifyDeviceFound(device); Loading @@ -342,60 +282,20 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { @MainThread @Override public void onScanFailed(int errorCode) { if (DEBUG) Log.w(TAG, "onScanFailed() " + nameForBleScanErrorCode(errorCode)); mScanning = false; } }; private static String nameForBtState(int state) { return nameForState(state) + "(" + state + ")"; } private static String nameForBleScanCallbackType(int callbackType) { final String name; switch (callbackType) { case CALLBACK_TYPE_ALL_MATCHES: name = "ALL_MATCHES"; break; case CALLBACK_TYPE_FIRST_MATCH: name = "FIRST_MATCH"; break; case CALLBACK_TYPE_MATCH_LOST: name = "MATCH_LOST"; break; default: name = "Unknown"; } final String name = switch (callbackType) { case CALLBACK_TYPE_ALL_MATCHES -> "ALL_MATCHES"; case CALLBACK_TYPE_FIRST_MATCH -> "FIRST_MATCH"; case CALLBACK_TYPE_MATCH_LOST -> "MATCH_LOST"; default -> "Unknown"; }; return name + "(" + callbackType + ")"; } private static String nameForBleScanErrorCode(int errorCode) { final String name; switch (errorCode) { case SCAN_FAILED_ALREADY_STARTED: name = "ALREADY_STARTED"; break; case SCAN_FAILED_APPLICATION_REGISTRATION_FAILED: name = "APPLICATION_REGISTRATION_FAILED"; break; case SCAN_FAILED_INTERNAL_ERROR: name = "INTERNAL_ERROR"; break; case SCAN_FAILED_FEATURE_UNSUPPORTED: name = "FEATURE_UNSUPPORTED"; break; case SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES: name = "OUT_OF_HARDWARE_RESOURCES"; break; case SCAN_FAILED_SCANNING_TOO_FREQUENTLY: name = "SCANNING_TOO_FREQUENTLY"; break; default: name = "Unknown"; } return name + "(" + errorCode + ")"; } private static final ScanSettings SCAN_SETTINGS = new ScanSettings.Builder() .setCallbackType(CALLBACK_TYPE_FIRST_MATCH | CALLBACK_TYPE_MATCH_LOST) .setScanMode(SCAN_MODE_LOW_POWER) Loading services/companion/java/com/android/server/companion/presence/BluetoothCompanionDeviceConnectionListener.java→services/companion/java/com/android/server/companion/devicepresence/BluetoothDeviceProcessor.java +21 −73 Original line number Diff line number Diff line Loading @@ -14,14 +14,11 @@ * limitations under the License. */ package com.android.server.companion.presence; package com.android.server.companion.devicepresence; import static android.companion.DevicePresenceEvent.EVENT_BT_CONNECTED; import static android.companion.DevicePresenceEvent.EVENT_BT_DISCONNECTED; import static com.android.server.companion.presence.DevicePresenceProcessor.DEBUG; import static com.android.server.companion.utils.Utils.btDeviceToString; import android.annotation.NonNull; import android.annotation.SuppressLint; import android.bluetooth.BluetoothAdapter; Loading @@ -32,8 +29,6 @@ import android.os.Handler; import android.os.HandlerExecutor; import android.os.ParcelUuid; import android.os.UserHandle; import android.os.UserManager; import android.util.Log; import com.android.internal.util.ArrayUtils; import com.android.server.companion.association.AssociationStore; Loading @@ -45,10 +40,10 @@ import java.util.List; import java.util.Map; @SuppressLint("LongLogTag") public class BluetoothCompanionDeviceConnectionListener public class BluetoothDeviceProcessor extends BluetoothAdapter.BluetoothConnectionCallback implements AssociationStore.OnChangeListener { private static final String TAG = "CDM_BluetoothCompanionDeviceConnectionListener"; private static final String TAG = "CDM_BluetoothDeviceProcessor"; interface Callback { void onBluetoothCompanionDeviceConnected(int associationId, int userId); Loading @@ -58,24 +53,25 @@ public class BluetoothCompanionDeviceConnectionListener void onDevicePresenceEventByUuid(ObservableUuid uuid, int event); } private final @NonNull AssociationStore mAssociationStore; private final @NonNull Callback mCallback; /** A set of ALL connected BT device (not only companion.) */ private final @NonNull Map<MacAddress, BluetoothDevice> mAllConnectedDevices = new HashMap<>(); @NonNull private final AssociationStore mAssociationStore; @NonNull private final ObservableUuidStore mObservableUuidStore; @NonNull private final Callback mCallback; private final @NonNull ObservableUuidStore mObservableUuidStore; /** A set of ALL connected BT device (not only companion.) */ @NonNull private final Map<MacAddress, BluetoothDevice> mAllConnectedDevices = new HashMap<>(); BluetoothCompanionDeviceConnectionListener(UserManager userManager, @NonNull AssociationStore associationStore, BluetoothDeviceProcessor(@NonNull AssociationStore associationStore, @NonNull ObservableUuidStore observableUuidStore, @NonNull Callback callback) { mAssociationStore = associationStore; mObservableUuidStore = observableUuidStore; mCallback = callback; } public void init(@NonNull BluetoothAdapter btAdapter) { if (DEBUG) Log.i(TAG, "init()"); void init(@NonNull BluetoothAdapter btAdapter) { btAdapter.registerBluetoothConnectionCallback( new HandlerExecutor(Handler.getMain()), /* callback */this); mAssociationStore.registerLocalListener(this); Loading @@ -87,13 +83,9 @@ public class BluetoothCompanionDeviceConnectionListener */ @Override public void onDeviceConnected(@NonNull BluetoothDevice device) { if (DEBUG) Log.i(TAG, "onDevice_Connected() " + btDeviceToString(device)); final MacAddress macAddress = MacAddress.fromString(device.getAddress()); final int userId = UserHandle.myUserId(); if (mAllConnectedDevices.put(macAddress, device) != null) { if (DEBUG) Log.w(TAG, "Device " + btDeviceToString(device) + " is already connected."); return; } Loading @@ -108,18 +100,9 @@ public class BluetoothCompanionDeviceConnectionListener @Override public void onDeviceDisconnected(@NonNull BluetoothDevice device, int reason) { if (DEBUG) { Log.i(TAG, "onDevice_Disconnected() " + btDeviceToString(device)); Log.d(TAG, " reason=" + disconnectReasonToString(reason)); } final MacAddress macAddress = MacAddress.fromString(device.getAddress()); final int userId = UserHandle.myUserId(); if (mAllConnectedDevices.remove(macAddress) == null) { if (DEBUG) { Log.w(TAG, "The device wasn't tracked as connected " + btDeviceToString(device)); } return; } Loading @@ -130,22 +113,6 @@ public class BluetoothCompanionDeviceConnectionListener int userId = UserHandle.myUserId(); final List<AssociationInfo> associations = mAssociationStore.getActiveAssociationsByAddress(device.getAddress()); final List<ObservableUuid> observableUuids = mObservableUuidStore.getObservableUuidsForUser(userId); final ParcelUuid[] bluetoothDeviceUuids = device.getUuids(); final List<ParcelUuid> deviceUuids = ArrayUtils.isEmpty(bluetoothDeviceUuids) ? Collections.emptyList() : Arrays.asList(bluetoothDeviceUuids); if (DEBUG) { Log.d(TAG, "onDevice_ConnectivityChanged() " + btDeviceToString(device) + " connected=" + connected); if (associations.isEmpty()) { Log.d(TAG, " > No CDM associations"); } else { Log.d(TAG, " > associations=" + Arrays.toString(associations.toArray())); } } for (AssociationInfo association : associations) { if (!association.isNotifyOnDeviceNearby()) continue; Loading @@ -157,6 +124,12 @@ public class BluetoothCompanionDeviceConnectionListener } } final List<ObservableUuid> observableUuids = mObservableUuidStore.getObservableUuidsForUser(userId); final ParcelUuid[] bluetoothDeviceUuids = device.getUuids(); final List<ParcelUuid> deviceUuids = ArrayUtils.isEmpty(bluetoothDeviceUuids) ? Collections.emptyList() : Arrays.asList(bluetoothDeviceUuids); for (ObservableUuid uuid : observableUuids) { if (deviceUuids.contains(uuid.getUuid())) { mCallback.onDevicePresenceEventByUuid(uuid, connected ? EVENT_BT_CONNECTED Loading @@ -167,34 +140,9 @@ public class BluetoothCompanionDeviceConnectionListener @Override public void onAssociationAdded(AssociationInfo association) { if (DEBUG) Log.d(TAG, "onAssociation_Added() " + association); if (mAllConnectedDevices.containsKey(association.getDeviceMacAddress())) { mCallback.onBluetoothCompanionDeviceConnected( association.getId(), association.getUserId()); } } @Override public void onAssociationRemoved(AssociationInfo association) { // Intentionally do nothing: CompanionDevicePresenceMonitor will do all the bookkeeping // required. } @Override public void onAssociationUpdated(AssociationInfo association, boolean addressChanged) { if (DEBUG) { Log.d(TAG, "onAssociation_Updated() addrChange=" + addressChanged + " " + association); } if (!addressChanged) { // Don't need to do anything. return; } // At the moment CDM does allow changing association addresses, so we will never come here. // This will be implemented when CDM support updating addresses. throw new IllegalArgumentException("Address changes are not supported."); } } Loading
services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +4 −4 Original line number Diff line number Diff line Loading @@ -103,10 +103,10 @@ import com.android.server.companion.datatransfer.SystemDataTransferRequestStore; import com.android.server.companion.datatransfer.contextsync.CrossDeviceCall; import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncController; import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncControllerCallback; import com.android.server.companion.presence.CompanionAppBinder; import com.android.server.companion.presence.DevicePresenceProcessor; import com.android.server.companion.presence.ObservableUuid; import com.android.server.companion.presence.ObservableUuidStore; import com.android.server.companion.devicepresence.CompanionAppBinder; import com.android.server.companion.devicepresence.DevicePresenceProcessor; import com.android.server.companion.devicepresence.ObservableUuid; import com.android.server.companion.devicepresence.ObservableUuidStore; import com.android.server.companion.transport.CompanionTransportManager; import com.android.server.pm.UserManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal; Loading
services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java +2 −2 Original line number Diff line number Diff line Loading @@ -36,8 +36,8 @@ import com.android.server.companion.association.DisassociationProcessor; import com.android.server.companion.datatransfer.SystemDataTransferProcessor; import com.android.server.companion.datatransfer.contextsync.BitmapUtils; import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncController; import com.android.server.companion.presence.DevicePresenceProcessor; import com.android.server.companion.presence.ObservableUuid; import com.android.server.companion.devicepresence.DevicePresenceProcessor; import com.android.server.companion.devicepresence.ObservableUuid; import com.android.server.companion.transport.CompanionTransportManager; import java.io.PrintWriter; Loading
services/companion/java/com/android/server/companion/association/DisassociationProcessor.java +2 −2 Original line number Diff line number Diff line Loading @@ -37,8 +37,8 @@ import android.os.UserHandle; import android.util.Slog; import com.android.server.companion.datatransfer.SystemDataTransferRequestStore; import com.android.server.companion.presence.CompanionAppBinder; import com.android.server.companion.presence.DevicePresenceProcessor; import com.android.server.companion.devicepresence.CompanionAppBinder; import com.android.server.companion.devicepresence.DevicePresenceProcessor; import com.android.server.companion.transport.CompanionTransportManager; /** Loading
services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java→services/companion/java/com/android/server/companion/devicepresence/BleDeviceProcessor.java +22 −122 Original line number Diff line number Diff line Loading @@ -15,27 +15,15 @@ */ package com.android.server.companion.presence; package com.android.server.companion.devicepresence; import static android.bluetooth.BluetoothAdapter.ACTION_BLE_STATE_CHANGED; import static android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED; import static android.bluetooth.BluetoothAdapter.EXTRA_PREVIOUS_STATE; import static android.bluetooth.BluetoothAdapter.EXTRA_STATE; import static android.bluetooth.BluetoothAdapter.nameForState; import static android.bluetooth.le.ScanCallback.SCAN_FAILED_ALREADY_STARTED; import static android.bluetooth.le.ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED; import static android.bluetooth.le.ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED; import static android.bluetooth.le.ScanCallback.SCAN_FAILED_INTERNAL_ERROR; import static android.bluetooth.le.ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES; import static android.bluetooth.le.ScanCallback.SCAN_FAILED_SCANNING_TOO_FREQUENTLY; import static android.bluetooth.le.ScanSettings.CALLBACK_TYPE_ALL_MATCHES; import static android.bluetooth.le.ScanSettings.CALLBACK_TYPE_FIRST_MATCH; import static android.bluetooth.le.ScanSettings.CALLBACK_TYPE_MATCH_LOST; import static android.bluetooth.le.ScanSettings.SCAN_MODE_LOW_POWER; import static com.android.server.companion.presence.DevicePresenceProcessor.DEBUG; import static com.android.server.companion.utils.Utils.btDeviceToString; import static java.util.Objects.requireNonNull; import android.annotation.MainThread; Loading @@ -56,21 +44,19 @@ import android.content.Intent; import android.content.IntentFilter; import android.os.Handler; import android.os.Looper; import android.util.Log; import android.util.Slog; import com.android.server.companion.association.AssociationStore; import com.android.server.companion.association.AssociationStore.ChangeType; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; @SuppressLint("LongLogTag") class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { private static final String TAG = "CDM_BleCompanionDeviceScanner"; class BleDeviceProcessor implements AssociationStore.OnChangeListener { private static final String TAG = "CDM_BleDeviceProcessor"; interface Callback { void onBleCompanionDeviceFound(int associationId, int userId); Loading @@ -78,26 +64,27 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { void onBleCompanionDeviceLost(int associationId, int userId); } private final @NonNull AssociationStore mAssociationStore; private final @NonNull Callback mCallback; @NonNull private final AssociationStore mAssociationStore; @NonNull private final Callback mCallback; // Non-null after init(). private @Nullable BluetoothAdapter mBtAdapter; @Nullable private BluetoothAdapter mBtAdapter; // Non-null after init() and when BLE is available. Otherwise - null. private @Nullable BluetoothLeScanner mBleScanner; @Nullable private BluetoothLeScanner mBleScanner; // Only accessed from the Main thread. private boolean mScanning = false; BleCompanionDeviceScanner( @NonNull AssociationStore associationStore, @NonNull Callback callback) { BleDeviceProcessor(@NonNull AssociationStore associationStore, @NonNull Callback callback) { mAssociationStore = associationStore; mCallback = callback; } @MainThread void init(@NonNull Context context, @NonNull BluetoothAdapter btAdapter) { if (DEBUG) Log.i(TAG, "init()"); if (mBtAdapter != null) { throw new IllegalStateException(getClass().getSimpleName() + " is already initialized"); } Loading @@ -113,9 +100,7 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { final void restartScan() { enforceInitialized(); if (DEBUG) Log.i(TAG , "restartScan()"); if (mBleScanner == null) { if (DEBUG) Log.d(TAG, " > BLE is not available"); return; } Loading @@ -138,12 +123,8 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { enforceInitialized(); final boolean bleAvailable = mBtAdapter.isLeEnabled(); if (DEBUG) { Log.i(TAG, "checkBleState() bleAvailable=" + bleAvailable); } if ((bleAvailable && mBleScanner != null) || (!bleAvailable && mBleScanner == null)) { // Nothing changed. if (DEBUG) Log.i(TAG, " > BLE status did not change"); return; } Loading @@ -153,12 +134,9 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { // Oops, that's a race condition. Can return. return; } if (DEBUG) Log.i(TAG, " > BLE is now available"); startScan(); } else { if (DEBUG) Log.i(TAG, " > BLE is now unavailable"); stopScanIfNeeded(); mBleScanner = null; } Loading Loading @@ -194,13 +172,7 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { } } if (macAddresses.isEmpty()) { if (DEBUG) Log.i(TAG, " > there are no (associated) devices to Scan for."); return; } else { if (DEBUG) { Log.d(TAG, " > addresses=(n=" + macAddresses.size() + ")" + "[" + String.join(", ", macAddresses) + "]"); } } final List<ScanFilter> filters = new ArrayList<>(macAddresses.size()); Loading Loading @@ -230,7 +202,6 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { Slog.i(TAG, "stopBleScan()"); if (!mScanning) { if (DEBUG) Log.d(TAG, " > not scanning."); return; } // mScanCallback is non-null here - it cannot be null when mScanning is true. Loading @@ -252,26 +223,16 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { @MainThread private void notifyDeviceFound(@NonNull BluetoothDevice device) { if (DEBUG) Log.i(TAG, "notifyDevice_Found()" + btDeviceToString(device)); final List<AssociationInfo> associations = mAssociationStore.getActiveAssociationsByAddress(device.getAddress()); if (DEBUG) Log.d(TAG, " > associations=" + Arrays.toString(associations.toArray())); for (AssociationInfo association : associations) { for (AssociationInfo association : mAssociationStore.getActiveAssociationsByAddress( device.getAddress())) { mCallback.onBleCompanionDeviceFound(association.getId(), association.getUserId()); } } @MainThread private void notifyDeviceLost(@NonNull BluetoothDevice device) { if (DEBUG) Log.i(TAG, "notifyDevice_Lost()" + btDeviceToString(device)); final List<AssociationInfo> associations = mAssociationStore.getActiveAssociationsByAddress(device.getAddress()); if (DEBUG) Log.d(TAG, " > associations=" + Arrays.toString(associations.toArray())); for (AssociationInfo association : associations) { for (AssociationInfo association : mAssociationStore.getActiveAssociationsByAddress( device.getAddress())) { mCallback.onBleCompanionDeviceLost(association.getId(), association.getUserId()); } } Loading @@ -280,17 +241,6 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { final BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final int prevState = intent.getIntExtra(EXTRA_PREVIOUS_STATE, -1); final int state = intent.getIntExtra(EXTRA_STATE, -1); if (DEBUG) { // The action is either STATE_CHANGED or BLE_STATE_CHANGED. final String action = intent.getAction().replace("android.bluetooth.adapter.", "bt."); Log.d(TAG, "on(Broadcast)Receive() " + action + ": " + nameForBtState(prevState) + "->" + nameForBtState(state)); } checkBleState(); } }; Loading @@ -313,16 +263,6 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { public void onScanResult(int callbackType, ScanResult result) { final BluetoothDevice device = result.getDevice(); if (DEBUG) { Log.d(TAG, "onScanResult() " + nameForBleScanCallbackType(callbackType) + " device=" + btDeviceToString(device)); Log.v(TAG, " > scanResult=" + result); final List<AssociationInfo> associations = mAssociationStore.getActiveAssociationsByAddress(device.getAddress()); Log.v(TAG, " > associations=" + Arrays.toString(associations.toArray())); } switch (callbackType) { case CALLBACK_TYPE_FIRST_MATCH: notifyDeviceFound(device); Loading @@ -342,60 +282,20 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { @MainThread @Override public void onScanFailed(int errorCode) { if (DEBUG) Log.w(TAG, "onScanFailed() " + nameForBleScanErrorCode(errorCode)); mScanning = false; } }; private static String nameForBtState(int state) { return nameForState(state) + "(" + state + ")"; } private static String nameForBleScanCallbackType(int callbackType) { final String name; switch (callbackType) { case CALLBACK_TYPE_ALL_MATCHES: name = "ALL_MATCHES"; break; case CALLBACK_TYPE_FIRST_MATCH: name = "FIRST_MATCH"; break; case CALLBACK_TYPE_MATCH_LOST: name = "MATCH_LOST"; break; default: name = "Unknown"; } final String name = switch (callbackType) { case CALLBACK_TYPE_ALL_MATCHES -> "ALL_MATCHES"; case CALLBACK_TYPE_FIRST_MATCH -> "FIRST_MATCH"; case CALLBACK_TYPE_MATCH_LOST -> "MATCH_LOST"; default -> "Unknown"; }; return name + "(" + callbackType + ")"; } private static String nameForBleScanErrorCode(int errorCode) { final String name; switch (errorCode) { case SCAN_FAILED_ALREADY_STARTED: name = "ALREADY_STARTED"; break; case SCAN_FAILED_APPLICATION_REGISTRATION_FAILED: name = "APPLICATION_REGISTRATION_FAILED"; break; case SCAN_FAILED_INTERNAL_ERROR: name = "INTERNAL_ERROR"; break; case SCAN_FAILED_FEATURE_UNSUPPORTED: name = "FEATURE_UNSUPPORTED"; break; case SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES: name = "OUT_OF_HARDWARE_RESOURCES"; break; case SCAN_FAILED_SCANNING_TOO_FREQUENTLY: name = "SCANNING_TOO_FREQUENTLY"; break; default: name = "Unknown"; } return name + "(" + errorCode + ")"; } private static final ScanSettings SCAN_SETTINGS = new ScanSettings.Builder() .setCallbackType(CALLBACK_TYPE_FIRST_MATCH | CALLBACK_TYPE_MATCH_LOST) .setScanMode(SCAN_MODE_LOW_POWER) Loading
services/companion/java/com/android/server/companion/presence/BluetoothCompanionDeviceConnectionListener.java→services/companion/java/com/android/server/companion/devicepresence/BluetoothDeviceProcessor.java +21 −73 Original line number Diff line number Diff line Loading @@ -14,14 +14,11 @@ * limitations under the License. */ package com.android.server.companion.presence; package com.android.server.companion.devicepresence; import static android.companion.DevicePresenceEvent.EVENT_BT_CONNECTED; import static android.companion.DevicePresenceEvent.EVENT_BT_DISCONNECTED; import static com.android.server.companion.presence.DevicePresenceProcessor.DEBUG; import static com.android.server.companion.utils.Utils.btDeviceToString; import android.annotation.NonNull; import android.annotation.SuppressLint; import android.bluetooth.BluetoothAdapter; Loading @@ -32,8 +29,6 @@ import android.os.Handler; import android.os.HandlerExecutor; import android.os.ParcelUuid; import android.os.UserHandle; import android.os.UserManager; import android.util.Log; import com.android.internal.util.ArrayUtils; import com.android.server.companion.association.AssociationStore; Loading @@ -45,10 +40,10 @@ import java.util.List; import java.util.Map; @SuppressLint("LongLogTag") public class BluetoothCompanionDeviceConnectionListener public class BluetoothDeviceProcessor extends BluetoothAdapter.BluetoothConnectionCallback implements AssociationStore.OnChangeListener { private static final String TAG = "CDM_BluetoothCompanionDeviceConnectionListener"; private static final String TAG = "CDM_BluetoothDeviceProcessor"; interface Callback { void onBluetoothCompanionDeviceConnected(int associationId, int userId); Loading @@ -58,24 +53,25 @@ public class BluetoothCompanionDeviceConnectionListener void onDevicePresenceEventByUuid(ObservableUuid uuid, int event); } private final @NonNull AssociationStore mAssociationStore; private final @NonNull Callback mCallback; /** A set of ALL connected BT device (not only companion.) */ private final @NonNull Map<MacAddress, BluetoothDevice> mAllConnectedDevices = new HashMap<>(); @NonNull private final AssociationStore mAssociationStore; @NonNull private final ObservableUuidStore mObservableUuidStore; @NonNull private final Callback mCallback; private final @NonNull ObservableUuidStore mObservableUuidStore; /** A set of ALL connected BT device (not only companion.) */ @NonNull private final Map<MacAddress, BluetoothDevice> mAllConnectedDevices = new HashMap<>(); BluetoothCompanionDeviceConnectionListener(UserManager userManager, @NonNull AssociationStore associationStore, BluetoothDeviceProcessor(@NonNull AssociationStore associationStore, @NonNull ObservableUuidStore observableUuidStore, @NonNull Callback callback) { mAssociationStore = associationStore; mObservableUuidStore = observableUuidStore; mCallback = callback; } public void init(@NonNull BluetoothAdapter btAdapter) { if (DEBUG) Log.i(TAG, "init()"); void init(@NonNull BluetoothAdapter btAdapter) { btAdapter.registerBluetoothConnectionCallback( new HandlerExecutor(Handler.getMain()), /* callback */this); mAssociationStore.registerLocalListener(this); Loading @@ -87,13 +83,9 @@ public class BluetoothCompanionDeviceConnectionListener */ @Override public void onDeviceConnected(@NonNull BluetoothDevice device) { if (DEBUG) Log.i(TAG, "onDevice_Connected() " + btDeviceToString(device)); final MacAddress macAddress = MacAddress.fromString(device.getAddress()); final int userId = UserHandle.myUserId(); if (mAllConnectedDevices.put(macAddress, device) != null) { if (DEBUG) Log.w(TAG, "Device " + btDeviceToString(device) + " is already connected."); return; } Loading @@ -108,18 +100,9 @@ public class BluetoothCompanionDeviceConnectionListener @Override public void onDeviceDisconnected(@NonNull BluetoothDevice device, int reason) { if (DEBUG) { Log.i(TAG, "onDevice_Disconnected() " + btDeviceToString(device)); Log.d(TAG, " reason=" + disconnectReasonToString(reason)); } final MacAddress macAddress = MacAddress.fromString(device.getAddress()); final int userId = UserHandle.myUserId(); if (mAllConnectedDevices.remove(macAddress) == null) { if (DEBUG) { Log.w(TAG, "The device wasn't tracked as connected " + btDeviceToString(device)); } return; } Loading @@ -130,22 +113,6 @@ public class BluetoothCompanionDeviceConnectionListener int userId = UserHandle.myUserId(); final List<AssociationInfo> associations = mAssociationStore.getActiveAssociationsByAddress(device.getAddress()); final List<ObservableUuid> observableUuids = mObservableUuidStore.getObservableUuidsForUser(userId); final ParcelUuid[] bluetoothDeviceUuids = device.getUuids(); final List<ParcelUuid> deviceUuids = ArrayUtils.isEmpty(bluetoothDeviceUuids) ? Collections.emptyList() : Arrays.asList(bluetoothDeviceUuids); if (DEBUG) { Log.d(TAG, "onDevice_ConnectivityChanged() " + btDeviceToString(device) + " connected=" + connected); if (associations.isEmpty()) { Log.d(TAG, " > No CDM associations"); } else { Log.d(TAG, " > associations=" + Arrays.toString(associations.toArray())); } } for (AssociationInfo association : associations) { if (!association.isNotifyOnDeviceNearby()) continue; Loading @@ -157,6 +124,12 @@ public class BluetoothCompanionDeviceConnectionListener } } final List<ObservableUuid> observableUuids = mObservableUuidStore.getObservableUuidsForUser(userId); final ParcelUuid[] bluetoothDeviceUuids = device.getUuids(); final List<ParcelUuid> deviceUuids = ArrayUtils.isEmpty(bluetoothDeviceUuids) ? Collections.emptyList() : Arrays.asList(bluetoothDeviceUuids); for (ObservableUuid uuid : observableUuids) { if (deviceUuids.contains(uuid.getUuid())) { mCallback.onDevicePresenceEventByUuid(uuid, connected ? EVENT_BT_CONNECTED Loading @@ -167,34 +140,9 @@ public class BluetoothCompanionDeviceConnectionListener @Override public void onAssociationAdded(AssociationInfo association) { if (DEBUG) Log.d(TAG, "onAssociation_Added() " + association); if (mAllConnectedDevices.containsKey(association.getDeviceMacAddress())) { mCallback.onBluetoothCompanionDeviceConnected( association.getId(), association.getUserId()); } } @Override public void onAssociationRemoved(AssociationInfo association) { // Intentionally do nothing: CompanionDevicePresenceMonitor will do all the bookkeeping // required. } @Override public void onAssociationUpdated(AssociationInfo association, boolean addressChanged) { if (DEBUG) { Log.d(TAG, "onAssociation_Updated() addrChange=" + addressChanged + " " + association); } if (!addressChanged) { // Don't need to do anything. return; } // At the moment CDM does allow changing association addresses, so we will never come here. // This will be implemented when CDM support updating addresses. throw new IllegalArgumentException("Address changes are not supported."); } }