summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Evan Chen <evanxinchen@google.com> 2023-04-27 19:31:02 +0000
committer Evan Chen <evanxinchen@google.com> 2023-05-01 22:55:21 +0000
commitf745fd611b22c6b13cb4d942947bd97cdf53af6b (patch)
tree587be0fa81e8f67d24d916e1e3a94a6254ada09a
parentd7fd5e789a617ab0762bb8525f4708c0b055fe71 (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
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java20
-rw-r--r--services/companion/java/com/android/server/companion/presence/BluetoothCompanionDeviceConnectionListener.java54
-rw-r--r--services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java21
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;