• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.nfc.cardemulation;
17 
18 import static android.content.pm.PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION;
19 import static android.nfc.cardemulation.CardEmulation.SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED;
20 
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.app.ActivityManager;
24 import android.app.role.RoleManager;
25 import android.content.ComponentName;
26 import android.content.Context;
27 import android.content.pm.ApplicationInfo;
28 import android.content.pm.PackageManager;
29 import android.content.pm.PackageManager.NameNotFoundException;
30 import android.nfc.ComponentNameAndUser;
31 import android.nfc.Constants;
32 import android.nfc.INfcCardEmulation;
33 import android.nfc.INfcEventCallback;
34 import android.nfc.INfcFCardEmulation;
35 import android.nfc.INfcOemExtensionCallback;
36 import android.nfc.NfcAdapter;
37 import android.nfc.NfcOemExtension;
38 import android.nfc.PackageAndUser;
39 import android.nfc.cardemulation.AidGroup;
40 import android.nfc.cardemulation.ApduServiceInfo;
41 import android.nfc.cardemulation.CardEmulation;
42 import android.nfc.cardemulation.NfcFServiceInfo;
43 import android.nfc.cardemulation.PollingFrame;
44 import android.os.Binder;
45 import android.os.Build;
46 import android.os.Looper;
47 import android.os.PowerManager;
48 import android.os.Process;
49 import android.os.RemoteCallbackList;
50 import android.os.RemoteException;
51 import android.os.SystemClock;
52 import android.os.SystemProperties;
53 import android.os.UserHandle;
54 import android.os.UserManager;
55 import android.provider.Settings;
56 import android.sysprop.NfcProperties;
57 import android.telephony.SubscriptionInfo;
58 import android.text.TextUtils;
59 import android.util.Log;
60 import android.util.proto.ProtoOutputStream;
61 
62 import com.android.internal.annotations.VisibleForTesting;
63 import com.android.nfc.DeviceConfigFacade;
64 import com.android.nfc.ExitFrame;
65 import com.android.nfc.ForegroundUtils;
66 import com.android.nfc.NfcEventLog;
67 import com.android.nfc.NfcInjector;
68 import com.android.nfc.NfcPermissions;
69 import com.android.nfc.NfcService;
70 import com.android.nfc.R;
71 import com.android.nfc.cardemulation.util.StatsdUtils;
72 import com.android.nfc.cardemulation.util.TelephonyUtils;
73 import com.android.nfc.flags.Flags;
74 import com.android.nfc.proto.NfcEventProto;
75 
76 import java.io.FileDescriptor;
77 import java.io.PrintWriter;
78 import java.util.ArrayList;
79 import java.util.Arrays;
80 import java.util.List;
81 import java.util.Objects;
82 import java.util.Optional;
83 import java.util.function.Consumer;
84 import java.util.function.Function;
85 import java.util.function.Supplier;
86 import java.util.regex.Pattern;
87 import java.util.stream.Collectors;
88 import java.util.stream.IntStream;
89 import java.util.stream.Stream;
90 
91 /**
92  * CardEmulationManager is the central entity
93  * responsible for delegating to individual components
94  * implementing card emulation:
95  * - RegisteredServicesCache keeping track of HCE and SE services on the device
96  * - RegisteredNfcFServicesCache keeping track of HCE-F services on the device
97  * - RegisteredAidCache keeping track of AIDs registered by those services and manages
98  *   the routing table in the NFCC.
99  * - RegisteredT3tIdentifiersCache keeping track of T3T Identifier registered by
100  *   those services and manages the routing table in the NFCC.
101  * - HostEmulationManager handles incoming APDUs for the host and forwards to HCE
102  *   services as necessary.
103  * - HostNfcFEmulationManager handles incoming NFC-F packets for the host and
104  *   forwards to HCE-F services as necessary.
105  */
106 public class CardEmulationManager implements RegisteredServicesCache.Callback,
107         RegisteredNfcFServicesCache.Callback, PreferredServices.Callback,
108         EnabledNfcFServices.Callback, WalletRoleObserver.Callback,
109         PreferredSubscriptionService.Callback,
110         HostEmulationManager.NfcAidRoutingListener {
111     static final String TAG = "CardEmulationManager";
112     static final boolean DBG = NfcProperties.debug_enabled().orElse(true);
113 
114     static final int NFC_HCE_APDU = 0x01;
115     static final int NFC_HCE_NFCF = 0x04;
116     /** Minimum AID length as per ISO7816 */
117     static final int MINIMUM_AID_LENGTH = 5;
118     /** Length of Select APDU header including length byte */
119     static final int SELECT_APDU_HDR_LENGTH = 5;
120     /** Length of the NDEF Tag application AID */
121     static final int NDEF_AID_LENGTH = 7;
122     /** AID of the NDEF Tag application Mapping Version 1.0 */
123     static final byte[] NDEF_AID_V1 =
124             new byte[] {(byte) 0xd2, 0x76, 0x00, 0x00, (byte) 0x85, 0x01, 0x00};
125     /** AID of the NDEF Tag application Mapping Version 2.0 */
126     static final byte[] NDEF_AID_V2 =
127             new byte[] {(byte) 0xd2, 0x76, 0x00, 0x00, (byte) 0x85, 0x01, 0x01};
128     /** Select APDU header */
129     static final byte[] SELECT_AID_HDR = new byte[] {0x00, (byte) 0xa4, 0x04, 0x00};
130     private static final int FIRMWARE_EXIT_FRAME_TIMEOUT_MS = 5000;
131 
132     final RegisteredAidCache mAidCache;
133     final RegisteredT3tIdentifiersCache mT3tIdentifiersCache;
134     final RegisteredServicesCache mServiceCache;
135     final RegisteredNfcFServicesCache mNfcFServicesCache;
136     final HostEmulationManager mHostEmulationManager;
137     final HostNfcFEmulationManager mHostNfcFEmulationManager;
138     final PreferredServices mPreferredServices;
139 
140     final WalletRoleObserver mWalletRoleObserver;
141     final EnabledNfcFServices mEnabledNfcFServices;
142     final Context mContext;
143     final CardEmulationInterface mCardEmulationInterface;
144     final NfcFCardEmulationInterface mNfcFCardEmulationInterface;
145     final PowerManager mPowerManager;
146     boolean mNotSkipAid;
147 
148     final ForegroundUtils mForegroundUtils;
149     private int mForegroundUid;
150 
151     private final RoutingOptionManager mRoutingOptionManager;
152     final byte[] mOffHostRouteUicc;
153     final byte[] mOffHostRouteEse;
154     private INfcOemExtensionCallback mNfcOemExtensionCallback;
155     private final NfcEventLog mNfcEventLog;
156     private final int mVendorApiLevel;
157     private PreferredSubscriptionService mPreferredSubscriptionService = null;
158     private TelephonyUtils mTelephonyUtils = null;
159     @Nullable
160     private final StatsdUtils mStatsdUtils;
161     private final DeviceConfigFacade mDeviceConfigFacade;
162     private final NfcInjector mNfcInjector;
163 
164     // TODO: Move this object instantiation and dependencies to NfcInjector.
CardEmulationManager(Context context, NfcInjector nfcInjector, DeviceConfigFacade deviceConfigFacade)165     public CardEmulationManager(Context context, NfcInjector nfcInjector,
166         DeviceConfigFacade deviceConfigFacade) {
167         mContext = context;
168         mNfcInjector = nfcInjector;
169         mCardEmulationInterface = new CardEmulationInterface();
170         mNfcFCardEmulationInterface = new NfcFCardEmulationInterface();
171         mForegroundUtils = ForegroundUtils.getInstance(
172             context.getSystemService(ActivityManager.class));
173         mWalletRoleObserver = new WalletRoleObserver(context,
174                 context.getSystemService(RoleManager.class), this, nfcInjector);
175 
176         mRoutingOptionManager = RoutingOptionManager.getInstance();
177         mOffHostRouteEse = mRoutingOptionManager.getOffHostRouteEse();
178         mOffHostRouteUicc = mRoutingOptionManager.getOffHostRouteUicc();
179         mRoutingOptionManager.readRoutingOptionsFromPrefs(mContext, deviceConfigFacade);
180 
181         mTelephonyUtils = TelephonyUtils.getInstance(mContext);
182         mTelephonyUtils.setMepMode(mRoutingOptionManager.getMepMode());
183 
184         mAidCache = new RegisteredAidCache(context, mWalletRoleObserver);
185         mT3tIdentifiersCache = new RegisteredT3tIdentifiersCache(context);
186         mHostEmulationManager =
187                 new HostEmulationManager(context, Looper.getMainLooper(), mAidCache, nfcInjector);
188         mHostNfcFEmulationManager = new HostNfcFEmulationManager(context, mT3tIdentifiersCache);
189         mServiceCache = new RegisteredServicesCache(context, this);
190         mNfcFServicesCache = new RegisteredNfcFServicesCache(context, this);
191         mPreferredServices = new PreferredServices(context, mServiceCache, mAidCache,
192                 mWalletRoleObserver, this);
193         mEnabledNfcFServices = new EnabledNfcFServices(
194                 context, mNfcFServicesCache, mT3tIdentifiersCache, this);
195         mPowerManager = context.getSystemService(PowerManager.class);
196         mNfcEventLog = nfcInjector.getNfcEventLog();
197         mVendorApiLevel = SystemProperties.getInt(
198                 "ro.vendor.api_level", Build.VERSION.DEVICE_INITIAL_SDK_INT);
199         mPreferredSubscriptionService = new PreferredSubscriptionService(mContext, this);
200         mStatsdUtils = nfcInjector.getStatsdUtils();
201         mDeviceConfigFacade = deviceConfigFacade;
202         initialize();
203     }
204 
205     @VisibleForTesting
CardEmulationManager(Context context, ForegroundUtils foregroundUtils, WalletRoleObserver walletRoleObserver, RegisteredAidCache registeredAidCache, RegisteredT3tIdentifiersCache registeredT3tIdentifiersCache, HostEmulationManager hostEmulationManager, HostNfcFEmulationManager hostNfcFEmulationManager, RegisteredServicesCache registeredServicesCache, RegisteredNfcFServicesCache registeredNfcFServicesCache, PreferredServices preferredServices, EnabledNfcFServices enabledNfcFServices, RoutingOptionManager routingOptionManager, PowerManager powerManager, NfcEventLog nfcEventLog, PreferredSubscriptionService preferredSubscriptionService, StatsdUtils statsdUtils, DeviceConfigFacade deviceConfigFacade, NfcInjector nfcInjector)206     CardEmulationManager(Context context,
207             ForegroundUtils foregroundUtils,
208             WalletRoleObserver walletRoleObserver,
209             RegisteredAidCache registeredAidCache,
210             RegisteredT3tIdentifiersCache registeredT3tIdentifiersCache,
211             HostEmulationManager hostEmulationManager,
212             HostNfcFEmulationManager hostNfcFEmulationManager,
213             RegisteredServicesCache registeredServicesCache,
214             RegisteredNfcFServicesCache registeredNfcFServicesCache,
215             PreferredServices preferredServices,
216             EnabledNfcFServices enabledNfcFServices,
217             RoutingOptionManager routingOptionManager,
218             PowerManager powerManager,
219             NfcEventLog nfcEventLog,
220             PreferredSubscriptionService preferredSubscriptionService,
221             StatsdUtils statsdUtils,
222             DeviceConfigFacade deviceConfigFacade,
223             NfcInjector nfcInjector) {
224         mContext = context;
225         mNfcInjector = nfcInjector;
226         mCardEmulationInterface = new CardEmulationInterface();
227         mNfcFCardEmulationInterface = new NfcFCardEmulationInterface();
228         mForegroundUtils = foregroundUtils;
229         mWalletRoleObserver = walletRoleObserver;
230         mAidCache = registeredAidCache;
231         mT3tIdentifiersCache = registeredT3tIdentifiersCache;
232         mHostEmulationManager = hostEmulationManager;
233         mHostNfcFEmulationManager = hostNfcFEmulationManager;
234         mServiceCache = registeredServicesCache;
235         mNfcFServicesCache = registeredNfcFServicesCache;
236         mPreferredServices = preferredServices;
237         mEnabledNfcFServices = enabledNfcFServices;
238         mPowerManager = powerManager;
239         mRoutingOptionManager = routingOptionManager;
240         mOffHostRouteEse = mRoutingOptionManager.getOffHostRouteEse();
241         mOffHostRouteUicc = mRoutingOptionManager.getOffHostRouteUicc();
242         mNfcEventLog = nfcEventLog;
243         mVendorApiLevel = SystemProperties.getInt(
244                 "ro.vendor.api_level", Build.VERSION.DEVICE_INITIAL_SDK_INT);
245         mPreferredSubscriptionService = preferredSubscriptionService;
246         mStatsdUtils = statsdUtils;
247         mDeviceConfigFacade = deviceConfigFacade;
248         initialize();
249     }
250 
setOemExtension(@ullable INfcOemExtensionCallback nfcOemExtensionCallback)251     public void setOemExtension(@Nullable INfcOemExtensionCallback nfcOemExtensionCallback) {
252         mNfcOemExtensionCallback = nfcOemExtensionCallback;
253         mHostEmulationManager.setOemExtension(mNfcOemExtensionCallback);
254         mAidCache.setOemExtension(nfcOemExtensionCallback);
255     }
256 
initialize()257     private void initialize() {
258         if (mPreferredSubscriptionService != null)
259             mPreferredSubscriptionService.initialize();
260         mServiceCache.initialize();
261         mNfcFServicesCache.initialize();
262         mForegroundUid = Process.INVALID_UID;
263         if (mWalletRoleObserver.isWalletRoleFeatureEnabled()) {
264             int currentUser = ActivityManager.getCurrentUser();
265             PackageAndUser roleHolder =
266                     mWalletRoleObserver.getDefaultWalletRoleHolder(currentUser);
267             onWalletRoleHolderChanged(roleHolder.getPackage(),
268                     roleHolder.getUserId());
269         }
270 
271         if (android.nfc.Flags.nfcEventListener()) {
272             mHostEmulationManager.setAidRoutingListener(this);
273         }
274     }
275 
getNfcCardEmulationInterface()276     public INfcCardEmulation getNfcCardEmulationInterface() {
277         return mCardEmulationInterface;
278     }
279 
getNfcFCardEmulationInterface()280     public INfcFCardEmulation getNfcFCardEmulationInterface() {
281         return mNfcFCardEmulationInterface;
282     }
283 
onPollingLoopDetected(List<PollingFrame> pollingFrames)284     public void onPollingLoopDetected(List<PollingFrame> pollingFrames) {
285         mHostEmulationManager.onPollingLoopDetected(pollingFrames);
286     }
287 
onObserveModeStateChanged(boolean enable)288     public void onObserveModeStateChanged(boolean enable) {
289         mHostEmulationManager.onObserveModeStateChange(enable);
290     }
291 
onFieldChangeDetected(boolean fieldOn)292     public void onFieldChangeDetected(boolean fieldOn) {
293         mHostEmulationManager.onFieldChangeDetected(fieldOn);
294     }
295 
onHostCardEmulationActivated(int technology)296     public void onHostCardEmulationActivated(int technology) {
297         if (mNfcOemExtensionCallback != null) {
298             try {
299                 mNfcOemExtensionCallback.onHceEventReceived(NfcOemExtension.HCE_ACTIVATE);
300             } catch (RemoteException e) {
301                 Log.e(TAG, "onHostCardEmulationActivated: failed", e);
302             }
303         }
304         if (mDeviceConfigFacade.getIndicateUserActivityForHce()
305                 && mPowerManager != null) {
306             // Use USER_ACTIVITY_FLAG_INDIRECT to applying power hints without resets
307             // the screen timeout
308             mPowerManager.userActivity(SystemClock.uptimeMillis(),
309                     PowerManager.USER_ACTIVITY_EVENT_TOUCH,
310                     PowerManager.USER_ACTIVITY_FLAG_INDIRECT);
311         }
312         if (technology == NFC_HCE_APDU) {
313             mHostEmulationManager.onHostEmulationActivated();
314             mPreferredServices.onHostEmulationActivated();
315             mNotSkipAid = false;
316         } else if (technology == NFC_HCE_NFCF) {
317             mHostNfcFEmulationManager.onHostEmulationActivated();
318             mNfcFServicesCache.onHostEmulationActivated();
319             mEnabledNfcFServices.onHostEmulationActivated();
320         }
321     }
322 
onHostCardEmulationData(int technology, byte[] data)323     public void onHostCardEmulationData(int technology, byte[] data) {
324         if (mNfcOemExtensionCallback != null) {
325             try {
326                 mNfcOemExtensionCallback.onHceEventReceived(NfcOemExtension.HCE_DATA_TRANSFERRED);
327             } catch (RemoteException e) {
328                 Log.e(TAG, "onHostCardEmulationData: failed", e);
329             }
330         }
331 
332         if (technology == NFC_HCE_APDU) {
333             mHostEmulationManager.onHostEmulationData(data);
334         } else if (technology == NFC_HCE_NFCF) {
335             mHostNfcFEmulationManager.onHostEmulationData(data);
336         }
337         // Don't trigger userActivity if it's selecting NDEF AID
338         if (mPowerManager != null && !(technology == NFC_HCE_APDU && isSkipAid(data))) {
339             // Caution!! USER_ACTIVITY_EVENT_TOUCH resets the screen timeout
340             mPowerManager.userActivity(SystemClock.uptimeMillis(),
341                     PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
342         }
343     }
344 
onHostCardEmulationDeactivated(int technology)345     public void onHostCardEmulationDeactivated(int technology) {
346         if (technology == NFC_HCE_APDU) {
347             mHostEmulationManager.onHostEmulationDeactivated();
348             mPreferredServices.onHostEmulationDeactivated();
349         } else if (technology == NFC_HCE_NFCF) {
350             mHostNfcFEmulationManager.onHostEmulationDeactivated();
351             mNfcFServicesCache.onHostEmulationDeactivated();
352             mEnabledNfcFServices.onHostEmulationDeactivated();
353         }
354         if (mNfcOemExtensionCallback != null) {
355             try {
356                 mNfcOemExtensionCallback.onHceEventReceived(NfcOemExtension.HCE_DEACTIVATE);
357             } catch (RemoteException e) {
358                 Log.e(TAG, "onHostCardEmulationDeactivated: failed", e);
359             }
360         }
361     }
362 
onOffHostAidSelected()363     public void onOffHostAidSelected() {
364         mHostEmulationManager.onOffHostAidSelected();
365     }
366 
onBootCompleted()367     public void onBootCompleted() {
368         mHostEmulationManager.onBootCompleted();
369         mServiceCache.onBootCompleted();
370     }
371 
onUserSwitched(int userId)372     public void onUserSwitched(int userId) {
373         mWalletRoleObserver.onUserSwitched(userId);
374         // for HCE
375         mServiceCache.onUserSwitched();
376         mPreferredServices.onUserSwitched(userId);
377         // for HCE-F
378         mHostNfcFEmulationManager.onUserSwitched();
379         mT3tIdentifiersCache.onUserSwitched();
380         mEnabledNfcFServices.onUserSwitched(userId);
381         mNfcFServicesCache.onUserSwitched();
382     }
383 
migrateSettingsFilesFromCe(Context ceContext)384     public void migrateSettingsFilesFromCe(Context ceContext) {
385         mServiceCache.migrateSettingsFilesFromCe(ceContext);
386     }
387 
onManagedProfileChanged()388     public void onManagedProfileChanged() {
389         // for HCE
390         mServiceCache.onManagedProfileChanged();
391         // for HCE-F
392         mNfcFServicesCache.onManagedProfileChanged();
393     }
394 
onNfcEnabled()395     public void onNfcEnabled() {
396         // for HCE
397         mAidCache.onNfcEnabled();
398         // for HCE-F
399         mT3tIdentifiersCache.onNfcEnabled();
400     }
401 
onNfcDisabled()402     public void onNfcDisabled() {
403         // for HCE
404         mAidCache.onNfcDisabled();
405         // for HCE-F
406         mHostNfcFEmulationManager.onNfcDisabled();
407         mNfcFServicesCache.onNfcDisabled();
408         mT3tIdentifiersCache.onNfcDisabled();
409         mEnabledNfcFServices.onNfcDisabled();
410     }
411 
onTriggerRoutingTableUpdate()412     public void onTriggerRoutingTableUpdate() {
413         if (DBG) Log.d(TAG, "onTriggerRoutingTableUpdate");
414         mAidCache.onTriggerRoutingTableUpdate();
415         mT3tIdentifiersCache.onTriggerRoutingTableUpdate();
416     }
417 
dump(FileDescriptor fd, PrintWriter pw, String[] args)418     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
419         mServiceCache.dump(fd, pw, args);
420         mNfcFServicesCache.dump(fd, pw ,args);
421         mPreferredServices.dump(fd, pw, args);
422         mEnabledNfcFServices.dump(fd, pw, args);
423         mAidCache.dump(fd, pw, args);
424         mT3tIdentifiersCache.dump(fd, pw, args);
425         mHostEmulationManager.dump(fd, pw, args);
426         mHostNfcFEmulationManager.dump(fd, pw, args);
427     }
428 
429     /**
430      * Dump debugging information as a CardEmulationManagerProto
431      *
432      * Note:
433      * See proto definition in frameworks/base/core/proto/android/nfc/card_emulation.proto
434      * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
435      * {@link ProtoOutputStream#end(long)} after.
436      * Never reuse a proto field number. When removing a field, mark it as reserved.
437      */
dumpDebug(ProtoOutputStream proto)438     public void dumpDebug(ProtoOutputStream proto) {
439         long token = proto.start(CardEmulationManagerProto.REGISTERED_SERVICES_CACHE);
440         mServiceCache.dumpDebug(proto);
441         proto.end(token);
442 
443         token = proto.start(CardEmulationManagerProto.REGISTERED_NFC_F_SERVICES_CACHE);
444         mNfcFServicesCache.dumpDebug(proto);
445         proto.end(token);
446 
447         token = proto.start(CardEmulationManagerProto.PREFERRED_SERVICES);
448         mPreferredServices.dumpDebug(proto);
449         proto.end(token);
450 
451         token = proto.start(CardEmulationManagerProto.ENABLED_NFC_F_SERVICES);
452         mEnabledNfcFServices.dumpDebug(proto);
453         proto.end(token);
454 
455         token = proto.start(CardEmulationManagerProto.AID_CACHE);
456         mAidCache.dumpDebug(proto);
457         proto.end(token);
458 
459         token = proto.start(CardEmulationManagerProto.T3T_IDENTIFIERS_CACHE);
460         mT3tIdentifiersCache.dumpDebug(proto);
461         proto.end(token);
462 
463         token = proto.start(CardEmulationManagerProto.HOST_EMULATION_MANAGER);
464         mHostEmulationManager.dumpDebug(proto);
465         proto.end(token);
466 
467         token = proto.start(CardEmulationManagerProto.HOST_NFC_F_EMULATION_MANAGER);
468         mHostNfcFEmulationManager.dumpDebug(proto);
469         proto.end(token);
470     }
471 
472     @Override
onServicesUpdated(int userId, List<ApduServiceInfo> services, boolean validateInstalled)473     public void onServicesUpdated(int userId, List<ApduServiceInfo> services,
474             boolean validateInstalled) {
475         if (!mWalletRoleObserver.isWalletRoleFeatureEnabled()) {
476             // Verify defaults are still the same
477             verifyDefaults(userId, services, validateInstalled);
478         }
479         // Update the AID cache
480         mAidCache.onServicesUpdated(userId, services);
481         // Update the preferred services list
482         mPreferredServices.onServicesUpdated();
483         mHostEmulationManager.updatePollingLoopFilters(userId, services);
484         if (Flags.exitFrames()) {
485             updateFirmwareExitFramesForWalletRole(userId);
486         }
487         NfcService.getInstance().onPreferredPaymentChanged(NfcAdapter.PREFERRED_PAYMENT_UPDATED);
488     }
489 
490     @Override
onNfcFServicesUpdated(int userId, List<NfcFServiceInfo> services)491     public void onNfcFServicesUpdated(int userId, List<NfcFServiceInfo> services) {
492         // Update the T3T identifier cache
493         mT3tIdentifiersCache.onServicesUpdated(userId, services);
494         // Update the enabled services list
495         mEnabledNfcFServices.onServicesUpdated();
496     }
497 
onEeListenActivated(boolean isActivated)498     public void onEeListenActivated(boolean isActivated) {
499         if (!isActivated) {
500             Log.d(TAG, "onEeListenActivated: Listen Mode is deactivated, "
501                     + "try to recovery routing table");
502             mPreferredServices.onHostEmulationDeactivated();
503         }
504     }
505 
verifyDefaults(int userId, List<ApduServiceInfo> services, boolean validateInstalled)506     void verifyDefaults(int userId, List<ApduServiceInfo> services, boolean validateInstalled) {
507         UserManager um = mContext.createContextAsUser(
508                 UserHandle.of(userId), /*flags=*/0).getSystemService(UserManager.class);
509         List<UserHandle> luh = um.getEnabledProfiles();
510 
511         ComponentName defaultPaymentService = null;
512         int numDefaultPaymentServices = 0;
513         int userIdDefaultPaymentService = userId;
514 
515         for (UserHandle uh : luh) {
516             ComponentName paymentService = getDefaultServiceForCategory(uh.getIdentifier(),
517                     CardEmulation.CATEGORY_PAYMENT,
518                     validateInstalled && (uh.getIdentifier() == userId));
519             if (DBG) Log.d(TAG, "verifyDefaults: default: " + paymentService + " for user:" + uh);
520             if (paymentService != null) {
521                 numDefaultPaymentServices++;
522                 defaultPaymentService = paymentService;
523                 userIdDefaultPaymentService = uh.getIdentifier();
524             }
525         }
526         if (numDefaultPaymentServices > 1) {
527             Log.e(TAG, "verifyDefaults: Current default is not aligned across multiple users");
528             // leave default unset
529             for (UserHandle uh : luh) {
530                 setDefaultServiceForCategoryChecked(uh.getIdentifier(), null,
531                         CardEmulation.CATEGORY_PAYMENT);
532             }
533         } else {
534             if (DBG)  {
535                 Log.d(TAG, "verifyDefaults: Current default: " + defaultPaymentService
536                         + " for user:" + userIdDefaultPaymentService);
537             }
538         }
539         if (defaultPaymentService == null) {
540             // A payment service may have been removed, leaving only one;
541             // in that case, automatically set that app as default.
542             int numPaymentServices = 0;
543             ComponentName lastFoundPaymentService = null;
544             PackageManager pm;
545             try {
546                 pm = mContext.createPackageContextAsUser("android", /*flags=*/0,
547                     UserHandle.of(userId)).getPackageManager();
548             } catch (NameNotFoundException e) {
549                 Log.e(TAG, "verifyDefaults: Could not create user package context");
550                 return;
551             }
552 
553             for (ApduServiceInfo service : services) {
554                 if (service.hasCategory(CardEmulation.CATEGORY_PAYMENT)
555                             && wasServicePreInstalled(pm, service.getComponent())) {
556                     numPaymentServices++;
557                     lastFoundPaymentService = service.getComponent();
558                 }
559             }
560             if (numPaymentServices > 1) {
561                 // More than one service left, leave default unset
562                 if (DBG) Log.d(TAG, "verifyDefaults: No default set, more than one service left.");
563                 setDefaultServiceForCategoryChecked(userId, null, CardEmulation.CATEGORY_PAYMENT);
564             } else if (numPaymentServices == 1) {
565                 // Make single found payment service the default
566                 if (DBG) {
567                     Log.d(TAG,
568                             "verifyDefaults: No default set, " + "making single service default.");
569                 }
570                 setDefaultServiceForCategoryChecked(userId, lastFoundPaymentService,
571                         CardEmulation.CATEGORY_PAYMENT);
572             } else {
573                 // No payment services left, leave default at null
574                 if (DBG) {
575                     Log.d(TAG,
576                             "verifyDefaults: No default set, " + "last payment service removed.");
577                 }
578                 setDefaultServiceForCategoryChecked(userId, null, CardEmulation.CATEGORY_PAYMENT);
579             }
580         }
581     }
582 
wasServicePreInstalled(PackageManager packageManager, ComponentName service)583     boolean wasServicePreInstalled(PackageManager packageManager, ComponentName service) {
584         try {
585             ApplicationInfo ai = packageManager
586                     .getApplicationInfo(service.getPackageName(), /*flags=*/0);
587             if ((ApplicationInfo.FLAG_SYSTEM & ai.flags) != 0) {
588                 if (DBG) {
589                     Log.d(TAG,
590                             "wasServicePreInstalled: Service was " + "pre-installed on the device");
591                 }
592                 return true;
593             }
594         } catch (NameNotFoundException e) {
595             Log.e(TAG, "wasServicePreInstalled: Service is not currently "
596                     + "installed on the device.");
597             return false;
598         }
599         if (DBG) {
600             Log.d(TAG, "wasServicePreInstalled: Service was not pre-installed on the device");
601         }
602         return false;
603     }
604 
getDefaultServiceForCategory(int userId, String category, boolean validateInstalled)605     ComponentName getDefaultServiceForCategory(int userId, String category,
606              boolean validateInstalled) {
607         if (!CardEmulation.CATEGORY_PAYMENT.equals(category)) {
608             Log.e(TAG,
609                     "getDefaultServiceForCategory: Not allowing defaults for category " + category);
610             return null;
611         }
612         // Load current payment default from settings
613         String name = Settings.Secure.getString(
614                 mContext.createContextAsUser(UserHandle.of(userId), 0).getContentResolver(),
615                 Constants.SETTINGS_SECURE_NFC_PAYMENT_DEFAULT_COMPONENT);
616         if (name != null) {
617             ComponentName service = ComponentName.unflattenFromString(name);
618             if (!validateInstalled || service == null) {
619                 return service;
620             } else {
621                 return mServiceCache.hasService(userId, service) ? service : null;
622             }
623         } else {
624             return null;
625         }
626     }
627 
setDefaultServiceForCategoryChecked(int userId, ComponentName service, String category)628     boolean setDefaultServiceForCategoryChecked(int userId, ComponentName service,
629             String category) {
630         if (!CardEmulation.CATEGORY_PAYMENT.equals(category)) {
631             Log.e(TAG, "setDefaultServiceForCategoryChecked: Not allowing defaults for category "
632                     + category);
633             return false;
634         }
635         // TODO Not really nice to be writing to Settings.Secure here...
636         // ideally we overlay our local changes over whatever is in
637         // Settings.Secure
638         if (service == null || mServiceCache.hasService(userId, service)) {
639             Settings.Secure.putString(mContext
640                     .createContextAsUser(UserHandle.of(userId), 0).getContentResolver(),
641                     Constants.SETTINGS_SECURE_NFC_PAYMENT_DEFAULT_COMPONENT,
642                     service != null ? service.flattenToString() : null);
643         } else {
644             Log.e(TAG,
645                     "setDefaultServiceForCategoryChecked: Could not find default "
646                             + "service to make default: "
647                             + service);
648         }
649         return true;
650     }
651 
isServiceRegistered(int userId, ComponentName service)652     boolean isServiceRegistered(int userId, ComponentName service) {
653         boolean serviceFound = mServiceCache.hasService(userId, service);
654         if (!serviceFound) {
655             // If we don't know about this service yet, it may have just been enabled
656             // using PackageManager.setComponentEnabledSetting(). The PackageManager
657             // broadcasts are delayed by 10 seconds in that scenario, which causes
658             // calls to our APIs referencing that service to fail.
659             // Hence, update the cache in case we don't know about the service.
660             if (DBG) {
661                 Log.d(TAG, "isServiceRegistered: Didn't find passed in service, "
662                         + "invalidating cache");
663             }
664             mServiceCache.invalidateCache(userId, true);
665         }
666         return mServiceCache.hasService(userId, service);
667     }
668 
isNfcFServiceInstalled(int userId, ComponentName service)669     boolean isNfcFServiceInstalled(int userId, ComponentName service) {
670         boolean serviceFound = mNfcFServicesCache.hasService(userId, service);
671         if (!serviceFound) {
672             // If we don't know about this service yet, it may have just been enabled
673             // using PackageManager.setComponentEnabledSetting(). The PackageManager
674             // broadcasts are delayed by 10 seconds in that scenario, which causes
675             // calls to our APIs referencing that service to fail.
676             // Hence, update the cache in case we don't know about the service.
677             if (DBG) {
678                 Log.d(TAG,
679                         "isNfcFServiceInstalled: Didn't find passed in service, "
680                                 + "invalidating cache");
681             }
682             mNfcFServicesCache.invalidateCache(userId);
683         }
684         return mNfcFServicesCache.hasService(userId, service);
685     }
686 
687     /**
688      * Returns true if it's not selecting NDEF AIDs
689      * It's used to skip userActivity if it only selects NDEF AIDs
690      */
isSkipAid(byte[] data)691     boolean isSkipAid(byte[] data) {
692         if (mNotSkipAid || data == null
693                 || data.length < SELECT_APDU_HDR_LENGTH + MINIMUM_AID_LENGTH
694                 || !Arrays.equals(SELECT_AID_HDR, 0, SELECT_AID_HDR.length,
695                         data, 0, SELECT_AID_HDR.length)) {
696             return false;
697         }
698         int aidLength = Byte.toUnsignedInt(data[SELECT_APDU_HDR_LENGTH - 1]);
699         if (data.length >= SELECT_APDU_HDR_LENGTH + NDEF_AID_LENGTH
700                 && aidLength == NDEF_AID_LENGTH) {
701             if (Arrays.equals(data, SELECT_APDU_HDR_LENGTH,
702                         SELECT_APDU_HDR_LENGTH + NDEF_AID_LENGTH,
703                         NDEF_AID_V1, 0, NDEF_AID_LENGTH)) {
704                 if (DBG) Log.d(TAG, "isSkipAid: Skip for NDEF_V1");
705                 return true;
706             } else if (Arrays.equals(data, SELECT_APDU_HDR_LENGTH,
707                         SELECT_APDU_HDR_LENGTH + NDEF_AID_LENGTH,
708                         NDEF_AID_V2, 0, NDEF_AID_LENGTH)) {
709                 if (DBG) Log.d(TAG, "isSkipAid: Skip for NDEF_V2");
710                 return true;
711             }
712         }
713         // The data payload is not selecting the skip AID.
714         mNotSkipAid = true;
715         return false;
716     }
717 
718     /**
719      * Returns whether a service in this package is preferred,
720      * either because it's the default payment app or it's running
721      * in the foreground.
722      */
packageHasPreferredService(String packageName)723     public boolean packageHasPreferredService(String packageName) {
724         return mPreferredServices.packageHasPreferredService(packageName);
725     }
726 
727     @Override
onPreferredSubscriptionChanged(int subscriptionId, boolean isActive)728     public void onPreferredSubscriptionChanged(int subscriptionId, boolean isActive) {
729         int simType = isActive ?  getSimTypeById(subscriptionId) : TelephonyUtils.SIM_TYPE_UNKNOWN;
730         Log.i(TAG, "onPreferredSubscriptionChanged: subscription_" + subscriptionId + "is active("
731                 + isActive + ")"
732                 + ", type(" + simType + ")");
733         mRoutingOptionManager.onPreferredSimChanged(simType);
734         if (simType != TelephonyUtils.SIM_TYPE_UNKNOWN) {
735             updateRouteBasedOnPreferredSim();
736         }
737         else {
738             Log.i(TAG, "onPreferredSubscriptionChanged: SIM is Invalid type");
739         }
740         mAidCache.onPreferredSimChanged(simType);
741         // try to nfc turned off and on to swp initialize
742         NfcService.getInstance().onPreferredSimChanged();
743     }
744 
updateRouteBasedOnPreferredSim()745     private void updateRouteBasedOnPreferredSim() {
746         boolean changed = false;
747         changed |= updateRouteToPreferredSim(()->mRoutingOptionManager.getDefaultRoute(),
748                 route->mRoutingOptionManager.overrideDefaultRoute(route));
749         changed |= updateRouteToPreferredSim(()->mRoutingOptionManager.getDefaultIsoDepRoute(),
750                 route->mRoutingOptionManager.overrideDefaultIsoDepRoute(route));
751         changed |= updateRouteToPreferredSim(()->mRoutingOptionManager.getDefaultOffHostRoute(),
752                 route->mRoutingOptionManager.overrideDefaultOffHostRoute(route));
753         if (changed) {
754             mRoutingOptionManager.overwriteRoutingTable();
755         }
756     }
updateRouteToPreferredSim(Supplier<Integer> getter, Consumer<Integer> setter)757     private boolean updateRouteToPreferredSim(Supplier<Integer> getter, Consumer<Integer> setter) {
758         String se = mRoutingOptionManager.getSecureElementForRoute(getter.get());
759         if (se.startsWith(RoutingOptionManager.SE_PREFIX_SIM)) {
760             int route = mRoutingOptionManager.getRouteForSecureElement(
761                     mRoutingOptionManager.getPreferredSim());
762             setter.accept(route);
763             return true;
764         }
765         else {
766             Log.d(TAG, "updateRouteToPreferredSim: ignore");
767         }
768         return false;
769     }
770 
771     /**
772      * This class implements the application-facing APIs and are called
773      * from binder. All calls must be permission-checked.
774      */
775     final class CardEmulationInterface extends INfcCardEmulation.Stub {
776         @Override
isDefaultServiceForCategory(int userId, ComponentName service, String category)777         public boolean isDefaultServiceForCategory(int userId, ComponentName service,
778                 String category) {
779             NfcPermissions.enforceUserPermissions(mContext);
780             NfcPermissions.validateUserId(userId);
781             if (!isServiceRegistered(userId, service)) {
782                 return false;
783             }
784             if (mWalletRoleObserver.isWalletRoleFeatureEnabled()) {
785                 PackageAndUser holder =
786                         mWalletRoleObserver.getDefaultWalletRoleHolder(userId);
787                 if (holder.getPackage() == null) {
788                     return false;
789                 }
790                 return service.getPackageName().equals(
791                         holder.getPackage()) && userId == holder.getUserId();
792             }
793             ComponentName defaultService =
794                     getDefaultServiceForCategory(userId, category, true);
795             return (defaultService != null && defaultService.equals(service));
796         }
797 
798         @Override
isDefaultServiceForAid(int userId, ComponentName service, String aid)799         public boolean isDefaultServiceForAid(int userId,
800                 ComponentName service, String aid) throws RemoteException {
801             NfcPermissions.validateUserId(userId);
802             NfcPermissions.enforceUserPermissions(mContext);
803             if (!isServiceRegistered(userId, service)) {
804                 return false;
805             }
806             return mAidCache.isDefaultServiceForAid(userId, service, aid);
807         }
808 
809         @Override
setDefaultServiceForCategory(int userId, ComponentName service, String category)810         public boolean setDefaultServiceForCategory(int userId,
811                 ComponentName service, String category) throws RemoteException {
812             NfcPermissions.validateUserId(userId);
813             NfcPermissions.enforceAdminPermissions(mContext);
814             if (!isServiceRegistered(userId, service)) {
815                 return false;
816             }
817             return setDefaultServiceForCategoryChecked(userId, service, category);
818         }
819 
820         @Override
setDefaultForNextTap(int userId, ComponentName service)821         public boolean setDefaultForNextTap(int userId, ComponentName service)
822                 throws RemoteException {
823             NfcPermissions.validateProfileId(mContext, userId);
824             NfcPermissions.enforceAdminPermissions(mContext);
825             if (service != null && !isServiceRegistered(userId, service)) {
826                 return false;
827             }
828             return mPreferredServices.setDefaultForNextTap(userId, service);
829         }
830 
831         @Override
setShouldDefaultToObserveModeForService(int userId, ComponentName service, boolean enable)832         public boolean setShouldDefaultToObserveModeForService(int userId,
833                 ComponentName service, boolean enable) {
834             NfcPermissions.validateUserId(userId);
835             NfcPermissions.enforceUserPermissions(mContext);
836             if (!isServiceRegistered(userId, service)) {
837                 return false;
838             }
839             Log.d(TAG, "setShouldDefaultToObserveModeForService: (" + service + ") to "
840                     + enable);
841             boolean currentStatus = mServiceCache.doesServiceShouldDefaultToObserveMode(userId,
842                     service);
843 
844             if (currentStatus != enable) {
845                 if (!mServiceCache.setShouldDefaultToObserveModeForService(userId,
846                         Binder.getCallingUid(), service, enable)) {
847                     return false;
848                 }
849                 updateForShouldDefaultToObserveMode(userId);
850             }
851             return true;
852         }
853 
854         @Override
registerAidGroupForService(int userId, ComponentName service, AidGroup aidGroup)855         public boolean registerAidGroupForService(int userId,
856                 ComponentName service, AidGroup aidGroup) throws RemoteException {
857             NfcPermissions.validateUserId(userId);
858             NfcPermissions.enforceUserPermissions(mContext);
859             if (!isServiceRegistered(userId, service)) {
860                 Log.e(TAG, "registerAidGroupForService: service (" + service
861                         + ") isn't registered for user " + userId);
862                 return false;
863             }
864             if (!mServiceCache.registerAidGroupForService(userId, Binder.getCallingUid(), service,
865                     aidGroup)) {
866                 return false;
867             }
868             NfcService.getInstance().onPreferredPaymentChanged(
869                     NfcAdapter.PREFERRED_PAYMENT_UPDATED);
870             mNfcEventLog.logEvent(
871                     NfcEventProto.EventType.newBuilder()
872                             .setAidRegistration(NfcEventProto.NfcAidRegistration.newBuilder()
873                                     .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder()
874                                             .setUid(Binder.getCallingUid())
875                                             .build())
876                                     .setComponentInfo(
877                                         NfcEventProto.NfcComponentInfo.newBuilder()
878                                             .setPackageName(
879                                                 service.getPackageName())
880                                             .setClassName(
881                                                 service.getClassName())
882                                             .build())
883                                     .setIsRegistration(true)
884                                     .addAllAids(aidGroup.getAids())
885                                     .build())
886                             .build());
887             return true;
888         }
889 
890         @Override
registerPollingLoopFilterForService(int userId, ComponentName service, String pollingLoopFilter, boolean autoTransact)891         public boolean registerPollingLoopFilterForService(int userId, ComponentName service,
892                 String pollingLoopFilter, boolean autoTransact) throws RemoteException {
893             NfcPermissions.validateUserId(userId);
894             NfcPermissions.enforceUserPermissions(mContext);
895             if (!isServiceRegistered(userId, service)) {
896                 Log.e(TAG, "registerPollingLoopFilterForService: service (" + service
897                         + ") isn't registered for user " + userId);
898                 return false;
899             }
900             if (!mServiceCache.registerPollingLoopFilterForService(userId, Binder.getCallingUid(),
901                     service, pollingLoopFilter, autoTransact)) {
902                 return false;
903             }
904             mNfcEventLog.logEvent(
905                     NfcEventProto.EventType.newBuilder()
906                             .setPollingLoopRegistration(NfcEventProto.NfcPollingLoopRegistration
907                                                             .newBuilder()
908                                     .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder()
909                                             .setUid(Binder.getCallingUid())
910                                             .build())
911                                     .setComponentInfo(
912                                         NfcEventProto.NfcComponentInfo.newBuilder()
913                                             .setPackageName(
914                                                 service.getPackageName())
915                                             .setClassName(
916                                                 service.getClassName())
917                                             .build())
918                                     .setIsRegistration(true)
919                                     .setPollingLoopFilter(pollingLoopFilter)
920                                     .build())
921                             .build());
922             return true;
923         }
924 
925         @Override
removePollingLoopFilterForService(int userId, ComponentName service, String pollingLoopFilter)926         public boolean removePollingLoopFilterForService(int userId, ComponentName service,
927                 String pollingLoopFilter) throws RemoteException {
928             NfcPermissions.validateUserId(userId);
929             NfcPermissions.enforceUserPermissions(mContext);
930             if (!isServiceRegistered(userId, service)) {
931                 Log.e(TAG, "removePollingLoopFilterForService: service (" + service
932                         + ") isn't registered for user " + userId);
933                 return false;
934             }
935             if (!mServiceCache.removePollingLoopFilterForService(userId, Binder.getCallingUid(),
936                     service, pollingLoopFilter)) {
937                 return false;
938             }
939             mNfcEventLog.logEvent(
940                     NfcEventProto.EventType.newBuilder()
941                             .setPollingLoopRegistration(NfcEventProto.NfcPollingLoopRegistration
942                                                             .newBuilder()
943                                     .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder()
944                                             .setUid(Binder.getCallingUid())
945                                             .build())
946                                     .setComponentInfo(
947                                         NfcEventProto.NfcComponentInfo.newBuilder()
948                                             .setPackageName(
949                                                 service.getPackageName())
950                                             .setClassName(
951                                                 service.getClassName())
952                                             .build())
953                                     .setIsRegistration(false)
954                                     .setPollingLoopFilter(pollingLoopFilter)
955                                     .build())
956                             .build());
957             return true;
958         }
959 
960         @Override
registerPollingLoopPatternFilterForService(int userId, ComponentName service, String pollingLoopPatternFilter, boolean autoTransact)961         public boolean registerPollingLoopPatternFilterForService(int userId, ComponentName service,
962                 String pollingLoopPatternFilter, boolean autoTransact) throws RemoteException {
963             NfcPermissions.validateUserId(userId);
964             NfcPermissions.enforceUserPermissions(mContext);
965             if (!isServiceRegistered(userId, service)) {
966                 Log.e(TAG, "registerPollingLoopPatternFilterForService: service (" + service
967                         + ") isn't registed for user " + userId);
968                 return false;
969             }
970             if (!mServiceCache.registerPollingLoopPatternFilterForService(userId,
971                     Binder.getCallingUid(), service, pollingLoopPatternFilter, autoTransact)) {
972                 return false;
973             }
974             mNfcEventLog.logEvent(
975                     NfcEventProto.EventType.newBuilder()
976                             .setPollingLoopRegistration(NfcEventProto.NfcPollingLoopRegistration
977                                                             .newBuilder()
978                                     .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder()
979                                             .setUid(Binder.getCallingUid())
980                                             .build())
981                                     .setComponentInfo(
982                                         NfcEventProto.NfcComponentInfo.newBuilder()
983                                             .setPackageName(
984                                                 service.getPackageName())
985                                             .setClassName(
986                                                 service.getClassName())
987                                             .build())
988                                     .setIsRegistration(true)
989                                     .setPollingLoopFilter(pollingLoopPatternFilter)
990                                     .build())
991                             .build());
992             return true;
993         }
994 
995         @Override
removePollingLoopPatternFilterForService(int userId, ComponentName service, String pollingLoopPatternFilter)996         public boolean removePollingLoopPatternFilterForService(int userId, ComponentName service,
997                 String pollingLoopPatternFilter) throws RemoteException {
998             NfcPermissions.validateUserId(userId);
999             NfcPermissions.enforceUserPermissions(mContext);
1000             if (!isServiceRegistered(userId, service)) {
1001                 Log.e(TAG, "removePollingLoopPatternFilterForService: service (" + service
1002                         + ") isn't registed for user " + userId);
1003                 return false;
1004             }
1005             if (!mServiceCache.removePollingLoopPatternFilterForService(userId,
1006                     Binder.getCallingUid(), service, pollingLoopPatternFilter)) {
1007                 return false;
1008             }
1009             mNfcEventLog.logEvent(
1010                     NfcEventProto.EventType.newBuilder()
1011                             .setPollingLoopRegistration(NfcEventProto.NfcPollingLoopRegistration
1012                                                             .newBuilder()
1013                                     .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder()
1014                                             .setUid(Binder.getCallingUid())
1015                                             .build())
1016                                     .setComponentInfo(
1017                                         NfcEventProto.NfcComponentInfo.newBuilder()
1018                                             .setPackageName(
1019                                                 service.getPackageName())
1020                                             .setClassName(
1021                                                 service.getClassName())
1022                                             .build())
1023                                     .setIsRegistration(false)
1024                                     .setPollingLoopFilter(pollingLoopPatternFilter)
1025                                     .build())
1026                             .build());
1027             return true;
1028         }
1029 
1030         @Override
setOffHostForService(int userId, ComponentName service, String offHostSE)1031         public boolean setOffHostForService(int userId, ComponentName service, String offHostSE) {
1032             NfcPermissions.validateUserId(userId);
1033             NfcPermissions.enforceUserPermissions(mContext);
1034             if (!isServiceRegistered(userId, service)) {
1035                 return false;
1036             }
1037             if (!mServiceCache.setOffHostSecureElement(userId, Binder.getCallingUid(), service,
1038                     offHostSE)) {
1039                 return false;
1040             }
1041             NfcService.getInstance().onPreferredPaymentChanged(
1042                     NfcAdapter.PREFERRED_PAYMENT_UPDATED);
1043             return true;
1044         }
1045 
1046         @Override
unsetOffHostForService(int userId, ComponentName service)1047         public boolean unsetOffHostForService(int userId, ComponentName service) {
1048             NfcPermissions.validateUserId(userId);
1049             NfcPermissions.enforceUserPermissions(mContext);
1050             if (!isServiceRegistered(userId, service)) {
1051                 return false;
1052             }
1053             if (!mServiceCache.resetOffHostSecureElement(userId, Binder.getCallingUid(), service)) {
1054                 return false;
1055             }
1056             NfcService.getInstance().onPreferredPaymentChanged(
1057                     NfcAdapter.PREFERRED_PAYMENT_UPDATED);
1058             return true;
1059         }
1060 
1061         @Override
getAidGroupForService(int userId, ComponentName service, String category)1062         public AidGroup getAidGroupForService(int userId,
1063                 ComponentName service, String category) throws RemoteException {
1064             NfcPermissions.validateUserId(userId);
1065             NfcPermissions.enforceUserPermissions(mContext);
1066             if (!isServiceRegistered(userId, service)) {
1067                 return null;
1068             }
1069             return mServiceCache.getAidGroupForService(userId, Binder.getCallingUid(), service,
1070                     category);
1071         }
1072 
1073         @Override
removeAidGroupForService(int userId, ComponentName service, String category)1074         public boolean removeAidGroupForService(int userId,
1075                 ComponentName service, String category) throws RemoteException {
1076             NfcPermissions.validateUserId(userId);
1077             NfcPermissions.enforceUserPermissions(mContext);
1078             if (!isServiceRegistered(userId, service)) {
1079                 return false;
1080             }
1081             if (!mServiceCache.removeAidGroupForService(userId, Binder.getCallingUid(), service,
1082                     category)) {
1083                 return false;
1084             }
1085             NfcService.getInstance().onPreferredPaymentChanged(
1086                     NfcAdapter.PREFERRED_PAYMENT_UPDATED);
1087             mNfcEventLog.logEvent(
1088                     NfcEventProto.EventType.newBuilder()
1089                             .setAidRegistration(NfcEventProto.NfcAidRegistration.newBuilder()
1090                                     .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder()
1091                                             .setUid(Binder.getCallingUid())
1092                                             .build())
1093                                     .setComponentInfo(
1094                                         NfcEventProto.NfcComponentInfo.newBuilder()
1095                                             .setPackageName(
1096                                                 service.getPackageName())
1097                                             .setClassName(
1098                                                 service.getClassName())
1099                                             .build())
1100                                     .setIsRegistration(false)
1101                                     .build())
1102                             .build());
1103             return true;
1104         }
1105 
1106         @Override
getServices(int userId, String category)1107         public List<ApduServiceInfo> getServices(int userId, String category)
1108                 throws RemoteException {
1109             NfcPermissions.validateProfileId(mContext, userId);
1110             NfcPermissions.enforceAdminPermissions(mContext);
1111             return mServiceCache.getServicesForCategory(userId, category);
1112         }
1113 
1114         @Override
setPreferredService(ComponentName service)1115         public boolean setPreferredService(ComponentName service)
1116                 throws RemoteException {
1117             NfcPermissions.enforceUserPermissions(mContext);
1118             if (!isServiceRegistered( UserHandle.getUserHandleForUid(
1119                     Binder.getCallingUid()).getIdentifier(), service)) {
1120                 Log.e(TAG, "setPreferredService: unknown component");
1121                 return false;
1122             }
1123             return mPreferredServices.registerPreferredForegroundService(service,
1124                     Binder.getCallingUid());
1125         }
1126 
1127         @Override
unsetPreferredService()1128         public boolean unsetPreferredService() throws RemoteException {
1129             NfcPermissions.enforceUserPermissions(mContext);
1130             return mPreferredServices.unregisteredPreferredForegroundService(
1131                     Binder.getCallingUid());
1132         }
1133 
1134         @Override
supportsAidPrefixRegistration()1135         public boolean supportsAidPrefixRegistration() throws RemoteException {
1136             return mAidCache.supportsAidPrefixRegistration();
1137         }
1138 
1139         @Override
getPreferredPaymentService(int userId)1140         public ApduServiceInfo getPreferredPaymentService(int userId) throws RemoteException {
1141             NfcPermissions.validateUserId(userId);
1142             NfcPermissions.enforceUserPermissions(mContext);
1143             NfcPermissions.enforcePreferredPaymentInfoPermissions(mContext);
1144             return mServiceCache.getService(userId,
1145                         mAidCache.getPreferredService().getComponentName());
1146         }
1147 
1148         @Override
setServiceEnabledForCategoryOther(int userId, ComponentName app, boolean status)1149         public int setServiceEnabledForCategoryOther(int userId,
1150                 ComponentName app, boolean status) throws RemoteException {
1151             if (!mDeviceConfigFacade.getEnableServiceOther())
1152               return SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED;
1153             NfcPermissions.enforceUserPermissions(mContext);
1154 
1155             return mServiceCache.registerOtherForService(userId, app, status);
1156         }
1157 
1158         @Override
isDefaultPaymentRegistered()1159         public boolean isDefaultPaymentRegistered() throws RemoteException {
1160             if (mWalletRoleObserver.isWalletRoleFeatureEnabled()) {
1161                 int callingUserId = Binder.getCallingUserHandle().getIdentifier();
1162                 return mWalletRoleObserver.getDefaultWalletRoleHolder(
1163                         callingUserId).getPackage() != null;
1164             }
1165             String defaultComponent = Settings.Secure.getString(mContext.getContentResolver(),
1166                     Constants.SETTINGS_SECURE_NFC_PAYMENT_DEFAULT_COMPONENT);
1167             return defaultComponent != null ? true : false;
1168         }
1169 
1170         @Override
overrideRoutingTable(int userHandle, String protocol, String technology, String pkg)1171         public void overrideRoutingTable(int userHandle, String protocol, String technology,
1172                 String pkg) {
1173             Log.d(TAG, "overrideRoutingTable: userHandle " + userHandle + ", protocol " + protocol
1174                     + ", technology " + technology);
1175 
1176             NfcPermissions.enforceAdminPermissions(mContext);
1177 
1178             if ((protocol != null && protocol.equals("default"))
1179                     || (technology != null && technology.equals("default"))) {
1180                 Log.e(TAG, "overrideRoutingTable: override value cannot be set to default");
1181                 throw new IllegalArgumentException("default value is not allowed.");
1182             }
1183 
1184             int callingUid = Binder.getCallingUid();
1185             if (android.nfc.Flags.nfcOverrideRecoverRoutingTable()) {
1186                 if (!isPreferredServicePackageNameForUser(pkg,
1187                         UserHandle.getUserHandleForUid(callingUid).getIdentifier())
1188                         && !mNfcInjector.isSignedWithPlatformKey(callingUid)) {
1189                     Log.e(TAG, "overrideRoutingTable: Caller not preferred NFC service.");
1190                     throw new SecurityException("Caller not preferred NFC service");
1191                 }
1192             }
1193             if (!mForegroundUtils
1194                     .registerUidToBackgroundCallback(mForegroundCallback, callingUid)) {
1195                 Log.e(TAG, "overrideRoutingTable: Caller is not in foreground.");
1196                 throw new IllegalArgumentException("Caller is not in foreground.");
1197             }
1198             mForegroundUid = callingUid;
1199 
1200             int protocolRoute = getRouteForSecureElement(protocol);
1201             int technologyRoute = getRouteForSecureElement(technology);
1202             if (DBG) {
1203                 Log.d(TAG, "overrideRoutingTable: protocolRoute " + protocolRoute
1204                         + ", technologyRoute " + technologyRoute);
1205             }
1206 
1207 //            mRoutingOptionManager.overrideDefaultRoute(protocolRoute);
1208             mRoutingOptionManager.overrideDefaultIsoDepRoute(protocolRoute);
1209             mRoutingOptionManager.overrideDefaultOffHostRoute(technologyRoute);
1210             int result = mAidCache.onRoutingOverridedOrRecovered();
1211             switch (result) {
1212                 case AidRoutingManager.CONFIGURE_ROUTING_SUCCESS:
1213                     break;
1214                 case AidRoutingManager.CONFIGURE_ROUTING_FAILURE_TABLE_FULL:
1215                     throw new IllegalArgumentException("CONFIGURE_ROUTING_FAILURE_TABLE_FULL");
1216                 case AidRoutingManager.CONFIGURE_ROUTING_FAILURE_UNKNOWN:
1217                     throw new IllegalArgumentException("CONFIGURE_ROUTING_FAILURE_UNKNOWN");
1218             }
1219         }
1220 
1221         @Override
recoverRoutingTable(int userHandle)1222         public void recoverRoutingTable(int userHandle) {
1223             Log.d(TAG, "recoverRoutingTable: userHandle " + userHandle);
1224 
1225             NfcPermissions.enforceAdminPermissions(mContext);
1226 
1227             if (!mForegroundUtils.isInForeground(Binder.getCallingUid())) {
1228                 if (DBG) Log.d(TAG, "recoverRoutingTable : not in foreground.");
1229                 throw new IllegalArgumentException("Caller is not in foreground.");
1230             }
1231             mForegroundUid = Process.INVALID_UID;
1232 
1233             mRoutingOptionManager.recoverOverridedRoutingTable();
1234             if (mAidCache.onRoutingOverridedOrRecovered()
1235                         != AidRoutingManager.CONFIGURE_ROUTING_SUCCESS) {
1236                 throw new IllegalArgumentException(
1237                         "recoverRoutingTable: " + "onRoutingOverridedOrRecovered() failed");
1238             }
1239         }
1240 
1241         @Override
overwriteRoutingTable(int userHandle, String aids, String protocol, String technology, String sc)1242         public void overwriteRoutingTable(int userHandle, String aids,
1243             String protocol, String technology, String sc) {
1244             Log.d(TAG, "overwriteRoutingTable(): userHandle: " + userHandle
1245                 + ", emptyAid: " + aids + ", protocol: " + protocol
1246                 + ", technology: " + technology + ", systemCode: " + sc);
1247 
1248             NfcPermissions.enforceAdminPermissions(mContext);
1249 
1250             int aidRoute = getRouteForSecureElement(aids);
1251             int protocolRoute = getRouteForSecureElement(protocol);
1252             int technologyRoute = getRouteForSecureElement(technology);
1253             int scRoute = getRouteForSecureElement(sc);
1254 
1255             if (DBG)  {
1256                 Log.d(TAG, "overwriteRoutingTable(): aidRoute: " + Integer.toHexString(aidRoute)
1257                         + ", protocolRoute: " + Integer.toHexString(protocolRoute)
1258                         + ", technologyRoute: " + Integer.toHexString(technologyRoute)
1259                         + ", scRoute: " + Integer.toHexString(scRoute));
1260             }
1261             if (aids != null) {
1262                 mRoutingOptionManager.overrideDefaultRoute(aidRoute);
1263             }
1264             if (protocol != null) {
1265                 mRoutingOptionManager.overrideDefaultIsoDepRoute(protocolRoute);
1266             }
1267             if (technology != null) {
1268                 mRoutingOptionManager.overrideDefaultOffHostRoute(technologyRoute);
1269             }
1270             if (sc != null) {
1271                 mRoutingOptionManager.overrideDefaultScRoute(scRoute);
1272             }
1273             if (aids != null || protocol != null || technology != null || sc != null) {
1274                 mRoutingOptionManager.overwriteRoutingTable();
1275             }
1276             if (mAidCache.onRoutingOverridedOrRecovered()
1277                         != AidRoutingManager.CONFIGURE_ROUTING_SUCCESS) {
1278                 throw new IllegalArgumentException("onRoutingOverridedOrRecovered() failed");
1279             }
1280         }
1281 
1282         @Override
getRoutingStatus()1283         public List<String> getRoutingStatus() {
1284             NfcPermissions.enforceAdminPermissions(mContext);
1285             List<Integer> routingList = new ArrayList<>();
1286 
1287             if (mRoutingOptionManager.isRoutingTableOverrided()) {
1288                 routingList.add(mRoutingOptionManager.getOverrideDefaultRoute());
1289                 routingList.add(mRoutingOptionManager.getOverrideDefaultIsoDepRoute());
1290                 routingList.add(mRoutingOptionManager.getOverrideDefaultOffHostRoute());
1291             }
1292             else {
1293                 routingList.add(mRoutingOptionManager.getDefaultRoute());
1294                 routingList.add(mRoutingOptionManager.getDefaultIsoDepRoute());
1295                 routingList.add(mRoutingOptionManager.getDefaultOffHostRoute());
1296             }
1297 
1298             return routingList.stream()
1299                 .map(route->mRoutingOptionManager.getSecureElementForRoute(route))
1300                 .collect(Collectors.toList());
1301         }
1302 
1303         @Override
setAutoChangeStatus(boolean state)1304         public void setAutoChangeStatus(boolean state) {
1305             NfcPermissions.enforceAdminPermissions(mContext);
1306             mRoutingOptionManager.setAutoChangeStatus(state);
1307         }
1308 
1309         @Override
isAutoChangeEnabled()1310         public boolean isAutoChangeEnabled() {
1311             NfcPermissions.enforceAdminPermissions(mContext);
1312             return mRoutingOptionManager.isAutoChangeEnabled();
1313         }
1314 
1315         @Override
isEuiccSupported()1316         public boolean isEuiccSupported() {
1317             NfcPermissions.enforceUserPermissions(mContext);
1318             return mContext.getResources().getBoolean(R.bool.enable_euicc_support)
1319                     && NfcInjector.NfcProperties.isEuiccSupported();
1320         }
1321 
1322         /**
1323          * Make sure the device has required telephony feature
1324          *
1325          * @throws UnsupportedOperationException if the device does not have required telephony feature
1326          */
enforceTelephonySubscriptionFeatureWithException( String callingPackage, String methodName)1327         private void enforceTelephonySubscriptionFeatureWithException(
1328                 String callingPackage, String methodName) {
1329             if (callingPackage == null) return;
1330             if (mVendorApiLevel < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
1331                 // Skip to check associated telephony feature,
1332                 // if compatibility change is not enabled for the current process or
1333                 // the SDK version of vendor partition is less than Android V.
1334                 return;
1335             }
1336             if (!mContext.getPackageManager().hasSystemFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
1337                 throw new UnsupportedOperationException(
1338                         methodName + " is unsupported without " + FEATURE_TELEPHONY_SUBSCRIPTION);
1339             }
1340         }
1341 
1342         @Override
setDefaultNfcSubscriptionId(int subscriptionId, String pkgName)1343         public int setDefaultNfcSubscriptionId(int subscriptionId, String pkgName) {
1344             NfcPermissions.enforceAdminPermissions(mContext);
1345             if (!android.nfc.Flags.enableCardEmulationEuicc()) {
1346                 Log.d(TAG, "setDefaultNfcSubscriptionId: Euicc CardEmulation isn't enabled");
1347                 return CardEmulation.SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED;
1348             }
1349             enforceTelephonySubscriptionFeatureWithException(pkgName, "setDefaultNfcSubscriptionId");
1350             mPreferredSubscriptionService.setPreferredSubscriptionId(subscriptionId, true);
1351             // TODO(b/321314635): Write to NFC persistent setting.
1352             return CardEmulation.SET_SUBSCRIPTION_ID_STATUS_SUCCESS;
1353         }
1354 
1355         @Override
getDefaultNfcSubscriptionId(String pkgName)1356         public int getDefaultNfcSubscriptionId(String pkgName) {
1357             NfcPermissions.enforceUserPermissions(mContext);
1358             enforceTelephonySubscriptionFeatureWithException(pkgName, "getDefaultNfcSubscriptionId");
1359             // TODO(b/321314635): Read NFC persistent setting.
1360             return mPreferredSubscriptionService.getPreferredSubscriptionId();
1361         }
1362 
1363         @Override
registerNfcEventCallback(INfcEventCallback listener)1364         public void registerNfcEventCallback(INfcEventCallback listener) {
1365             if (!android.nfc.Flags.nfcEventListener()) {
1366                 return;
1367             }
1368             mNfcEventCallbacks.register(listener);
1369         }
1370 
1371         @Override
unregisterNfcEventCallback( INfcEventCallback listener)1372         public void unregisterNfcEventCallback(
1373                 INfcEventCallback listener) {
1374             if (!android.nfc.Flags.nfcEventListener()) {
1375                 return;
1376             }
1377             mNfcEventCallbacks.unregister(listener);
1378         }
1379     }
1380 
1381     final RemoteCallbackList<INfcEventCallback> mNfcEventCallbacks = new RemoteCallbackList<>();
1382 
1383     private interface ListenerCall {
invoke(INfcEventCallback listener)1384         void invoke(INfcEventCallback listener) throws RemoteException;
1385     }
1386 
callNfcEventCallbacks(ListenerCall call)1387     private void callNfcEventCallbacks(ListenerCall call) {
1388         synchronized (mNfcEventCallbacks) {
1389             int numListeners = mNfcEventCallbacks.beginBroadcast();
1390             try {
1391                 IntStream.range(0, numListeners).forEach(i -> {
1392                     try {
1393                         call.invoke(mNfcEventCallbacks.getBroadcastItem(i));
1394                     } catch (RemoteException re) {
1395                         Log.i(TAG, "callNfcEventCallbacks: Service died", re);
1396                     }
1397                 });
1398 
1399             } finally {
1400                 mNfcEventCallbacks.finishBroadcast();
1401             }
1402         }
1403     }
1404 
notifyPreferredServiceListeners(ComponentNameAndUser preferredService)1405     void notifyPreferredServiceListeners(ComponentNameAndUser preferredService) {
1406         if (!android.nfc.Flags.nfcEventListener()) {
1407             return;
1408         }
1409         callNfcEventCallbacks(listener -> listener.onPreferredServiceChanged(preferredService));
1410     }
1411 
1412     @Override
onAidConflict(@onNull String aid)1413     public void onAidConflict(@NonNull String aid) {
1414         if (android.nfc.Flags.nfcEventListener()) {
1415             callNfcEventCallbacks(listener -> listener.onAidConflictOccurred(aid));
1416         }
1417     }
1418 
1419     @Override
onAidNotRouted(@onNull String aid)1420     public void onAidNotRouted(@NonNull String aid) {
1421         if (android.nfc.Flags.nfcEventListener()) {
1422             callNfcEventCallbacks(listener -> listener.onAidNotRouted(aid));
1423         }
1424     }
1425 
onNfcStateChanged(int state)1426     public void onNfcStateChanged(int state) {
1427         if (android.nfc.Flags.nfcEventListener()) {
1428             callNfcEventCallbacks(listener -> listener.onNfcStateChanged(state));
1429         }
1430     }
1431 
onRemoteFieldChanged(boolean isDetected)1432     public void onRemoteFieldChanged(boolean isDetected) {
1433         if (android.nfc.Flags.nfcEventListener()) {
1434             callNfcEventCallbacks(listener -> listener.onRemoteFieldChanged(isDetected));
1435         }
1436     }
1437 
onInternalErrorReported(@ardEmulation.NfcInternalErrorType int errorType)1438     public void onInternalErrorReported(@CardEmulation.NfcInternalErrorType int errorType) {
1439         if (android.nfc.Flags.nfcEventListener()) {
1440             callNfcEventCallbacks(listener -> listener.onInternalErrorReported(errorType));
1441         }
1442     }
1443 
1444     final ForegroundUtils.Callback mForegroundCallback = new ForegroundCallbackImpl();
1445 
1446     class ForegroundCallbackImpl implements ForegroundUtils.Callback {
1447         @Override
onUidToBackground(int uid)1448         public void onUidToBackground(int uid) {
1449             synchronized (CardEmulationManager.this) {
1450                 if (mForegroundUid == uid) {
1451                     if (DBG) {
1452                         Log.d(TAG, "onUidToBackground: Uid " + uid + " switch to background");
1453                     }
1454                     mForegroundUid = Process.INVALID_UID;
1455                     mRoutingOptionManager.recoverOverridedRoutingTable();
1456                 }
1457             }
1458         }
1459     }
1460 
getRouteForSecureElement(String se)1461     private int getRouteForSecureElement(String se) {
1462         String route = se;
1463         if (route == null) {
1464             return -1;
1465         }
1466 
1467         if (route.equals("DH")) {
1468             return 0;
1469         }
1470 
1471         if (route.length() == 3) {
1472             route = route + '1';
1473         }
1474         return mRoutingOptionManager.getRouteForSecureElement(route);
1475     }
1476 
1477     /**
1478      * This class implements the application-facing APIs and are called
1479      * from binder. All calls must be permission-checked.
1480      */
1481     final class NfcFCardEmulationInterface extends INfcFCardEmulation.Stub {
1482         @Override
getSystemCodeForService(int userId, ComponentName service)1483         public String getSystemCodeForService(int userId, ComponentName service)
1484                 throws RemoteException {
1485             NfcPermissions.validateUserId(userId);
1486             NfcPermissions.enforceUserPermissions(mContext);
1487             if (!isNfcFServiceInstalled(userId, service)) {
1488                 return null;
1489             }
1490             return mNfcFServicesCache.getSystemCodeForService(
1491                     userId, Binder.getCallingUid(), service);
1492         }
1493 
1494         @Override
registerSystemCodeForService(int userId, ComponentName service, String systemCode)1495         public boolean registerSystemCodeForService(int userId, ComponentName service,
1496                 String systemCode)
1497                 throws RemoteException {
1498             NfcPermissions.validateUserId(userId);
1499             NfcPermissions.enforceUserPermissions(mContext);
1500             if (!isNfcFServiceInstalled(userId, service)) {
1501                 return false;
1502             }
1503             return mNfcFServicesCache.registerSystemCodeForService(
1504                     userId, Binder.getCallingUid(), service, systemCode);
1505         }
1506 
1507         @Override
removeSystemCodeForService(int userId, ComponentName service)1508         public boolean removeSystemCodeForService(int userId, ComponentName service)
1509                 throws RemoteException {
1510             NfcPermissions.validateUserId(userId);
1511             NfcPermissions.enforceUserPermissions(mContext);
1512             if (!isNfcFServiceInstalled(userId, service)) {
1513                 return false;
1514             }
1515             return mNfcFServicesCache.removeSystemCodeForService(
1516                     userId, Binder.getCallingUid(), service);
1517         }
1518 
1519         @Override
getNfcid2ForService(int userId, ComponentName service)1520         public String getNfcid2ForService(int userId, ComponentName service)
1521                 throws RemoteException {
1522             NfcPermissions.validateUserId(userId);
1523             NfcPermissions.enforceUserPermissions(mContext);
1524             if (!isNfcFServiceInstalled(userId, service)) {
1525                 return null;
1526             }
1527             return mNfcFServicesCache.getNfcid2ForService(
1528                     userId, Binder.getCallingUid(), service);
1529         }
1530 
1531         @Override
setNfcid2ForService(int userId, ComponentName service, String nfcid2)1532         public boolean setNfcid2ForService(int userId,
1533                 ComponentName service, String nfcid2) throws RemoteException {
1534             NfcPermissions.validateUserId(userId);
1535             NfcPermissions.enforceUserPermissions(mContext);
1536             if (!isNfcFServiceInstalled(userId, service)) {
1537                 return false;
1538             }
1539             return mNfcFServicesCache.setNfcid2ForService(
1540                     userId, Binder.getCallingUid(), service, nfcid2);
1541         }
1542 
1543         @Override
enableNfcFForegroundService(ComponentName service)1544         public boolean enableNfcFForegroundService(ComponentName service)
1545                 throws RemoteException {
1546             NfcPermissions.enforceUserPermissions(mContext);
1547             if (isNfcFServiceInstalled(UserHandle.getUserHandleForUid(
1548                     Binder.getCallingUid()).getIdentifier(), service)) {
1549                 return mEnabledNfcFServices.registerEnabledForegroundService(service,
1550                         Binder.getCallingUid());
1551             }
1552             return false;
1553         }
1554 
1555         @Override
disableNfcFForegroundService()1556         public boolean disableNfcFForegroundService() throws RemoteException {
1557             NfcPermissions.enforceUserPermissions(mContext);
1558             return mEnabledNfcFServices.unregisteredEnabledForegroundService(
1559                     Binder.getCallingUid());
1560         }
1561 
1562         @Override
getNfcFServices(int userId)1563         public List<NfcFServiceInfo> getNfcFServices(int userId)
1564                 throws RemoteException {
1565             NfcPermissions.validateProfileId(mContext, userId);
1566             NfcPermissions.enforceUserPermissions(mContext);
1567             return mNfcFServicesCache.getServices(userId);
1568         }
1569 
1570         @Override
getMaxNumOfRegisterableSystemCodes()1571         public int getMaxNumOfRegisterableSystemCodes()
1572                 throws RemoteException {
1573             NfcPermissions.enforceUserPermissions(mContext);
1574             return NfcService.getInstance().getLfT3tMax();
1575         }
1576     }
1577 
1578     @Override
onPreferredPaymentServiceChanged(ComponentNameAndUser service)1579     public void onPreferredPaymentServiceChanged(ComponentNameAndUser service) {
1580         Log.i(TAG, "onPreferredPaymentServiceChanged");
1581         ComponentNameAndUser oldPreferredService = mAidCache.getPreferredService();
1582         mAidCache.onPreferredPaymentServiceChanged(service);
1583         mHostEmulationManager.onPreferredPaymentServiceChanged(service);
1584         ComponentNameAndUser newPreferredService = mAidCache.getPreferredService();
1585 
1586         NfcService.getInstance().onPreferredPaymentChanged(
1587                     NfcAdapter.PREFERRED_PAYMENT_CHANGED);
1588         if (!Objects.equals(oldPreferredService, newPreferredService)) {
1589             updateForShouldDefaultToObserveMode(newPreferredService.getUserId());
1590             notifyPreferredServiceListeners(newPreferredService);
1591         }
1592     }
1593 
1594     @Override
onPreferredForegroundServiceChanged(ComponentNameAndUser service)1595     public void onPreferredForegroundServiceChanged(ComponentNameAndUser service) {
1596         Log.i(TAG, "onPreferredForegroundServiceChanged");
1597         ComponentNameAndUser oldPreferredService = mAidCache.getPreferredService();
1598         mHostEmulationManager.onPreferredForegroundServiceChanged(service);
1599         ComponentNameAndUser newPreferredService = mAidCache.getPreferredService();
1600 
1601         NfcService.getInstance().onPreferredPaymentChanged(
1602                 NfcAdapter.PREFERRED_PAYMENT_CHANGED);
1603         if (!Objects.equals(oldPreferredService, newPreferredService)) {
1604             updateForShouldDefaultToObserveMode(newPreferredService.getUserId());
1605             notifyPreferredServiceListeners(newPreferredService);
1606         }
1607     }
1608 
updateForDefaultSwpToEuicc()1609     public void updateForDefaultSwpToEuicc() {
1610         if (!android.nfc.Flags.enableCardEmulationEuicc()) {
1611             Log.d(TAG, "updateForDefaultSwpToEuicc: Euicc CardEmulation isn't  enabled");
1612             return;
1613         }
1614 
1615         if (!mContext.getResources().getBoolean(R.bool.enable_euicc_support)
1616                 || !NfcInjector.NfcProperties.isEuiccSupported()) {
1617             Log.d(TAG, "updateForDefaultSwpToEuicc: Euicc CardEmulation is not support");
1618             return;
1619         }
1620 
1621         if (DBG) Log.d(TAG, "updateForDefaultSwpToEuicc: Assign SWP for eSIM before NFC turned on");
1622 
1623         int preferredSubscriptionId = mPreferredSubscriptionService.getPreferredSubscriptionId();
1624         String response = mTelephonyUtils
1625                 .updateSwpStatusForEuicc(getSimTypeById(preferredSubscriptionId));
1626         Log.d(TAG, "updateForDefaultSwpToEuicc: response: " + response);
1627         if (response.length() >= 4) {
1628             String statusWord = response.substring(response.length() - 4);
1629             if (!TextUtils.equals(statusWord, "9000")) {
1630                 Log.e(TAG, "updateForDefaultSwpToEuicc: ASSIGN_SWP(LSE) Command is fail: "
1631                         + statusWord);
1632             }
1633         } else {
1634             Log.e(TAG, "updateForDefaultSwpToEuicc: response.length() is wrong length : "
1635                     + response.length());
1636         }
1637     }
1638 
getSimTypeById(int subscriptionId)1639     private int getSimTypeById(int subscriptionId) {
1640         Optional<SubscriptionInfo> optionalInfo =
1641                 mTelephonyUtils.getActiveSubscriptionInfoById(subscriptionId);
1642         if (optionalInfo.isPresent()) {
1643             SubscriptionInfo info = optionalInfo.get();
1644             if (info.isEmbedded()) {
1645                 return info.getPortIndex() == 0
1646                         ? TelephonyUtils.SIM_TYPE_EUICC_1 : TelephonyUtils.SIM_TYPE_EUICC_2;
1647             }
1648             else {
1649                 return TelephonyUtils.SIM_TYPE_UICC;
1650             }
1651         }
1652 
1653         return TelephonyUtils.SIM_TYPE_UNKNOWN;
1654     }
1655 
updateForShouldDefaultToObserveMode(int userId)1656     public void updateForShouldDefaultToObserveMode(int userId) {
1657         long token = Binder.clearCallingIdentity();
1658         try {
1659             NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
1660             if (adapter == null) {
1661                 Log.e(TAG, "updateForShouldDefaultToObserveMode: adapter is null, returning");
1662                 return;
1663             }
1664             ComponentNameAndUser preferredServiceAndUser = mAidCache.getPreferredService();
1665             if (preferredServiceAndUser == null) {
1666                 return;
1667             }
1668             ComponentName preferredService = preferredServiceAndUser.getComponentName();
1669             boolean enableObserveMode = mServiceCache.doesServiceShouldDefaultToObserveMode(userId,
1670                     preferredService);
1671             mHostEmulationManager.updateForShouldDefaultToObserveMode(enableObserveMode);
1672         } finally {
1673             Binder.restoreCallingIdentity(token);
1674         }
1675     }
1676 
updateFirmwareExitFramesForWalletRole(int userId)1677     public void updateFirmwareExitFramesForWalletRole(int userId) {
1678         if (!Flags.exitFrames()) {
1679             return;
1680         }
1681 
1682         NfcService nfcService = NfcService.getInstance();
1683         if (!nfcService.isFirmwareExitFramesSupported()
1684                 || nfcService.getNumberOfFirmwareExitFramesSupported() <= 0) {
1685             return;
1686         }
1687 
1688         // Get all services then find those associated with role holder
1689         Stream<ApduServiceInfo> roleServices = mServiceCache.getServices(userId).stream().filter(
1690                 serviceInfo -> mAidCache.isDefaultOrAssociatedWalletService(serviceInfo, userId));
1691 
1692         // Not every pattern filter is a valid exit frame, so this function catches
1693         // exceptions that could be thrown creating an ExitFrame object from a pattern.
1694         Function<String, ExitFrame> toExitFrameOrNull = (s) -> {
1695             try {
1696                 return new ExitFrame(s);
1697             } catch (Exception e) {
1698                 return null;
1699             }
1700         };
1701         // Combine filters and pattern filters, slice to size of supported, build list of exit
1702         // frames
1703         List<ExitFrame> exitFrames = roleServices.flatMap(serviceInfo ->
1704                         Stream.concat(
1705                                         serviceInfo.getPollingLoopFilters().stream(),
1706                                         serviceInfo.getPollingLoopPatternFilters()
1707                                                 .stream().map(Pattern::toString)
1708                                 )
1709                                 .filter(
1710                                         serviceInfo::getShouldAutoTransact))
1711                 .distinct()
1712                 .map(toExitFrameOrNull)
1713                 .filter(Objects::nonNull)
1714                 .limit(nfcService.getNumberOfFirmwareExitFramesSupported())
1715                 .collect(Collectors.toList());
1716         Log.d(TAG, "updateFirmwareExitFramesForWalletRole: " + exitFrames.size() + " frames");
1717         nfcService.setFirmwareExitFrameTable(exitFrames, FIRMWARE_EXIT_FRAME_TIMEOUT_MS);
1718     }
1719 
onObserveModeStateChange(boolean enabled)1720     public void onObserveModeStateChange(boolean enabled) {
1721         mHostEmulationManager.onObserveModeStateChange(enabled);
1722         if (android.nfc.Flags.nfcEventListener()) {
1723             callNfcEventCallbacks(listener -> listener.onObserveModeStateChanged(enabled));
1724         }
1725     }
1726 
onObserveModeDisabledInFirmware(PollingFrame exitFrame)1727     public void onObserveModeDisabledInFirmware(PollingFrame exitFrame) {
1728         if (android.nfc.Flags.nfcEventListener()) {
1729             callNfcEventCallbacks(listener -> listener.onObserveModeDisabledInFirmware(exitFrame));
1730         }
1731         mHostEmulationManager.onObserveModeDisabledInFirmware(exitFrame);
1732 
1733         if (mStatsdUtils != null) {
1734             mStatsdUtils.logAutoTransactReported(StatsdUtils.PROCESSOR_NFCC, exitFrame.getData());
1735         }
1736     }
1737 
1738     @Override
onWalletRoleHolderChanged(String holder, int userId)1739     public void onWalletRoleHolderChanged(String holder, int userId) {
1740         mPreferredServices.onWalletRoleHolderChanged(holder, userId);
1741         mAidCache.onWalletRoleHolderChanged(holder, userId);
1742         if (Flags.exitFrames()) {
1743             updateFirmwareExitFramesForWalletRole(userId);
1744         }
1745     }
1746 
1747     @Override
onEnabledForegroundNfcFServiceChanged(int userId, ComponentName service)1748     public void onEnabledForegroundNfcFServiceChanged(int userId, ComponentName service) {
1749         mT3tIdentifiersCache.onEnabledForegroundNfcFServiceChanged(userId, service);
1750         mHostNfcFEmulationManager.onEnabledForegroundNfcFServiceChanged(userId, service);
1751     }
1752 
getRegisteredAidCategory(String aid)1753     public String getRegisteredAidCategory(String aid) {
1754         RegisteredAidCache.AidResolveInfo resolvedInfo = mAidCache.resolveAid(aid);
1755         if (resolvedInfo != null) {
1756             return resolvedInfo.getCategory();
1757         }
1758         return "";
1759     }
1760 
isRequiresScreenOnServiceExist()1761     public boolean isRequiresScreenOnServiceExist() {
1762         return mAidCache.isRequiresScreenOnServiceExist();
1763     }
1764 
isPreferredServicePackageNameForUser(String packageName, int userId)1765     public boolean isPreferredServicePackageNameForUser(String packageName, int userId) {
1766         return mAidCache.isPreferredServicePackageNameForUser(packageName, userId);
1767     }
1768 
isHostCardEmulationActivated()1769     public boolean isHostCardEmulationActivated() {
1770         return mHostEmulationManager.isHostCardEmulationActivated();
1771     }
1772 }
1773