diff options
| author | 2023-04-27 19:31:02 +0000 | |
|---|---|---|
| committer | 2023-05-01 22:55:21 +0000 | |
| commit | f745fd611b22c6b13cb4d942947bd97cdf53af6b (patch) | |
| tree | 587be0fa81e8f67d24d916e1e3a94a6254ada09a | |
| parent | d7fd5e789a617ab0762bb8525f4708c0b055fe71 (diff) | |
Notify/bind app after the phone is unlocked
CDM is not able to bind the app before the phone is unlocked(if password was set)
if the app is not boot aware.
This cl contains:
1. Store the the device info when receive the BT.onDeviceConnected()
if !UserManager.isUserUnlockingOrUnlocked which means CDM received the bt callback before user unlock the phone.
2. Trigger the callback in SystemService.onUserUnlocked() if we find any devices info were stored
Bug: 235614233,276311331
Fix: 279789812
Test: manully test
Change-Id: I13ffc67bb5b1cf74b537f9fc0c12d883d6904034
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; |