• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 
17 package com.android.nfc;
18 
19 import android.app.ActivityManager;
20 import android.app.Application;
21 import android.app.BroadcastOptions;
22 import android.app.KeyguardManager;
23 import android.app.KeyguardManager.KeyguardLockedStateListener;
24 import android.app.PendingIntent;
25 import android.app.VrManager;
26 import android.app.admin.DevicePolicyManager;
27 import android.app.backup.BackupManager;
28 import android.content.BroadcastReceiver;
29 import android.content.ComponentName;
30 import android.content.ContentResolver;
31 import android.content.Context;
32 import android.content.Intent;
33 import android.content.IntentFilter;
34 import android.content.SharedPreferences;
35 import android.content.pm.ApplicationInfo;
36 import android.content.pm.PackageInfo;
37 import android.content.pm.PackageManager;
38 import android.content.res.Resources.NotFoundException;
39 import android.database.ContentObserver;
40 import android.media.AudioAttributes;
41 import android.media.SoundPool;
42 import android.net.Uri;
43 import android.nfc.AvailableNfcAntenna;
44 import android.nfc.NfcFrameworkInitializer;
45 import android.nfc.NfcServiceManager;
46 import android.nfc.cardemulation.CardEmulation;
47 import android.nfc.ErrorCodes;
48 import android.nfc.FormatException;
49 import android.nfc.IAppCallback;
50 import android.nfc.INfcAdapter;
51 import android.nfc.INfcAdapterExtras;
52 import android.nfc.INfcCardEmulation;
53 import android.nfc.INfcControllerAlwaysOnListener;
54 import android.nfc.INfcDta;
55 import android.nfc.INfcFCardEmulation;
56 import android.nfc.INfcTag;
57 import android.nfc.INfcUnlockHandler;
58 import android.nfc.ITagRemovedCallback;
59 import android.nfc.NdefMessage;
60 import android.nfc.NfcAdapter;
61 import android.nfc.NfcAntennaInfo;
62 import android.nfc.Tag;
63 import android.nfc.TechListParcel;
64 import android.nfc.TransceiveResult;
65 import android.nfc.tech.Ndef;
66 import android.nfc.tech.TagTechnology;
67 import android.os.AsyncTask;
68 import android.os.Binder;
69 import android.os.Build;
70 import android.os.Bundle;
71 import android.os.Handler;
72 import android.os.IBinder;
73 import android.os.Message;
74 import android.os.PowerManager;
75 import android.os.Process;
76 import android.os.RemoteException;
77 import android.os.ServiceManager;
78 import android.os.SystemClock;
79 import android.os.SystemProperties;
80 import android.os.UserHandle;
81 import android.os.UserManager;
82 import android.os.VibrationAttributes;
83 import android.os.VibrationEffect;
84 import android.os.Vibrator;
85 import android.provider.Settings;
86 import android.provider.Settings.SettingNotFoundException;
87 import android.se.omapi.ISecureElementService;
88 import android.sysprop.NfcProperties;
89 import android.text.TextUtils;
90 import android.util.EventLog;
91 import android.util.Log;
92 import android.util.proto.ProtoOutputStream;
93 import android.widget.Toast;
94 
95 import com.android.nfc.DeviceHost.DeviceHostListener;
96 import com.android.nfc.DeviceHost.LlcpConnectionlessSocket;
97 import com.android.nfc.DeviceHost.LlcpServerSocket;
98 import com.android.nfc.DeviceHost.LlcpSocket;
99 import com.android.nfc.DeviceHost.NfcDepEndpoint;
100 import com.android.nfc.DeviceHost.TagEndpoint;
101 import com.android.nfc.cardemulation.CardEmulationManager;
102 import com.android.nfc.dhimpl.NativeNfcManager;
103 import com.android.nfc.Utils;
104 import com.android.nfc.handover.HandoverDataParser;
105 
106 import org.json.JSONException;
107 import org.json.JSONObject;
108 
109 import java.io.File;
110 import java.io.FileDescriptor;
111 import java.io.FileOutputStream;
112 import java.io.IOException;
113 import java.io.PrintWriter;
114 import java.io.UnsupportedEncodingException;
115 import java.nio.ByteBuffer;
116 import java.nio.file.Files;
117 import java.security.SecureRandom;
118 import java.util.ArrayList;
119 import java.util.Arrays;
120 import java.util.Collections;
121 import java.util.HashMap;
122 import java.util.HashSet;
123 import java.util.Iterator;
124 import java.util.List;
125 import java.util.Map;
126 import java.util.NoSuchElementException;
127 import java.util.Scanner;
128 import java.util.Set;
129 import java.util.concurrent.atomic.AtomicInteger;
130 import java.util.stream.Collectors;
131 
132 public class NfcService implements DeviceHostListener, ForegroundUtils.Callback {
133     static final boolean DBG = NfcProperties.debug_enabled().orElse(false);
134     static final String TAG = "NfcService";
135 
136     public static final String SERVICE_NAME = "nfc";
137 
138     private static final String SYSTEM_UI = "com.android.systemui";
139 
140     public static final String PREF = "NfcServicePrefs";
141     public static final String PREF_TAG_APP_LIST = "TagIntentAppPreferenceListPrefs";
142 
143     static final String PREF_NFC_ON = "nfc_on";
144     static final boolean NFC_ON_DEFAULT = true;
145     static final String PREF_SECURE_NFC_ON = "secure_nfc_on";
146     static final boolean SECURE_NFC_ON_DEFAULT = false;
147     static final String PREF_FIRST_BOOT = "first_boot";
148 
149     static final String PREF_ANTENNA_BLOCKED_MESSAGE_SHOWN = "antenna_blocked_message_shown";
150     static final boolean ANTENNA_BLOCKED_MESSAGE_SHOWN_DEFAULT = false;
151 
152     static final String NATIVE_LOG_FILE_NAME = "native_crash_logs";
153     static final String NATIVE_LOG_FILE_PATH = "/data/misc/nfc/logs";
154     static final int NATIVE_CRASH_FILE_SIZE = 1024 * 1024;
155 
156     static final int MSG_NDEF_TAG = 0;
157     // Previously used: MSG_LLCP_LINK_ACTIVATION = 1
158     // Previously used: MSG_LLCP_LINK_DEACTIVATED = 2
159     static final int MSG_MOCK_NDEF = 3;
160     // Previously used: MSG_LLCP_LINK_FIRST_PACKET = 4
161     static final int MSG_ROUTE_AID = 5;
162     static final int MSG_UNROUTE_AID = 6;
163     static final int MSG_COMMIT_ROUTING = 7;
164     // Previously used: MSG_INVOKE_BEAM = 8
165     static final int MSG_RF_FIELD_ACTIVATED = 9;
166     static final int MSG_RF_FIELD_DEACTIVATED = 10;
167     static final int MSG_RESUME_POLLING = 11;
168     static final int MSG_REGISTER_T3T_IDENTIFIER = 12;
169     static final int MSG_DEREGISTER_T3T_IDENTIFIER = 13;
170     static final int MSG_TAG_DEBOUNCE = 14;
171     // Previously used: MSG_UPDATE_STATS = 15
172     static final int MSG_APPLY_SCREEN_STATE = 16;
173     static final int MSG_TRANSACTION_EVENT = 17;
174     static final int MSG_PREFERRED_PAYMENT_CHANGED = 18;
175     static final int MSG_TOAST_DEBOUNCE_EVENT = 19;
176     static final int MSG_DELAY_POLLING = 20;
177 
178     static final String MSG_ROUTE_AID_PARAM_TAG = "power";
179 
180     // Negative value for NO polling delay
181     static final int NO_POLL_DELAY = -1;
182 
183     static final long MAX_POLLING_PAUSE_TIMEOUT = 40000;
184 
185     static final int MAX_TOAST_DEBOUNCE_TIME = 10000;
186 
187     static final int TASK_ENABLE = 1;
188     static final int TASK_DISABLE = 2;
189     static final int TASK_BOOT = 3;
190     static final int TASK_ENABLE_ALWAYS_ON = 4;
191     static final int TASK_DISABLE_ALWAYS_ON = 5;
192 
193     // Polling technology masks
194     static final int NFC_POLL_A = 0x01;
195     static final int NFC_POLL_B = 0x02;
196     static final int NFC_POLL_F = 0x04;
197     static final int NFC_POLL_V = 0x08;
198     static final int NFC_POLL_B_PRIME = 0x10;
199     static final int NFC_POLL_KOVIO = 0x20;
200 
201     // minimum screen state that enables NFC polling
202     static final int NFC_POLLING_MODE = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED;
203 
204     // Time to wait for NFC controller to initialize before watchdog
205     // goes off. This time is chosen large, because firmware download
206     // may be a part of initialization.
207     static final int INIT_WATCHDOG_MS = 90000;
208 
209     // Time to wait for routing to be applied before watchdog
210     // goes off
211     static final int ROUTING_WATCHDOG_MS = 10000;
212 
213     // Default delay used for presence checks
214     static final int DEFAULT_PRESENCE_CHECK_DELAY = 125;
215 
216     static final NfcProperties.snoop_log_mode_values NFC_SNOOP_LOG_MODE =
217             NfcProperties.snoop_log_mode().orElse(NfcProperties.snoop_log_mode_values.FILTERED);
218     static final boolean NFC_VENDOR_DEBUG_ENABLED = NfcProperties.vendor_debug_enabled().orElse(false);
219 
220     // RF field events as defined in NFC extras
221     public static final String ACTION_RF_FIELD_ON_DETECTED =
222             "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED";
223     public static final String ACTION_RF_FIELD_OFF_DETECTED =
224             "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED";
225 
226     public static boolean sIsShortRecordLayout = false;
227 
228     // for use with playSound()
229     public static final int SOUND_START = 0;
230     public static final int SOUND_END = 1;
231     public static final int SOUND_ERROR = 2;
232 
233     public static final int NCI_VERSION_2_0 = 0x20;
234 
235     public static final int NCI_VERSION_1_0 = 0x10;
236 
237     public static final String ACTION_LLCP_UP =
238             "com.android.nfc.action.LLCP_UP";
239 
240     public static final String ACTION_LLCP_DOWN =
241             "com.android.nfc.action.LLCP_DOWN";
242 
243     // Timeout to re-apply routing if a tag was present and we postponed it
244     private static final int APPLY_ROUTING_RETRY_TIMEOUT_MS = 5000;
245 
246     private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES =
247             VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK);
248 
249     private final UserManager mUserManager;
250     private final ActivityManager mActivityManager;
251 
252     private static int nci_version = NCI_VERSION_1_0;
253     // NFC Execution Environment
254     // fields below are protected by this
255     private final boolean mPollingDisableAllowed;
256     private HashMap<Integer, ReaderModeDeathRecipient> mPollingDisableDeathRecipients =
257             new HashMap<Integer, ReaderModeDeathRecipient>();
258     private final ReaderModeDeathRecipient mReaderModeDeathRecipient =
259             new ReaderModeDeathRecipient();
260     private final SeServiceDeathRecipient mSeServiceDeathRecipient =
261             new SeServiceDeathRecipient();
262     private final NfcUnlockManager mNfcUnlockManager;
263 
264     private final BackupManager mBackupManager;
265 
266     private final SecureRandom mCookieGenerator = new SecureRandom();
267 
268     // Tag app preference list for the target UserId.
269     HashMap<Integer, HashMap<String, Boolean>> mTagAppPrefList =
270             new HashMap<Integer, HashMap<String, Boolean>>();
271 
272     // cached version of installed packages requesting Android.permission.NFC_TRANSACTION_EVENTS
273     // for current user and profiles. The Integer part is the userId.
274     HashMap<Integer, List<String>> mNfcEventInstalledPackages =
275             new HashMap<Integer, List<String>>();
276 
277     // cached version of installed packages requesting
278     // Android.permission.NFC_PREFERRED_PAYMENT_INFO for current user and profiles.
279     // The Integer part is the userId.
280     HashMap<Integer, List<String>> mNfcPreferredPaymentChangedInstalledPackages =
281             new HashMap<Integer, List<String>>();
282 
283     // fields below are used in multiple threads and protected by synchronized(this)
284     final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>();
285     int mScreenState;
286     boolean mInProvisionMode; // whether we're in setup wizard and enabled NFC provisioning
287     boolean mIsSecureNfcEnabled;
288     boolean mSkipNdefRead;
289     NfcDiscoveryParameters mCurrentDiscoveryParameters =
290             NfcDiscoveryParameters.getNfcOffParameters();
291 
292     ReaderModeParams mReaderModeParams;
293 
294     private int mUserId;
295     boolean mPollingPaused;
296 
297     // True if nfc notification message already shown
298     boolean mAntennaBlockedMessageShown;
299     private static int mDispatchFailedCount;
300     private static int mDispatchFailedMax;
301 
302     static final int INVALID_NATIVE_HANDLE = -1;
303     byte mDebounceTagUid[];
304     int mDebounceTagDebounceMs;
305     int mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE;
306     ITagRemovedCallback mDebounceTagRemovedCallback;
307 
308     // Only accessed on one thread so doesn't need locking
309     NdefMessage mLastReadNdefMessage;
310 
311     // mState is protected by this, however it is only modified in onCreate()
312     // and the default AsyncTask thread so it is read unprotected from that
313     // thread
314     int mState;  // one of NfcAdapter.STATE_ON, STATE_TURNING_ON, etc
315     // mAlwaysOnState is protected by this, however it is only modified in onCreate()
316     // and the default AsyncTask thread so it is read unprotected from that thread
317     int mAlwaysOnState;  // one of NfcAdapter.STATE_ON, STATE_TURNING_ON, etc
318     // fields below are final after onCreate()
319     Context mContext;
320     private DeviceHost mDeviceHost;
321     private SharedPreferences mPrefs;
322     private SharedPreferences.Editor mPrefsEditor;
323     private SharedPreferences mTagAppPrefListPrefs;
324 
325     private PowerManager.WakeLock mRoutingWakeLock;
326     private PowerManager.WakeLock mRequireUnlockWakeLock;
327 
328     int mStartSound;
329     int mEndSound;
330     int mErrorSound;
331     SoundPool mSoundPool; // playback synchronized on this
332     TagService mNfcTagService;
333     NfcAdapterService mNfcAdapter;
334     NfcDtaService mNfcDtaService;
335     RoutingTableParser mRoutingTableParser;
336     boolean mIsDebugBuild;
337     boolean mIsHceCapable;
338     boolean mIsHceFCapable;
339     boolean mIsSecureNfcCapable;
340     boolean mIsRequestUnlockShowed;
341     boolean mIsRecovering;
342 
343     // polling delay control variables
344     private final int mPollDelayTime;
345     private final int mPollDelayTimeLong;
346     private final int mPollDelayCountMax;
347     private int mPollDelayCount;
348     private boolean mPollDelayed;
349 
350     boolean mNotifyDispatchFailed;
351     boolean mNotifyReadFailed;
352 
353     // for recording the latest Tag object cookie
354     long mCookieUpToDate = -1;
355 
356     private NfcDispatcher mNfcDispatcher;
357     private PowerManager mPowerManager;
358     private KeyguardManager mKeyguard;
359     private HandoverDataParser mHandoverDataParser;
360     private ContentResolver mContentResolver;
361     private CardEmulationManager mCardEmulationManager;
362     private Vibrator mVibrator;
363     private VibrationEffect mVibrationEffect;
364     private ISecureElementService mSEService;
365     private VrManager mVrManager;
366 
367     private ScreenStateHelper mScreenStateHelper;
368     private ForegroundUtils mForegroundUtils;
369 
370     private static NfcService sService;
371     private static boolean sToast_debounce = false;
372     private static int sToast_debounce_time_ms = 3000;
373     public  static boolean sIsDtaMode = false;
374 
375     boolean mIsVrModeEnabled;
376 
377     private final boolean mIsTagAppPrefSupported;
378 
379     private final boolean mIsAlwaysOnSupported;
380     private final Set<INfcControllerAlwaysOnListener> mAlwaysOnListeners =
381             Collections.synchronizedSet(new HashSet<>());
382 
getInstance()383     public static NfcService getInstance() {
384         return sService;
385     }
386 
387     @Override
onRemoteEndpointDiscovered(TagEndpoint tag)388     public void onRemoteEndpointDiscovered(TagEndpoint tag) {
389         sendMessage(NfcService.MSG_NDEF_TAG, tag);
390     }
391 
392     /**
393      * Notifies transaction
394      */
395     @Override
onHostCardEmulationActivated(int technology)396     public void onHostCardEmulationActivated(int technology) {
397         if (mCardEmulationManager != null) {
398             mCardEmulationManager.onHostCardEmulationActivated(technology);
399         }
400     }
401 
402     @Override
onHostCardEmulationData(int technology, byte[] data)403     public void onHostCardEmulationData(int technology, byte[] data) {
404         if (mCardEmulationManager != null) {
405             mCardEmulationManager.onHostCardEmulationData(technology, data);
406         }
407     }
408 
409     @Override
onHostCardEmulationDeactivated(int technology)410     public void onHostCardEmulationDeactivated(int technology) {
411         if (mCardEmulationManager != null) {
412             mCardEmulationManager.onHostCardEmulationDeactivated(technology);
413         }
414     }
415 
416     /**
417      * Notifies P2P Device detected, to activate LLCP link
418      */
419     @Override
onLlcpLinkActivated(NfcDepEndpoint device)420     public void onLlcpLinkActivated(NfcDepEndpoint device) {
421     }
422 
423     /**
424      * Notifies P2P Device detected, to activate LLCP link
425      */
426     @Override
onLlcpLinkDeactivated(NfcDepEndpoint device)427     public void onLlcpLinkDeactivated(NfcDepEndpoint device) {
428     }
429 
430     /**
431      * Notifies P2P Device detected, first packet received over LLCP link
432      */
433     @Override
onLlcpFirstPacketReceived(NfcDepEndpoint device)434     public void onLlcpFirstPacketReceived(NfcDepEndpoint device) {
435     }
436 
437     @Override
onRemoteFieldActivated()438     public void onRemoteFieldActivated() {
439         sendMessage(NfcService.MSG_RF_FIELD_ACTIVATED, null);
440     }
441 
442     @Override
onRemoteFieldDeactivated()443     public void onRemoteFieldDeactivated() {
444         sendMessage(NfcService.MSG_RF_FIELD_DEACTIVATED, null);
445     }
446 
447     @Override
onNfcTransactionEvent(byte[] aid, byte[] data, String seName)448     public void onNfcTransactionEvent(byte[] aid, byte[] data, String seName) {
449         byte[][] dataObj = {aid, data, seName.getBytes()};
450         sendMessage(NfcService.MSG_TRANSACTION_EVENT, dataObj);
451     }
452 
453     @Override
onEeUpdated()454     public void onEeUpdated() {
455         new ApplyRoutingTask().execute();
456     }
457 
458     @Override
onHwErrorReported()459     public void onHwErrorReported() {
460         try {
461             mContext.unregisterReceiver(mReceiver);
462         } catch (IllegalArgumentException e) {
463             Log.w(TAG, "Failed to unregisterScreenState BroadCastReceiver: " + e);
464         }
465         mIsRecovering = true;
466         new EnableDisableTask().execute(TASK_DISABLE);
467         new EnableDisableTask().execute(TASK_ENABLE);
468     }
469 
470     final class ReaderModeParams {
471         public int flags;
472         public IAppCallback callback;
473         public int presenceCheckDelay;
474         public IBinder binder;
475         public int uid;
476     }
477 
saveNfcOnSetting(boolean on)478     void saveNfcOnSetting(boolean on) {
479         synchronized (NfcService.this) {
480             mPrefsEditor.putBoolean(PREF_NFC_ON, on);
481             mPrefsEditor.apply();
482             mBackupManager.dataChanged();
483         }
484     }
485 
getNfcOnSetting()486     boolean getNfcOnSetting() {
487         synchronized (NfcService.this) {
488             return mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT);
489         }
490     }
491 
492     /**
493      * @hide constant copied from {@link Settings.Global}
494      * TODO(b/274636414): Migrate to official API in Android V.
495      */
496     private static final String SETTINGS_SATELLITE_MODE_RADIOS = "satellite_mode_radios";
497     /**
498      * @hide constant copied from {@link Settings.Global}
499      * TODO(b/274636414): Migrate to official API in Android V.
500      */
501     private static final String SETTINGS_SATELLITE_MODE_ENABLED = "satellite_mode_enabled";
502 
isSatelliteModeSensitive()503     private boolean isSatelliteModeSensitive() {
504         final String satelliteRadios =
505                 Settings.Global.getString(mContentResolver, SETTINGS_SATELLITE_MODE_RADIOS);
506         return satelliteRadios == null || satelliteRadios.contains(Settings.Global.RADIO_NFC);
507     }
508 
509     /** Returns true if satellite mode is turned on. */
isSatelliteModeOn()510     private boolean isSatelliteModeOn() {
511         if (!isSatelliteModeSensitive()) return false;
512         return Settings.Global.getInt(mContentResolver, SETTINGS_SATELLITE_MODE_ENABLED, 0) == 1;
513     }
514 
shouldEnableNfc()515     boolean shouldEnableNfc() {
516         return getNfcOnSetting() && !isSatelliteModeOn();
517     }
518 
NfcService(Application nfcApplication)519     public NfcService(Application nfcApplication) {
520         mUserId = ActivityManager.getCurrentUser();
521         mContext = nfcApplication;
522 
523         mNfcTagService = new TagService();
524         mNfcAdapter = new NfcAdapterService();
525         mRoutingTableParser = new RoutingTableParser();
526         Log.i(TAG, "Starting NFC service");
527 
528         sService = this;
529 
530         mScreenStateHelper = new ScreenStateHelper(mContext);
531         mContentResolver = mContext.getContentResolver();
532         mDeviceHost = new NativeNfcManager(mContext, this);
533 
534         mNfcUnlockManager = NfcUnlockManager.getInstance();
535 
536         mHandoverDataParser = new HandoverDataParser();
537         boolean isNfcProvisioningEnabled = false;
538         try {
539             isNfcProvisioningEnabled = mContext.getResources().getBoolean(
540                     R.bool.enable_nfc_provisioning);
541         } catch (NotFoundException e) {
542         }
543 
544         if (isNfcProvisioningEnabled) {
545             mInProvisionMode = Settings.Global.getInt(mContentResolver,
546                     Settings.Global.DEVICE_PROVISIONED, 0) == 0;
547         } else {
548             mInProvisionMode = false;
549         }
550 
551         mNfcDispatcher = new NfcDispatcher(mContext, mHandoverDataParser, mInProvisionMode);
552 
553         mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE);
554         mPrefsEditor = mPrefs.edit();
555 
556         mState = NfcAdapter.STATE_OFF;
557         mAlwaysOnState = NfcAdapter.STATE_OFF;
558 
559         mIsDebugBuild = "userdebug".equals(Build.TYPE) || "eng".equals(Build.TYPE);
560 
561         mPowerManager = mContext.getSystemService(PowerManager.class);
562 
563         mRoutingWakeLock = mPowerManager.newWakeLock(
564                 PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mRoutingWakeLock");
565 
566         mRequireUnlockWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
567                         | PowerManager.ACQUIRE_CAUSES_WAKEUP
568                         | PowerManager.ON_AFTER_RELEASE, "NfcService:mRequireUnlockWakeLock");
569 
570         mKeyguard = mContext.getSystemService(KeyguardManager.class);
571         mUserManager = mContext.getSystemService(UserManager.class);
572         mActivityManager = mContext.getSystemService(ActivityManager.class);
573         mVibrator = mContext.getSystemService(Vibrator.class);
574         mVibrationEffect = VibrationEffect.createOneShot(200, VibrationEffect.DEFAULT_AMPLITUDE);
575         mVrManager = mContext.getSystemService(VrManager.class);
576 
577         mScreenState = mScreenStateHelper.checkScreenState();
578 
579         mBackupManager = new BackupManager(mContext);
580 
581         // Intents for all users
582         IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
583         filter.addAction(Intent.ACTION_SCREEN_ON);
584         filter.addAction(Intent.ACTION_USER_PRESENT);
585         filter.addAction(Intent.ACTION_USER_SWITCHED);
586         filter.addAction(Intent.ACTION_USER_ADDED);
587         mContext.registerReceiverForAllUsers(mReceiver, filter, null, null);
588 
589         // Listen for work profile adds or removes.
590         IntentFilter managedProfileFilter = new IntentFilter();
591         managedProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
592         managedProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
593         managedProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
594         managedProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
595         mContext.registerReceiverForAllUsers(mManagedProfileReceiver,
596                 managedProfileFilter, null, null);
597 
598         IntentFilter ownerFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
599         ownerFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
600         ownerFilter.addAction(Intent.ACTION_SHUTDOWN);
601         mContext.registerReceiverForAllUsers(mOwnerReceiver, ownerFilter, null, null);
602 
603         ownerFilter = new IntentFilter();
604         ownerFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
605         ownerFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
606         ownerFilter.addDataScheme("package");
607         mContext.registerReceiverForAllUsers(mOwnerReceiver, ownerFilter, null, null);
608 
609         addKeyguardLockedStateListener();
610 
611         updatePackageCache();
612 
613         PackageManager pm = mContext.getPackageManager();
614 
615         mIsHceCapable =
616                 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION) ||
617                 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF);
618         mIsHceFCapable =
619                 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF);
620         if (mIsHceCapable) {
621             mCardEmulationManager = new CardEmulationManager(mContext);
622         }
623         mForegroundUtils = ForegroundUtils.getInstance(mActivityManager);
624 
625         mIsSecureNfcCapable = mNfcAdapter.deviceSupportsNfcSecure();
626         mIsSecureNfcEnabled =
627             mPrefs.getBoolean(PREF_SECURE_NFC_ON, SECURE_NFC_ON_DEFAULT) &&
628             mIsSecureNfcCapable;
629         mDeviceHost.setNfcSecure(mIsSecureNfcEnabled);
630 
631         sToast_debounce_time_ms =
632                 mContext.getResources().getInteger(R.integer.toast_debounce_time_ms);
633         if(sToast_debounce_time_ms > MAX_TOAST_DEBOUNCE_TIME) {
634             sToast_debounce_time_ms = MAX_TOAST_DEBOUNCE_TIME;
635         }
636 
637         // Notification message variables
638         mDispatchFailedCount = 0;
639         if (mContext.getResources().getBoolean(R.bool.enable_antenna_blocked_alert) &&
640             !mPrefs.getBoolean(PREF_ANTENNA_BLOCKED_MESSAGE_SHOWN, ANTENNA_BLOCKED_MESSAGE_SHOWN_DEFAULT)) {
641             mAntennaBlockedMessageShown = false;
642             mDispatchFailedMax =
643                 mContext.getResources().getInteger(R.integer.max_antenna_blocked_failure_count);
644         } else {
645             mAntennaBlockedMessageShown = true;
646         }
647 
648         // Polling delay count for switching from stage one to stage two.
649         mPollDelayCountMax =
650                 mContext.getResources().getInteger(R.integer.unknown_tag_polling_delay_count_max);
651         // Stage one: polling delay time for the first few unknown tag detections
652         mPollDelayTime = mContext.getResources().getInteger(R.integer.unknown_tag_polling_delay);
653         // Stage two: longer polling delay time after max_poll_delay_count
654         mPollDelayTimeLong =
655                 mContext.getResources().getInteger(R.integer.unknown_tag_polling_delay_long);
656 
657         mNotifyDispatchFailed = mContext.getResources().getBoolean(R.bool.enable_notify_dispatch_failed);
658         mNotifyReadFailed = mContext.getResources().getBoolean(R.bool.enable_notify_read_failed);
659 
660         mPollingDisableAllowed = mContext.getResources().getBoolean(R.bool.polling_disable_allowed);
661 
662         // Make sure this is only called when object construction is complete.
663         NfcServiceManager manager = NfcFrameworkInitializer.getNfcServiceManager();
664         if (manager == null) {
665             Log.e(TAG, "NfcServiceManager is null");
666             throw new UnsupportedOperationException();
667         }
668         manager.getNfcManagerServiceRegisterer().register(mNfcAdapter);
669 
670         mIsAlwaysOnSupported =
671             mContext.getResources().getBoolean(R.bool.nfcc_always_on_allowed);
672 
673         mIsTagAppPrefSupported =
674             mContext.getResources().getBoolean(R.bool.tag_intent_app_pref_supported);
675 
676         Uri uri = Settings.Global.getUriFor(SETTINGS_SATELLITE_MODE_ENABLED);
677         if (uri == null) {
678             Log.e(TAG, "satellite mode key does not exist in Settings");
679         } else {
680             mContext.getContentResolver().registerContentObserver(
681                     uri,
682                     false,
683                     new ContentObserver(null) {
684                         @Override
685                         public void onChange(boolean selfChange) {
686                             if (isSatelliteModeSensitive()) {
687                                 Log.i(TAG, "Satellite mode change detected");
688                                 if (shouldEnableNfc()) {
689                                     new EnableDisableTask().execute(TASK_ENABLE);
690                                 } else {
691                                     new EnableDisableTask().execute(TASK_DISABLE);
692                                 }
693                             }
694                         }
695                     });
696         }
697 
698         new EnableDisableTask().execute(TASK_BOOT);  // do blocking boot tasks
699 
700         if (NFC_SNOOP_LOG_MODE.equals(NfcProperties.snoop_log_mode_values.FULL) ||
701             NFC_VENDOR_DEBUG_ENABLED) {
702             new NfcDeveloperOptionNotification(mContext).startNotification();
703         }
704 
705         connectToSeService();
706     }
707 
initTagAppPrefList()708     private void initTagAppPrefList() {
709         if (!mIsTagAppPrefSupported) return;
710         mTagAppPrefList.clear();
711         mTagAppPrefListPrefs = mContext.getSharedPreferences(PREF_TAG_APP_LIST,
712                 Context.MODE_PRIVATE);
713         try {
714             if (mTagAppPrefListPrefs != null) {
715                 UserManager um = mContext.createContextAsUser(
716                         UserHandle.of(ActivityManager.getCurrentUser()), 0)
717                         .getSystemService(UserManager.class);
718                 List<UserHandle> luh = um.getEnabledProfiles();
719                 for (UserHandle uh : luh) {
720                     HashMap<String, Boolean> map = new HashMap<>();
721                     int userId = uh.getIdentifier();
722                     String jsonString =
723                             mTagAppPrefListPrefs.getString(Integer.toString(userId),
724                                     (new JSONObject()).toString());
725                     if (jsonString != null) {
726                         JSONObject jsonObject = new JSONObject(jsonString);
727                         Iterator<String> keysItr = jsonObject.keys();
728                         while (keysItr.hasNext()) {
729                             String key = keysItr.next();
730                             Boolean value = jsonObject.getBoolean(key);
731                             map.put(key, value);
732                             if (DBG) Log.d(TAG, "uid:" + userId + "key:" + key + ": " + value);
733                         }
734                     }
735                     mTagAppPrefList.put(userId, map);
736                 }
737             } else {
738                 Log.e(TAG, "Can't get PREF_TAG_APP_LIST");
739             }
740         } catch (JSONException e) {
741             Log.e(TAG, "JSONException: " + e);
742         }
743     }
744 
storeTagAppPrefList()745     private void storeTagAppPrefList() {
746         if (!mIsTagAppPrefSupported) return;
747         mTagAppPrefListPrefs = mContext.getSharedPreferences(PREF_TAG_APP_LIST,
748                 Context.MODE_PRIVATE);
749         if (mTagAppPrefListPrefs != null) {
750             UserManager um = mContext.createContextAsUser(
751                     UserHandle.of(ActivityManager.getCurrentUser()), 0)
752                     .getSystemService(UserManager.class);
753             List<UserHandle> luh = um.getEnabledProfiles();
754             for (UserHandle uh : luh) {
755                 SharedPreferences.Editor editor = mTagAppPrefListPrefs.edit();
756                 int userId = uh.getIdentifier();
757                 HashMap<String, Boolean> map;
758                 synchronized (NfcService.this) {
759                     map = mTagAppPrefList.getOrDefault(userId, new HashMap<>());
760                 }
761                 if (map.size() > 0) {
762                     String userIdStr = Integer.toString(userId);
763                     JSONObject jsonObject = new JSONObject(map);
764                     String jsonString = jsonObject.toString();
765                     editor.remove(userIdStr).putString(userIdStr, jsonString).apply();
766                 }
767             }
768         } else {
769             Log.e(TAG, "Can't get PREF_TAG_APP_LIST");
770         }
771     }
isPackageInstalled(String pkgName, int userId)772     private boolean isPackageInstalled(String pkgName, int userId) {
773         final PackageInfo info;
774         try {
775             info = mContext.createContextAsUser(UserHandle.of(userId), 0)
776                     .getPackageManager().getPackageInfo(pkgName, PackageManager.MATCH_ALL);
777         } catch (PackageManager.NameNotFoundException e) {
778             return false;
779         }
780         return info != null;
781     }
782     // Remove obsolete entries
783     // return true if the preference list changed.
renewTagAppPrefList()784     private boolean renewTagAppPrefList() {
785         if (!mIsTagAppPrefSupported) return false;
786         boolean changed = false;
787         UserManager um = mContext.createContextAsUser(
788                 UserHandle.of(ActivityManager.getCurrentUser()), 0)
789                 .getSystemService(UserManager.class);
790         List<UserHandle> luh = um.getEnabledProfiles();
791         for (UserHandle uh : luh) {
792             int userId = uh.getIdentifier();
793             synchronized (NfcService.this) {
794                 changed = mTagAppPrefList.getOrDefault(userId, new HashMap<>())
795                         .keySet().removeIf(k2 -> !isPackageInstalled(k2, userId));
796             }
797         }
798         if (DBG) Log.d(TAG, "TagAppPreference changed " + changed);
799         return changed;
800     }
801 
isSEServiceAvailable()802     private boolean isSEServiceAvailable() {
803         if (mSEService == null) {
804             connectToSeService();
805         }
806         return (mSEService != null);
807     }
808 
connectToSeService()809     private void connectToSeService() {
810         try {
811             mSEService = ISecureElementService.Stub.asInterface(ServiceManager.getService(
812                   Context.SECURE_ELEMENT_SERVICE));
813             if (mSEService != null) {
814                 IBinder seServiceBinder = mSEService.asBinder();
815                 seServiceBinder.linkToDeath(mSeServiceDeathRecipient, 0);
816             }
817         } catch (RemoteException e) {
818             Log.e(TAG, "Error Registering SE service to linktoDeath : " + e);
819         }
820     }
821 
initSoundPool()822     void initSoundPool() {
823         synchronized (this) {
824             if (mSoundPool == null) {
825                 mSoundPool = new SoundPool.Builder()
826                         .setMaxStreams(1)
827                         .setAudioAttributes(
828                                 new AudioAttributes.Builder()
829                                         .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
830                                         .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
831                                         .build())
832                         .build();
833                 mStartSound = mSoundPool.load(mContext, R.raw.start, 1);
834                 mEndSound = mSoundPool.load(mContext, R.raw.end, 1);
835                 mErrorSound = mSoundPool.load(mContext, R.raw.error, 1);
836             }
837         }
838     }
839 
releaseSoundPool()840     void releaseSoundPool() {
841         synchronized (this) {
842             if (mSoundPool != null) {
843                 mSoundPool.release();
844                 mSoundPool = null;
845             }
846         }
847     }
848 
updatePackageCache()849     void updatePackageCache() {
850         UserManager um = mContext.createContextAsUser(
851                 UserHandle.of(ActivityManager.getCurrentUser()), /*flags=*/0)
852                 .getSystemService(UserManager.class);
853         List<UserHandle> luh = um.getEnabledProfiles();
854 
855         synchronized (this) {
856             mNfcEventInstalledPackages.clear();
857             mNfcPreferredPaymentChangedInstalledPackages.clear();
858             for (UserHandle uh : luh) {
859                 if (um.isQuietModeEnabled(uh)) continue;
860 
861                 PackageManager pm;
862                 try {
863                     pm = mContext.createContextAsUser(uh, /*flags=*/0).getPackageManager();
864                 } catch (IllegalStateException e) {
865                     Log.d(TAG, "Fail to get PackageManager for user: " + uh);
866                     continue;
867                 }
868 
869                 List<PackageInfo> packagesNfcEvents = pm.getPackagesHoldingPermissions(
870                         new String[] {android.Manifest.permission.NFC_TRANSACTION_EVENT},
871                         PackageManager.GET_ACTIVITIES);
872                 List<PackageInfo> packagesNfcPreferredPaymentChanged =
873                         pm.getPackagesHoldingPermissions(
874                         new String[] {android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO},
875                         PackageManager.GET_ACTIVITIES);
876                 List<String> packageListNfcEvent = new ArrayList<String>();
877                 for (int i = 0; i < packagesNfcEvents.size(); i++) {
878                     packageListNfcEvent.add(packagesNfcEvents.get(i).packageName);
879                 }
880                 mNfcEventInstalledPackages.put(uh.getIdentifier(), packageListNfcEvent);
881 
882                 List<String> packageListNfcPreferredPaymentChanged = new ArrayList<String>();
883                 for (int i = 0; i < packagesNfcPreferredPaymentChanged.size(); i++) {
884                     packageListNfcPreferredPaymentChanged.add(
885                             packagesNfcPreferredPaymentChanged.get(i).packageName);
886                 }
887                 mNfcPreferredPaymentChangedInstalledPackages.put(
888                         uh.getIdentifier(), packageListNfcPreferredPaymentChanged);
889             }
890         }
891     }
892 
893     /**
894      * Manages tasks that involve turning on/off the NFC controller.
895      * <p/>
896      * <p>All work that might turn the NFC adapter on or off must be done
897      * through this task, to keep the handling of mState simple.
898      * In other words, mState is only modified in these tasks (and we
899      * don't need a lock to read it in these tasks).
900      * <p/>
901      * <p>These tasks are all done on the same AsyncTask background
902      * thread, so they are serialized. Each task may temporarily transition
903      * mState to STATE_TURNING_OFF or STATE_TURNING_ON, but must exit in
904      * either STATE_ON or STATE_OFF. This way each task can be guaranteed
905      * of starting in either STATE_OFF or STATE_ON, without needing to hold
906      * NfcService.this for the entire task.
907      * <p/>
908      * <p>AsyncTask's are also implicitly queued. This is useful for corner
909      * cases like turning airplane mode on while TASK_ENABLE is in progress.
910      * The TASK_DISABLE triggered by airplane mode will be correctly executed
911      * immediately after TASK_ENABLE is complete. This seems like the most sane
912      * way to deal with these situations.
913      * <p/>
914      * <p>{@link #TASK_ENABLE} enables the NFC adapter, without changing
915      * preferences
916      * <p>{@link #TASK_DISABLE} disables the NFC adapter, without changing
917      * preferences
918      * <p>{@link #TASK_BOOT} does first boot work and may enable NFC
919      */
920     class EnableDisableTask extends AsyncTask<Integer, Void, Void> {
921         @Override
doInBackground(Integer... params)922         protected Void doInBackground(Integer... params) {
923             // Quick check mState
924             switch (mState) {
925                 case NfcAdapter.STATE_TURNING_OFF:
926                 case NfcAdapter.STATE_TURNING_ON:
927                     Log.e(TAG, "Processing EnableDisable task " + params[0] + " from bad state " +
928                             mState);
929                     return null;
930             }
931 
932             /* AsyncTask sets this thread to THREAD_PRIORITY_BACKGROUND,
933              * override with the default. THREAD_PRIORITY_BACKGROUND causes
934              * us to service software I2C too slow for firmware download
935              * with the NXP PN544.
936              * TODO: move this to the DAL I2C layer in libnfc-nxp, since this
937              * problem only occurs on I2C platforms using PN544
938              */
939             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
940 
941             switch (params[0].intValue()) {
942                 case TASK_ENABLE:
943                     enableInternal();
944                     break;
945                 case TASK_DISABLE:
946                     disableInternal();
947                     break;
948                 case TASK_BOOT:
949                     boolean initialized;
950                     if (mPrefs.getBoolean(PREF_FIRST_BOOT, true)) {
951                         Log.i(TAG, "First Boot");
952                         mPrefsEditor.putBoolean(PREF_FIRST_BOOT, false);
953                         mPrefsEditor.apply();
954                         mDeviceHost.factoryReset();
955                         setPaymentForegroundPreference(mUserId);
956                     }
957                     Log.d(TAG, "checking on firmware download");
958                     if (shouldEnableNfc()) {
959                         Log.d(TAG, "NFC is on. Doing normal stuff");
960                         initialized = enableInternal();
961                     } else {
962                         Log.d(TAG, "NFC is off.  Checking firmware version");
963                         initialized = mDeviceHost.checkFirmware();
964                     }
965                     if (initialized) {
966                         // TODO(279846422) The system property will be temporary
967                         // available for vendors that depend on it.
968                         // Remove this code when a replacement API is added.
969                         SystemProperties.set("nfc.initialized", "true");
970                     }
971                     if (mIsTagAppPrefSupported) {
972                         synchronized (NfcService.this) {
973                             initTagAppPrefList();
974                         }
975                     }
976                     break;
977                 case TASK_ENABLE_ALWAYS_ON:
978                     enableAlwaysOnInternal();
979                     break;
980                 case TASK_DISABLE_ALWAYS_ON:
981                     disableAlwaysOnInternal();
982                     break;
983             }
984 
985             // Restore default AsyncTask priority
986             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
987             return null;
988         }
989 
990         /**
991          * Enable NFC adapter functions.
992          * Does not toggle preferences.
993          */
enableInternal()994         boolean enableInternal() {
995             if (mState == NfcAdapter.STATE_ON) {
996                 return true;
997             }
998             Log.i(TAG, "Enabling NFC");
999             NfcStatsLog.write(NfcStatsLog.NFC_STATE_CHANGED,
1000                     mIsSecureNfcEnabled ? NfcStatsLog.NFC_STATE_CHANGED__STATE__ON_LOCKED :
1001                     NfcStatsLog.NFC_STATE_CHANGED__STATE__ON);
1002             updateState(NfcAdapter.STATE_TURNING_ON);
1003 
1004             WatchDogThread watchDog = new WatchDogThread("enableInternal", INIT_WATCHDOG_MS);
1005             watchDog.start();
1006             try {
1007                 mRoutingWakeLock.acquire();
1008                 try {
1009                     if (!mIsAlwaysOnSupported || mIsRecovering
1010                             || (mAlwaysOnState != NfcAdapter.STATE_ON
1011                                 && mAlwaysOnState != NfcAdapter.STATE_TURNING_OFF)) {
1012                         if (!mDeviceHost.initialize()) {
1013                             Log.w(TAG, "Error enabling NFC");
1014                             updateState(NfcAdapter.STATE_OFF);
1015                             return false;
1016                         }
1017                     } else if (mAlwaysOnState == NfcAdapter.STATE_ON
1018                             || mAlwaysOnState == NfcAdapter.STATE_TURNING_OFF) {
1019                         Log.i(TAG, "Already initialized");
1020                     } else {
1021                         Log.e(TAG, "Unexptected bad state " + mAlwaysOnState);
1022                         updateState(NfcAdapter.STATE_OFF);
1023                         return false;
1024                     }
1025                 } finally {
1026                     mRoutingWakeLock.release();
1027                 }
1028             } finally {
1029                 watchDog.cancel();
1030             }
1031 
1032             if (mIsHceCapable) {
1033                 // Generate the initial card emulation routing table
1034                 mCardEmulationManager.onNfcEnabled();
1035             }
1036 
1037             mSkipNdefRead = NfcProperties.skipNdefRead().orElse(false);
1038             nci_version = getNciVersion();
1039             Log.d(TAG, "NCI_Version: " + nci_version);
1040 
1041             synchronized (NfcService.this) {
1042                 mObjectMap.clear();
1043 
1044                 updateState(NfcAdapter.STATE_ON);
1045 
1046                 onPreferredPaymentChanged(NfcAdapter.PREFERRED_PAYMENT_LOADED);
1047             }
1048 
1049             initSoundPool();
1050 
1051             mScreenState = mScreenStateHelper.checkScreenState();
1052             int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ?
1053                              (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState;
1054 
1055             if(mNfcUnlockManager.isLockscreenPollingEnabled())
1056                 applyRouting(false);
1057 
1058             mDeviceHost.doSetScreenState(screen_state_mask);
1059 
1060             sToast_debounce = false;
1061 
1062             /* Skip applyRouting if always on state is switching */
1063             if (!mIsAlwaysOnSupported
1064                     || (mAlwaysOnState != NfcAdapter.STATE_TURNING_ON
1065                         && mAlwaysOnState != NfcAdapter.STATE_TURNING_OFF)) {
1066                 /* Start polling loop */
1067                 applyRouting(true);
1068             }
1069 
1070             if (mIsRecovering) {
1071                  // Intents for all users
1072                  IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
1073                  filter.addAction(Intent.ACTION_SCREEN_ON);
1074                  filter.addAction(Intent.ACTION_USER_PRESENT);
1075                  filter.addAction(Intent.ACTION_USER_SWITCHED);
1076                  filter.addAction(Intent.ACTION_USER_ADDED);
1077                  mContext.registerReceiverForAllUsers(mReceiver, filter, null, null);
1078                  mIsRecovering = false;
1079             }
1080 
1081             return true;
1082         }
1083 
1084         /**
1085          * Disable all NFC adapter functions.
1086          * Does not toggle preferences.
1087          */
disableInternal()1088         boolean disableInternal() {
1089             if (mState == NfcAdapter.STATE_OFF) {
1090                 return true;
1091             }
1092             Log.i(TAG, "Disabling NFC");
1093             NfcStatsLog.write(
1094                     NfcStatsLog.NFC_STATE_CHANGED, NfcStatsLog.NFC_STATE_CHANGED__STATE__OFF);
1095             updateState(NfcAdapter.STATE_TURNING_OFF);
1096 
1097             /* Sometimes mDeviceHost.deinitialize() hangs, use a watch-dog.
1098              * Implemented with a new thread (instead of a Handler or AsyncTask),
1099              * because the UI Thread and AsyncTask thread-pools can also get hung
1100              * when the NFC controller stops responding */
1101             WatchDogThread watchDog = new WatchDogThread("disableInternal", ROUTING_WATCHDOG_MS);
1102             watchDog.start();
1103 
1104             if (mIsHceCapable) {
1105                 mCardEmulationManager.onNfcDisabled();
1106             }
1107 
1108             // Stop watchdog if tag present
1109             // A convenient way to stop the watchdog properly consists of
1110             // disconnecting the tag. The polling loop shall be stopped before
1111             // to avoid the tag being discovered again.
1112             maybeDisconnectTarget();
1113 
1114             synchronized (NfcService.this) {
1115                 // Disable delay polling when disabling
1116                 mPollDelayed = false;
1117                 mPollDelayCount = 0;
1118                 mHandler.removeMessages(MSG_DELAY_POLLING);
1119                 mPollingDisableDeathRecipients.clear();
1120                 mReaderModeParams = null;
1121             }
1122             mNfcDispatcher.setForegroundDispatch(null, null, null);
1123 
1124             boolean result;
1125             if (!mIsAlwaysOnSupported || mIsRecovering
1126                     || (mAlwaysOnState == NfcAdapter.STATE_OFF)
1127                     || (mAlwaysOnState == NfcAdapter.STATE_TURNING_OFF)) {
1128                 result = mDeviceHost.deinitialize();
1129                 if (DBG) Log.d(TAG, "mDeviceHost.deinitialize() = " + result);
1130             } else {
1131                 mDeviceHost.disableDiscovery();
1132                 result = true;
1133                 Log.i(TAG, "AlwaysOn set, disableDiscovery()");
1134             }
1135 
1136             watchDog.cancel();
1137 
1138             synchronized (NfcService.this) {
1139                 mCurrentDiscoveryParameters = NfcDiscoveryParameters.getNfcOffParameters();
1140                 updateState(NfcAdapter.STATE_OFF);
1141             }
1142 
1143             releaseSoundPool();
1144 
1145             return result;
1146         }
1147 
1148         /**
1149          * Enable always on feature.
1150          */
enableAlwaysOnInternal()1151         void enableAlwaysOnInternal() {
1152             if (mAlwaysOnState == NfcAdapter.STATE_ON) {
1153                 return;
1154             } else if (mState == NfcAdapter.STATE_TURNING_ON
1155                     || mAlwaysOnState == NfcAdapter.STATE_TURNING_OFF) {
1156                 Log.e(TAG, "Processing enableAlwaysOnInternal() from bad state");
1157                 return;
1158             } else if (mState == NfcAdapter.STATE_ON) {
1159                 updateAlwaysOnState(NfcAdapter.STATE_TURNING_ON);
1160                 mDeviceHost.setNfceePowerAndLinkCtrl(true);
1161                 updateAlwaysOnState(NfcAdapter.STATE_ON);
1162             } else if (mState == NfcAdapter.STATE_OFF) {
1163                 /* Special case when NFCC is OFF without initialize.
1164                  * Temperatorily enable NfcAdapter but don't applyRouting.
1165                  * Then disable NfcAdapter without deinitialize to keep the NFCC stays initialized.
1166                  * mState will switch back to OFF in the end.
1167                  * And the NFCC stays initialized.
1168                  */
1169                 updateAlwaysOnState(NfcAdapter.STATE_TURNING_ON);
1170                 if (!enableInternal()) {
1171                     updateAlwaysOnState(NfcAdapter.STATE_OFF);
1172                     return;
1173                 }
1174                 disableInternal();
1175                 mDeviceHost.setNfceePowerAndLinkCtrl(true);
1176                 updateAlwaysOnState(NfcAdapter.STATE_ON);
1177             }
1178         }
1179 
1180         /**
1181          * Disable always on feature.
1182          */
disableAlwaysOnInternal()1183         void disableAlwaysOnInternal() {
1184             if (mAlwaysOnState == NfcAdapter.STATE_OFF) {
1185                 return;
1186             } else if (mState == NfcAdapter.STATE_TURNING_ON
1187                     || mAlwaysOnState == NfcAdapter.STATE_TURNING_OFF) {
1188                 Log.e(TAG, "Processing disableAlwaysOnInternal() from bad state");
1189                 return;
1190             } else if (mState == NfcAdapter.STATE_ON) {
1191                 updateAlwaysOnState(NfcAdapter.STATE_TURNING_OFF);
1192                 mDeviceHost.setNfceePowerAndLinkCtrl(false);
1193                 updateAlwaysOnState(NfcAdapter.STATE_OFF);
1194             } else if (mState == NfcAdapter.STATE_OFF) {
1195                 /* Special case when mState is OFF but NFCC is already initialized.
1196                  * Deinitialize mDevicehost directly.
1197                  */
1198                 updateAlwaysOnState(NfcAdapter.STATE_TURNING_OFF);
1199                 mDeviceHost.setNfceePowerAndLinkCtrl(false);
1200                 boolean result = mDeviceHost.deinitialize();
1201                 if (DBG) Log.d(TAG, "mDeviceHost.deinitialize() = " + result);
1202                 updateAlwaysOnState(NfcAdapter.STATE_OFF);
1203             }
1204         }
1205 
updateState(int newState)1206         void updateState(int newState) {
1207             synchronized (NfcService.this) {
1208                 if (newState == mState) {
1209                     return;
1210                 }
1211                 mState = newState;
1212                 Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
1213                 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1214                 intent.putExtra(NfcAdapter.EXTRA_ADAPTER_STATE, mState);
1215                 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
1216             }
1217         }
1218 
updateAlwaysOnState(int newState)1219         void updateAlwaysOnState(int newState) {
1220             synchronized (NfcService.this) {
1221                 if (newState == mAlwaysOnState) {
1222                     return;
1223                 }
1224                 mAlwaysOnState = newState;
1225                 if (mAlwaysOnState == NfcAdapter.STATE_OFF
1226                         || mAlwaysOnState == NfcAdapter.STATE_ON) {
1227                     synchronized (mAlwaysOnListeners) {
1228                         for (INfcControllerAlwaysOnListener listener
1229                                 : mAlwaysOnListeners) {
1230                             try {
1231                                 listener.onControllerAlwaysOnChanged(
1232                                         mAlwaysOnState == NfcAdapter.STATE_ON);
1233                             } catch (RemoteException e) {
1234                                 Log.e(TAG, "error in updateAlwaysOnState");
1235                             }
1236                         }
1237                     }
1238                 }
1239             }
1240         }
1241 
getAlwaysOnState()1242         int getAlwaysOnState() {
1243             synchronized (NfcService.this) {
1244                 if (!mIsAlwaysOnSupported) {
1245                     return NfcAdapter.STATE_OFF;
1246                 } else {
1247                     return mAlwaysOnState;
1248                 }
1249             }
1250         }
1251     }
1252 
playSound(int sound)1253     public void playSound(int sound) {
1254         synchronized (this) {
1255             if (mSoundPool == null) {
1256                 Log.w(TAG, "Not playing sound when NFC is disabled");
1257                 return;
1258             }
1259 
1260             if (mVrManager != null && mVrManager.isVrModeEnabled()) {
1261                 Log.d(TAG, "Not playing NFC sound when Vr Mode is enabled");
1262                 return;
1263             }
1264             switch (sound) {
1265                 case SOUND_START:
1266                     mSoundPool.play(mStartSound, 1.0f, 1.0f, 0, 0, 1.0f);
1267                     break;
1268                 case SOUND_END:
1269                     mSoundPool.play(mEndSound, 1.0f, 1.0f, 0, 0, 1.0f);
1270                     break;
1271                 case SOUND_ERROR:
1272                     mSoundPool.play(mErrorSound, 1.0f, 1.0f, 0, 0, 1.0f);
1273                     break;
1274             }
1275         }
1276     }
1277 
getUserId()1278     synchronized int getUserId() {
1279         return mUserId;
1280     }
1281 
resetReaderModeParams()1282     private void resetReaderModeParams() {
1283         synchronized (NfcService.this) {
1284             if (mPollingDisableDeathRecipients.size() == 0) {
1285                 Log.d(TAG, "Disabling reader mode because app died or moved to background");
1286                 mReaderModeParams = null;
1287                 StopPresenceChecking();
1288                 if (isNfcEnabled()) {
1289                     applyRouting(false);
1290                 }
1291             }
1292         }
1293     }
1294 
1295     @Override
onUidToBackground(int uid)1296     public void onUidToBackground(int uid) {
1297         Log.i(TAG, "Uid " + uid + " switch to background.");
1298         synchronized (NfcService.this) {
1299             if (mReaderModeParams != null && mReaderModeParams.uid == uid) {
1300                 mReaderModeParams.binder.unlinkToDeath(mReaderModeDeathRecipient, 0);
1301                 resetReaderModeParams();
1302             }
1303         }
1304     }
1305 
isSecureNfcEnabled()1306     public boolean isSecureNfcEnabled() {
1307         return mIsSecureNfcEnabled;
1308     }
1309 
1310     final class NfcAdapterService extends INfcAdapter.Stub {
1311         @Override
enable()1312         public boolean enable() throws RemoteException {
1313             NfcPermissions.enforceAdminPermissions(mContext);
1314 
1315             saveNfcOnSetting(true);
1316 
1317             if (shouldEnableNfc()) {
1318                 new EnableDisableTask().execute(TASK_ENABLE);
1319             }
1320 
1321             return true;
1322         }
1323 
1324         @Override
disable(boolean saveState)1325         public boolean disable(boolean saveState) throws RemoteException {
1326             NfcPermissions.enforceAdminPermissions(mContext);
1327 
1328             if (saveState) {
1329                 saveNfcOnSetting(false);
1330             }
1331 
1332             new EnableDisableTask().execute(TASK_DISABLE);
1333 
1334             return true;
1335         }
1336 
1337         @Override
pausePolling(int timeoutInMs)1338         public void pausePolling(int timeoutInMs) {
1339             NfcPermissions.enforceAdminPermissions(mContext);
1340 
1341             if (timeoutInMs <= 0 || timeoutInMs > MAX_POLLING_PAUSE_TIMEOUT) {
1342                 Log.e(TAG, "Refusing to pause polling for " + timeoutInMs + "ms.");
1343                 return;
1344             }
1345 
1346             synchronized (NfcService.this) {
1347                 mPollingPaused = true;
1348                 mDeviceHost.disableDiscovery();
1349                 mHandler.sendMessageDelayed(
1350                         mHandler.obtainMessage(MSG_RESUME_POLLING), timeoutInMs);
1351             }
1352         }
1353 
1354         @Override
resumePolling()1355         public void resumePolling() {
1356             NfcPermissions.enforceAdminPermissions(mContext);
1357 
1358             synchronized (NfcService.this) {
1359                 if (!mPollingPaused) {
1360                     return;
1361                 }
1362 
1363                 mHandler.removeMessages(MSG_RESUME_POLLING);
1364                 mPollingPaused = false;
1365                 new ApplyRoutingTask().execute();
1366             }
1367             if (DBG) Log.d(TAG, "Polling is resumed");
1368         }
1369 
1370         @Override
isNfcSecureEnabled()1371         public boolean isNfcSecureEnabled() throws RemoteException {
1372             synchronized (NfcService.this) {
1373                 return mIsSecureNfcEnabled;
1374             }
1375         }
1376 
1377         @Override
setNfcSecure(boolean enable)1378         public boolean setNfcSecure(boolean enable) {
1379             NfcPermissions.enforceAdminPermissions(mContext);
1380             if(mKeyguard.isKeyguardLocked() && !enable) {
1381                 Log.i(TAG, "KeyGuard need to be unlocked before setting Secure NFC OFF");
1382                 return false;
1383             }
1384 
1385             synchronized (NfcService.this) {
1386                 if (mIsSecureNfcEnabled == enable) {
1387                     Log.e(TAG, "setNfcSecure error, can't apply the same state twice!");
1388                     return false;
1389                 }
1390                 Log.i(TAG, "setting Secure NFC " + enable);
1391                 mPrefsEditor.putBoolean(PREF_SECURE_NFC_ON, enable);
1392                 mPrefsEditor.apply();
1393                 mIsSecureNfcEnabled = enable;
1394                 mBackupManager.dataChanged();
1395                 mDeviceHost.setNfcSecure(enable);
1396                 if (mIsHceCapable) {
1397                     // update HCE/HCEF routing and commitRouting if Nfc is enabled
1398                     mCardEmulationManager.onSecureNfcToggled();
1399                 } else if (isNfcEnabled()) {
1400                     // commit only tech/protocol route without HCE support
1401                     mDeviceHost.commitRouting();
1402                 }
1403             }
1404 
1405             NfcStatsLog.write(NfcStatsLog.NFC_STATE_CHANGED,
1406                     mIsSecureNfcEnabled ? NfcStatsLog.NFC_STATE_CHANGED__STATE__ON_LOCKED :
1407                     NfcStatsLog.NFC_STATE_CHANGED__STATE__ON);
1408             return true;
1409         }
1410 
1411         @Override
setForegroundDispatch(PendingIntent intent, IntentFilter[] filters, TechListParcel techListsParcel)1412         public void setForegroundDispatch(PendingIntent intent,
1413                 IntentFilter[] filters, TechListParcel techListsParcel) {
1414             NfcPermissions.enforceUserPermissions(mContext);
1415             if (!mForegroundUtils.isInForeground(Binder.getCallingUid())) {
1416                 Log.e(TAG, "setForegroundDispatch: Caller not in foreground.");
1417                 return;
1418             }
1419             // Short-cut the disable path
1420             if (intent == null && filters == null && techListsParcel == null) {
1421                 mNfcDispatcher.setForegroundDispatch(null, null, null);
1422                 return;
1423             }
1424 
1425             // Validate the IntentFilters
1426             if (filters != null) {
1427                 if (filters.length == 0) {
1428                     filters = null;
1429                 } else {
1430                     for (IntentFilter filter : filters) {
1431                         if (filter == null) {
1432                             throw new IllegalArgumentException("null IntentFilter");
1433                         }
1434                     }
1435                 }
1436             }
1437 
1438             // Validate the tech lists
1439             String[][] techLists = null;
1440             if (techListsParcel != null) {
1441                 techLists = techListsParcel.getTechLists();
1442             }
1443 
1444             mNfcDispatcher.setForegroundDispatch(intent, filters, techLists);
1445         }
1446 
1447 
1448         @Override
setAppCallback(IAppCallback callback)1449         public void setAppCallback(IAppCallback callback) {
1450             NfcPermissions.enforceUserPermissions(mContext);
1451         }
1452 
1453         @Override
ignore(int nativeHandle, int debounceMs, ITagRemovedCallback callback)1454         public boolean ignore(int nativeHandle, int debounceMs, ITagRemovedCallback callback)
1455                 throws RemoteException {
1456             NfcPermissions.enforceUserPermissions(mContext);
1457 
1458             if (debounceMs == 0 && mDebounceTagNativeHandle != INVALID_NATIVE_HANDLE
1459                 && nativeHandle == mDebounceTagNativeHandle) {
1460               // Remove any previous messages and immediately debounce.
1461               mHandler.removeMessages(MSG_TAG_DEBOUNCE);
1462               mHandler.sendEmptyMessage(MSG_TAG_DEBOUNCE);
1463               return true;
1464             }
1465 
1466             TagEndpoint tag = (TagEndpoint) findAndRemoveObject(nativeHandle);
1467             if (tag != null) {
1468                 // Store UID and params
1469                 int uidLength = tag.getUid().length;
1470                 synchronized (NfcService.this) {
1471                     mDebounceTagDebounceMs = debounceMs;
1472                     mDebounceTagNativeHandle = nativeHandle;
1473                     mDebounceTagUid = new byte[uidLength];
1474                     mDebounceTagRemovedCallback = callback;
1475                     System.arraycopy(tag.getUid(), 0, mDebounceTagUid, 0, uidLength);
1476                 }
1477 
1478                 // Disconnect from this tag; this should resume the normal
1479                 // polling loop (and enter listen mode for a while), before
1480                 // we pick up any tags again.
1481                 tag.disconnect();
1482                 mHandler.sendEmptyMessageDelayed(MSG_TAG_DEBOUNCE, debounceMs);
1483                 return true;
1484             } else {
1485                 return false;
1486             }
1487         }
1488 
1489         @Override
verifyNfcPermission()1490         public void verifyNfcPermission() {
1491             NfcPermissions.enforceUserPermissions(mContext);
1492         }
1493 
1494         @Override
getNfcTagInterface()1495         public INfcTag getNfcTagInterface() throws RemoteException {
1496             return mNfcTagService;
1497         }
1498 
1499         @Override
getNfcCardEmulationInterface()1500         public INfcCardEmulation getNfcCardEmulationInterface() {
1501             if (mIsHceCapable) {
1502                 return mCardEmulationManager.getNfcCardEmulationInterface();
1503             } else {
1504                 return null;
1505             }
1506         }
1507 
1508         @Override
getNfcFCardEmulationInterface()1509         public INfcFCardEmulation getNfcFCardEmulationInterface() {
1510             if (mIsHceFCapable) {
1511                 return mCardEmulationManager.getNfcFCardEmulationInterface();
1512             } else {
1513                 return null;
1514             }
1515         }
1516 
1517         @Override
getState()1518         public int getState() throws RemoteException {
1519             synchronized (NfcService.this) {
1520                 return mState;
1521             }
1522         }
1523 
1524         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1525         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1526             NfcService.this.dump(fd, pw, args);
1527         }
1528 
1529         @Override
dispatch(Tag tag)1530         public void dispatch(Tag tag) throws RemoteException {
1531             NfcPermissions.enforceAdminPermissions(mContext);
1532             mNfcDispatcher.dispatchTag(tag);
1533         }
1534 
1535         @Override
setReaderMode(IBinder binder, IAppCallback callback, int flags, Bundle extras)1536         public void setReaderMode(IBinder binder, IAppCallback callback, int flags, Bundle extras)
1537                 throws RemoteException {
1538             boolean privilegedCaller = false;
1539             int callingUid = Binder.getCallingUid();
1540             int callingPid = Binder.getCallingPid();
1541             // Allow non-foreground callers with system uid or systemui
1542             String packageName = getPackageNameFromUid(callingUid);
1543             if (packageName != null) {
1544                 privilegedCaller = (callingUid == Process.SYSTEM_UID
1545                         || packageName.equals(SYSTEM_UI));
1546             } else {
1547                 privilegedCaller = (callingUid == Process.SYSTEM_UID);
1548             }
1549             Log.d(TAG, "setReaderMode: uid=" + callingUid + ", packageName: "
1550                     + packageName + ", flags: " + flags);
1551             if (!privilegedCaller
1552                     && !mForegroundUtils.registerUidToBackgroundCallback(
1553                             NfcService.this, callingUid)) {
1554                 Log.e(TAG, "setReaderMode: Caller is not in foreground and is not system process.");
1555                 return;
1556             }
1557             boolean disablePolling = flags != 0 && getReaderModeTechMask(flags) == 0;
1558             // Only allow to disable polling for specific callers
1559             if (disablePolling && !(privilegedCaller && mPollingDisableAllowed)) {
1560                 Log.e(TAG, "setReaderMode() called with invalid flag parameter.");
1561                 return;
1562             }
1563             synchronized (NfcService.this) {
1564                 if (!isNfcEnabled() && !privilegedCaller) {
1565                     Log.e(TAG, "setReaderMode() called while NFC is not enabled.");
1566                     return;
1567                 }
1568                 if (flags != 0) {
1569                     try {
1570                         if (disablePolling) {
1571                             ReaderModeDeathRecipient pollingDisableDeathRecipient =
1572                                     new ReaderModeDeathRecipient();
1573                             binder.linkToDeath(pollingDisableDeathRecipient, 0);
1574                             mPollingDisableDeathRecipients.put(
1575                                     callingPid, pollingDisableDeathRecipient);
1576                         } else {
1577                             if (mPollingDisableDeathRecipients.size() != 0) {
1578                                 Log.e(TAG, "active polling is forced to disable now.");
1579                                 return;
1580                             }
1581                             binder.linkToDeath(mReaderModeDeathRecipient, 0);
1582                         }
1583                         if (mPollDelayed) {
1584                             mHandler.removeMessages(MSG_DELAY_POLLING);
1585                             mPollDelayCount = 0;
1586                             mPollDelayed = false;
1587                             mDeviceHost.startStopPolling(true);
1588                             if (DBG) Log.d(TAG, "setReaderMode() polling is started");
1589                         }
1590                         updateReaderModeParams(callback, flags, extras, binder, callingUid);
1591                     } catch (RemoteException e) {
1592                         Log.e(TAG, "Remote binder has already died.");
1593                         return;
1594                     }
1595                 } else {
1596                     try {
1597                         ReaderModeDeathRecipient pollingDisableDeathRecipient =
1598                                 mPollingDisableDeathRecipients.get(callingPid);
1599                         mPollingDisableDeathRecipients.remove(callingPid);
1600 
1601                         if (mPollingDisableDeathRecipients.size() == 0) {
1602                             mReaderModeParams = null;
1603                             StopPresenceChecking();
1604                         }
1605 
1606                         if (pollingDisableDeathRecipient != null) {
1607                             binder.unlinkToDeath(pollingDisableDeathRecipient, 0);
1608                         } else {
1609                             binder.unlinkToDeath(mReaderModeDeathRecipient, 0);
1610                         }
1611                     } catch (NoSuchElementException e) {
1612                         Log.e(TAG, "Reader mode Binder was never registered.");
1613                     }
1614                 }
1615                 if (isNfcEnabled()) {
1616                     applyRouting(false);
1617                 }
1618             }
1619         }
1620 
1621         @Override
getNfcAdapterExtrasInterface(String pkg)1622         public INfcAdapterExtras getNfcAdapterExtrasInterface(String pkg) throws RemoteException {
1623             // nfc-extras implementation is no longer present in AOSP.
1624             return null;
1625         }
1626 
1627         @Override
getNfcDtaInterface(String pkg)1628         public INfcDta getNfcDtaInterface(String pkg) throws RemoteException {
1629             NfcPermissions.enforceAdminPermissions(mContext);
1630             if (mNfcDtaService == null) {
1631                 mNfcDtaService = new NfcDtaService();
1632             }
1633             return mNfcDtaService;
1634         }
1635 
1636         @Override
addNfcUnlockHandler(INfcUnlockHandler unlockHandler, int[] techList)1637         public void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, int[] techList) {
1638             NfcPermissions.enforceAdminPermissions(mContext);
1639 
1640             int lockscreenPollMask = computeLockscreenPollMask(techList);
1641             synchronized (NfcService.this) {
1642                 mNfcUnlockManager.addUnlockHandler(unlockHandler, lockscreenPollMask);
1643             }
1644 
1645             applyRouting(false);
1646         }
1647 
1648         @Override
removeNfcUnlockHandler(INfcUnlockHandler token)1649         public void removeNfcUnlockHandler(INfcUnlockHandler token) throws RemoteException {
1650             synchronized (NfcService.this) {
1651                 mNfcUnlockManager.removeUnlockHandler(token.asBinder());
1652             }
1653 
1654             applyRouting(false);
1655         }
1656 
1657         @Override
deviceSupportsNfcSecure()1658         public boolean deviceSupportsNfcSecure() {
1659             String skuList[] = mContext.getResources().getStringArray(
1660                 R.array.config_skuSupportsSecureNfc);
1661             String sku = SystemProperties.get("ro.boot.hardware.sku");
1662             if (TextUtils.isEmpty(sku) || !Utils.arrayContains(skuList, sku)) {
1663                 return false;
1664             }
1665             return true;
1666         }
1667 
1668         @Override
getNfcAntennaInfo()1669         public NfcAntennaInfo getNfcAntennaInfo() {
1670             int positionX[] = mContext.getResources().getIntArray(
1671                     R.array.antenna_x);
1672             int positionY[] = mContext.getResources().getIntArray(
1673                     R.array.antenna_y);
1674             if(positionX.length != positionY.length){
1675                 return null;
1676             }
1677             int width = mContext.getResources().getInteger(R.integer.device_width);
1678             int height = mContext.getResources().getInteger(R.integer.device_height);
1679             List<AvailableNfcAntenna> availableNfcAntennas = new ArrayList<>();
1680             for(int i = 0; i < positionX.length; i++){
1681                 if(positionX[i] >= width | positionY[i] >= height){
1682                     return null;
1683                 }
1684                 availableNfcAntennas.add(new AvailableNfcAntenna(positionX[i], positionY[i]));
1685             }
1686             return new NfcAntennaInfo(
1687                     width,
1688                     height,
1689                     mContext.getResources().getBoolean(R.bool.device_foldable),
1690                     availableNfcAntennas);
1691         }
1692 
computeLockscreenPollMask(int[] techList)1693         private int computeLockscreenPollMask(int[] techList) {
1694 
1695             Map<Integer, Integer> techCodeToMask = new HashMap<Integer, Integer>();
1696 
1697             techCodeToMask.put(TagTechnology.NFC_A, NfcService.NFC_POLL_A);
1698             techCodeToMask.put(TagTechnology.NFC_B, NfcService.NFC_POLL_B);
1699             techCodeToMask.put(TagTechnology.NFC_V, NfcService.NFC_POLL_V);
1700             techCodeToMask.put(TagTechnology.NFC_F, NfcService.NFC_POLL_F);
1701             techCodeToMask.put(TagTechnology.NFC_BARCODE, NfcService.NFC_POLL_KOVIO);
1702 
1703             int mask = 0;
1704 
1705             for (int i = 0; i < techList.length; i++) {
1706                 if (techCodeToMask.containsKey(techList[i])) {
1707                     mask |= techCodeToMask.get(techList[i]).intValue();
1708                 }
1709             }
1710 
1711             return mask;
1712         }
1713 
getReaderModeTechMask(int flags)1714         private int getReaderModeTechMask(int flags) {
1715             int techMask = 0;
1716             if ((flags & NfcAdapter.FLAG_READER_NFC_A) != 0) {
1717                 techMask |= NFC_POLL_A;
1718             }
1719             if ((flags & NfcAdapter.FLAG_READER_NFC_B) != 0) {
1720                 techMask |= NFC_POLL_B;
1721             }
1722             if ((flags & NfcAdapter.FLAG_READER_NFC_F) != 0) {
1723                 techMask |= NFC_POLL_F;
1724             }
1725             if ((flags & NfcAdapter.FLAG_READER_NFC_V) != 0) {
1726                 techMask |= NFC_POLL_V;
1727             }
1728             if ((flags & NfcAdapter.FLAG_READER_NFC_BARCODE) != 0) {
1729                 techMask |= NFC_POLL_KOVIO;
1730             }
1731 
1732             return techMask;
1733         }
1734 
getPackageNameFromUid(int uid)1735         private String getPackageNameFromUid(int uid) {
1736             PackageManager packageManager = mContext.getPackageManager();
1737             if (packageManager != null) {
1738                 String[] packageName = packageManager.getPackagesForUid(uid);
1739                 if (packageName != null && packageName.length > 0) {
1740                     return packageName[0];
1741                 }
1742             }
1743             return null;
1744         }
1745 
updateReaderModeParams( IAppCallback callback, int flags, Bundle extras, IBinder binder, int uid)1746         private void updateReaderModeParams(
1747                 IAppCallback callback, int flags, Bundle extras, IBinder binder, int uid) {
1748             synchronized (NfcService.this) {
1749                 mReaderModeParams = new ReaderModeParams();
1750                 mReaderModeParams.callback = callback;
1751                 mReaderModeParams.flags = flags;
1752                 mReaderModeParams.presenceCheckDelay = extras != null
1753                         ? (extras.getInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY,
1754                                 DEFAULT_PRESENCE_CHECK_DELAY))
1755                         : DEFAULT_PRESENCE_CHECK_DELAY;
1756                 mReaderModeParams.binder = binder;
1757                 mReaderModeParams.uid = uid;
1758             }
1759         }
1760 
setTagAppPreferenceInternal(int userId, String pkg, boolean allow)1761         private int setTagAppPreferenceInternal(int userId, String pkg, boolean allow) {
1762             if (!isPackageInstalled(pkg, userId)) {
1763                 return NfcAdapter.TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND;
1764             }
1765             if (DBG) Log.i(TAG, "UserId:" + userId + " pkg:" + pkg + ":" + allow);
1766             synchronized (NfcService.this) {
1767                 mTagAppPrefList.computeIfAbsent(userId, key -> new HashMap<String, Boolean>())
1768                         .put(pkg, allow);
1769             }
1770             storeTagAppPrefList();
1771             return NfcAdapter.TAG_INTENT_APP_PREF_RESULT_SUCCESS;
1772         }
1773 
1774         @Override
setControllerAlwaysOn(boolean value)1775         public boolean setControllerAlwaysOn(boolean value) throws RemoteException {
1776             NfcPermissions.enforceSetControllerAlwaysOnPermissions(mContext);
1777             if (!mIsAlwaysOnSupported) {
1778                 return false;
1779             }
1780             if (value) {
1781                 new EnableDisableTask().execute(TASK_ENABLE_ALWAYS_ON);
1782             } else {
1783                 new EnableDisableTask().execute(TASK_DISABLE_ALWAYS_ON);
1784             }
1785             return true;
1786         }
1787 
1788         @Override
isControllerAlwaysOn()1789         public boolean isControllerAlwaysOn() throws RemoteException {
1790             NfcPermissions.enforceSetControllerAlwaysOnPermissions(mContext);
1791             return mIsAlwaysOnSupported && mAlwaysOnState == NfcAdapter.STATE_ON;
1792         }
1793 
1794         @Override
isControllerAlwaysOnSupported()1795         public boolean isControllerAlwaysOnSupported() throws RemoteException {
1796             NfcPermissions.enforceSetControllerAlwaysOnPermissions(mContext);
1797             return mIsAlwaysOnSupported;
1798         }
1799 
1800         @Override
registerControllerAlwaysOnListener( INfcControllerAlwaysOnListener listener)1801         public void registerControllerAlwaysOnListener(
1802                 INfcControllerAlwaysOnListener listener) throws RemoteException {
1803             NfcPermissions.enforceSetControllerAlwaysOnPermissions(mContext);
1804             if (!mIsAlwaysOnSupported) return;
1805 
1806             mAlwaysOnListeners.add(listener);
1807         }
1808 
1809         @Override
unregisterControllerAlwaysOnListener( INfcControllerAlwaysOnListener listener)1810         public void unregisterControllerAlwaysOnListener(
1811                 INfcControllerAlwaysOnListener listener) throws RemoteException {
1812             NfcPermissions.enforceSetControllerAlwaysOnPermissions(mContext);
1813             if (!mIsAlwaysOnSupported) return;
1814 
1815             mAlwaysOnListeners.remove(listener);
1816         }
1817         @Override
isTagIntentAppPreferenceSupported()1818         public boolean isTagIntentAppPreferenceSupported() throws RemoteException {
1819             NfcPermissions.enforceAdminPermissions(mContext);
1820             return mIsTagAppPrefSupported;
1821         }
1822         @Override
getTagIntentAppPreferenceForUser(int userId)1823         public Map getTagIntentAppPreferenceForUser(int userId) throws RemoteException {
1824             NfcPermissions.enforceAdminPermissions(mContext);
1825             if (!mIsTagAppPrefSupported) throw new UnsupportedOperationException();
1826             synchronized (NfcService.this) {
1827                 return mTagAppPrefList.getOrDefault(userId, new HashMap<>());
1828             }
1829         }
1830         @Override
setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)1831         public int setTagIntentAppPreferenceForUser(int userId,
1832                 String pkg, boolean allow) throws RemoteException {
1833             NfcPermissions.enforceAdminPermissions(mContext);
1834             if (!mIsTagAppPrefSupported) throw new UnsupportedOperationException();
1835             return setTagAppPreferenceInternal(userId, pkg, allow);
1836         }
1837     }
1838 
1839     final class SeServiceDeathRecipient implements IBinder.DeathRecipient {
1840         @Override
binderDied()1841         public void binderDied() {
1842             synchronized (NfcService.this) {
1843                 Log.i(TAG, "SE Service died");
1844                 mSEService = null;
1845             }
1846         }
1847     }
1848 
1849     final class ReaderModeDeathRecipient implements IBinder.DeathRecipient {
1850         @Override
binderDied()1851         public void binderDied() {
1852             synchronized (NfcService.this) {
1853                 if (mReaderModeParams != null) {
1854                     mPollingDisableDeathRecipients.values().remove(this);
1855                     resetReaderModeParams();
1856                 }
1857             }
1858         }
1859     }
1860 
1861     final class TagService extends INfcTag.Stub {
1862         @Override
connect(int nativeHandle, int technology)1863         public int connect(int nativeHandle, int technology) throws RemoteException {
1864             NfcPermissions.enforceUserPermissions(mContext);
1865 
1866             TagEndpoint tag = null;
1867 
1868             if (!isNfcEnabled()) {
1869                 return ErrorCodes.ERROR_NOT_INITIALIZED;
1870             }
1871 
1872             /* find the tag in the hmap */
1873             tag = (TagEndpoint) findObject(nativeHandle);
1874             if (tag == null) {
1875                 return ErrorCodes.ERROR_DISCONNECT;
1876             }
1877 
1878             if (!tag.isPresent()) {
1879                 return ErrorCodes.ERROR_DISCONNECT;
1880             }
1881 
1882             // Note that on most tags, all technologies are behind a single
1883             // handle. This means that the connect at the lower levels
1884             // will do nothing, as the tag is already connected to that handle.
1885             if (tag.connect(technology)) {
1886                 return ErrorCodes.SUCCESS;
1887             } else {
1888                 return ErrorCodes.ERROR_DISCONNECT;
1889             }
1890         }
1891 
1892         @Override
reconnect(int nativeHandle)1893         public int reconnect(int nativeHandle) throws RemoteException {
1894             NfcPermissions.enforceUserPermissions(mContext);
1895 
1896             TagEndpoint tag = null;
1897 
1898             // Check if NFC is enabled
1899             if (!isNfcEnabled()) {
1900                 return ErrorCodes.ERROR_NOT_INITIALIZED;
1901             }
1902 
1903             /* find the tag in the hmap */
1904             tag = (TagEndpoint) findObject(nativeHandle);
1905             if (tag != null) {
1906                 if (tag.reconnect()) {
1907                     return ErrorCodes.SUCCESS;
1908                 } else {
1909                     return ErrorCodes.ERROR_DISCONNECT;
1910                 }
1911             }
1912             return ErrorCodes.ERROR_DISCONNECT;
1913         }
1914 
1915         @Override
getTechList(int nativeHandle)1916         public int[] getTechList(int nativeHandle) throws RemoteException {
1917             NfcPermissions.enforceUserPermissions(mContext);
1918 
1919             // Check if NFC is enabled
1920             if (!isNfcEnabled()) {
1921                 return null;
1922             }
1923 
1924             /* find the tag in the hmap */
1925             TagEndpoint tag = (TagEndpoint) findObject(nativeHandle);
1926             if (tag != null) {
1927                 return tag.getTechList();
1928             }
1929             return null;
1930         }
1931 
1932         @Override
isPresent(int nativeHandle)1933         public boolean isPresent(int nativeHandle) throws RemoteException {
1934             TagEndpoint tag = null;
1935 
1936             // Check if NFC is enabled
1937             if (!isNfcEnabled()) {
1938                 return false;
1939             }
1940 
1941             /* find the tag in the hmap */
1942             tag = (TagEndpoint) findObject(nativeHandle);
1943             if (tag == null) {
1944                 return false;
1945             }
1946 
1947             return tag.isPresent();
1948         }
1949 
1950         @Override
isNdef(int nativeHandle)1951         public boolean isNdef(int nativeHandle) throws RemoteException {
1952             NfcPermissions.enforceUserPermissions(mContext);
1953 
1954             TagEndpoint tag = null;
1955 
1956             // Check if NFC is enabled
1957             if (!isNfcEnabled()) {
1958                 return false;
1959             }
1960 
1961             /* find the tag in the hmap */
1962             tag = (TagEndpoint) findObject(nativeHandle);
1963             int[] ndefInfo = new int[2];
1964             if (tag == null) {
1965                 return false;
1966             }
1967             return tag.checkNdef(ndefInfo);
1968         }
1969 
1970         @Override
transceive(int nativeHandle, byte[] data, boolean raw)1971         public TransceiveResult transceive(int nativeHandle, byte[] data, boolean raw)
1972                 throws RemoteException {
1973             NfcPermissions.enforceUserPermissions(mContext);
1974 
1975             TagEndpoint tag = null;
1976             byte[] response;
1977 
1978             // Check if NFC is enabled
1979             if (!isNfcEnabled()) {
1980                 return null;
1981             }
1982 
1983             /* find the tag in the hmap */
1984             tag = (TagEndpoint) findObject(nativeHandle);
1985             if (tag != null) {
1986                 // Check if length is within limits
1987                 if (data.length > getMaxTransceiveLength(tag.getConnectedTechnology())) {
1988                     return new TransceiveResult(TransceiveResult.RESULT_EXCEEDED_LENGTH, null);
1989                 }
1990                 int[] targetLost = new int[1];
1991                 response = tag.transceive(data, raw, targetLost);
1992                 int result;
1993                 if (response != null) {
1994                     result = TransceiveResult.RESULT_SUCCESS;
1995                 } else if (targetLost[0] == 1) {
1996                     result = TransceiveResult.RESULT_TAGLOST;
1997                 } else {
1998                     result = TransceiveResult.RESULT_FAILURE;
1999                 }
2000                 return new TransceiveResult(result, response);
2001             }
2002             return null;
2003         }
2004 
2005         @Override
ndefRead(int nativeHandle)2006         public NdefMessage ndefRead(int nativeHandle) throws RemoteException {
2007             NfcPermissions.enforceUserPermissions(mContext);
2008 
2009             TagEndpoint tag;
2010 
2011             // Check if NFC is enabled
2012             if (!isNfcEnabled()) {
2013                 return null;
2014             }
2015 
2016             /* find the tag in the hmap */
2017             tag = (TagEndpoint) findObject(nativeHandle);
2018             if (tag != null) {
2019                 byte[] buf = tag.readNdef();
2020                 if (buf == null) {
2021                     return null;
2022                 }
2023 
2024                 /* Create an NdefMessage */
2025                 try {
2026                     return new NdefMessage(buf);
2027                 } catch (FormatException e) {
2028                     return null;
2029                 }
2030             }
2031             return null;
2032         }
2033 
2034         @Override
ndefWrite(int nativeHandle, NdefMessage msg)2035         public int ndefWrite(int nativeHandle, NdefMessage msg) throws RemoteException {
2036             NfcPermissions.enforceUserPermissions(mContext);
2037 
2038             TagEndpoint tag;
2039 
2040             // Check if NFC is enabled
2041             if (!isNfcEnabled()) {
2042                 return ErrorCodes.ERROR_NOT_INITIALIZED;
2043             }
2044 
2045             /* find the tag in the hmap */
2046             tag = (TagEndpoint) findObject(nativeHandle);
2047             if (tag == null) {
2048                 return ErrorCodes.ERROR_IO;
2049             }
2050 
2051             if (msg == null) return ErrorCodes.ERROR_INVALID_PARAM;
2052 
2053             if (tag.writeNdef(msg.toByteArray())) {
2054                 return ErrorCodes.SUCCESS;
2055             } else {
2056                 return ErrorCodes.ERROR_IO;
2057             }
2058 
2059         }
2060 
2061         @Override
ndefIsWritable(int nativeHandle)2062         public boolean ndefIsWritable(int nativeHandle) throws RemoteException {
2063             throw new UnsupportedOperationException();
2064         }
2065 
2066         @Override
ndefMakeReadOnly(int nativeHandle)2067         public int ndefMakeReadOnly(int nativeHandle) throws RemoteException {
2068             NfcPermissions.enforceUserPermissions(mContext);
2069 
2070             TagEndpoint tag;
2071 
2072             // Check if NFC is enabled
2073             if (!isNfcEnabled()) {
2074                 return ErrorCodes.ERROR_NOT_INITIALIZED;
2075             }
2076 
2077             /* find the tag in the hmap */
2078             tag = (TagEndpoint) findObject(nativeHandle);
2079             if (tag == null) {
2080                 return ErrorCodes.ERROR_IO;
2081             }
2082 
2083             if (tag.makeReadOnly()) {
2084                 return ErrorCodes.SUCCESS;
2085             } else {
2086                 return ErrorCodes.ERROR_IO;
2087             }
2088         }
2089 
2090         @Override
formatNdef(int nativeHandle, byte[] key)2091         public int formatNdef(int nativeHandle, byte[] key) throws RemoteException {
2092             NfcPermissions.enforceUserPermissions(mContext);
2093 
2094             TagEndpoint tag;
2095 
2096             // Check if NFC is enabled
2097             if (!isNfcEnabled()) {
2098                 return ErrorCodes.ERROR_NOT_INITIALIZED;
2099             }
2100 
2101             /* find the tag in the hmap */
2102             tag = (TagEndpoint) findObject(nativeHandle);
2103             if (tag == null) {
2104                 return ErrorCodes.ERROR_IO;
2105             }
2106 
2107             if (tag.formatNdef(key)) {
2108                 return ErrorCodes.SUCCESS;
2109             } else {
2110                 return ErrorCodes.ERROR_IO;
2111             }
2112         }
2113 
2114         @Override
rediscover(int nativeHandle)2115         public Tag rediscover(int nativeHandle) throws RemoteException {
2116             NfcPermissions.enforceUserPermissions(mContext);
2117 
2118             TagEndpoint tag = null;
2119 
2120             // Check if NFC is enabled
2121             if (!isNfcEnabled()) {
2122                 return null;
2123             }
2124 
2125             /* find the tag in the hmap */
2126             tag = (TagEndpoint) findObject(nativeHandle);
2127             if (tag != null) {
2128                 // For now the prime usecase for rediscover() is to be able
2129                 // to access the NDEF technology after formatting without
2130                 // having to remove the tag from the field, or similar
2131                 // to have access to NdefFormatable in case low-level commands
2132                 // were used to remove NDEF. So instead of doing a full stack
2133                 // rediscover (which is poorly supported at the moment anyway),
2134                 // we simply remove these two technologies and detect them
2135                 // again.
2136                 tag.removeTechnology(TagTechnology.NDEF);
2137                 tag.removeTechnology(TagTechnology.NDEF_FORMATABLE);
2138                 tag.findAndReadNdef();
2139                 // Build a new Tag object to return
2140                 try {
2141                     /* Avoid setting mCookieUpToDate to negative values */
2142                     mCookieUpToDate = mCookieGenerator.nextLong() >>> 1;
2143                     Tag newTag = new Tag(tag.getUid(), tag.getTechList(),
2144                             tag.getTechExtras(), tag.getHandle(), mCookieUpToDate, this);
2145                     return newTag;
2146                 } catch (Exception e) {
2147                     Log.e(TAG, "Tag creation exception.", e);
2148                     return null;
2149                 }
2150             }
2151             return null;
2152         }
2153 
2154         @Override
setTimeout(int tech, int timeout)2155         public int setTimeout(int tech, int timeout) throws RemoteException {
2156             NfcPermissions.enforceUserPermissions(mContext);
2157             boolean success = mDeviceHost.setTimeout(tech, timeout);
2158             if (success) {
2159                 return ErrorCodes.SUCCESS;
2160             } else {
2161                 return ErrorCodes.ERROR_INVALID_PARAM;
2162             }
2163         }
2164 
2165         @Override
getTimeout(int tech)2166         public int getTimeout(int tech) throws RemoteException {
2167             NfcPermissions.enforceUserPermissions(mContext);
2168 
2169             return mDeviceHost.getTimeout(tech);
2170         }
2171 
2172         @Override
resetTimeouts()2173         public void resetTimeouts() throws RemoteException {
2174             NfcPermissions.enforceUserPermissions(mContext);
2175 
2176             mDeviceHost.resetTimeouts();
2177         }
2178 
2179         @Override
canMakeReadOnly(int ndefType)2180         public boolean canMakeReadOnly(int ndefType) throws RemoteException {
2181             return mDeviceHost.canMakeReadOnly(ndefType);
2182         }
2183 
2184         @Override
getMaxTransceiveLength(int tech)2185         public int getMaxTransceiveLength(int tech) throws RemoteException {
2186             return mDeviceHost.getMaxTransceiveLength(tech);
2187         }
2188 
2189         @Override
getExtendedLengthApdusSupported()2190         public boolean getExtendedLengthApdusSupported() throws RemoteException {
2191             return mDeviceHost.getExtendedLengthApdusSupported();
2192         }
2193 
2194         @Override
isTagUpToDate(long cookie)2195         public boolean isTagUpToDate(long cookie) throws RemoteException {
2196             if (mCookieUpToDate != -1 && mCookieUpToDate == cookie) {
2197                 if (DBG) Log.d(TAG, "Tag " + Long.toString(cookie) + " is up to date");
2198                 return true;
2199             }
2200 
2201             if (DBG) Log.d(TAG, "Tag " + Long.toString(cookie) + " is out of date");
2202             EventLog.writeEvent(0x534e4554, "199291025", -1,
2203                     "The obsolete tag was attempted to be accessed");
2204             return false;
2205         }
2206     }
2207 
2208     final class NfcDtaService extends INfcDta.Stub {
enableDta()2209         public void enableDta() throws RemoteException {
2210             NfcPermissions.enforceAdminPermissions(mContext);
2211             if(!sIsDtaMode) {
2212                 mDeviceHost.enableDtaMode();
2213                 sIsDtaMode = true;
2214                 Log.d(TAG, "DTA Mode is Enabled ");
2215             }
2216         }
2217 
disableDta()2218         public void disableDta() throws RemoteException {
2219             NfcPermissions.enforceAdminPermissions(mContext);
2220             if(sIsDtaMode) {
2221                 mDeviceHost.disableDtaMode();
2222                 sIsDtaMode = false;
2223             }
2224         }
2225 
enableServer(String serviceName, int serviceSap, int miu, int rwSize,int testCaseId)2226         public boolean enableServer(String serviceName, int serviceSap, int miu,
2227                 int rwSize,int testCaseId) throws RemoteException {
2228             NfcPermissions.enforceAdminPermissions(mContext);
2229             return false;
2230         }
2231 
disableServer()2232         public void disableServer() throws RemoteException {
2233         }
2234 
enableClient(String serviceName, int miu, int rwSize, int testCaseId)2235         public boolean enableClient(String serviceName, int miu, int rwSize,
2236                 int testCaseId) throws RemoteException {
2237             NfcPermissions.enforceAdminPermissions(mContext);
2238             return false;
2239         }
2240 
disableClient()2241         public void disableClient() throws RemoteException {
2242             return;
2243         }
2244 
registerMessageService(String msgServiceName)2245         public boolean registerMessageService(String msgServiceName)
2246                 throws RemoteException {
2247             NfcPermissions.enforceAdminPermissions(mContext);
2248             if(msgServiceName == null)
2249                 return false;
2250 
2251             DtaServiceConnector.setMessageService(msgServiceName);
2252             return true;
2253         }
2254 
2255     };
2256 
isNfcEnabledOrShuttingDown()2257     boolean isNfcEnabledOrShuttingDown() {
2258         synchronized (this) {
2259             return (mState == NfcAdapter.STATE_ON || mState == NfcAdapter.STATE_TURNING_OFF);
2260         }
2261     }
2262 
isNfcEnabled()2263     boolean isNfcEnabled() {
2264         synchronized (this) {
2265             return mState == NfcAdapter.STATE_ON;
2266         }
2267     }
2268 
2269     class WatchDogThread extends Thread {
2270         final Object mCancelWaiter = new Object();
2271         final int mTimeout;
2272         boolean mCanceled = false;
2273 
WatchDogThread(String threadName, int timeout)2274         public WatchDogThread(String threadName, int timeout) {
2275             super(threadName);
2276             mTimeout = timeout;
2277         }
2278 
2279         @Override
run()2280         public void run() {
2281             try {
2282                 synchronized (mCancelWaiter) {
2283                     mCancelWaiter.wait(mTimeout);
2284                     if (mCanceled) {
2285                         return;
2286                     }
2287                 }
2288             } catch (InterruptedException e) {
2289                 // Should not happen; fall-through to abort.
2290                 Log.w(TAG, "Watchdog thread interruped.");
2291                 interrupt();
2292             }
2293             if(mRoutingWakeLock.isHeld()){
2294                 Log.e(TAG, "Watchdog triggered, release lock before aborting.");
2295                 mRoutingWakeLock.release();
2296             }
2297             Log.e(TAG, "Watchdog triggered, aborting.");
2298             NfcStatsLog.write(NfcStatsLog.NFC_STATE_CHANGED,
2299                     NfcStatsLog.NFC_STATE_CHANGED__STATE__CRASH_RESTART);
2300             storeNativeCrashLogs();
2301             mDeviceHost.doAbort(getName());
2302         }
2303 
cancel()2304         public synchronized void cancel() {
2305             synchronized (mCancelWaiter) {
2306                 mCanceled = true;
2307                 mCancelWaiter.notify();
2308             }
2309         }
2310     }
2311 
hexStringToBytes(String s)2312     static byte[] hexStringToBytes(String s) {
2313         if (s == null || s.length() == 0) return null;
2314         int len = s.length();
2315         if (len % 2 != 0) {
2316             s = '0' + s;
2317             len++;
2318         }
2319         byte[] data = new byte[len / 2];
2320         for (int i = 0; i < len; i += 2) {
2321             data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
2322                     + Character.digit(s.charAt(i + 1), 16));
2323         }
2324         return data;
2325     }
2326 
addKeyguardLockedStateListener()2327     private void addKeyguardLockedStateListener() {
2328         try {
2329             mKeyguard.addKeyguardLockedStateListener(mContext.getMainExecutor(),
2330                     mIKeyguardLockedStateListener);
2331         } catch (Exception e) {
2332             Log.e(TAG, "Exception in addKeyguardLockedStateListener " + e);
2333         }
2334     }
2335 
2336     /**
2337      * Receives KeyGuard lock state updates
2338      */
2339     private KeyguardLockedStateListener mIKeyguardLockedStateListener =
2340             new KeyguardLockedStateListener() {
2341         @Override
2342         public void onKeyguardLockedStateChanged(boolean isKeyguardLocked) {
2343             applyScreenState(mScreenStateHelper.checkScreenState());
2344         }
2345     };
2346 
2347     /**
2348      * Read mScreenState and apply NFC-C polling and NFC-EE routing
2349      */
applyRouting(boolean force)2350     void applyRouting(boolean force) {
2351         synchronized (this) {
2352             if (!isNfcEnabledOrShuttingDown()) {
2353                 return;
2354             }
2355             WatchDogThread watchDog = new WatchDogThread("applyRouting", ROUTING_WATCHDOG_MS);
2356             if (mInProvisionMode) {
2357                 mInProvisionMode = Settings.Global.getInt(mContentResolver,
2358                         Settings.Global.DEVICE_PROVISIONED, 0) == 0;
2359                 if (!mInProvisionMode) {
2360                     // Notify dispatcher it's fine to dispatch to any package now
2361                     // and allow handover transfers.
2362                     mNfcDispatcher.disableProvisioningMode();
2363                 }
2364             }
2365             // Special case: if we're transitioning to unlocked state while
2366             // still talking to a tag, postpone re-configuration.
2367             if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED && isTagPresent()) {
2368                 Log.d(TAG, "Not updating discovery parameters, tag connected.");
2369                 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESUME_POLLING),
2370                         APPLY_ROUTING_RETRY_TIMEOUT_MS);
2371                 return;
2372             }
2373 
2374             try {
2375                 watchDog.start();
2376                 // Compute new polling parameters
2377                 NfcDiscoveryParameters newParams = computeDiscoveryParameters(mScreenState);
2378                 if (force || !newParams.equals(mCurrentDiscoveryParameters)) {
2379                     if (newParams.shouldEnableDiscovery()) {
2380                         boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery();
2381                         mDeviceHost.enableDiscovery(newParams, shouldRestart);
2382                     } else {
2383                         mDeviceHost.disableDiscovery();
2384                     }
2385                     mCurrentDiscoveryParameters = newParams;
2386                 } else {
2387                     Log.d(TAG, "Discovery configuration equal, not updating.");
2388                 }
2389             } finally {
2390                 watchDog.cancel();
2391             }
2392         }
2393     }
2394 
computeDiscoveryParameters(int screenState)2395     private NfcDiscoveryParameters computeDiscoveryParameters(int screenState) {
2396         // Recompute discovery parameters based on screen state
2397         NfcDiscoveryParameters.Builder paramsBuilder = NfcDiscoveryParameters.newBuilder();
2398         // Polling
2399         if (screenState >= NFC_POLLING_MODE) {
2400             // Check if reader-mode is enabled
2401             if (mReaderModeParams != null) {
2402                 int techMask = 0;
2403                 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_A) != 0)
2404                     techMask |= NFC_POLL_A;
2405                 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_B) != 0)
2406                     techMask |= NFC_POLL_B;
2407                 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_F) != 0)
2408                     techMask |= NFC_POLL_F;
2409                 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_V) != 0)
2410                     techMask |= NFC_POLL_V;
2411                 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_BARCODE) != 0)
2412                     techMask |= NFC_POLL_KOVIO;
2413 
2414                 paramsBuilder.setTechMask(techMask);
2415                 paramsBuilder.setEnableReaderMode(true);
2416                 if (mReaderModeParams.flags != 0 && techMask == 0) {
2417                     paramsBuilder.setEnableHostRouting(true);
2418                 }
2419             } else {
2420                 paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT);
2421                 paramsBuilder.setEnableP2p(false);
2422             }
2423         } else if (screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mInProvisionMode) {
2424             paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT);
2425             // enable P2P for MFM/EDU/Corp provisioning
2426             paramsBuilder.setEnableP2p(false);
2427         } else if (screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED &&
2428             mNfcUnlockManager.isLockscreenPollingEnabled()) {
2429             int techMask = 0;
2430             if (mNfcUnlockManager.isLockscreenPollingEnabled())
2431                 techMask |= mNfcUnlockManager.getLockscreenPollMask();
2432             paramsBuilder.setTechMask(techMask);
2433             paramsBuilder.setEnableLowPowerDiscovery(false);
2434             paramsBuilder.setEnableP2p(false);
2435         }
2436 
2437         if (mIsHceCapable && mReaderModeParams == null) {
2438             // Host routing is always enabled, provided we aren't in reader mode
2439             paramsBuilder.setEnableHostRouting(true);
2440         }
2441 
2442         return paramsBuilder.build();
2443     }
2444 
isTagPresent()2445     private boolean isTagPresent() {
2446         for (Object object : mObjectMap.values()) {
2447             if (object instanceof TagEndpoint) {
2448                 return ((TagEndpoint) object).isPresent();
2449             }
2450         }
2451         return false;
2452     }
2453 
StopPresenceChecking()2454     private void StopPresenceChecking() {
2455         Object[] objectValues = mObjectMap.values().toArray();
2456         for (Object object : objectValues) {
2457             if (object instanceof TagEndpoint) {
2458                 TagEndpoint tag = (TagEndpoint)object;
2459                 ((TagEndpoint) object).stopPresenceChecking();
2460             }
2461         }
2462     }
2463 
2464     /**
2465      * Disconnect any target if present
2466      */
maybeDisconnectTarget()2467     void maybeDisconnectTarget() {
2468         if (!isNfcEnabledOrShuttingDown()) {
2469             return;
2470         }
2471         Object[] objectsToDisconnect;
2472         synchronized (this) {
2473             Object[] objectValues = mObjectMap.values().toArray();
2474             // Copy the array before we clear mObjectMap,
2475             // just in case the HashMap values are backed by the same array
2476             objectsToDisconnect = Arrays.copyOf(objectValues, objectValues.length);
2477             mObjectMap.clear();
2478         }
2479         for (Object o : objectsToDisconnect) {
2480             if (DBG) Log.d(TAG, "disconnecting " + o.getClass().getName());
2481             if (o instanceof TagEndpoint) {
2482                 // Disconnect from tags
2483                 TagEndpoint tag = (TagEndpoint) o;
2484                 tag.disconnect();
2485             } else if (o instanceof NfcDepEndpoint) {
2486                 // Disconnect from P2P devices
2487                 NfcDepEndpoint device = (NfcDepEndpoint) o;
2488                 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) {
2489                     // Remote peer is target, request disconnection
2490                     device.disconnect();
2491                 } else {
2492                     // Remote peer is initiator, we cannot disconnect
2493                     // Just wait for field removal
2494                 }
2495             }
2496         }
2497     }
2498 
findObject(int key)2499     Object findObject(int key) {
2500         synchronized (this) {
2501             Object device = mObjectMap.get(key);
2502             if (device == null) {
2503                 Log.w(TAG, "Handle not found");
2504             }
2505             return device;
2506         }
2507     }
2508 
findAndRemoveObject(int handle)2509     Object findAndRemoveObject(int handle) {
2510         synchronized (this) {
2511             Object device = mObjectMap.get(handle);
2512             if (device == null) {
2513                 Log.w(TAG, "Handle not found");
2514             } else {
2515                 mObjectMap.remove(handle);
2516             }
2517             return device;
2518         }
2519     }
2520 
registerTagObject(TagEndpoint tag)2521     void registerTagObject(TagEndpoint tag) {
2522         synchronized (this) {
2523             mObjectMap.put(tag.getHandle(), tag);
2524         }
2525     }
2526 
unregisterObject(int handle)2527     void unregisterObject(int handle) {
2528         synchronized (this) {
2529             mObjectMap.remove(handle);
2530         }
2531     }
2532 
2533     /**
2534      * For use by code in this process
2535      */
createLlcpSocket(int sap, int miu, int rw, int linearBufferLength)2536     public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength)
2537             throws LlcpException {
2538         return mDeviceHost.createLlcpSocket(sap, miu, rw, linearBufferLength);
2539     }
2540 
2541     /**
2542      * For use by code in this process
2543      */
createLlcpConnectionLessSocket(int sap, String sn)2544     public LlcpConnectionlessSocket createLlcpConnectionLessSocket(int sap, String sn)
2545             throws LlcpException {
2546         return mDeviceHost.createLlcpConnectionlessSocket(sap, sn);
2547     }
2548 
2549     /**
2550      * For use by code in this process
2551      */
createLlcpServerSocket(int sap, String sn, int miu, int rw, int linearBufferLength)2552     public LlcpServerSocket createLlcpServerSocket(int sap, String sn, int miu, int rw,
2553             int linearBufferLength) throws LlcpException {
2554         return mDeviceHost.createLlcpServerSocket(sap, sn, miu, rw, linearBufferLength);
2555     }
2556 
getAidRoutingTableSize()2557     public int getAidRoutingTableSize ()
2558     {
2559         int aidTableSize = 0x00;
2560         aidTableSize = mDeviceHost.getAidTableSize();
2561         return aidTableSize;
2562     }
2563 
sendMockNdefTag(NdefMessage msg)2564     public void sendMockNdefTag(NdefMessage msg) {
2565         sendMessage(MSG_MOCK_NDEF, msg);
2566     }
2567 
routeAids(String aid, int route, int aidInfo, int power)2568     public void routeAids(String aid, int route, int aidInfo, int power) {
2569         Message msg = mHandler.obtainMessage();
2570         msg.what = MSG_ROUTE_AID;
2571         msg.arg1 = route;
2572         msg.obj = aid;
2573         msg.arg2 = aidInfo;
2574 
2575         Bundle aidPowerState = new Bundle();
2576         aidPowerState.putInt(MSG_ROUTE_AID_PARAM_TAG, power);
2577         msg.setData(aidPowerState);
2578 
2579         mHandler.sendMessage(msg);
2580     }
2581 
unrouteAids(String aid)2582     public void unrouteAids(String aid) {
2583         sendMessage(MSG_UNROUTE_AID, aid);
2584     }
2585 
getNciVersion()2586     public int getNciVersion() {
2587         return mDeviceHost.getNciVersion();
2588     }
2589 
getT3tIdentifierBytes(String systemCode, String nfcId2, String t3tPmm)2590     private byte[] getT3tIdentifierBytes(String systemCode, String nfcId2, String t3tPmm) {
2591         ByteBuffer buffer = ByteBuffer.allocate(2 + 8 + 8); /* systemcode + nfcid2 + t3tpmm */
2592         buffer.put(hexStringToBytes(systemCode));
2593         buffer.put(hexStringToBytes(nfcId2));
2594         buffer.put(hexStringToBytes(t3tPmm));
2595         byte[] t3tIdBytes = new byte[buffer.position()];
2596         buffer.position(0);
2597         buffer.get(t3tIdBytes);
2598 
2599         return t3tIdBytes;
2600     }
2601 
registerT3tIdentifier(String systemCode, String nfcId2, String t3tPmm)2602     public void registerT3tIdentifier(String systemCode, String nfcId2, String t3tPmm) {
2603         Log.d(TAG, "request to register LF_T3T_IDENTIFIER");
2604 
2605         byte[] t3tIdentifier = getT3tIdentifierBytes(systemCode, nfcId2, t3tPmm);
2606         sendMessage(MSG_REGISTER_T3T_IDENTIFIER, t3tIdentifier);
2607     }
2608 
deregisterT3tIdentifier(String systemCode, String nfcId2, String t3tPmm)2609     public void deregisterT3tIdentifier(String systemCode, String nfcId2, String t3tPmm) {
2610         Log.d(TAG, "request to deregister LF_T3T_IDENTIFIER");
2611 
2612         byte[] t3tIdentifier = getT3tIdentifierBytes(systemCode, nfcId2, t3tPmm);
2613         sendMessage(MSG_DEREGISTER_T3T_IDENTIFIER, t3tIdentifier);
2614     }
2615 
clearT3tIdentifiersCache()2616     public void clearT3tIdentifiersCache() {
2617         Log.d(TAG, "clear T3t Identifiers Cache");
2618         mDeviceHost.clearT3tIdentifiersCache();
2619     }
2620 
getLfT3tMax()2621     public int getLfT3tMax() {
2622         return mDeviceHost.getLfT3tMax();
2623     }
2624 
commitRouting()2625     public void commitRouting() {
2626         mHandler.sendEmptyMessage(MSG_COMMIT_ROUTING);
2627     }
2628 
sendData(byte[] data)2629     public boolean sendData(byte[] data) {
2630         return mDeviceHost.sendRawFrame(data);
2631     }
2632 
onPreferredPaymentChanged(int reason)2633     public void onPreferredPaymentChanged(int reason) {
2634         sendMessage(MSG_PREFERRED_PAYMENT_CHANGED, reason);
2635     }
2636 
sendMessage(int what, Object obj)2637     void sendMessage(int what, Object obj) {
2638         Message msg = mHandler.obtainMessage();
2639         msg.what = what;
2640         msg.obj = obj;
2641         mHandler.sendMessage(msg);
2642     }
2643 
2644     /**
2645      * Send require device unlock for NFC intent to system UI.
2646      */
sendRequireUnlockIntent()2647     public void sendRequireUnlockIntent() {
2648         if (!mIsRequestUnlockShowed && mKeyguard.isKeyguardLocked()) {
2649             if (DBG) Log.d(TAG, "Request unlock");
2650             mIsRequestUnlockShowed = true;
2651             mRequireUnlockWakeLock.acquire();
2652             Intent requireUnlockIntent =
2653                     new Intent(NfcAdapter.ACTION_REQUIRE_UNLOCK_FOR_NFC);
2654             requireUnlockIntent.setPackage(SYSTEM_UI);
2655             mContext.sendBroadcast(requireUnlockIntent);
2656             mRequireUnlockWakeLock.release();
2657         }
2658     }
2659 
2660     final class NfcServiceHandler extends Handler {
2661         @Override
handleMessage(Message msg)2662         public void handleMessage(Message msg) {
2663             switch (msg.what) {
2664                 case MSG_ROUTE_AID: {
2665                     int route = msg.arg1;
2666                     int aidInfo = msg.arg2;
2667                     String aid = (String) msg.obj;
2668 
2669                     int power = 0x00;
2670                     Bundle bundle = msg.getData();
2671                     if (bundle != null) {
2672                         power = bundle.getInt(MSG_ROUTE_AID_PARAM_TAG);
2673                     }
2674 
2675                     mDeviceHost.routeAid(hexStringToBytes(aid), route, aidInfo, power);
2676                     // Restart polling config
2677                     break;
2678                 }
2679                 case MSG_UNROUTE_AID: {
2680                     String aid = (String) msg.obj;
2681                     mDeviceHost.unrouteAid(hexStringToBytes(aid));
2682                     break;
2683                 }
2684                 case MSG_REGISTER_T3T_IDENTIFIER: {
2685                     Log.d(TAG, "message to register LF_T3T_IDENTIFIER");
2686                     mDeviceHost.disableDiscovery();
2687 
2688                     byte[] t3tIdentifier = (byte[]) msg.obj;
2689                     mDeviceHost.registerT3tIdentifier(t3tIdentifier);
2690 
2691                     NfcDiscoveryParameters params = computeDiscoveryParameters(mScreenState);
2692                     boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery();
2693                     mDeviceHost.enableDiscovery(params, shouldRestart);
2694                     break;
2695                 }
2696                 case MSG_DEREGISTER_T3T_IDENTIFIER: {
2697                     Log.d(TAG, "message to deregister LF_T3T_IDENTIFIER");
2698                     mDeviceHost.disableDiscovery();
2699 
2700                     byte[] t3tIdentifier = (byte[]) msg.obj;
2701                     mDeviceHost.deregisterT3tIdentifier(t3tIdentifier);
2702 
2703                     NfcDiscoveryParameters params = computeDiscoveryParameters(mScreenState);
2704                     boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery();
2705                     mDeviceHost.enableDiscovery(params, shouldRestart);
2706                     break;
2707                 }
2708                 case MSG_COMMIT_ROUTING: {
2709                     synchronized (NfcService.this) {
2710                         if (mState == NfcAdapter.STATE_OFF
2711                                 || mState == NfcAdapter.STATE_TURNING_OFF) {
2712                             Log.d(TAG, "Skip commit routing when NFCC is off or turning off");
2713                             return;
2714                         }
2715                         if (mCurrentDiscoveryParameters.shouldEnableDiscovery()) {
2716                             mDeviceHost.commitRouting();
2717                         } else {
2718                             Log.d(TAG, "Not committing routing because discovery is disabled.");
2719                         }
2720                     }
2721                     break;
2722                 }
2723                 case MSG_MOCK_NDEF: {
2724                     NdefMessage ndefMsg = (NdefMessage) msg.obj;
2725                     Bundle extras = new Bundle();
2726                     extras.putParcelable(Ndef.EXTRA_NDEF_MSG, ndefMsg);
2727                     extras.putInt(Ndef.EXTRA_NDEF_MAXLENGTH, 0);
2728                     extras.putInt(Ndef.EXTRA_NDEF_CARDSTATE, Ndef.NDEF_MODE_READ_ONLY);
2729                     extras.putInt(Ndef.EXTRA_NDEF_TYPE, Ndef.TYPE_OTHER);
2730                     /* Avoid setting mCookieUpToDate to negative values */
2731                     mCookieUpToDate = mCookieGenerator.nextLong() >>> 1;
2732                     Tag tag = Tag.createMockTag(new byte[]{0x00},
2733                             new int[]{TagTechnology.NDEF},
2734                             new Bundle[]{extras}, mCookieUpToDate);
2735                     Log.d(TAG, "mock NDEF tag, starting corresponding activity");
2736                     Log.d(TAG, tag.toString());
2737                     int dispatchStatus = mNfcDispatcher.dispatchTag(tag);
2738                     if (dispatchStatus == NfcDispatcher.DISPATCH_SUCCESS) {
2739                         playSound(SOUND_END);
2740                     } else if (dispatchStatus == NfcDispatcher.DISPATCH_FAIL) {
2741                         playSound(SOUND_ERROR);
2742                     }
2743                     break;
2744                 }
2745 
2746                 case MSG_NDEF_TAG:
2747                     if (DBG) Log.d(TAG, "Tag detected, notifying applications");
2748                     TagEndpoint tag = (TagEndpoint) msg.obj;
2749                     byte[] debounceTagUid;
2750                     int debounceTagMs;
2751                     ITagRemovedCallback debounceTagRemovedCallback;
2752                     synchronized (NfcService.this) {
2753                         debounceTagUid = mDebounceTagUid;
2754                         debounceTagMs = mDebounceTagDebounceMs;
2755                         debounceTagRemovedCallback = mDebounceTagRemovedCallback;
2756                     }
2757                     ReaderModeParams readerParams = null;
2758                     int presenceCheckDelay = DEFAULT_PRESENCE_CHECK_DELAY;
2759                     DeviceHost.TagDisconnectedCallback callback =
2760                             new DeviceHost.TagDisconnectedCallback() {
2761                                 @Override
2762                                 public void onTagDisconnected(long handle) {
2763                                     mCookieUpToDate = -1;
2764                                     applyRouting(false);
2765                                 }
2766                             };
2767                     synchronized (NfcService.this) {
2768                         readerParams = mReaderModeParams;
2769                     }
2770                     if (readerParams != null) {
2771                         presenceCheckDelay = readerParams.presenceCheckDelay;
2772                         if ((readerParams.flags & NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK) != 0) {
2773                             if (DBG) Log.d(TAG, "Skipping NDEF detection in reader mode");
2774                             tag.startPresenceChecking(presenceCheckDelay, callback);
2775                             dispatchTagEndpoint(tag, readerParams);
2776                             break;
2777                         }
2778 
2779                         if (mIsDebugBuild && mSkipNdefRead) {
2780                             if (DBG) Log.d(TAG, "Only NDEF detection in reader mode");
2781                             tag.findNdef();
2782                             tag.startPresenceChecking(presenceCheckDelay, callback);
2783                             dispatchTagEndpoint(tag, readerParams);
2784                             break;
2785                         }
2786                     }
2787 
2788                     if (tag.getConnectedTechnology() == TagTechnology.NFC_BARCODE) {
2789                         // When these tags start containing NDEF, they will require
2790                         // the stack to deal with them in a different way, since
2791                         // they are activated only really shortly.
2792                         // For now, don't consider NDEF on these.
2793                         if (DBG) Log.d(TAG, "Skipping NDEF detection for NFC Barcode");
2794                         tag.startPresenceChecking(presenceCheckDelay, callback);
2795                         dispatchTagEndpoint(tag, readerParams);
2796                         break;
2797                     }
2798                     NdefMessage ndefMsg = tag.findAndReadNdef();
2799 
2800                     if (ndefMsg == null) {
2801                         // First try to see if this was a bad tag read
2802                         if (!tag.reconnect()) {
2803                             tag.disconnect();
2804                             if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) {
2805                                 if (!sToast_debounce && mNotifyReadFailed) {
2806                                     Toast.makeText(mContext, R.string.tag_read_error,
2807                                                    Toast.LENGTH_SHORT).show();
2808                                     sToast_debounce = true;
2809                                     mHandler.sendEmptyMessageDelayed(MSG_TOAST_DEBOUNCE_EVENT,
2810                                                                      sToast_debounce_time_ms);
2811                                 }
2812                             }
2813                             break;
2814                         }
2815                     }
2816 
2817                     if (debounceTagUid != null) {
2818                         // If we're debouncing and the UID or the NDEF message of the tag match,
2819                         // don't dispatch but drop it.
2820                         if (Arrays.equals(debounceTagUid, tag.getUid()) ||
2821                                 (ndefMsg != null && ndefMsg.equals(mLastReadNdefMessage))) {
2822                             mHandler.removeMessages(MSG_TAG_DEBOUNCE);
2823                             mHandler.sendEmptyMessageDelayed(MSG_TAG_DEBOUNCE, debounceTagMs);
2824                             tag.disconnect();
2825                             return;
2826                         } else {
2827                             synchronized (NfcService.this) {
2828                                 mDebounceTagUid = null;
2829                                 mDebounceTagRemovedCallback = null;
2830                                 mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE;
2831                             }
2832                             if (debounceTagRemovedCallback != null) {
2833                                 try {
2834                                     debounceTagRemovedCallback.onTagRemoved();
2835                                 } catch (RemoteException e) {
2836                                     // Ignore
2837                                 }
2838                             }
2839                         }
2840                     }
2841 
2842                     mLastReadNdefMessage = ndefMsg;
2843 
2844                     tag.startPresenceChecking(presenceCheckDelay, callback);
2845                     dispatchTagEndpoint(tag, readerParams);
2846                     break;
2847 
2848                 case MSG_RF_FIELD_ACTIVATED:
2849                     Intent fieldOnIntent = new Intent(ACTION_RF_FIELD_ON_DETECTED);
2850                     sendNfcPermissionProtectedBroadcast(fieldOnIntent);
2851                     if (mIsSecureNfcEnabled) {
2852                         sendRequireUnlockIntent();
2853                     }
2854                     break;
2855                 case MSG_RF_FIELD_DEACTIVATED:
2856                     Intent fieldOffIntent = new Intent(ACTION_RF_FIELD_OFF_DETECTED);
2857                     sendNfcPermissionProtectedBroadcast(fieldOffIntent);
2858                     break;
2859                 case MSG_RESUME_POLLING:
2860                     mNfcAdapter.resumePolling();
2861                     break;
2862                 case MSG_TAG_DEBOUNCE:
2863                     // Didn't see the tag again, tag is gone
2864                     ITagRemovedCallback tagRemovedCallback;
2865                     synchronized (NfcService.this) {
2866                         mDebounceTagUid = null;
2867                         tagRemovedCallback = mDebounceTagRemovedCallback;
2868                         mDebounceTagRemovedCallback = null;
2869                         mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE;
2870                     }
2871                     if (tagRemovedCallback != null) {
2872                         try {
2873                             tagRemovedCallback.onTagRemoved();
2874                         } catch (RemoteException e) {
2875                             // Ignore
2876                         }
2877                     }
2878                     break;
2879 
2880                 case MSG_APPLY_SCREEN_STATE:
2881                     mScreenState = (Integer)msg.obj;
2882                     Log.d(TAG, "MSG_APPLY_SCREEN_STATE " + mScreenState);
2883 
2884                     synchronized (NfcService.this) {
2885                         // Disable delay polling when screen state changed
2886                         mPollDelayed = false;
2887                         mHandler.removeMessages(MSG_DELAY_POLLING);
2888                         // If NFC is turning off, we shouldn't need any changes here
2889                         if (mState == NfcAdapter.STATE_TURNING_OFF)
2890                             return;
2891                     }
2892 
2893                     mRoutingWakeLock.acquire();
2894                     try {
2895                         if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) {
2896                             applyRouting(false);
2897                             mIsRequestUnlockShowed = false;
2898                         }
2899                         int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled())
2900                                 ? (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) :
2901                                 mScreenState;
2902 
2903                         if (mNfcUnlockManager.isLockscreenPollingEnabled()) {
2904                             applyRouting(false);
2905                         }
2906 
2907                         mDeviceHost.doSetScreenState(screen_state_mask);
2908                     } finally {
2909                         mRoutingWakeLock.release();
2910                     }
2911                     break;
2912 
2913                 case MSG_TRANSACTION_EVENT:
2914                     if (mCardEmulationManager != null) {
2915                         mCardEmulationManager.onOffHostAidSelected();
2916                     }
2917                     byte[][] data = (byte[][]) msg.obj;
2918                     sendOffHostTransactionEvent(data[0], data[1], data[2]);
2919                     break;
2920 
2921                 case MSG_PREFERRED_PAYMENT_CHANGED:
2922                     Intent preferredPaymentChangedIntent =
2923                             new Intent(NfcAdapter.ACTION_PREFERRED_PAYMENT_CHANGED);
2924                     preferredPaymentChangedIntent.putExtra(
2925                             NfcAdapter.EXTRA_PREFERRED_PAYMENT_CHANGED_REASON, (int)msg.obj);
2926                     sendPreferredPaymentChangedEvent(preferredPaymentChangedIntent);
2927                     break;
2928 
2929                 case MSG_TOAST_DEBOUNCE_EVENT:
2930                     sToast_debounce = false;
2931                     break;
2932 
2933                 case MSG_DELAY_POLLING:
2934                     synchronized (NfcService.this) {
2935                         if (!mPollDelayed) {
2936                             return;
2937                         }
2938                         mPollDelayed = false;
2939                         mDeviceHost.startStopPolling(true);
2940                     }
2941                     if (DBG) Log.d(TAG, "Polling is started");
2942                     break;
2943                 default:
2944                     Log.e(TAG, "Unknown message received");
2945                     break;
2946             }
2947         }
2948 
sendOffHostTransactionEvent(byte[] aid, byte[] data, byte[] readerByteArray)2949         private void sendOffHostTransactionEvent(byte[] aid, byte[] data, byte[] readerByteArray) {
2950             if (!isSEServiceAvailable() || mNfcEventInstalledPackages.isEmpty()) {
2951                 return;
2952             }
2953 
2954             try {
2955                 String reader = new String(readerByteArray, "UTF-8");
2956                 int uid = -1;
2957                 StringBuilder aidString = new StringBuilder(aid.length);
2958                 for (byte b : aid) {
2959                     aidString.append(String.format("%02X", b));
2960                 }
2961                 for (int userId : mNfcEventInstalledPackages.keySet()) {
2962                     List<String> packagesOfUser = mNfcEventInstalledPackages.get(userId);
2963                     String[] installedPackages = new String[packagesOfUser.size()];
2964                     boolean[] nfcAccess = mSEService.isNfcEventAllowed(reader, aid,
2965                             packagesOfUser.toArray(installedPackages), userId);
2966                     if (nfcAccess == null) {
2967                         continue;
2968                     }
2969                     Intent intent = new Intent(NfcAdapter.ACTION_TRANSACTION_DETECTED);
2970                     intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
2971                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2972                     intent.putExtra(NfcAdapter.EXTRA_AID, aid);
2973                     intent.putExtra(NfcAdapter.EXTRA_DATA, data);
2974                     intent.putExtra(NfcAdapter.EXTRA_SECURE_ELEMENT_NAME, reader);
2975                     String url =
2976                             new String("nfc://secure:0/" + reader + "/" + aidString.toString());
2977                     intent.setData(Uri.parse(url));
2978 
2979                     final BroadcastOptions options = BroadcastOptions.makeBasic();
2980                     options.setBackgroundActivityStartsAllowed(true);
2981 
2982                     Map<String, Integer> hasIntentPackages = mContext
2983                             .getPackageManager()
2984                             .queryBroadcastReceiversAsUser(intent, 0, UserHandle.of(userId))
2985                             .stream()
2986                             .collect(Collectors.toMap(
2987                                       activity -> activity.activityInfo.applicationInfo.packageName,
2988                                       activity -> activity.activityInfo.applicationInfo.uid,
2989                                       (packageName1, packageName2) -> {
2990                                           if (DBG) {
2991                                               Log.d(TAG,
2992                                                       "queryBroadcastReceiversAsUser duplicate: " +
2993                                                       packageName1 + ", " + packageName2);
2994                                           }
2995                                           return packageName1;
2996                                       }));
2997                     if (DBG) {
2998                         String[] packageNames = hasIntentPackages
2999                                 .keySet().toArray(new String[hasIntentPackages.size()]);
3000                         Log.d(TAG,
3001                                 "queryBroadcastReceiversAsUser: " + Arrays.toString(packageNames));
3002                     }
3003 
3004                     for (int i = 0; i < nfcAccess.length; i++) {
3005                         if (nfcAccess[i]) {
3006                             if (DBG) {
3007                                 Log.d(TAG,
3008                                         "sendOffHostTransactionEvent to " + packagesOfUser.get(i));
3009                             }
3010                             if (uid == -1 && hasIntentPackages.containsKey(packagesOfUser.get(i))) {
3011                                 uid = hasIntentPackages.get(packagesOfUser.get(i));
3012                             }
3013                             intent.setPackage(packagesOfUser.get(i));
3014                             mContext.sendBroadcastAsUser(intent, UserHandle.of(userId), null,
3015                                     options.toBundle());
3016                         }
3017                     }
3018                 }
3019                 String aidCategory = mCardEmulationManager
3020                         .getRegisteredAidCategory(aidString.toString());
3021                 if (DBG) Log.d(TAG, "aid cateogry: " + aidCategory);
3022 
3023                 int offhostCategory;
3024                 switch (aidCategory) {
3025                     case CardEmulation.CATEGORY_PAYMENT:
3026                         offhostCategory = NfcStatsLog
3027                               .NFC_CARDEMULATION_OCCURRED__CATEGORY__OFFHOST_PAYMENT;
3028                         break;
3029                     case CardEmulation.CATEGORY_OTHER:
3030                         offhostCategory = NfcStatsLog
3031                                 .NFC_CARDEMULATION_OCCURRED__CATEGORY__OFFHOST_OTHER;
3032                         break;
3033                     default:
3034                         offhostCategory = NfcStatsLog
3035                             .NFC_CARDEMULATION_OCCURRED__CATEGORY__OFFHOST;
3036                 };
3037 
3038                 NfcStatsLog.write(NfcStatsLog.NFC_CARDEMULATION_OCCURRED,
3039                         offhostCategory,
3040                         reader,
3041                         uid);
3042             } catch (RemoteException e) {
3043                 Log.e(TAG, "Error in isNfcEventAllowed() " + e);
3044             } catch (UnsupportedEncodingException e) {
3045                 Log.e(TAG, "Incorrect format for Secure Element name" + e);
3046             }
3047         }
3048 
sendNfcPermissionProtectedBroadcast(Intent intent)3049         private void sendNfcPermissionProtectedBroadcast(Intent intent) {
3050             if (mNfcEventInstalledPackages.isEmpty()) {
3051                 return;
3052             }
3053             intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
3054             for (int userId : mNfcEventInstalledPackages.keySet()) {
3055                 for (String packageName : mNfcEventInstalledPackages.get(userId)) {
3056                     intent.setPackage(packageName);
3057                     mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
3058                 }
3059             }
3060         }
3061 
3062         /* Returns the list of packages request for nfc preferred payment service changed and
3063          * have access to NFC Events on any SE */
getNfcPreferredPaymentChangedSEAccessAllowedPackages(int userId)3064         private ArrayList<String> getNfcPreferredPaymentChangedSEAccessAllowedPackages(int userId) {
3065             if (!isSEServiceAvailable()
3066                     || mNfcPreferredPaymentChangedInstalledPackages.get(userId).isEmpty()) {
3067                 return null;
3068             }
3069             String[] readers = null;
3070             try {
3071                 readers = mSEService.getReaders();
3072             } catch (RemoteException e) {
3073                 Log.e(TAG, "Error in getReaders() " + e);
3074                 return null;
3075             }
3076 
3077             if (readers == null || readers.length == 0) {
3078                 return null;
3079             }
3080             boolean[] nfcAccessFinal = null;
3081             List<String> packagesOfUser = mNfcPreferredPaymentChangedInstalledPackages.get(userId);
3082             String[] installedPackages = new String[packagesOfUser.size()];
3083 
3084             for (String reader : readers) {
3085                 try {
3086                     boolean[] accessList = mSEService.isNfcEventAllowed(reader, null,
3087                             packagesOfUser.toArray(installedPackages), userId
3088                             );
3089                     if (accessList == null) {
3090                         continue;
3091                     }
3092                     if (nfcAccessFinal == null) {
3093                         nfcAccessFinal = accessList;
3094                     }
3095                     for (int i = 0; i < accessList.length; i++) {
3096                         if (accessList[i]) {
3097                             nfcAccessFinal[i] = true;
3098                         }
3099                     }
3100                 } catch (RemoteException e) {
3101                     Log.e(TAG, "Error in isNfcEventAllowed() " + e);
3102                 }
3103             }
3104             if (nfcAccessFinal == null) {
3105                 return null;
3106             }
3107             ArrayList<String> packages = new ArrayList<String>();
3108             for (int i = 0; i < nfcAccessFinal.length; i++) {
3109                 if (nfcAccessFinal[i]) {
3110                     packages.add(packagesOfUser.get(i));
3111                 }
3112             }
3113             return packages;
3114         }
3115 
sendPreferredPaymentChangedEvent(Intent intent)3116         private void sendPreferredPaymentChangedEvent(Intent intent) {
3117             intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
3118             // Resume app switches so the receivers can start activities without delay
3119             mNfcDispatcher.resumeAppSwitches();
3120             synchronized (this) {
3121                 for (int userId : mNfcPreferredPaymentChangedInstalledPackages.keySet()) {
3122                     ArrayList<String> SEPackages =
3123                             getNfcPreferredPaymentChangedSEAccessAllowedPackages(userId);
3124                     UserHandle userHandle = UserHandle.of(userId);
3125                     if (SEPackages != null && !SEPackages.isEmpty()) {
3126                         for (String packageName : SEPackages) {
3127                             intent.setPackage(packageName);
3128                             intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
3129                             mContext.sendBroadcastAsUser(intent, userHandle);
3130                         }
3131                     }
3132                     PackageManager pm;
3133                     try {
3134                         pm = mContext.createContextAsUser(userHandle, /*flags=*/0)
3135                                 .getPackageManager();
3136                     } catch (IllegalStateException e) {
3137                         Log.d(TAG, "Fail to get PackageManager for user: " + userHandle);
3138                         continue;
3139                     }
3140                     for (String pkgName :
3141                             mNfcPreferredPaymentChangedInstalledPackages.get(userId)) {
3142                         try {
3143                             PackageInfo info = pm.getPackageInfo(pkgName, 0);
3144                             if (SEPackages != null && SEPackages.contains(pkgName)) {
3145                                 continue;
3146                             }
3147                             if (info.applicationInfo != null && ((info.applicationInfo.flags
3148                                     & ApplicationInfo.FLAG_SYSTEM) != 0
3149                                     || (info.applicationInfo.privateFlags
3150                                     & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0)) {
3151                                 intent.setPackage(pkgName);
3152                                 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
3153                                 mContext.sendBroadcastAsUser(intent, userHandle);
3154                             }
3155                         } catch (Exception e) {
3156                             Log.e(TAG, "Exception in getPackageInfo " + e);
3157                         }
3158                     }
3159                 }
3160             }
3161         }
3162 
llcpActivated(NfcDepEndpoint device)3163         private boolean llcpActivated(NfcDepEndpoint device) {
3164             Log.d(TAG, "LLCP Activation message");
3165 
3166             if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) {
3167                 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_TARGET");
3168                 if (device.connect()) {
3169                     /* Check LLCP compliancy */
3170                     if (mDeviceHost.doCheckLlcp()) {
3171                         /* Activate LLCP Link */
3172                         if (mDeviceHost.doActivateLlcp()) {
3173                             if (DBG) Log.d(TAG, "Initiator Activate LLCP OK");
3174                             synchronized (NfcService.this) {
3175                                 // Register P2P device
3176                                 mObjectMap.put(device.getHandle(), device);
3177                             }
3178                             return true;
3179                         } else {
3180                             /* should not happen */
3181                             Log.w(TAG, "Initiator LLCP activation failed. Disconnect.");
3182                             device.disconnect();
3183                         }
3184                     } else {
3185                         if (DBG) Log.d(TAG, "Remote Target does not support LLCP. Disconnect.");
3186                         device.disconnect();
3187                     }
3188                 } else {
3189                     if (DBG) Log.d(TAG, "Cannot connect remote Target. Polling loop restarted.");
3190                     /*
3191                      * The polling loop should have been restarted in failing
3192                      * doConnect
3193                      */
3194                 }
3195             } else if (device.getMode() == NfcDepEndpoint.MODE_P2P_INITIATOR) {
3196                 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_INITIATOR");
3197                 /* Check LLCP compliancy */
3198                 if (mDeviceHost.doCheckLlcp()) {
3199                     /* Activate LLCP Link */
3200                     if (mDeviceHost.doActivateLlcp()) {
3201                         if (DBG) Log.d(TAG, "Target Activate LLCP OK");
3202                         synchronized (NfcService.this) {
3203                             // Register P2P device
3204                             mObjectMap.put(device.getHandle(), device);
3205                         }
3206                         return true;
3207                     }
3208                 } else {
3209                     Log.w(TAG, "checkLlcp failed");
3210                 }
3211             }
3212 
3213             return false;
3214         }
3215 
dispatchTagEndpoint(TagEndpoint tagEndpoint, ReaderModeParams readerParams)3216         private void dispatchTagEndpoint(TagEndpoint tagEndpoint, ReaderModeParams readerParams) {
3217             try {
3218                 /* Avoid setting mCookieUpToDate to negative values */
3219                 mCookieUpToDate = mCookieGenerator.nextLong() >>> 1;
3220                 Tag tag = new Tag(tagEndpoint.getUid(), tagEndpoint.getTechList(),
3221                         tagEndpoint.getTechExtras(), tagEndpoint.getHandle(),
3222                         mCookieUpToDate, mNfcTagService);
3223                 registerTagObject(tagEndpoint);
3224                 if (readerParams != null) {
3225                     try {
3226                         if ((readerParams.flags & NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS) == 0) {
3227                             mVibrator.vibrate(mVibrationEffect,
3228                                     HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES);
3229                             playSound(SOUND_END);
3230                         }
3231                         if (readerParams.callback != null) {
3232                             if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) {
3233                                 mPowerManager.userActivity(SystemClock.uptimeMillis(),
3234                                         PowerManager.USER_ACTIVITY_EVENT_OTHER, 0);
3235                             }
3236                             readerParams.callback.onTagDiscovered(tag);
3237                             return;
3238                         } else {
3239                             // Follow normal dispatch below
3240                         }
3241                     } catch (RemoteException e) {
3242                         Log.e(TAG, "Reader mode remote has died, falling back.", e);
3243                         // Intentional fall-through
3244                     } catch (Exception e) {
3245                         // Catch any other exception
3246                         Log.e(TAG, "App exception, not dispatching.", e);
3247                         return;
3248                     }
3249                 }
3250                 int dispatchResult = mNfcDispatcher.dispatchTag(tag);
3251                 if (dispatchResult == NfcDispatcher.DISPATCH_FAIL && !mInProvisionMode) {
3252                     if (DBG) Log.d(TAG, "Tag dispatch failed");
3253                     unregisterObject(tagEndpoint.getHandle());
3254                     if (mPollDelayTime > NO_POLL_DELAY) {
3255                         tagEndpoint.stopPresenceChecking();
3256                         synchronized (NfcService.this) {
3257                             if (!mPollDelayed) {
3258                                 int delayTime = mPollDelayTime;
3259                                 mPollDelayed = true;
3260                                 mDeviceHost.startStopPolling(false);
3261                                 if (mPollDelayCount < mPollDelayCountMax) {
3262                                     mPollDelayCount++;
3263                                 } else {
3264                                     delayTime = mPollDelayTimeLong;
3265                                 }
3266                                 if (DBG) Log.d(TAG, "Polling delayed " + delayTime);
3267                                 mHandler.sendMessageDelayed(
3268                                         mHandler.obtainMessage(MSG_DELAY_POLLING), delayTime);
3269                             } else {
3270                                 if (DBG) Log.d(TAG, "Keep waiting for polling delay");
3271                             }
3272                         }
3273                     } else {
3274                         Log.d(TAG, "Keep presence checking.");
3275                     }
3276                     if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED && mNotifyDispatchFailed) {
3277                         if (!sToast_debounce) {
3278                             Toast.makeText(mContext, R.string.tag_dispatch_failed,
3279                                            Toast.LENGTH_SHORT).show();
3280                             sToast_debounce = true;
3281                             mHandler.sendEmptyMessageDelayed(MSG_TOAST_DEBOUNCE_EVENT,
3282                                                              sToast_debounce_time_ms);
3283                         }
3284                         playSound(SOUND_ERROR);
3285                     }
3286                     if (!mAntennaBlockedMessageShown && mDispatchFailedCount++ > mDispatchFailedMax) {
3287                         new NfcBlockedNotification(mContext).startNotification();
3288                         synchronized (NfcService.this) {
3289                             mPrefsEditor.putBoolean(PREF_ANTENNA_BLOCKED_MESSAGE_SHOWN, true);
3290                             mPrefsEditor.apply();
3291                         }
3292                         mBackupManager.dataChanged();
3293                         mAntennaBlockedMessageShown = true;
3294                         mDispatchFailedCount = 0;
3295                         if (DBG) Log.d(TAG, "Tag dispatch failed notification");
3296                     }
3297                 } else if (dispatchResult == NfcDispatcher.DISPATCH_SUCCESS) {
3298                     synchronized (NfcService.this) {
3299                         mPollDelayCount = 0;
3300                     }
3301                     if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) {
3302                         mPowerManager.userActivity(SystemClock.uptimeMillis(),
3303                                 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0);
3304                     }
3305                     mDispatchFailedCount = 0;
3306                     mVibrator.vibrate(mVibrationEffect, HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES);
3307                     playSound(SOUND_END);
3308                 }
3309             } catch (Exception e) {
3310                 Log.e(TAG, "Tag creation exception, not dispatching.", e);
3311                 return;
3312             }
3313         }
3314     }
3315 
3316     private NfcServiceHandler mHandler = new NfcServiceHandler();
3317 
3318     class ApplyRoutingTask extends AsyncTask<Integer, Void, Void> {
3319         @Override
doInBackground(Integer... params)3320         protected Void doInBackground(Integer... params) {
3321             synchronized (NfcService.this) {
3322                 if (params == null || params.length != 1) {
3323                     // force apply current routing
3324                     applyRouting(true);
3325                     return null;
3326                 }
3327                 mScreenState = params[0].intValue();
3328 
3329                 mRoutingWakeLock.acquire();
3330                 try {
3331                     applyRouting(false);
3332                 } finally {
3333                     mRoutingWakeLock.release();
3334                 }
3335                 return null;
3336             }
3337         }
3338     }
3339 
3340     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
3341         @Override
3342         public void onReceive(Context context, Intent intent) {
3343             String action = intent.getAction();
3344             if (action.equals(Intent.ACTION_SCREEN_ON)
3345                     || action.equals(Intent.ACTION_SCREEN_OFF)
3346                     || action.equals(Intent.ACTION_USER_PRESENT)) {
3347                 // Perform applyRouting() in AsyncTask to serialize blocking calls
3348                 if (action.equals(Intent.ACTION_SCREEN_ON)) {
3349                     synchronized (NfcService.this) {
3350                         mPollDelayCount = 0;
3351                     }
3352                 }
3353                 applyScreenState(mScreenStateHelper.checkScreenState());
3354             } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
3355                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
3356                 mUserId = userId;
3357                 updatePackageCache();
3358                 if (mIsHceCapable) {
3359                     mCardEmulationManager.onUserSwitched(getUserId());
3360                 }
3361                 applyScreenState(mScreenStateHelper.checkScreenState());
3362 
3363                 if (NFC_SNOOP_LOG_MODE.equals(NfcProperties.snoop_log_mode_values.FULL) ||
3364                         NFC_VENDOR_DEBUG_ENABLED) {
3365                     new NfcDeveloperOptionNotification(mContext.createContextAsUser(
3366                             UserHandle.of(ActivityManager.getCurrentUser()), /*flags=*/0))
3367                             .startNotification();
3368                 }
3369             } else if (action.equals(Intent.ACTION_USER_ADDED)) {
3370                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
3371                 setPaymentForegroundPreference(userId);
3372 
3373                 if (NFC_SNOOP_LOG_MODE.equals(NfcProperties.snoop_log_mode_values.FULL) ||
3374                         NFC_VENDOR_DEBUG_ENABLED) {
3375                     new NfcDeveloperOptionNotification(mContext.createContextAsUser(
3376                             UserHandle.of(ActivityManager.getCurrentUser()), /*flags=*/0))
3377                             .startNotification();
3378                 }
3379             }
3380         }
3381     };
3382 
3383     private final BroadcastReceiver mManagedProfileReceiver = new BroadcastReceiver() {
3384         @Override
3385         public void onReceive(Context context, Intent intent) {
3386             String action = intent.getAction();
3387             UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
3388 
3389             // User should be filled for below intents, check the existence.
3390             if (user == null) {
3391                 Log.d(TAG, intent.getAction() + " broadcast without EXTRA_USER.");
3392                 return;
3393             }
3394 
3395             if (mCardEmulationManager == null) {
3396                 return;
3397             }
3398             if (action.equals(Intent.ACTION_MANAGED_PROFILE_ADDED) ||
3399                     action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) ||
3400                     action.equals(Intent.ACTION_MANAGED_PROFILE_REMOVED) ||
3401                     action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)) {
3402                 mCardEmulationManager.onManagedProfileChanged();
3403                 setPaymentForegroundPreference(user.getIdentifier());
3404             }
3405         }
3406     };
3407 
3408     private final BroadcastReceiver mOwnerReceiver = new BroadcastReceiver() {
3409         @Override
3410         public void onReceive(Context context, Intent intent) {
3411             String action = intent.getAction();
3412             if (action.equals(Intent.ACTION_PACKAGE_REMOVED) ||
3413                     action.equals(Intent.ACTION_PACKAGE_ADDED) ||
3414                     action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE) ||
3415                     action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) {
3416                 updatePackageCache();
3417                 if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
3418                         && renewTagAppPrefList()) storeTagAppPrefList();
3419             } else if (action.equals(Intent.ACTION_SHUTDOWN)) {
3420                 if (DBG) Log.d(TAG, "Shutdown received with UserId: " +
3421                                  getSendingUser().getIdentifier());
3422                 if (!getSendingUser().equals(UserHandle.ALL)) {
3423                     return;
3424                 }
3425                 if (DBG) Log.d(TAG, "Device is shutting down.");
3426                 if (mIsAlwaysOnSupported && mAlwaysOnState == NfcAdapter.STATE_ON) {
3427                     new EnableDisableTask().execute(TASK_DISABLE_ALWAYS_ON);
3428                 }
3429                 if (isNfcEnabled()) {
3430                     mDeviceHost.shutdown();
3431                 }
3432             }
3433         }
3434     };
3435 
applyScreenState(int screenState)3436     private void applyScreenState(int screenState) {
3437         if (mScreenState != screenState) {
3438             if (nci_version != NCI_VERSION_2_0) {
3439                 new ApplyRoutingTask().execute(Integer.valueOf(screenState));
3440             }
3441             sendMessage(NfcService.MSG_APPLY_SCREEN_STATE, screenState);
3442         }
3443     }
3444 
setPaymentForegroundPreference(int user)3445     private void setPaymentForegroundPreference(int user) {
3446         Context uc = mContext.createContextAsUser(UserHandle.of(user), 0);
3447         try {
3448             // Check whether the Settings.Secure.NFC_PAYMENT_FOREGROUND exists or not.
3449             Settings.Secure.getInt(uc.getContentResolver(),
3450                     Settings.Secure.NFC_PAYMENT_FOREGROUND);
3451         } catch (SettingNotFoundException e) {
3452             boolean foregroundPreference =
3453                     mContext.getResources().getBoolean(R.bool.payment_foreground_preference);
3454             Settings.Secure.putInt(uc.getContentResolver(),
3455                     Settings.Secure.NFC_PAYMENT_FOREGROUND, foregroundPreference ? 1 : 0);
3456             Log.d(TAG, "Set NFC_PAYMENT_FOREGROUND preference:" + foregroundPreference);
3457         }
3458     }
3459 
3460     /**
3461      * for debugging only - no i18n
3462      */
stateToString(int state)3463     static String stateToString(int state) {
3464         switch (state) {
3465             case NfcAdapter.STATE_OFF:
3466                 return "off";
3467             case NfcAdapter.STATE_TURNING_ON:
3468                 return "turning on";
3469             case NfcAdapter.STATE_ON:
3470                 return "on";
3471             case NfcAdapter.STATE_TURNING_OFF:
3472                 return "turning off";
3473             default:
3474                 return "<error>";
3475         }
3476     }
3477 
stateToProtoEnum(int state)3478     static int stateToProtoEnum(int state) {
3479         switch (state) {
3480             case NfcAdapter.STATE_OFF:
3481                 return NfcServiceDumpProto.STATE_OFF;
3482             case NfcAdapter.STATE_TURNING_ON:
3483                 return NfcServiceDumpProto.STATE_TURNING_ON;
3484             case NfcAdapter.STATE_ON:
3485                 return NfcServiceDumpProto.STATE_ON;
3486             case NfcAdapter.STATE_TURNING_OFF:
3487                 return NfcServiceDumpProto.STATE_TURNING_OFF;
3488             default:
3489                 return NfcServiceDumpProto.STATE_UNKNOWN;
3490         }
3491     }
3492 
getNfaStorageDir()3493     public String getNfaStorageDir() {
3494         return mDeviceHost.getNfaStorageDir();
3495     }
3496 
copyNativeCrashLogsIfAny(PrintWriter pw)3497     private void copyNativeCrashLogsIfAny(PrintWriter pw) {
3498       try {
3499           File file = new File(NATIVE_LOG_FILE_PATH, NATIVE_LOG_FILE_NAME);
3500           if (!file.exists()) {
3501             return;
3502           }
3503           pw.println("---BEGIN: NATIVE CRASH LOG----");
3504           Scanner sc = new Scanner(file);
3505           while(sc.hasNextLine()) {
3506               String s = sc.nextLine();
3507               pw.println(s);
3508           }
3509           pw.println("---END: NATIVE CRASH LOG----");
3510           sc.close();
3511       } catch (IOException e) {
3512           Log.e(TAG, "Exception in copyNativeCrashLogsIfAny " + e);
3513       }
3514     }
3515 
storeNativeCrashLogs()3516     private void storeNativeCrashLogs() {
3517         FileOutputStream fos = null;
3518         try {
3519             File file = new File(NATIVE_LOG_FILE_PATH, NATIVE_LOG_FILE_NAME);
3520             if (file.length() >= NATIVE_CRASH_FILE_SIZE) {
3521                 file.createNewFile();
3522             }
3523 
3524             fos = new FileOutputStream(file, true);
3525             mDeviceHost.dump(fos.getFD());
3526             fos.flush();
3527         } catch (IOException e) {
3528             Log.e(TAG, "Exception in storeNativeCrashLogs " + e);
3529         } finally {
3530             if (fos != null) {
3531                 try {
3532                     fos.close();
3533                 } catch (IOException e) {
3534                     Log.e(TAG, "Exception in storeNativeCrashLogs: file close " + e);
3535                 }
3536             }
3537         }
3538     }
3539 
dumpTagAppPreference(PrintWriter pw)3540     private void dumpTagAppPreference(PrintWriter pw) {
3541         pw.println("mIsTagAppPrefSupported =" + mIsTagAppPrefSupported);
3542         if (mIsTagAppPrefSupported) {
3543             pw.println("TagAppPreference:");
3544             UserManager um = mContext.createContextAsUser(
3545                     UserHandle.of(ActivityManager.getCurrentUser()), 0)
3546                     .getSystemService(UserManager.class);
3547             List<UserHandle> luh = um.getEnabledProfiles();
3548             for (UserHandle uh : luh) {
3549                 int userId = uh.getIdentifier();
3550                 HashMap<String, Boolean> map;
3551                 synchronized (NfcService.this) {
3552                     map = mTagAppPrefList.getOrDefault(userId, new HashMap<>());
3553                 }
3554                 if (map.size() > 0) pw.println("userId=" + userId);
3555                 for (Map.Entry<String, Boolean> entry : map.entrySet()) {
3556                     pw.println("pkg: " + entry.getKey() + " : " + entry.getValue());
3557                 }
3558             }
3559         }
3560     }
3561 
dump(FileDescriptor fd, PrintWriter pw, String[] args)3562     void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
3563         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
3564                 != PackageManager.PERMISSION_GRANTED) {
3565             pw.println("Permission Denial: can't dump nfc from from pid="
3566                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
3567                     + " without permission " + android.Manifest.permission.DUMP);
3568             return;
3569         }
3570 
3571         for (String arg : args) {
3572             if ("--proto".equals(arg)) {
3573                 FileOutputStream fos = null;
3574                 try {
3575                     fos = new FileOutputStream(fd);
3576                     ProtoOutputStream proto = new ProtoOutputStream(fos);
3577                     synchronized (this) {
3578                         dumpDebug(proto);
3579                     }
3580                     proto.flush();
3581                 } catch (Exception e) {
3582                     Log.e(TAG, "Exception in dump nfc --proto " + e);
3583                 } finally {
3584                     if (fos != null) {
3585                         try {
3586                             fos.close();
3587                         } catch (IOException e) {
3588                             Log.e(TAG, "Exception in storeNativeCrashLogs " + e);
3589                         }
3590                     }
3591                 }
3592                 return;
3593             }
3594         }
3595 
3596         synchronized (this) {
3597             pw.println("mState=" + stateToString(mState));
3598             pw.println("mAlwaysOnState=" + stateToString(mAlwaysOnState));
3599             pw.println("mScreenState=" + ScreenStateHelper.screenStateToString(mScreenState));
3600             pw.println("mIsSecureNfcEnabled=" + mIsSecureNfcEnabled);
3601             pw.println("mIsAlwaysOnSupported=" + mIsAlwaysOnSupported);
3602             pw.println("SnoopLogMode=" + NFC_SNOOP_LOG_MODE);
3603             pw.println("VendorDebugEnabled=" + NFC_VENDOR_DEBUG_ENABLED);
3604             pw.println(mCurrentDiscoveryParameters);
3605             if (mIsHceCapable) {
3606                 mCardEmulationManager.dump(fd, pw, args);
3607             }
3608             mNfcDispatcher.dump(fd, pw, args);
3609             if (mState == NfcAdapter.STATE_ON) {
3610                 mRoutingTableParser.dump(mDeviceHost, pw);
3611             }
3612             dumpTagAppPreference(pw);
3613             copyNativeCrashLogsIfAny(pw);
3614             pw.flush();
3615             mDeviceHost.dump(fd);
3616         }
3617     }
3618 
3619     /**
3620      * Dump debugging information as a NfcServiceDumpProto
3621      *
3622      * Note:
3623      * See proto definition in frameworks/base/core/proto/android/nfc/nfc_service.proto
3624      * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
3625      * {@link ProtoOutputStream#end(long)} after.
3626      * Never reuse a proto field number. When removing a field, mark it as reserved.
3627      */
dumpDebug(ProtoOutputStream proto)3628     private void dumpDebug(ProtoOutputStream proto) {
3629         proto.write(NfcServiceDumpProto.STATE, stateToProtoEnum(mState));
3630         proto.write(NfcServiceDumpProto.IN_PROVISION_MODE, mInProvisionMode);
3631         proto.write(NfcServiceDumpProto.SCREEN_STATE,
3632                 ScreenStateHelper.screenStateToProtoEnum(mScreenState));
3633         proto.write(NfcServiceDumpProto.SECURE_NFC_ENABLED, mIsSecureNfcEnabled);
3634         proto.write(NfcServiceDumpProto.POLLING_PAUSED, mPollingPaused);
3635         proto.write(NfcServiceDumpProto.HCE_CAPABLE, mIsHceCapable);
3636         proto.write(NfcServiceDumpProto.HCE_F_CAPABLE, mIsHceFCapable);
3637         proto.write(NfcServiceDumpProto.SECURE_NFC_CAPABLE, mIsSecureNfcCapable);
3638         proto.write(NfcServiceDumpProto.VR_MODE_ENABLED,
3639                 (mVrManager != null) ? mVrManager.isVrModeEnabled() : false);
3640 
3641         long token = proto.start(NfcServiceDumpProto.DISCOVERY_PARAMS);
3642         mCurrentDiscoveryParameters.dumpDebug(proto);
3643         proto.end(token);
3644 
3645         if (mIsHceCapable) {
3646             token = proto.start(NfcServiceDumpProto.CARD_EMULATION_MANAGER);
3647             mCardEmulationManager.dumpDebug(proto);
3648             proto.end(token);
3649         }
3650 
3651         token = proto.start(NfcServiceDumpProto.NFC_DISPATCHER);
3652         mNfcDispatcher.dumpDebug(proto);
3653         proto.end(token);
3654 
3655         // Dump native crash logs if any
3656         File file = new File(NATIVE_LOG_FILE_PATH, NATIVE_LOG_FILE_NAME);
3657         if (!file.exists()) {
3658             return;
3659         }
3660         try {
3661             String logs = Files.lines(file.toPath()).collect(Collectors.joining("\n"));
3662             proto.write(NfcServiceDumpProto.NATIVE_CRASH_LOGS, logs);
3663         } catch (IOException e) {
3664             Log.e(TAG, "IOException in dumpDebug(ProtoOutputStream): " + e);
3665         }
3666     }
3667 }
3668