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