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