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