diff options
3 files changed, 85 insertions, 10 deletions
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index 0172eaf03fa7..c8db662a7f49 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -54,6 +54,7 @@ import android.app.ActivityManagerInternal; import android.app.AppOpsManager; import android.app.NotificationManager; import android.app.PendingIntent; +import android.bluetooth.BluetoothDevice; import android.companion.AssociationInfo; import android.companion.AssociationRequest; import android.companion.DeviceNotAssociatedException; @@ -234,7 +235,7 @@ public class CompanionDeviceManagerService extends SystemService { loadAssociationsFromDisk(); mAssociationStore.registerListener(mAssociationStoreChangeListener); - mDevicePresenceMonitor = new CompanionDevicePresenceMonitor( + mDevicePresenceMonitor = new CompanionDevicePresenceMonitor(mUserManager, mAssociationStore, mDevicePresenceCallback); mAssociationRequestsProcessor = new AssociationRequestsProcessor( @@ -322,6 +323,23 @@ public class CompanionDeviceManagerService extends SystemService { MINUTES.toMillis(10)); } + @Override + public void onUserUnlocked(@NonNull TargetUser user) { + // Notify and bind the app after the phone is unlocked. + final int userId = user.getUserIdentifier(); + final Set<BluetoothDevice> blueToothDevices = + mDevicePresenceMonitor.getPendingConnectedDevices().get(userId); + if (blueToothDevices != null) { + for (BluetoothDevice bluetoothDevice : blueToothDevices) { + for (AssociationInfo ai: + mAssociationStore.getAssociationsByAddress(bluetoothDevice.getAddress())) { + Slog.i(TAG, "onUserUnlocked, device id( " + ai.getId() + " ) is connected"); + mDevicePresenceMonitor.onBluetoothCompanionDeviceConnected(ai.getId()); + } + } + } + } + @NonNull AssociationInfo getAssociationWithCallerChecks( @UserIdInt int userId, @NonNull String packageName, @NonNull String macAddress) { diff --git a/services/companion/java/com/android/server/companion/presence/BluetoothCompanionDeviceConnectionListener.java b/services/companion/java/com/android/server/companion/presence/BluetoothCompanionDeviceConnectionListener.java index f6b99b551ecb..a5410e448c7b 100644 --- a/services/companion/java/com/android/server/companion/presence/BluetoothCompanionDeviceConnectionListener.java +++ b/services/companion/java/com/android/server/companion/presence/BluetoothCompanionDeviceConnectionListener.java @@ -27,17 +27,24 @@ import android.companion.AssociationInfo; import android.net.MacAddress; import android.os.Handler; import android.os.HandlerExecutor; +import android.os.UserHandle; +import android.os.UserManager; import android.util.Log; +import android.util.Slog; +import android.util.SparseArray; +import com.android.internal.annotations.GuardedBy; import com.android.server.companion.AssociationStore; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; @SuppressLint("LongLogTag") -class BluetoothCompanionDeviceConnectionListener +public class BluetoothCompanionDeviceConnectionListener extends BluetoothAdapter.BluetoothConnectionCallback implements AssociationStore.OnChangeListener { private static final String TAG = "CDM_BluetoothCompanionDeviceConnectionListener"; @@ -48,15 +55,25 @@ class BluetoothCompanionDeviceConnectionListener void onBluetoothCompanionDeviceDisconnected(int associationId); } + private final UserManager mUserManager; 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<>(); - BluetoothCompanionDeviceConnectionListener(@NonNull AssociationStore associationStore, - @NonNull Callback callback) { + /** + * A structure hold the connected BT devices that are pending to be reported to the companion + * app when the user unlocks the local device per userId. + */ + @GuardedBy("mPendingConnectedDevices") + @NonNull + final SparseArray<Set<BluetoothDevice>> mPendingConnectedDevices = new SparseArray<>(); + + BluetoothCompanionDeviceConnectionListener(UserManager userManager, + @NonNull AssociationStore associationStore, @NonNull Callback callback) { mAssociationStore = associationStore; mCallback = callback; + mUserManager = userManager; } public void init(@NonNull BluetoothAdapter btAdapter) { @@ -76,12 +93,26 @@ class BluetoothCompanionDeviceConnectionListener 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; } + // Try to bind and notify the app after the phone is unlocked. + if (!mUserManager.isUserUnlockingOrUnlocked(UserHandle.myUserId())) { + Slog.i(TAG, "Current user is not in unlocking or unlocked stage yet. Notify " + + "the application when the phone is unlocked"); + synchronized (mPendingConnectedDevices) { + Set<BluetoothDevice> bluetoothDevices = mPendingConnectedDevices.get( + userId, new HashSet<>()); + bluetoothDevices.add(device); + mPendingConnectedDevices.put(userId, bluetoothDevices); + } - onDeviceConnectivityChanged(device, true); + } else { + onDeviceConnectivityChanged(device, true); + } } /** @@ -98,6 +129,8 @@ class BluetoothCompanionDeviceConnectionListener } 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)); @@ -105,6 +138,19 @@ class BluetoothCompanionDeviceConnectionListener return; } + // Do not need to report the connectivity since the user is not unlock the phone so + // that cdm is not bind with the app yet. + if (!mUserManager.isUserUnlockingOrUnlocked(userId)) { + synchronized (mPendingConnectedDevices) { + Set<BluetoothDevice> bluetoothDevices = mPendingConnectedDevices.get(userId); + if (bluetoothDevices != null) { + bluetoothDevices.remove(device); + } + } + + return; + } + onDeviceConnectivityChanged(device, false); } diff --git a/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java b/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java index 4010be922b2c..f6e9415a2a7e 100644 --- a/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java +++ b/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java @@ -23,13 +23,16 @@ import android.annotation.NonNull; import android.annotation.SuppressLint; import android.annotation.TestApi; import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; import android.companion.AssociationInfo; import android.content.Context; import android.os.Binder; import android.os.Handler; import android.os.Looper; import android.os.Message; +import android.os.UserManager; import android.util.Log; +import android.util.SparseArray; import com.android.server.companion.AssociationStore; @@ -86,13 +89,12 @@ public class CompanionDevicePresenceMonitor implements AssociationStore.OnChange private final SimulatedDevicePresenceSchedulerHelper mSchedulerHelper = new SimulatedDevicePresenceSchedulerHelper(); - public CompanionDevicePresenceMonitor(@NonNull AssociationStore associationStore, - @NonNull Callback callback) { + public CompanionDevicePresenceMonitor(UserManager userManager, + @NonNull AssociationStore associationStore, @NonNull Callback callback) { mAssociationStore = associationStore; mCallback = callback; - - mBtConnectionListener = new BluetoothCompanionDeviceConnectionListener(associationStore, - /* BluetoothCompanionDeviceConnectionListener.Callback */ this); + mBtConnectionListener = new BluetoothCompanionDeviceConnectionListener(userManager, + associationStore, /* BluetoothCompanionDeviceConnectionListener.Callback */ this); mBleScanner = new BleCompanionDeviceScanner(associationStore, /* BleCompanionDeviceScanner.Callback */ this); } @@ -298,6 +300,15 @@ public class CompanionDevicePresenceMonitor implements AssociationStore.OnChange // what's needed. } + /** + * Return a set of devices that pending to report connectivity + */ + public SparseArray<Set<BluetoothDevice>> getPendingConnectedDevices() { + synchronized (mBtConnectionListener.mPendingConnectedDevices) { + return mBtConnectionListener.mPendingConnectedDevices; + } + } + private static void enforceCallerShellOrRoot() { final int callingUid = Binder.getCallingUid(); if (callingUid == SHELL_UID || callingUid == ROOT_UID) return; |