summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2021-09-02 08:56:28 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2021-09-02 08:56:28 +0000
commitd5720420b8b5b15a50f3c19fd43e7314636540ec (patch)
tree47876ef063ff9d07d04dc542a66186d2294e0382
parent64a4c76336833441b299dca6573baa67c337457b (diff)
parent0e3c71daa7debc6f2e7de26e9e9255eb4b4b7fad (diff)
downloadplatform_packages_apps_Nfc-d5720420b8b5b15a50f3c19fd43e7314636540ec.tar.gz
platform_packages_apps_Nfc-d5720420b8b5b15a50f3c19fd43e7314636540ec.tar.bz2
platform_packages_apps_Nfc-d5720420b8b5b15a50f3c19fd43e7314636540ec.zip
Merge "Support multi users for NFC payments"android-s-beta-5android-s-beta-5
-rw-r--r--src/com/android/nfc/NfcService.java29
-rw-r--r--src/com/android/nfc/cardemulation/CardEmulationManager.java10
-rw-r--r--src/com/android/nfc/cardemulation/HostEmulationManager.java2
-rw-r--r--src/com/android/nfc/cardemulation/PreferredServices.java12
-rw-r--r--src/com/android/nfc/cardemulation/RegisteredNfcFServicesCache.java60
-rw-r--r--src/com/android/nfc/cardemulation/RegisteredServicesCache.java67
6 files changed, 148 insertions, 32 deletions
diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java
index b0b0c29b..f5d34be5 100644
--- a/src/com/android/nfc/NfcService.java
+++ b/src/com/android/nfc/NfcService.java
@@ -525,6 +525,15 @@ public class NfcService implements DeviceHostListener {
filter.addAction(Intent.ACTION_USER_SWITCHED);
mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null);
+ // Listen for work profile adds or removes.
+ IntentFilter managedProfileFilter = new IntentFilter();
+ managedProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
+ managedProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
+ managedProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
+ managedProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
+ mContext.registerReceiverAsUser(mManagedProfileReceiver, UserHandle.ALL,
+ managedProfileFilter, null, null);
+
IntentFilter ownerFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
ownerFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
ownerFilter.addAction(Intent.ACTION_SHUTDOWN);
@@ -3200,6 +3209,26 @@ public class NfcService implements DeviceHostListener {
}
};
+ private final BroadcastReceiver mManagedProfileReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
+
+ // User should be filled for below intents, check the existence.
+ if (user == null) {
+ Log.d(TAG, intent.getAction() + " broadcast without EXTRA_USER.");
+ return;
+ }
+
+ if (action.equals(Intent.ACTION_MANAGED_PROFILE_ADDED) ||
+ action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) ||
+ action.equals(Intent.ACTION_MANAGED_PROFILE_REMOVED) ||
+ action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)) {
+ mCardEmulationManager.onManagedProfileChanged();
+ }
+ }
+ };
private final BroadcastReceiver mOwnerReceiver = new BroadcastReceiver() {
@Override
diff --git a/src/com/android/nfc/cardemulation/CardEmulationManager.java b/src/com/android/nfc/cardemulation/CardEmulationManager.java
index a2fee532..70b4cd87 100644
--- a/src/com/android/nfc/cardemulation/CardEmulationManager.java
+++ b/src/com/android/nfc/cardemulation/CardEmulationManager.java
@@ -152,14 +152,20 @@ public class CardEmulationManager implements RegisteredServicesCache.Callback,
public void onUserSwitched(int userId) {
// for HCE
- mServiceCache.invalidateCache(userId);
+ mServiceCache.onUserSwitched();
mPreferredServices.onUserSwitched(userId);
// for HCE-F
mHostNfcFEmulationManager.onUserSwitched();
mT3tIdentifiersCache.onUserSwitched();
mEnabledNfcFServices.onUserSwitched(userId);
mNfcFServicesCache.onUserSwitched();
- mNfcFServicesCache.invalidateCache(userId);
+ }
+
+ public void onManagedProfileChanged() {
+ // for HCE
+ mServiceCache.onManagedProfileChanged();
+ // for HCE-F
+ mNfcFServicesCache.onManagedProfileChanged();
}
public void onNfcEnabled() {
diff --git a/src/com/android/nfc/cardemulation/HostEmulationManager.java b/src/com/android/nfc/cardemulation/HostEmulationManager.java
index c00f1502..f25306ba 100644
--- a/src/com/android/nfc/cardemulation/HostEmulationManager.java
+++ b/src/com/android/nfc/cardemulation/HostEmulationManager.java
@@ -379,11 +379,11 @@ public class HostEmulationManager {
Intent intent = new Intent(HostApduService.SERVICE_INTERFACE);
intent.setComponent(service);
- mLastBoundPaymentServiceName = service;
if (mContext.bindServiceAsUser(intent, mPaymentConnection,
Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS,
new UserHandle(userId))) {
mPaymentServiceBound = true;
+ mLastBoundPaymentServiceName = service;
} else {
Log.e(TAG, "Could not bind (persistent) payment service.");
}
diff --git a/src/com/android/nfc/cardemulation/PreferredServices.java b/src/com/android/nfc/cardemulation/PreferredServices.java
index 533ae96b..e51f6fc1 100644
--- a/src/com/android/nfc/cardemulation/PreferredServices.java
+++ b/src/com/android/nfc/cardemulation/PreferredServices.java
@@ -109,7 +109,7 @@ public class PreferredServices implements com.android.nfc.ForegroundUtils.Callba
true, mSettingsObserver, UserHandle.USER_ALL);
// Load current settings defaults for payments
- loadDefaultsFromSettings(ActivityManager.getCurrentUser());
+ loadDefaultsFromSettings(ActivityManager.getCurrentUser(), false);
}
private final class SettingsObserver extends ContentObserver {
@@ -124,11 +124,11 @@ public class PreferredServices implements com.android.nfc.ForegroundUtils.Callba
// a change made for another user, we'll sync it down
// on user switch.
int currentUser = ActivityManager.getCurrentUser();
- loadDefaultsFromSettings(currentUser);
+ loadDefaultsFromSettings(currentUser, false);
}
};
- void loadDefaultsFromSettings(int userId) {
+ void loadDefaultsFromSettings(int userId, boolean force) {
boolean paymentDefaultChanged = false;
boolean paymentPreferForegroundChanged = false;
// Load current payment default from settings
@@ -158,10 +158,10 @@ public class PreferredServices implements com.android.nfc.ForegroundUtils.Callba
}
}
// Notify if anything changed
- if (paymentDefaultChanged) {
+ if (paymentDefaultChanged || force) {
mCallback.onPreferredPaymentServiceChanged(newDefault);
}
- if (paymentPreferForegroundChanged) {
+ if (paymentPreferForegroundChanged || force) {
computePreferredForegroundService();
}
}
@@ -359,7 +359,7 @@ public class PreferredServices implements com.android.nfc.ForegroundUtils.Callba
}
public void onUserSwitched(int userId) {
- loadDefaultsFromSettings(userId);
+ loadDefaultsFromSettings(userId, true);
}
public boolean packageHasPreferredService(String packageName) {
diff --git a/src/com/android/nfc/cardemulation/RegisteredNfcFServicesCache.java b/src/com/android/nfc/cardemulation/RegisteredNfcFServicesCache.java
index d46b5a2f..698c8a73 100644
--- a/src/com/android/nfc/cardemulation/RegisteredNfcFServicesCache.java
+++ b/src/com/android/nfc/cardemulation/RegisteredNfcFServicesCache.java
@@ -16,10 +16,6 @@
package com.android.nfc.cardemulation;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -27,23 +23,28 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.nfc.cardemulation.NfcFServiceInfo;
-import android.nfc.cardemulation.NfcFCardEmulation;
import android.nfc.cardemulation.HostNfcFService;
+import android.nfc.cardemulation.NfcFCardEmulation;
+import android.nfc.cardemulation.NfcFServiceInfo;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.os.UserManager;
import android.util.AtomicFile;
import android.util.Log;
import android.util.SparseArray;
import android.util.Xml;
import android.util.proto.ProtoOutputStream;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.FastXmlSerializer;
import com.google.android.collect.Maps;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
import java.io.File;
import java.io.FileDescriptor;
@@ -70,6 +71,10 @@ public class RegisteredNfcFServicesCache {
final Object mLock = new Object();
// All variables below synchronized on mLock
+ // mUserHandles holds the UserHandles of all the profiles that belong to current user
+ @GuardedBy("mLock")
+ List<UserHandle> mUserHandles;
+
// mUserServices holds the card emulation services that are running for each user
final SparseArray<UserServices> mUserServices = new SparseArray<UserServices>();
final Callback mCallback;
@@ -126,6 +131,8 @@ public class RegisteredNfcFServicesCache {
mContext = context;
mCallback = callback;
+ refreshUserProfilesLocked();
+
final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -176,8 +183,10 @@ public class RegisteredNfcFServicesCache {
void initialize() {
synchronized (mLock) {
readDynamicSystemCodeNfcid2Locked();
+ for (UserHandle uh : mUserHandles) {
+ invalidateCache(uh.getIdentifier());
+ }
}
- invalidateCache(ActivityManager.getCurrentUser());
}
void dump(ArrayList<NfcFServiceInfo> services) {
@@ -702,7 +711,29 @@ public class RegisteredNfcFServicesCache {
public void onUserSwitched() {
synchronized (mLock) {
mUserSwitched = true;
+ refreshUserProfilesLocked();
+ }
+ }
+
+ public void onManagedProfileChanged() {
+ synchronized (mLock) {
+ refreshUserProfilesLocked();
+ }
+ }
+
+ private void refreshUserProfilesLocked() {
+ UserManager um = mContext.createContextAsUser(
+ UserHandle.of(ActivityManager.getCurrentUser()), /*flags=*/0)
+ .getSystemService(UserManager.class);
+ mUserHandles = um.getEnabledProfiles();
+ List<UserHandle> removeUserHandles = new ArrayList<UserHandle>();
+
+ for (UserHandle uh : mUserHandles) {
+ if (um.isQuietModeEnabled(uh)) {
+ removeUserHandles.add(uh);
+ }
}
+ mUserHandles.removeAll(removeUserHandles);
}
private String generateRandomNfcid2() {
@@ -719,12 +750,17 @@ public class RegisteredNfcFServicesCache {
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("Registered HCE-F services for current user: ");
synchronized (mLock) {
- UserServices userServices = findOrCreateUserLocked(ActivityManager.getCurrentUser());
- for (NfcFServiceInfo service : userServices.services.values()) {
- service.dump(fd, pw, args);
+ for (UserHandle uh : mUserHandles) {
+ UserManager um = mContext.createContextAsUser(
+ uh, /*flags=*/0).getSystemService(UserManager.class);
+ pw.println("User " + um.getUserName() + " : ");
+ UserServices userServices = findOrCreateUserLocked(uh.getIdentifier());
+ for (NfcFServiceInfo service : userServices.services.values()) {
+ service.dump(fd, pw, args);
+ pw.println("");
+ }
pw.println("");
}
- pw.println("");
}
}
diff --git a/src/com/android/nfc/cardemulation/RegisteredServicesCache.java b/src/com/android/nfc/cardemulation/RegisteredServicesCache.java
index b3a59b7f..14ddc3e1 100644
--- a/src/com/android/nfc/cardemulation/RegisteredServicesCache.java
+++ b/src/com/android/nfc/cardemulation/RegisteredServicesCache.java
@@ -16,10 +16,6 @@
package com.android.nfc.cardemulation;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -27,9 +23,9 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.nfc.cardemulation.AidGroup;
import android.nfc.cardemulation.ApduServiceInfo;
import android.nfc.cardemulation.CardEmulation;
@@ -37,15 +33,21 @@ import android.nfc.cardemulation.HostApduService;
import android.nfc.cardemulation.OffHostApduService;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.os.UserManager;
import android.util.AtomicFile;
import android.util.Log;
import android.util.SparseArray;
import android.util.Xml;
import android.util.proto.ProtoOutputStream;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.FastXmlSerializer;
import com.google.android.collect.Maps;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -78,6 +80,10 @@ public class RegisteredServicesCache {
final Object mLock = new Object();
// All variables below synchronized on mLock
+ // mUserHandles holds the UserHandles of all the profiles that belong to current user
+ @GuardedBy("mLock")
+ List<UserHandle> mUserHandles;
+
// mUserServices holds the card emulation services that are running for each user
final SparseArray<UserServices> mUserServices = new SparseArray<UserServices>();
final Callback mCallback;
@@ -120,6 +126,8 @@ public class RegisteredServicesCache {
mContext = context;
mCallback = callback;
+ refreshUserProfilesLocked();
+
final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -168,8 +176,37 @@ public class RegisteredServicesCache {
void initialize() {
synchronized (mLock) {
readDynamicSettingsLocked();
+ for (UserHandle uh : mUserHandles) {
+ invalidateCache(uh.getIdentifier());
+ }
+ }
+ }
+
+ public void onUserSwitched() {
+ synchronized (mLock) {
+ refreshUserProfilesLocked();
+ }
+ }
+
+ public void onManagedProfileChanged() {
+ synchronized (mLock) {
+ refreshUserProfilesLocked();
+ }
+ }
+
+ private void refreshUserProfilesLocked() {
+ UserManager um = mContext.createContextAsUser(
+ UserHandle.of(ActivityManager.getCurrentUser()), /*flags=*/0)
+ .getSystemService(UserManager.class);
+ mUserHandles = um.getEnabledProfiles();
+ List<UserHandle> removeUserHandles = new ArrayList<UserHandle>();
+
+ for (UserHandle uh : mUserHandles) {
+ if (um.isQuietModeEnabled(uh)) {
+ removeUserHandles.add(uh);
+ }
}
- invalidateCache(ActivityManager.getCurrentUser());
+ mUserHandles.removeAll(removeUserHandles);
}
void dump(ArrayList<ApduServiceInfo> services) {
@@ -651,12 +688,20 @@ public class RegisteredServicesCache {
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("Registered HCE services for current user: ");
- UserServices userServices = findOrCreateUserLocked(ActivityManager.getCurrentUser());
- for (ApduServiceInfo service : userServices.services.values()) {
- service.dump(fd, pw, args);
- pw.println("");
+
+ synchronized (mLock) {
+ for (UserHandle uh : mUserHandles) {
+ UserManager um = mContext.createContextAsUser(
+ uh, /*flags=*/0).getSystemService(UserManager.class);
+ pw.println("User " + um.getUserName() + " : ");
+ UserServices userServices = findOrCreateUserLocked(uh.getIdentifier());
+ for (ApduServiceInfo service : userServices.services.values()) {
+ service.dump(fd, pw, args);
+ pw.println("");
+ }
+ pw.println("");
+ }
}
- pw.println("");
}
/**