diff options
| author | Treehugger Robot <treehugger-gerrit@google.com> | 2021-09-02 08:56:28 +0000 |
|---|---|---|
| committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2021-09-02 08:56:28 +0000 |
| commit | d5720420b8b5b15a50f3c19fd43e7314636540ec (patch) | |
| tree | 47876ef063ff9d07d04dc542a66186d2294e0382 | |
| parent | 64a4c76336833441b299dca6573baa67c337457b (diff) | |
| parent | 0e3c71daa7debc6f2e7de26e9e9255eb4b4b7fad (diff) | |
| download | platform_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
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(""); } /** |
