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 com.android.nfc.DeviceHost.DeviceHostListener; 20 import com.android.nfc.DeviceHost.LlcpConnectionlessSocket; 21 import com.android.nfc.DeviceHost.LlcpServerSocket; 22 import com.android.nfc.DeviceHost.LlcpSocket; 23 import com.android.nfc.DeviceHost.NfcDepEndpoint; 24 import com.android.nfc.DeviceHost.TagEndpoint; 25 import com.android.nfc.handover.HandoverManager; 26 import com.android.nfc.cardemulation.AidRoutingManager; 27 import com.android.nfc.cardemulation.HostEmulationManager; 28 import com.android.nfc.cardemulation.RegisteredAidCache; 29 import com.android.nfc.dhimpl.NativeNfcManager; 30 import com.android.nfc.dhimpl.NativeNfcSecureElement; 31 32 import android.app.ActivityManager; 33 import android.app.Application; 34 import android.app.KeyguardManager; 35 import android.app.PendingIntent; 36 import android.content.BroadcastReceiver; 37 import android.content.ComponentName; 38 import android.content.ContentResolver; 39 import android.content.Context; 40 import android.content.Intent; 41 import android.content.IntentFilter; 42 import android.content.SharedPreferences; 43 import android.content.pm.PackageInfo; 44 import android.content.pm.PackageManager; 45 import android.content.res.Resources.NotFoundException; 46 import android.media.AudioManager; 47 import android.media.SoundPool; 48 import android.net.Uri; 49 import android.nfc.ErrorCodes; 50 import android.nfc.FormatException; 51 import android.nfc.IAppCallback; 52 import android.nfc.INfcAdapter; 53 import android.nfc.INfcAdapterExtras; 54 import android.nfc.INfcCardEmulation; 55 import android.nfc.INfcTag; 56 import android.nfc.NdefMessage; 57 import android.nfc.NfcAdapter; 58 import android.nfc.Tag; 59 import android.nfc.TechListParcel; 60 import android.nfc.TransceiveResult; 61 import android.nfc.cardemulation.ApduServiceInfo; 62 import android.nfc.tech.Ndef; 63 import android.nfc.tech.TagTechnology; 64 import android.os.AsyncTask; 65 import android.os.Binder; 66 import android.os.Build; 67 import android.os.Bundle; 68 import android.os.Handler; 69 import android.os.IBinder; 70 import android.os.Message; 71 import android.os.PowerManager; 72 import android.os.Process; 73 import android.os.RemoteException; 74 import android.os.ServiceManager; 75 import android.os.SystemClock; 76 import android.os.UserHandle; 77 import android.provider.Settings; 78 import android.util.Log; 79 import java.io.FileDescriptor; 80 import java.io.IOException; 81 import java.io.PrintWriter; 82 import java.util.Arrays; 83 import java.util.HashMap; 84 import java.util.HashSet; 85 import java.util.List; 86 import java.util.NoSuchElementException; 87 import java.util.concurrent.ExecutionException; 88 89 public class NfcService implements DeviceHostListener { 90 private static final String ACTION_MASTER_CLEAR_NOTIFICATION = "android.intent.action.MASTER_CLEAR_NOTIFICATION"; 91 92 static final boolean DBG = false; 93 static final String TAG = "NfcService"; 94 95 public static final String SERVICE_NAME = "nfc"; 96 97 /** Regular NFC permission */ 98 private static final String NFC_PERM = android.Manifest.permission.NFC; 99 private static final String NFC_PERM_ERROR = "NFC permission required"; 100 101 /** NFC ADMIN permission - only for system apps */ 102 private static final String ADMIN_PERM = android.Manifest.permission.WRITE_SECURE_SETTINGS; 103 private static final String ADMIN_PERM_ERROR = "WRITE_SECURE_SETTINGS permission required"; 104 105 public static final String PREF = "NfcServicePrefs"; 106 107 static final String PREF_NFC_ON = "nfc_on"; 108 static final boolean NFC_ON_DEFAULT = true; 109 static final String PREF_NDEF_PUSH_ON = "ndef_push_on"; 110 static final boolean NDEF_PUSH_ON_DEFAULT = true; 111 static final String PREF_FIRST_BEAM = "first_beam"; 112 static final String PREF_FIRST_BOOT = "first_boot"; 113 static final String PREF_AIRPLANE_OVERRIDE = "airplane_override"; 114 static final boolean SE_BROADCASTS_WITH_HCE = true; 115 116 static final int MSG_NDEF_TAG = 0; 117 static final int MSG_CARD_EMULATION = 1; 118 static final int MSG_LLCP_LINK_ACTIVATION = 2; 119 static final int MSG_LLCP_LINK_DEACTIVATED = 3; 120 static final int MSG_TARGET_DESELECTED = 4; 121 static final int MSG_MOCK_NDEF = 7; 122 static final int MSG_SE_FIELD_ACTIVATED = 8; 123 static final int MSG_SE_FIELD_DEACTIVATED = 9; 124 static final int MSG_SE_APDU_RECEIVED = 10; 125 static final int MSG_SE_EMV_CARD_REMOVAL = 11; 126 static final int MSG_SE_MIFARE_ACCESS = 12; 127 static final int MSG_SE_LISTEN_ACTIVATED = 13; 128 static final int MSG_SE_LISTEN_DEACTIVATED = 14; 129 static final int MSG_LLCP_LINK_FIRST_PACKET = 15; 130 static final int MSG_ROUTE_AID = 16; 131 static final int MSG_UNROUTE_AID = 17; 132 static final int MSG_COMMIT_ROUTING = 18; 133 134 static final int TASK_ENABLE = 1; 135 static final int TASK_DISABLE = 2; 136 static final int TASK_BOOT = 3; 137 static final int TASK_EE_WIPE = 4; 138 139 // Screen state, used by mScreenState 140 static final int SCREEN_STATE_UNKNOWN = 0; 141 static final int SCREEN_STATE_OFF = 1; 142 static final int SCREEN_STATE_ON_LOCKED = 2; 143 static final int SCREEN_STATE_ON_UNLOCKED = 3; 144 145 // Copied from com.android.nfc_extras to avoid library dependency 146 // Must keep in sync with com.android.nfc_extras 147 static final int ROUTE_OFF = 1; 148 static final int ROUTE_ON_WHEN_SCREEN_ON = 2; 149 150 // Return values from NfcEe.open() - these are 1:1 mapped 151 // to the thrown EE_EXCEPTION_ exceptions in nfc-extras. 152 static final int EE_ERROR_IO = -1; 153 static final int EE_ERROR_ALREADY_OPEN = -2; 154 static final int EE_ERROR_INIT = -3; 155 static final int EE_ERROR_LISTEN_MODE = -4; 156 static final int EE_ERROR_EXT_FIELD = -5; 157 static final int EE_ERROR_NFC_DISABLED = -6; 158 159 /** minimum screen state that enables NFC polling (discovery) */ 160 static final int POLLING_MODE = SCREEN_STATE_ON_UNLOCKED; 161 162 // Time to wait for NFC controller to initialize before watchdog 163 // goes off. This time is chosen large, because firmware download 164 // may be a part of initialization. 165 static final int INIT_WATCHDOG_MS = 90000; 166 167 // Time to wait for routing to be applied before watchdog 168 // goes off 169 static final int ROUTING_WATCHDOG_MS = 10000; 170 171 // Amount of time to wait before closing the NFCEE connection 172 // in a disable/shutdown scenario. 173 static final int WAIT_FOR_NFCEE_OPERATIONS_MS = 5000; 174 // Polling interval for waiting on NFCEE operations 175 static final int WAIT_FOR_NFCEE_POLL_MS = 100; 176 177 // Default delay used for presence checks 178 static final int DEFAULT_PRESENCE_CHECK_DELAY = 125; 179 180 // for use with playSound() 181 public static final int SOUND_START = 0; 182 public static final int SOUND_END = 1; 183 public static final int SOUND_ERROR = 2; 184 185 public static final String ACTION_RF_FIELD_ON_DETECTED = 186 "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED"; 187 public static final String ACTION_RF_FIELD_OFF_DETECTED = 188 "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED"; 189 public static final String ACTION_AID_SELECTED = 190 "com.android.nfc_extras.action.AID_SELECTED"; 191 public static final String EXTRA_AID = "com.android.nfc_extras.extra.AID"; 192 193 public static final String ACTION_LLCP_UP = 194 "com.android.nfc.action.LLCP_UP"; 195 196 public static final String ACTION_LLCP_DOWN = 197 "com.android.nfc.action.LLCP_DOWN"; 198 199 public static final String ACTION_APDU_RECEIVED = 200 "com.android.nfc_extras.action.APDU_RECEIVED"; 201 public static final String EXTRA_APDU_BYTES = 202 "com.android.nfc_extras.extra.APDU_BYTES"; 203 204 public static final String ACTION_EMV_CARD_REMOVAL = 205 "com.android.nfc_extras.action.EMV_CARD_REMOVAL"; 206 207 public static final String ACTION_MIFARE_ACCESS_DETECTED = 208 "com.android.nfc_extras.action.MIFARE_ACCESS_DETECTED"; 209 public static final String EXTRA_MIFARE_BLOCK = 210 "com.android.nfc_extras.extra.MIFARE_BLOCK"; 211 212 public static final String ACTION_SE_LISTEN_ACTIVATED = 213 "com.android.nfc_extras.action.SE_LISTEN_ACTIVATED"; 214 public static final String ACTION_SE_LISTEN_DEACTIVATED = 215 "com.android.nfc_extras.action.SE_LISTEN_DEACTIVATED"; 216 217 // NFC Execution Environment 218 // fields below are protected by this 219 private NativeNfcSecureElement mSecureElement; 220 private OpenSecureElement mOpenEe; // null when EE closed 221 private final ReaderModeDeathRecipient mReaderModeDeathRecipient = 222 new ReaderModeDeathRecipient(); 223 private int mEeRoutingState; // contactless interface routing 224 225 // fields below must be used only on the UI thread and therefore aren't synchronized 226 boolean mP2pStarted = false; 227 228 // fields below are used in multiple threads and protected by synchronized(this) 229 final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>(); 230 // mSePackages holds packages that accessed the SE, but only for the owner user, 231 // as SE access is not granted for non-owner users. 232 HashSet<String> mSePackages = new HashSet<String>(); 233 int mScreenState; 234 boolean mInProvisionMode; // whether we're in setup wizard and enabled NFC provisioning 235 boolean mIsNdefPushEnabled; 236 boolean mNfceeRouteEnabled; // current Device Host state of NFC-EE routing 237 boolean mNfcPollingEnabled; // current Device Host state of NFC-C polling 238 boolean mHostRouteEnabled; // current Device Host state of host-based routing 239 boolean mReaderModeEnabled; // current Device Host state of reader mode 240 ReaderModeParams mReaderModeParams; 241 242 List<PackageInfo> mInstalledPackages; // cached version of installed packages 243 244 // mState is protected by this, however it is only modified in onCreate() 245 // and the default AsyncTask thread so it is read unprotected from that 246 // thread 247 int mState; // one of NfcAdapter.STATE_ON, STATE_TURNING_ON, etc 248 249 // fields below are final after onCreate() 250 Context mContext; 251 private DeviceHost mDeviceHost; 252 private SharedPreferences mPrefs; 253 private SharedPreferences.Editor mPrefsEditor; 254 private PowerManager.WakeLock mRoutingWakeLock; 255 private PowerManager.WakeLock mEeWakeLock; 256 257 int mStartSound; 258 int mEndSound; 259 int mErrorSound; 260 SoundPool mSoundPool; // playback synchronized on this 261 P2pLinkManager mP2pLinkManager; 262 TagService mNfcTagService; 263 NfcAdapterService mNfcAdapter; 264 NfcAdapterExtrasService mExtrasService; 265 CardEmulationService mCardEmulationService; 266 boolean mIsAirplaneSensitive; 267 boolean mIsAirplaneToggleable; 268 boolean mIsDebugBuild; 269 boolean mIsHceCapable; 270 NfceeAccessControl mNfceeAccessControl; 271 272 private NfcDispatcher mNfcDispatcher; 273 private PowerManager mPowerManager; 274 private KeyguardManager mKeyguard; 275 private HandoverManager mHandoverManager; 276 private ContentResolver mContentResolver; 277 private RegisteredAidCache mAidCache; 278 private HostEmulationManager mHostEmulationManager; 279 private AidRoutingManager mAidRoutingManager; 280 281 private static NfcService sService; 282 283 public static void enforceAdminPerm(Context context) { 284 context.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 285 } 286 287 public static void validateUserId(int userId) { 288 if (userId != UserHandle.getCallingUserId()) { 289 throw new SecurityException("userId passed in it not the calling user."); 290 } 291 } 292 293 public void enforceNfceeAdminPerm(String pkg) { 294 if (pkg == null) { 295 throw new SecurityException("caller must pass a package name"); 296 } 297 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 298 if (!mNfceeAccessControl.check(Binder.getCallingUid(), pkg)) { 299 throw new SecurityException(NfceeAccessControl.NFCEE_ACCESS_PATH + 300 " denies NFCEE access to " + pkg); 301 } 302 if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) { 303 throw new SecurityException("only the owner is allowed to call SE APIs"); 304 } 305 } 306 307 public static NfcService getInstance() { 308 return sService; 309 } 310 311 @Override 312 public void onRemoteEndpointDiscovered(TagEndpoint tag) { 313 sendMessage(NfcService.MSG_NDEF_TAG, tag); 314 } 315 316 /** 317 * Notifies transaction 318 */ 319 @Override 320 public void onCardEmulationDeselected() { 321 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { 322 sendMessage(NfcService.MSG_TARGET_DESELECTED, null); 323 } 324 } 325 326 /** 327 * Notifies transaction 328 */ 329 @Override 330 public void onCardEmulationAidSelected(byte[] aid) { 331 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { 332 sendMessage(NfcService.MSG_CARD_EMULATION, aid); 333 } 334 } 335 336 /** 337 * Notifies transaction 338 */ 339 @Override 340 public void onHostCardEmulationActivated() { 341 if (mHostEmulationManager != null) { 342 mHostEmulationManager.notifyHostEmulationActivated(); 343 } 344 } 345 346 @Override 347 public void onHostCardEmulationData(byte[] data) { 348 if (mHostEmulationManager != null) { 349 mHostEmulationManager.notifyHostEmulationData(data); 350 } 351 } 352 353 @Override 354 public void onHostCardEmulationDeactivated() { 355 if (mHostEmulationManager != null) { 356 mHostEmulationManager.notifyNostEmulationDeactivated(); 357 } 358 } 359 360 /** 361 * Notifies P2P Device detected, to activate LLCP link 362 */ 363 @Override 364 public void onLlcpLinkActivated(NfcDepEndpoint device) { 365 sendMessage(NfcService.MSG_LLCP_LINK_ACTIVATION, device); 366 } 367 368 /** 369 * Notifies P2P Device detected, to activate LLCP link 370 */ 371 @Override 372 public void onLlcpLinkDeactivated(NfcDepEndpoint device) { 373 sendMessage(NfcService.MSG_LLCP_LINK_DEACTIVATED, device); 374 } 375 376 /** 377 * Notifies P2P Device detected, first packet received over LLCP link 378 */ 379 @Override 380 public void onLlcpFirstPacketReceived(NfcDepEndpoint device) { 381 sendMessage(NfcService.MSG_LLCP_LINK_FIRST_PACKET, device); 382 } 383 384 @Override 385 public void onRemoteFieldActivated() { 386 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { 387 sendMessage(NfcService.MSG_SE_FIELD_ACTIVATED, null); 388 } 389 } 390 391 @Override 392 public void onRemoteFieldDeactivated() { 393 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { 394 sendMessage(NfcService.MSG_SE_FIELD_DEACTIVATED, null); 395 } 396 } 397 398 @Override 399 public void onSeListenActivated() { 400 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { 401 sendMessage(NfcService.MSG_SE_LISTEN_ACTIVATED, null); 402 } 403 } 404 405 @Override 406 public void onSeListenDeactivated() { 407 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { 408 sendMessage(NfcService.MSG_SE_LISTEN_DEACTIVATED, null); 409 } 410 } 411 412 413 @Override 414 public void onSeApduReceived(byte[] apdu) { 415 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { 416 sendMessage(NfcService.MSG_SE_APDU_RECEIVED, apdu); 417 } 418 } 419 420 @Override 421 public void onSeEmvCardRemoval() { 422 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { 423 sendMessage(NfcService.MSG_SE_EMV_CARD_REMOVAL, null); 424 } 425 } 426 427 @Override 428 public void onSeMifareAccess(byte[] block) { 429 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { 430 sendMessage(NfcService.MSG_SE_MIFARE_ACCESS, block); 431 } 432 } 433 434 final class ReaderModeParams { 435 public int flags; 436 public IAppCallback callback; 437 public int presenceCheckDelay; 438 } 439 440 public NfcService(Application nfcApplication) { 441 mNfcTagService = new TagService(); 442 mNfcAdapter = new NfcAdapterService(); 443 mExtrasService = new NfcAdapterExtrasService(); 444 mCardEmulationService = new CardEmulationService(); 445 446 Log.i(TAG, "Starting NFC service"); 447 448 sService = this; 449 450 mContext = nfcApplication; 451 mContentResolver = mContext.getContentResolver(); 452 mDeviceHost = new NativeNfcManager(mContext, this); 453 454 mHandoverManager = new HandoverManager(mContext); 455 boolean isNfcProvisioningEnabled = false; 456 try { 457 isNfcProvisioningEnabled = mContext.getResources().getBoolean( 458 R.bool.enable_nfc_provisioning); 459 } catch (NotFoundException e) { 460 } 461 462 if (isNfcProvisioningEnabled) { 463 mInProvisionMode = Settings.Secure.getInt(mContentResolver, 464 Settings.Global.DEVICE_PROVISIONED, 0) == 0; 465 } else { 466 mInProvisionMode = false; 467 } 468 469 mHandoverManager.setEnabled(!mInProvisionMode); 470 mNfcDispatcher = new NfcDispatcher(mContext, mHandoverManager, mInProvisionMode); 471 mP2pLinkManager = new P2pLinkManager(mContext, mHandoverManager, 472 mDeviceHost.getDefaultLlcpMiu(), mDeviceHost.getDefaultLlcpRwSize()); 473 474 mSecureElement = new NativeNfcSecureElement(mContext); 475 mEeRoutingState = ROUTE_OFF; 476 477 mNfceeAccessControl = new NfceeAccessControl(mContext); 478 479 mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE); 480 mPrefsEditor = mPrefs.edit(); 481 482 mState = NfcAdapter.STATE_OFF; 483 mIsNdefPushEnabled = mPrefs.getBoolean(PREF_NDEF_PUSH_ON, NDEF_PUSH_ON_DEFAULT); 484 485 mIsDebugBuild = "userdebug".equals(Build.TYPE) || "eng".equals(Build.TYPE); 486 487 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 488 489 mRoutingWakeLock = mPowerManager.newWakeLock( 490 PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mRoutingWakeLock"); 491 mEeWakeLock = mPowerManager.newWakeLock( 492 PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mEeWakeLock"); 493 494 mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); 495 mScreenState = checkScreenState(); 496 497 ServiceManager.addService(SERVICE_NAME, mNfcAdapter); 498 499 // Intents for all users 500 IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION); 501 filter.addAction(Intent.ACTION_SCREEN_OFF); 502 filter.addAction(Intent.ACTION_SCREEN_ON); 503 filter.addAction(Intent.ACTION_USER_PRESENT); 504 filter.addAction(Intent.ACTION_USER_SWITCHED); 505 registerForAirplaneMode(filter); 506 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null); 507 508 PackageManager pm = mContext.getPackageManager(); 509 mIsHceCapable = pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION); 510 if (mIsHceCapable) { 511 mAidRoutingManager = new AidRoutingManager(); 512 mAidCache = new RegisteredAidCache(mContext, mAidRoutingManager); 513 mHostEmulationManager = new HostEmulationManager(mContext, mAidCache); 514 } 515 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { 516 IntentFilter ownerFilter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION); 517 ownerFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); 518 ownerFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 519 ownerFilter.addAction(ACTION_MASTER_CLEAR_NOTIFICATION); 520 521 mContext.registerReceiver(mOwnerReceiver, ownerFilter); 522 523 ownerFilter = new IntentFilter(); 524 ownerFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 525 ownerFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 526 ownerFilter.addDataScheme("package"); 527 528 mContext.registerReceiver(mOwnerReceiver, ownerFilter); 529 530 updatePackageCache(); 531 } 532 533 new EnableDisableTask().execute(TASK_BOOT); // do blocking boot tasks 534 } 535 536 void initSoundPool() { 537 synchronized(this) { 538 if (mSoundPool == null) { 539 mSoundPool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0); 540 mStartSound = mSoundPool.load(mContext, R.raw.start, 1); 541 mEndSound = mSoundPool.load(mContext, R.raw.end, 1); 542 mErrorSound = mSoundPool.load(mContext, R.raw.error, 1); 543 } 544 } 545 } 546 547 void releaseSoundPool() { 548 synchronized(this) { 549 if (mSoundPool != null) { 550 mSoundPool.release(); 551 mSoundPool = null; 552 } 553 } 554 } 555 556 void registerForAirplaneMode(IntentFilter filter) { 557 final String airplaneModeRadios = Settings.System.getString(mContentResolver, 558 Settings.Global.AIRPLANE_MODE_RADIOS); 559 final String toggleableRadios = Settings.System.getString(mContentResolver, 560 Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS); 561 562 mIsAirplaneSensitive = airplaneModeRadios == null ? true : 563 airplaneModeRadios.contains(Settings.Global.RADIO_NFC); 564 mIsAirplaneToggleable = toggleableRadios == null ? false : 565 toggleableRadios.contains(Settings.Global.RADIO_NFC); 566 567 if (mIsAirplaneSensitive) { 568 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); 569 } 570 } 571 572 void updatePackageCache() { 573 PackageManager pm = mContext.getPackageManager(); 574 List<PackageInfo> packages = pm.getInstalledPackages(0, UserHandle.USER_OWNER); 575 synchronized (this) { 576 mInstalledPackages = packages; 577 } 578 } 579 580 int checkScreenState() { 581 if (!mPowerManager.isScreenOn()) { 582 return SCREEN_STATE_OFF; 583 } else if (mKeyguard.isKeyguardLocked()) { 584 return SCREEN_STATE_ON_LOCKED; 585 } else { 586 return SCREEN_STATE_ON_UNLOCKED; 587 } 588 } 589 590 int doOpenSecureElementConnection() { 591 mEeWakeLock.acquire(); 592 try { 593 return mSecureElement.doOpenSecureElementConnection(); 594 } finally { 595 mEeWakeLock.release(); 596 } 597 } 598 599 byte[] doTransceive(int handle, byte[] cmd) { 600 mEeWakeLock.acquire(); 601 try { 602 return doTransceiveNoLock(handle, cmd); 603 } finally { 604 mEeWakeLock.release(); 605 } 606 } 607 608 byte[] doTransceiveNoLock(int handle, byte[] cmd) { 609 return mSecureElement.doTransceive(handle, cmd); 610 } 611 612 void doDisconnect(int handle) { 613 mEeWakeLock.acquire(); 614 try { 615 mSecureElement.doDisconnect(handle); 616 } finally { 617 mEeWakeLock.release(); 618 } 619 } 620 621 /** 622 * Manages tasks that involve turning on/off the NFC controller. 623 * 624 * <p>All work that might turn the NFC adapter on or off must be done 625 * through this task, to keep the handling of mState simple. 626 * In other words, mState is only modified in these tasks (and we 627 * don't need a lock to read it in these tasks). 628 * 629 * <p>These tasks are all done on the same AsyncTask background 630 * thread, so they are serialized. Each task may temporarily transition 631 * mState to STATE_TURNING_OFF or STATE_TURNING_ON, but must exit in 632 * either STATE_ON or STATE_OFF. This way each task can be guaranteed 633 * of starting in either STATE_OFF or STATE_ON, without needing to hold 634 * NfcService.this for the entire task. 635 * 636 * <p>AsyncTask's are also implicitly queued. This is useful for corner 637 * cases like turning airplane mode on while TASK_ENABLE is in progress. 638 * The TASK_DISABLE triggered by airplane mode will be correctly executed 639 * immediately after TASK_ENABLE is complete. This seems like the most sane 640 * way to deal with these situations. 641 * 642 * <p>{@link #TASK_ENABLE} enables the NFC adapter, without changing 643 * preferences 644 * <p>{@link #TASK_DISABLE} disables the NFC adapter, without changing 645 * preferences 646 * <p>{@link #TASK_BOOT} does first boot work and may enable NFC 647 * <p>{@link #TASK_EE_WIPE} wipes the Execution Environment, and in the 648 * process may temporarily enable the NFC adapter 649 */ 650 class EnableDisableTask extends AsyncTask<Integer, Void, Void> { 651 @Override 652 protected Void doInBackground(Integer... params) { 653 // Sanity check mState 654 switch (mState) { 655 case NfcAdapter.STATE_TURNING_OFF: 656 case NfcAdapter.STATE_TURNING_ON: 657 Log.e(TAG, "Processing EnableDisable task " + params[0] + " from bad state " + 658 mState); 659 return null; 660 } 661 662 /* AsyncTask sets this thread to THREAD_PRIORITY_BACKGROUND, 663 * override with the default. THREAD_PRIORITY_BACKGROUND causes 664 * us to service software I2C too slow for firmware download 665 * with the NXP PN544. 666 * TODO: move this to the DAL I2C layer in libnfc-nxp, since this 667 * problem only occurs on I2C platforms using PN544 668 */ 669 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 670 671 switch (params[0].intValue()) { 672 case TASK_ENABLE: 673 enableInternal(); 674 break; 675 case TASK_DISABLE: 676 disableInternal(); 677 break; 678 case TASK_BOOT: 679 Log.d(TAG,"checking on firmware download"); 680 boolean airplaneOverride = mPrefs.getBoolean(PREF_AIRPLANE_OVERRIDE, false); 681 if (mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT) && 682 (!mIsAirplaneSensitive || !isAirplaneModeOn() || airplaneOverride)) { 683 Log.d(TAG,"NFC is on. Doing normal stuff"); 684 enableInternal(); 685 } else { 686 Log.d(TAG,"NFC is off. Checking firmware version"); 687 mDeviceHost.checkFirmware(); 688 // Build initial AID cache even if NFC is off 689 if (mIsHceCapable) { 690 mAidCache.invalidateCache(ActivityManager.getCurrentUser()); 691 } 692 } 693 if (mPrefs.getBoolean(PREF_FIRST_BOOT, true)) { 694 Log.i(TAG, "First Boot"); 695 mPrefsEditor.putBoolean(PREF_FIRST_BOOT, false); 696 mPrefsEditor.apply(); 697 executeEeWipe(); 698 } 699 break; 700 case TASK_EE_WIPE: 701 executeEeWipe(); 702 break; 703 } 704 705 // Restore default AsyncTask priority 706 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 707 return null; 708 } 709 710 /** 711 * Enable NFC adapter functions. 712 * Does not toggle preferences. 713 */ 714 boolean enableInternal() { 715 if (mState == NfcAdapter.STATE_ON) { 716 return true; 717 } 718 Log.i(TAG, "Enabling NFC"); 719 updateState(NfcAdapter.STATE_TURNING_ON); 720 721 WatchDogThread watchDog = new WatchDogThread("enableInternal", INIT_WATCHDOG_MS); 722 watchDog.start(); 723 try { 724 mRoutingWakeLock.acquire(); 725 try { 726 if (!mDeviceHost.initialize()) { 727 Log.w(TAG, "Error enabling NFC"); 728 updateState(NfcAdapter.STATE_OFF); 729 return false; 730 } 731 } finally { 732 mRoutingWakeLock.release(); 733 } 734 } finally { 735 watchDog.cancel(); 736 } 737 738 if (mIsHceCapable) { 739 // Generate the initial card emulation routing table 740 mAidCache.onNfcEnabled(); 741 } 742 743 synchronized(NfcService.this) { 744 mObjectMap.clear(); 745 mP2pLinkManager.enableDisable(mIsNdefPushEnabled, true); 746 updateState(NfcAdapter.STATE_ON); 747 } 748 749 initSoundPool(); 750 751 /* Start polling loop */ 752 753 applyRouting(true); 754 return true; 755 } 756 757 /** 758 * Disable all NFC adapter functions. 759 * Does not toggle preferences. 760 */ 761 boolean disableInternal() { 762 if (mState == NfcAdapter.STATE_OFF) { 763 return true; 764 } 765 Log.i(TAG, "Disabling NFC"); 766 updateState(NfcAdapter.STATE_TURNING_OFF); 767 768 /* Sometimes mDeviceHost.deinitialize() hangs, use a watch-dog. 769 * Implemented with a new thread (instead of a Handler or AsyncTask), 770 * because the UI Thread and AsyncTask thread-pools can also get hung 771 * when the NFC controller stops responding */ 772 WatchDogThread watchDog = new WatchDogThread("disableInternal", ROUTING_WATCHDOG_MS); 773 watchDog.start(); 774 775 if (mIsHceCapable) { 776 mAidCache.onNfcDisabled(); 777 } 778 779 mP2pLinkManager.enableDisable(false, false); 780 781 /* The NFC-EE may still be opened by another process, 782 * and a transceive() could still be in progress on 783 * another Binder thread. 784 * Give it a while to finish existing operations 785 * before we close it. 786 */ 787 Long startTime = SystemClock.elapsedRealtime(); 788 do { 789 synchronized (NfcService.this) { 790 if (mOpenEe == null) 791 break; 792 } 793 try { 794 Thread.sleep(WAIT_FOR_NFCEE_POLL_MS); 795 } catch (InterruptedException e) { 796 // Ignore 797 } 798 } while (SystemClock.elapsedRealtime() - startTime < WAIT_FOR_NFCEE_OPERATIONS_MS); 799 800 synchronized (NfcService.this) { 801 if (mOpenEe != null) { 802 try { 803 _nfcEeClose(-1, mOpenEe.binder); 804 } catch (IOException e) { } 805 } 806 } 807 808 // Stop watchdog if tag present 809 // A convenient way to stop the watchdog properly consists of 810 // disconnecting the tag. The polling loop shall be stopped before 811 // to avoid the tag being discovered again. 812 maybeDisconnectTarget(); 813 814 mNfcDispatcher.setForegroundDispatch(null, null, null); 815 816 boolean result = mDeviceHost.deinitialize(); 817 if (DBG) Log.d(TAG, "mDeviceHost.deinitialize() = " + result); 818 819 watchDog.cancel(); 820 821 updateState(NfcAdapter.STATE_OFF); 822 823 releaseSoundPool(); 824 825 return result; 826 } 827 828 void executeEeWipe() { 829 // TODO: read SE reset list from /system/etc 830 byte[][]apdus = mDeviceHost.getWipeApdus(); 831 832 if (apdus == null) { 833 Log.d(TAG, "No wipe APDUs found"); 834 return; 835 } 836 837 boolean tempEnable = mState == NfcAdapter.STATE_OFF; 838 // Hold a wake-lock over the entire wipe procedure 839 mEeWakeLock.acquire(); 840 try { 841 if (tempEnable && !enableInternal()) { 842 Log.w(TAG, "Could not enable NFC to wipe NFC-EE"); 843 return; 844 } 845 try { 846 // NFC enabled 847 int handle = 0; 848 try { 849 Log.i(TAG, "Executing SE wipe"); 850 handle = doOpenSecureElementConnection(); 851 if (handle < 0) { 852 Log.w(TAG, "Could not open the secure element"); 853 return; 854 } 855 // TODO: remove this hack 856 try { 857 Thread.sleep(1000); 858 } catch (InterruptedException e) { 859 // Ignore 860 } 861 862 mDeviceHost.setTimeout(TagTechnology.ISO_DEP, 10000); 863 try { 864 for (byte[] cmd : apdus) { 865 byte[] resp = doTransceiveNoLock(handle, cmd); 866 if (resp == null) { 867 Log.w(TAG, "Transceive failed, could not wipe NFC-EE"); 868 break; 869 } 870 } 871 } finally { 872 mDeviceHost.resetTimeouts(); 873 } 874 } finally { 875 if (handle >= 0) { 876 doDisconnect(handle); 877 } 878 } 879 } finally { 880 if (tempEnable) { 881 disableInternal(); 882 } 883 } 884 } finally { 885 mEeWakeLock.release(); 886 } 887 Log.i(TAG, "SE wipe done"); 888 } 889 890 void updateState(int newState) { 891 synchronized (NfcService.this) { 892 if (newState == mState) { 893 return; 894 } 895 mState = newState; 896 Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED); 897 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 898 intent.putExtra(NfcAdapter.EXTRA_ADAPTER_STATE, mState); 899 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT); 900 } 901 } 902 } 903 904 void saveNfcOnSetting(boolean on) { 905 synchronized (NfcService.this) { 906 mPrefsEditor.putBoolean(PREF_NFC_ON, on); 907 mPrefsEditor.apply(); 908 } 909 } 910 911 public void playSound(int sound) { 912 synchronized (this) { 913 if (mSoundPool == null) { 914 Log.w(TAG, "Not playing sound when NFC is disabled"); 915 return; 916 } 917 switch (sound) { 918 case SOUND_START: 919 mSoundPool.play(mStartSound, 1.0f, 1.0f, 0, 0, 1.0f); 920 break; 921 case SOUND_END: 922 mSoundPool.play(mEndSound, 1.0f, 1.0f, 0, 0, 1.0f); 923 break; 924 case SOUND_ERROR: 925 mSoundPool.play(mErrorSound, 1.0f, 1.0f, 0, 0, 1.0f); 926 break; 927 } 928 } 929 } 930 931 932 final class NfcAdapterService extends INfcAdapter.Stub { 933 @Override 934 public boolean enable() throws RemoteException { 935 NfcService.enforceAdminPerm(mContext); 936 937 saveNfcOnSetting(true); 938 939 if (mIsAirplaneSensitive && isAirplaneModeOn()) { 940 if (!mIsAirplaneToggleable) { 941 Log.i(TAG, "denying enable() request (airplane mode)"); 942 return false; 943 } 944 // Make sure the override survives a reboot 945 mPrefsEditor.putBoolean(PREF_AIRPLANE_OVERRIDE, true); 946 mPrefsEditor.apply(); 947 } 948 new EnableDisableTask().execute(TASK_ENABLE); 949 950 return true; 951 } 952 953 @Override 954 public boolean disable(boolean saveState) throws RemoteException { 955 NfcService.enforceAdminPerm(mContext); 956 957 if (saveState) { 958 saveNfcOnSetting(false); 959 } 960 961 new EnableDisableTask().execute(TASK_DISABLE); 962 963 return true; 964 } 965 966 @Override 967 public boolean isNdefPushEnabled() throws RemoteException { 968 synchronized (NfcService.this) { 969 return mState == NfcAdapter.STATE_ON && mIsNdefPushEnabled; 970 } 971 } 972 973 @Override 974 public boolean enableNdefPush() throws RemoteException { 975 NfcService.enforceAdminPerm(mContext); 976 synchronized(NfcService.this) { 977 if (mIsNdefPushEnabled) { 978 return true; 979 } 980 Log.i(TAG, "enabling NDEF Push"); 981 mPrefsEditor.putBoolean(PREF_NDEF_PUSH_ON, true); 982 mPrefsEditor.apply(); 983 mIsNdefPushEnabled = true; 984 if (isNfcEnabled()) { 985 mP2pLinkManager.enableDisable(true, true); 986 } 987 } 988 return true; 989 } 990 991 @Override 992 public boolean disableNdefPush() throws RemoteException { 993 NfcService.enforceAdminPerm(mContext); 994 synchronized(NfcService.this) { 995 if (!mIsNdefPushEnabled) { 996 return true; 997 } 998 Log.i(TAG, "disabling NDEF Push"); 999 mPrefsEditor.putBoolean(PREF_NDEF_PUSH_ON, false); 1000 mPrefsEditor.apply(); 1001 mIsNdefPushEnabled = false; 1002 if (isNfcEnabled()) { 1003 mP2pLinkManager.enableDisable(false, true); 1004 } 1005 } 1006 return true; 1007 } 1008 1009 @Override 1010 public void setForegroundDispatch(PendingIntent intent, 1011 IntentFilter[] filters, TechListParcel techListsParcel) { 1012 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1013 1014 // Short-cut the disable path 1015 if (intent == null && filters == null && techListsParcel == null) { 1016 mNfcDispatcher.setForegroundDispatch(null, null, null); 1017 return; 1018 } 1019 1020 // Validate the IntentFilters 1021 if (filters != null) { 1022 if (filters.length == 0) { 1023 filters = null; 1024 } else { 1025 for (IntentFilter filter : filters) { 1026 if (filter == null) { 1027 throw new IllegalArgumentException("null IntentFilter"); 1028 } 1029 } 1030 } 1031 } 1032 1033 // Validate the tech lists 1034 String[][] techLists = null; 1035 if (techListsParcel != null) { 1036 techLists = techListsParcel.getTechLists(); 1037 } 1038 1039 mNfcDispatcher.setForegroundDispatch(intent, filters, techLists); 1040 } 1041 1042 @Override 1043 public void setAppCallback(IAppCallback callback) { 1044 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1045 mP2pLinkManager.setNdefCallback(callback, Binder.getCallingUid()); 1046 } 1047 1048 @Override 1049 public INfcTag getNfcTagInterface() throws RemoteException { 1050 return mNfcTagService; 1051 } 1052 1053 @Override 1054 public INfcAdapterExtras getNfcAdapterExtrasInterface(String pkg) { 1055 NfcService.this.enforceNfceeAdminPerm(pkg); 1056 return mExtrasService; 1057 } 1058 1059 @Override 1060 public INfcCardEmulation getNfcCardEmulationInterface() { 1061 return mCardEmulationService; 1062 } 1063 1064 @Override 1065 public int getState() throws RemoteException { 1066 synchronized (NfcService.this) { 1067 return mState; 1068 } 1069 } 1070 1071 @Override 1072 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1073 NfcService.this.dump(fd, pw, args); 1074 } 1075 1076 @Override 1077 public void dispatch(Tag tag) throws RemoteException { 1078 enforceAdminPerm(mContext); 1079 mNfcDispatcher.dispatchTag(tag); 1080 } 1081 1082 @Override 1083 public void setP2pModes(int initiatorModes, int targetModes) throws RemoteException { 1084 enforceAdminPerm(mContext); 1085 1086 mDeviceHost.setP2pInitiatorModes(initiatorModes); 1087 mDeviceHost.setP2pTargetModes(targetModes); 1088 mDeviceHost.disableDiscovery(); 1089 mDeviceHost.enableDiscovery(); 1090 } 1091 1092 @Override 1093 public void setReaderMode(IBinder binder, IAppCallback callback, int flags, Bundle extras) 1094 throws RemoteException { 1095 synchronized (NfcService.this) { 1096 if (flags != 0) { 1097 try { 1098 mReaderModeParams = new ReaderModeParams(); 1099 mReaderModeParams.callback = callback; 1100 mReaderModeParams.flags = flags; 1101 mReaderModeParams.presenceCheckDelay = extras != null ? 1102 (extras.getInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 1103 DEFAULT_PRESENCE_CHECK_DELAY)) : DEFAULT_PRESENCE_CHECK_DELAY; 1104 binder.linkToDeath(mReaderModeDeathRecipient, 0); 1105 } catch (RemoteException e) { 1106 Log.e(TAG, "Remote binder has already died."); 1107 return; 1108 } 1109 } else { 1110 try { 1111 mReaderModeParams = null; 1112 binder.unlinkToDeath(mReaderModeDeathRecipient, 0); 1113 } catch (NoSuchElementException e) { 1114 Log.e(TAG, "Reader mode Binder was never registered."); 1115 } 1116 } 1117 applyRouting(false); 1118 } 1119 } 1120 } 1121 1122 final class ReaderModeDeathRecipient implements IBinder.DeathRecipient { 1123 @Override 1124 public void binderDied() { 1125 synchronized (NfcService.this) { 1126 if (mReaderModeParams != null) { 1127 mReaderModeParams = null; 1128 applyRouting(false); 1129 } 1130 } 1131 } 1132 } 1133 1134 final class CardEmulationService extends INfcCardEmulation.Stub { 1135 @Override 1136 public boolean isDefaultServiceForCategory(int userId, ComponentName service, 1137 String category) throws RemoteException { 1138 if (!mIsHceCapable) { 1139 return false; 1140 } 1141 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1142 validateUserId(userId); 1143 return mAidCache.isDefaultServiceForCategory(userId, category, service); 1144 } 1145 1146 @Override 1147 public boolean isDefaultServiceForAid(int userId, ComponentName service, String aid) 1148 throws RemoteException { 1149 if (!mIsHceCapable) { 1150 return false; 1151 } 1152 validateUserId(userId); 1153 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1154 return mAidCache.isDefaultServiceForAid(userId, service, aid); 1155 } 1156 1157 @Override 1158 public boolean setDefaultServiceForCategory(int userId, ComponentName service, 1159 String category) throws RemoteException { 1160 if (!mIsHceCapable) { 1161 return false; 1162 } 1163 validateUserId(userId); 1164 enforceAdminPerm(mContext); 1165 return mAidCache.setDefaultServiceForCategory(userId, service, category); 1166 } 1167 1168 @Override 1169 public boolean setDefaultForNextTap(int userId, ComponentName service) 1170 throws RemoteException { 1171 if (!mIsHceCapable) { 1172 return false; 1173 } 1174 validateUserId(userId); 1175 enforceAdminPerm(mContext); 1176 mHostEmulationManager.setDefaultForNextTap(service); 1177 return mAidCache.setDefaultForNextTap(userId, service); 1178 } 1179 1180 @Override 1181 public List<ApduServiceInfo> getServices(int userId, String category) 1182 throws RemoteException { 1183 if (!mIsHceCapable) { 1184 return null; 1185 } 1186 validateUserId(userId); 1187 enforceAdminPerm(mContext); 1188 return mAidCache.getServicesForCategory(userId, category); 1189 } 1190 }; 1191 1192 final class TagService extends INfcTag.Stub { 1193 @Override 1194 public int close(int nativeHandle) throws RemoteException { 1195 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1196 1197 TagEndpoint tag = null; 1198 1199 if (!isNfcEnabled()) { 1200 return ErrorCodes.ERROR_NOT_INITIALIZED; 1201 } 1202 1203 /* find the tag in the hmap */ 1204 tag = (TagEndpoint) findObject(nativeHandle); 1205 if (tag != null) { 1206 /* Remove the device from the hmap */ 1207 unregisterObject(nativeHandle); 1208 tag.disconnect(); 1209 return ErrorCodes.SUCCESS; 1210 } 1211 /* Restart polling loop for notification */ 1212 applyRouting(true); 1213 return ErrorCodes.ERROR_DISCONNECT; 1214 } 1215 1216 @Override 1217 public int connect(int nativeHandle, int technology) throws RemoteException { 1218 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 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 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 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 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 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 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 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 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 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 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 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 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 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 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 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 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 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 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 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 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 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 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1515 1516 return mDeviceHost.getTimeout(tech); 1517 } 1518 1519 @Override 1520 public void resetTimeouts() throws RemoteException { 1521 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 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 void _nfcEeClose(int callingPid, IBinder binder) throws IOException { 1543 // Blocks until a pending open() or transceive() times out. 1544 //TODO: This is incorrect behavior - the close should interrupt pending 1545 // operations. However this is not supported by current hardware. 1546 1547 synchronized (NfcService.this) { 1548 if (!isNfcEnabledOrShuttingDown()) { 1549 throw new IOException("NFC adapter is disabled"); 1550 } 1551 if (mOpenEe == null) { 1552 throw new IOException("NFC EE closed"); 1553 } 1554 if (callingPid != -1 && callingPid != mOpenEe.pid) { 1555 throw new SecurityException("Wrong PID"); 1556 } 1557 if (mOpenEe.binder != binder) { 1558 throw new SecurityException("Wrong binder handle"); 1559 } 1560 1561 binder.unlinkToDeath(mOpenEe, 0); 1562 mDeviceHost.resetTimeouts(); 1563 doDisconnect(mOpenEe.handle); 1564 mOpenEe = null; 1565 1566 applyRouting(true); 1567 } 1568 } 1569 1570 final class NfcAdapterExtrasService extends INfcAdapterExtras.Stub { 1571 private Bundle writeNoException() { 1572 Bundle p = new Bundle(); 1573 p.putInt("e", 0); 1574 return p; 1575 } 1576 1577 private Bundle writeEeException(int exceptionType, String message) { 1578 Bundle p = new Bundle(); 1579 p.putInt("e", exceptionType); 1580 p.putString("m", message); 1581 return p; 1582 } 1583 1584 @Override 1585 public Bundle open(String pkg, IBinder b) throws RemoteException { 1586 NfcService.this.enforceNfceeAdminPerm(pkg); 1587 1588 Bundle result; 1589 int handle = _open(b); 1590 if (handle < 0) { 1591 result = writeEeException(handle, "NFCEE open exception."); 1592 } else { 1593 result = writeNoException(); 1594 } 1595 return result; 1596 } 1597 1598 /** 1599 * Opens a connection to the secure element. 1600 * 1601 * @return A handle with a value >= 0 in case of success, or a 1602 * negative value in case of failure. 1603 */ 1604 private int _open(IBinder b) { 1605 synchronized(NfcService.this) { 1606 if (!isNfcEnabled()) { 1607 return EE_ERROR_NFC_DISABLED; 1608 } 1609 if (mInProvisionMode) { 1610 // Deny access to the NFCEE as long as the device is being setup 1611 return EE_ERROR_IO; 1612 } 1613 if (mDeviceHost.enablePN544Quirks() && mP2pLinkManager.isLlcpActive()) { 1614 // Don't allow PN544-based devices to open the SE while the LLCP 1615 // link is still up or in a debounce state. This avoids race 1616 // conditions in the NXP stack around P2P/SMX switching. 1617 return EE_ERROR_EXT_FIELD; 1618 } 1619 if (mOpenEe != null) { 1620 return EE_ERROR_ALREADY_OPEN; 1621 } 1622 1623 boolean restorePolling = false; 1624 if (mDeviceHost.enablePN544Quirks() && mNfcPollingEnabled) { 1625 // Disable polling for tags/P2P when connecting to the SMX 1626 // on PN544-based devices. Whenever nfceeClose is called, 1627 // the polling configuration will be restored. 1628 mDeviceHost.disableDiscovery(); 1629 mNfcPollingEnabled = false; 1630 restorePolling = true; 1631 } 1632 1633 int handle = doOpenSecureElementConnection(); 1634 if (handle < 0) { 1635 1636 if (restorePolling) { 1637 mDeviceHost.enableDiscovery(); 1638 mNfcPollingEnabled = true; 1639 } 1640 return handle; 1641 } 1642 mDeviceHost.setTimeout(TagTechnology.ISO_DEP, 30000); 1643 1644 mOpenEe = new OpenSecureElement(getCallingPid(), handle, b); 1645 try { 1646 b.linkToDeath(mOpenEe, 0); 1647 } catch (RemoteException e) { 1648 mOpenEe.binderDied(); 1649 } 1650 1651 // Add the calling package to the list of packages that have accessed 1652 // the secure element. 1653 for (String packageName : mContext.getPackageManager().getPackagesForUid(getCallingUid())) { 1654 mSePackages.add(packageName); 1655 } 1656 1657 return handle; 1658 } 1659 } 1660 1661 @Override 1662 public Bundle close(String pkg, IBinder binder) throws RemoteException { 1663 NfcService.this.enforceNfceeAdminPerm(pkg); 1664 1665 Bundle result; 1666 try { 1667 _nfcEeClose(getCallingPid(), binder); 1668 result = writeNoException(); 1669 } catch (IOException e) { 1670 result = writeEeException(EE_ERROR_IO, e.getMessage()); 1671 } 1672 return result; 1673 } 1674 1675 @Override 1676 public Bundle transceive(String pkg, byte[] in) throws RemoteException { 1677 NfcService.this.enforceNfceeAdminPerm(pkg); 1678 1679 Bundle result; 1680 byte[] out; 1681 try { 1682 out = _transceive(in); 1683 result = writeNoException(); 1684 result.putByteArray("out", out); 1685 } catch (IOException e) { 1686 result = writeEeException(EE_ERROR_IO, e.getMessage()); 1687 } 1688 return result; 1689 } 1690 1691 private byte[] _transceive(byte[] data) throws IOException { 1692 synchronized(NfcService.this) { 1693 if (!isNfcEnabled()) { 1694 throw new IOException("NFC is not enabled"); 1695 } 1696 if (mOpenEe == null) { 1697 throw new IOException("NFC EE is not open"); 1698 } 1699 if (getCallingPid() != mOpenEe.pid) { 1700 throw new SecurityException("Wrong PID"); 1701 } 1702 } 1703 1704 return doTransceive(mOpenEe.handle, data); 1705 } 1706 1707 @Override 1708 public int getCardEmulationRoute(String pkg) throws RemoteException { 1709 NfcService.this.enforceNfceeAdminPerm(pkg); 1710 return mEeRoutingState; 1711 } 1712 1713 @Override 1714 public void setCardEmulationRoute(String pkg, int route) throws RemoteException { 1715 NfcService.this.enforceNfceeAdminPerm(pkg); 1716 mEeRoutingState = route; 1717 ApplyRoutingTask applyRoutingTask = new ApplyRoutingTask(); 1718 applyRoutingTask.execute(); 1719 try { 1720 // Block until route is set 1721 applyRoutingTask.get(); 1722 } catch (ExecutionException e) { 1723 Log.e(TAG, "failed to set card emulation mode"); 1724 } catch (InterruptedException e) { 1725 Log.e(TAG, "failed to set card emulation mode"); 1726 } 1727 } 1728 1729 @Override 1730 public void authenticate(String pkg, byte[] token) throws RemoteException { 1731 NfcService.this.enforceNfceeAdminPerm(pkg); 1732 } 1733 1734 @Override 1735 public String getDriverName(String pkg) throws RemoteException { 1736 NfcService.this.enforceNfceeAdminPerm(pkg); 1737 return mDeviceHost.getName(); 1738 } 1739 } 1740 1741 /** resources kept while secure element is open */ 1742 private class OpenSecureElement implements IBinder.DeathRecipient { 1743 public int pid; // pid that opened SE 1744 // binder handle used for DeathReceipient. Must keep 1745 // a reference to this, otherwise it can get GC'd and 1746 // the binder stub code might create a different BinderProxy 1747 // for the same remote IBinder, causing mismatched 1748 // link()/unlink() 1749 public IBinder binder; 1750 public int handle; // low-level handle 1751 public OpenSecureElement(int pid, int handle, IBinder binder) { 1752 this.pid = pid; 1753 this.handle = handle; 1754 this.binder = binder; 1755 } 1756 @Override 1757 public void binderDied() { 1758 synchronized (NfcService.this) { 1759 Log.i(TAG, "Tracked app " + pid + " died"); 1760 pid = -1; 1761 try { 1762 _nfcEeClose(-1, binder); 1763 } catch (IOException e) { /* already closed */ } 1764 } 1765 } 1766 @Override 1767 public String toString() { 1768 return new StringBuilder('@').append(Integer.toHexString(hashCode())).append("[pid=") 1769 .append(pid).append(" handle=").append(handle).append("]").toString(); 1770 } 1771 } 1772 1773 boolean isNfcEnabledOrShuttingDown() { 1774 synchronized (this) { 1775 return (mState == NfcAdapter.STATE_ON || mState == NfcAdapter.STATE_TURNING_OFF); 1776 } 1777 } 1778 1779 boolean isNfcEnabled() { 1780 synchronized (this) { 1781 return mState == NfcAdapter.STATE_ON; 1782 } 1783 } 1784 1785 class WatchDogThread extends Thread { 1786 final Object mCancelWaiter = new Object(); 1787 final int mTimeout; 1788 boolean mCanceled = false; 1789 1790 public WatchDogThread(String threadName, int timeout) { 1791 super(threadName); 1792 mTimeout = timeout; 1793 } 1794 1795 @Override 1796 public void run() { 1797 try { 1798 synchronized (mCancelWaiter) { 1799 mCancelWaiter.wait(mTimeout); 1800 if (mCanceled) { 1801 return; 1802 } 1803 } 1804 } catch (InterruptedException e) { 1805 // Should not happen; fall-through to abort. 1806 Log.w(TAG, "Watchdog thread interruped."); 1807 interrupt(); 1808 } 1809 Log.e(TAG, "Watchdog triggered, aborting."); 1810 mDeviceHost.doAbort(); 1811 } 1812 1813 public synchronized void cancel() { 1814 synchronized (mCancelWaiter) { 1815 mCanceled = true; 1816 mCancelWaiter.notify(); 1817 } 1818 } 1819 } 1820 1821 static byte[] hexStringToBytes(String s) { 1822 if (s == null || s.length() == 0) return null; 1823 int len = s.length(); 1824 if (len % 2 != 0) { 1825 s = '0' + s; 1826 len++; 1827 } 1828 byte[] data = new byte[len / 2]; 1829 for (int i = 0; i < len; i += 2) { 1830 data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 1831 + Character.digit(s.charAt(i+1), 16)); 1832 } 1833 return data; 1834 } 1835 1836 /** 1837 * Read mScreenState and apply NFC-C polling and NFC-EE routing 1838 */ 1839 void applyRouting(boolean force) { 1840 synchronized (this) { 1841 if (!isNfcEnabledOrShuttingDown() || mOpenEe != null) { 1842 // PN544 cannot be reconfigured while EE is open 1843 return; 1844 } 1845 WatchDogThread watchDog = new WatchDogThread("applyRouting", ROUTING_WATCHDOG_MS); 1846 if (mInProvisionMode) { 1847 mInProvisionMode = Settings.Secure.getInt(mContentResolver, 1848 Settings.Global.DEVICE_PROVISIONED, 0) == 0; 1849 if (!mInProvisionMode) { 1850 // Notify dispatcher it's fine to dispatch to any package now 1851 // and allow handover transfers. 1852 mNfcDispatcher.disableProvisioningMode(); 1853 mHandoverManager.setEnabled(true); 1854 } 1855 } 1856 try { 1857 watchDog.start(); 1858 1859 if (mDeviceHost.enablePN544Quirks() && mScreenState == SCREEN_STATE_OFF) { 1860 /* TODO undo this after the LLCP stack is fixed. 1861 * Use a different sequence when turning the screen off to 1862 * workaround race conditions in pn544 libnfc. The race occurs 1863 * when we change routing while there is a P2P target connect. 1864 * The async LLCP callback will crash since the routing code 1865 * is overwriting globals it relies on. 1866 */ 1867 if (POLLING_MODE > SCREEN_STATE_OFF) { 1868 if (force || mNfcPollingEnabled) { 1869 Log.d(TAG, "NFC-C OFF, disconnect"); 1870 mNfcPollingEnabled = false; 1871 mDeviceHost.disableDiscovery(); 1872 maybeDisconnectTarget(); 1873 } 1874 } 1875 if (mEeRoutingState == ROUTE_ON_WHEN_SCREEN_ON) { 1876 if (force || mNfceeRouteEnabled) { 1877 Log.d(TAG, "NFC-EE OFF"); 1878 mNfceeRouteEnabled = false; 1879 mDeviceHost.doDeselectSecureElement(); 1880 } 1881 } 1882 return; 1883 } 1884 1885 if (mIsHceCapable && mScreenState >= SCREEN_STATE_ON_LOCKED && 1886 mAidRoutingManager.aidsRoutedToHost()) { 1887 if (!mHostRouteEnabled || force) { 1888 mHostRouteEnabled = true; 1889 mDeviceHost.enableRoutingToHost(); 1890 } 1891 } else { 1892 if (force || mHostRouteEnabled) { 1893 mHostRouteEnabled = false; 1894 mDeviceHost.disableRoutingToHost(); 1895 } 1896 } 1897 1898 // configure NFC-EE routing 1899 if (mScreenState >= SCREEN_STATE_ON_LOCKED && 1900 mEeRoutingState == ROUTE_ON_WHEN_SCREEN_ON) { 1901 if (force || !mNfceeRouteEnabled) { 1902 Log.d(TAG, "NFC-EE ON"); 1903 mNfceeRouteEnabled = true; 1904 mDeviceHost.doSelectSecureElement(); 1905 } 1906 } else { 1907 if (force || mNfceeRouteEnabled) { 1908 Log.d(TAG, "NFC-EE OFF"); 1909 mNfceeRouteEnabled = false; 1910 mDeviceHost.doDeselectSecureElement(); 1911 } 1912 } 1913 1914 // configure NFC-C polling 1915 if (mScreenState >= POLLING_MODE) { 1916 if (force || !mNfcPollingEnabled) { 1917 Log.d(TAG, "NFC-C ON"); 1918 mNfcPollingEnabled = true; 1919 mDeviceHost.enableDiscovery(); 1920 } 1921 if (mReaderModeParams != null && !mReaderModeEnabled) { 1922 mReaderModeEnabled = true; 1923 mDeviceHost.enableReaderMode(mReaderModeParams.flags); 1924 } 1925 if (mReaderModeParams == null && mReaderModeEnabled) { 1926 mReaderModeEnabled = false; 1927 mDeviceHost.disableReaderMode(); 1928 } 1929 } else if (mInProvisionMode && mScreenState >= SCREEN_STATE_ON_LOCKED) { 1930 // Special case for setup provisioning 1931 if (!mNfcPollingEnabled) { 1932 Log.d(TAG, "NFC-C ON"); 1933 mNfcPollingEnabled = true; 1934 mDeviceHost.enableDiscovery(); 1935 } 1936 } else { 1937 if (force || mNfcPollingEnabled) { 1938 Log.d(TAG, "NFC-C OFF"); 1939 if (mReaderModeEnabled) { 1940 mReaderModeEnabled = false; 1941 mDeviceHost.disableReaderMode(); 1942 } 1943 mNfcPollingEnabled = false; 1944 mDeviceHost.disableDiscovery(); 1945 } 1946 } 1947 } finally { 1948 watchDog.cancel(); 1949 } 1950 } 1951 } 1952 1953 /** Disconnect any target if present */ 1954 void maybeDisconnectTarget() { 1955 if (!isNfcEnabledOrShuttingDown()) { 1956 return; 1957 } 1958 Object[] objectsToDisconnect; 1959 synchronized (this) { 1960 Object[] objectValues = mObjectMap.values().toArray(); 1961 // Copy the array before we clear mObjectMap, 1962 // just in case the HashMap values are backed by the same array 1963 objectsToDisconnect = Arrays.copyOf(objectValues, objectValues.length); 1964 mObjectMap.clear(); 1965 } 1966 for (Object o : objectsToDisconnect) { 1967 if (DBG) Log.d(TAG, "disconnecting " + o.getClass().getName()); 1968 if (o instanceof TagEndpoint) { 1969 // Disconnect from tags 1970 TagEndpoint tag = (TagEndpoint) o; 1971 tag.disconnect(); 1972 } else if (o instanceof NfcDepEndpoint) { 1973 // Disconnect from P2P devices 1974 NfcDepEndpoint device = (NfcDepEndpoint) o; 1975 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) { 1976 // Remote peer is target, request disconnection 1977 device.disconnect(); 1978 } else { 1979 // Remote peer is initiator, we cannot disconnect 1980 // Just wait for field removal 1981 } 1982 } 1983 } 1984 } 1985 1986 Object findObject(int key) { 1987 synchronized (this) { 1988 Object device = mObjectMap.get(key); 1989 if (device == null) { 1990 Log.w(TAG, "Handle not found"); 1991 } 1992 return device; 1993 } 1994 } 1995 1996 void registerTagObject(TagEndpoint tag) { 1997 synchronized (this) { 1998 mObjectMap.put(tag.getHandle(), tag); 1999 } 2000 } 2001 2002 void unregisterObject(int handle) { 2003 synchronized (this) { 2004 mObjectMap.remove(handle); 2005 } 2006 } 2007 2008 /** For use by code in this process */ 2009 public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) 2010 throws LlcpException { 2011 return mDeviceHost.createLlcpSocket(sap, miu, rw, linearBufferLength); 2012 } 2013 2014 /** For use by code in this process */ 2015 public LlcpConnectionlessSocket createLlcpConnectionLessSocket(int sap, String sn) 2016 throws LlcpException { 2017 return mDeviceHost.createLlcpConnectionlessSocket(sap, sn); 2018 } 2019 2020 /** For use by code in this process */ 2021 public LlcpServerSocket createLlcpServerSocket(int sap, String sn, int miu, int rw, 2022 int linearBufferLength) throws LlcpException { 2023 return mDeviceHost.createLlcpServerSocket(sap, sn, miu, rw, linearBufferLength); 2024 } 2025 2026 public void sendMockNdefTag(NdefMessage msg) { 2027 sendMessage(MSG_MOCK_NDEF, msg); 2028 } 2029 2030 public void routeAids(String aid, int route) { 2031 Message msg = mHandler.obtainMessage(); 2032 msg.what = MSG_ROUTE_AID; 2033 msg.arg1 = route; 2034 msg.obj = aid; 2035 mHandler.sendMessage(msg); 2036 } 2037 2038 public void unrouteAids(String aid) { 2039 sendMessage(MSG_UNROUTE_AID, aid); 2040 } 2041 2042 public void commitRouting() { 2043 mHandler.sendEmptyMessage(MSG_COMMIT_ROUTING); 2044 } 2045 2046 public boolean sendData(byte[] data) { 2047 return mDeviceHost.sendRawFrame(data); 2048 } 2049 2050 void sendMessage(int what, Object obj) { 2051 Message msg = mHandler.obtainMessage(); 2052 msg.what = what; 2053 msg.obj = obj; 2054 mHandler.sendMessage(msg); 2055 } 2056 2057 final class NfcServiceHandler extends Handler { 2058 @Override 2059 public void handleMessage(Message msg) { 2060 switch (msg.what) { 2061 case MSG_ROUTE_AID: { 2062 int route = msg.arg1; 2063 String aid = (String) msg.obj; 2064 mDeviceHost.routeAid(hexStringToBytes(aid), route); 2065 // Restart polling config 2066 break; 2067 } 2068 case MSG_UNROUTE_AID: { 2069 String aid = (String) msg.obj; 2070 mDeviceHost.unrouteAid(hexStringToBytes(aid)); 2071 break; 2072 } 2073 case MSG_COMMIT_ROUTING: { 2074 applyRouting(true); 2075 break; 2076 } 2077 case MSG_MOCK_NDEF: { 2078 NdefMessage ndefMsg = (NdefMessage) msg.obj; 2079 Bundle extras = new Bundle(); 2080 extras.putParcelable(Ndef.EXTRA_NDEF_MSG, ndefMsg); 2081 extras.putInt(Ndef.EXTRA_NDEF_MAXLENGTH, 0); 2082 extras.putInt(Ndef.EXTRA_NDEF_CARDSTATE, Ndef.NDEF_MODE_READ_ONLY); 2083 extras.putInt(Ndef.EXTRA_NDEF_TYPE, Ndef.TYPE_OTHER); 2084 Tag tag = Tag.createMockTag(new byte[] { 0x00 }, 2085 new int[] { TagTechnology.NDEF }, 2086 new Bundle[] { extras }); 2087 Log.d(TAG, "mock NDEF tag, starting corresponding activity"); 2088 Log.d(TAG, tag.toString()); 2089 boolean delivered = mNfcDispatcher.dispatchTag(tag); 2090 if (delivered) { 2091 playSound(SOUND_END); 2092 } else { 2093 playSound(SOUND_ERROR); 2094 } 2095 break; 2096 } 2097 2098 case MSG_NDEF_TAG: 2099 if (DBG) Log.d(TAG, "Tag detected, notifying applications"); 2100 TagEndpoint tag = (TagEndpoint) msg.obj; 2101 ReaderModeParams readerParams = null; 2102 int presenceCheckDelay = DEFAULT_PRESENCE_CHECK_DELAY; 2103 synchronized (NfcService.this) { 2104 readerParams = mReaderModeParams; 2105 } 2106 if (readerParams != null) { 2107 presenceCheckDelay = readerParams.presenceCheckDelay; 2108 if ((readerParams.flags & NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK) != 0) { 2109 if (DBG) Log.d(TAG, "Skipping NDEF detection in reader mode"); 2110 tag.startPresenceChecking(presenceCheckDelay); 2111 dispatchTagEndpoint(tag, readerParams); 2112 break; 2113 } 2114 } 2115 if (readerParams == null || 2116 (readerParams.flags & NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS) == 0) { 2117 playSound(SOUND_START); 2118 } 2119 if (tag.getConnectedTechnology() == TagTechnology.NFC_BARCODE) { 2120 // When these tags start containing NDEF, they will require 2121 // the stack to deal with them in a different way, since 2122 // they are activated only really shortly. 2123 // For now, don't consider NDEF on these. 2124 if (DBG) Log.d(TAG, "Skipping NDEF detection for NFC Barcode"); 2125 tag.startPresenceChecking(presenceCheckDelay); 2126 dispatchTagEndpoint(tag, readerParams); 2127 break; 2128 } 2129 NdefMessage ndefMsg = tag.findAndReadNdef(); 2130 2131 if (ndefMsg != null) { 2132 tag.startPresenceChecking(presenceCheckDelay); 2133 dispatchTagEndpoint(tag, readerParams); 2134 } else { 2135 if (tag.reconnect()) { 2136 tag.startPresenceChecking(presenceCheckDelay); 2137 dispatchTagEndpoint(tag, readerParams); 2138 } else { 2139 tag.disconnect(); 2140 playSound(SOUND_ERROR); 2141 } 2142 } 2143 break; 2144 2145 case MSG_CARD_EMULATION: 2146 if (DBG) Log.d(TAG, "Card Emulation message"); 2147 /* Tell the host-emu manager an AID has been selected on 2148 * a secure element. 2149 */ 2150 if (mHostEmulationManager != null) { 2151 mHostEmulationManager.notifyOffHostAidSelected(); 2152 } 2153 byte[] aid = (byte[]) msg.obj; 2154 /* Send broadcast */ 2155 Intent aidIntent = new Intent(); 2156 aidIntent.setAction(ACTION_AID_SELECTED); 2157 aidIntent.putExtra(EXTRA_AID, aid); 2158 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_AID_SELECTED); 2159 sendSeBroadcast(aidIntent); 2160 break; 2161 2162 case MSG_SE_EMV_CARD_REMOVAL: 2163 if (DBG) Log.d(TAG, "Card Removal message"); 2164 /* Send broadcast */ 2165 Intent cardRemovalIntent = new Intent(); 2166 cardRemovalIntent.setAction(ACTION_EMV_CARD_REMOVAL); 2167 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_EMV_CARD_REMOVAL); 2168 sendSeBroadcast(cardRemovalIntent); 2169 break; 2170 2171 case MSG_SE_APDU_RECEIVED: 2172 if (DBG) Log.d(TAG, "APDU Received message"); 2173 byte[] apduBytes = (byte[]) msg.obj; 2174 /* Send broadcast */ 2175 Intent apduReceivedIntent = new Intent(); 2176 apduReceivedIntent.setAction(ACTION_APDU_RECEIVED); 2177 if (apduBytes != null && apduBytes.length > 0) { 2178 apduReceivedIntent.putExtra(EXTRA_APDU_BYTES, apduBytes); 2179 } 2180 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_APDU_RECEIVED); 2181 sendSeBroadcast(apduReceivedIntent); 2182 break; 2183 2184 case MSG_SE_MIFARE_ACCESS: 2185 if (DBG) Log.d(TAG, "MIFARE access message"); 2186 /* Send broadcast */ 2187 byte[] mifareCmd = (byte[]) msg.obj; 2188 Intent mifareAccessIntent = new Intent(); 2189 mifareAccessIntent.setAction(ACTION_MIFARE_ACCESS_DETECTED); 2190 if (mifareCmd != null && mifareCmd.length > 1) { 2191 int mifareBlock = mifareCmd[1] & 0xff; 2192 if (DBG) Log.d(TAG, "Mifare Block=" + mifareBlock); 2193 mifareAccessIntent.putExtra(EXTRA_MIFARE_BLOCK, mifareBlock); 2194 } 2195 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_MIFARE_ACCESS_DETECTED); 2196 sendSeBroadcast(mifareAccessIntent); 2197 break; 2198 2199 case MSG_LLCP_LINK_ACTIVATION: 2200 if (mIsDebugBuild) { 2201 Intent actIntent = new Intent(ACTION_LLCP_UP); 2202 mContext.sendBroadcast(actIntent); 2203 } 2204 llcpActivated((NfcDepEndpoint) msg.obj); 2205 break; 2206 2207 case MSG_LLCP_LINK_DEACTIVATED: 2208 if (mIsDebugBuild) { 2209 Intent deactIntent = new Intent(ACTION_LLCP_DOWN); 2210 mContext.sendBroadcast(deactIntent); 2211 } 2212 NfcDepEndpoint device = (NfcDepEndpoint) msg.obj; 2213 boolean needsDisconnect = false; 2214 2215 Log.d(TAG, "LLCP Link Deactivated message. Restart polling loop."); 2216 synchronized (NfcService.this) { 2217 /* Check if the device has been already unregistered */ 2218 if (mObjectMap.remove(device.getHandle()) != null) { 2219 /* Disconnect if we are initiator */ 2220 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) { 2221 if (DBG) Log.d(TAG, "disconnecting from target"); 2222 needsDisconnect = true; 2223 } else { 2224 if (DBG) Log.d(TAG, "not disconnecting from initiator"); 2225 } 2226 } 2227 } 2228 if (needsDisconnect) { 2229 device.disconnect(); // restarts polling loop 2230 } 2231 2232 mP2pLinkManager.onLlcpDeactivated(); 2233 break; 2234 case MSG_LLCP_LINK_FIRST_PACKET: 2235 mP2pLinkManager.onLlcpFirstPacketReceived(); 2236 break; 2237 case MSG_TARGET_DESELECTED: 2238 /* Broadcast Intent Target Deselected */ 2239 if (DBG) Log.d(TAG, "Target Deselected"); 2240 Intent intent = new Intent(); 2241 intent.setAction(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION); 2242 if (DBG) Log.d(TAG, "Broadcasting Intent"); 2243 mContext.sendOrderedBroadcast(intent, NFC_PERM); 2244 break; 2245 2246 case MSG_SE_FIELD_ACTIVATED: { 2247 if (DBG) Log.d(TAG, "SE FIELD ACTIVATED"); 2248 Intent eventFieldOnIntent = new Intent(); 2249 eventFieldOnIntent.setAction(ACTION_RF_FIELD_ON_DETECTED); 2250 sendSeBroadcast(eventFieldOnIntent); 2251 break; 2252 } 2253 2254 case MSG_SE_FIELD_DEACTIVATED: { 2255 if (DBG) Log.d(TAG, "SE FIELD DEACTIVATED"); 2256 Intent eventFieldOffIntent = new Intent(); 2257 eventFieldOffIntent.setAction(ACTION_RF_FIELD_OFF_DETECTED); 2258 sendSeBroadcast(eventFieldOffIntent); 2259 break; 2260 } 2261 2262 case MSG_SE_LISTEN_ACTIVATED: { 2263 if (DBG) Log.d(TAG, "SE LISTEN MODE ACTIVATED"); 2264 Intent listenModeActivated = new Intent(); 2265 listenModeActivated.setAction(ACTION_SE_LISTEN_ACTIVATED); 2266 sendSeBroadcast(listenModeActivated); 2267 break; 2268 } 2269 2270 case MSG_SE_LISTEN_DEACTIVATED: { 2271 if (DBG) Log.d(TAG, "SE LISTEN MODE DEACTIVATED"); 2272 Intent listenModeDeactivated = new Intent(); 2273 listenModeDeactivated.setAction(ACTION_SE_LISTEN_DEACTIVATED); 2274 sendSeBroadcast(listenModeDeactivated); 2275 break; 2276 } 2277 default: 2278 Log.e(TAG, "Unknown message received"); 2279 break; 2280 } 2281 } 2282 2283 private void sendSeBroadcast(Intent intent) { 2284 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 2285 // Resume app switches so the receivers can start activites without delay 2286 mNfcDispatcher.resumeAppSwitches(); 2287 2288 synchronized(this) { 2289 for (PackageInfo pkg : mInstalledPackages) { 2290 if (pkg != null && pkg.applicationInfo != null) { 2291 if (mNfceeAccessControl.check(pkg.applicationInfo)) { 2292 intent.setPackage(pkg.packageName); 2293 mContext.sendBroadcast(intent); 2294 } 2295 } 2296 } 2297 } 2298 } 2299 2300 private boolean llcpActivated(NfcDepEndpoint device) { 2301 Log.d(TAG, "LLCP Activation message"); 2302 2303 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) { 2304 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_TARGET"); 2305 if (device.connect()) { 2306 /* Check LLCP compliancy */ 2307 if (mDeviceHost.doCheckLlcp()) { 2308 /* Activate LLCP Link */ 2309 if (mDeviceHost.doActivateLlcp()) { 2310 if (DBG) Log.d(TAG, "Initiator Activate LLCP OK"); 2311 synchronized (NfcService.this) { 2312 // Register P2P device 2313 mObjectMap.put(device.getHandle(), device); 2314 } 2315 mP2pLinkManager.onLlcpActivated(); 2316 return true; 2317 } else { 2318 /* should not happen */ 2319 Log.w(TAG, "Initiator LLCP activation failed. Disconnect."); 2320 device.disconnect(); 2321 } 2322 } else { 2323 if (DBG) Log.d(TAG, "Remote Target does not support LLCP. Disconnect."); 2324 device.disconnect(); 2325 } 2326 } else { 2327 if (DBG) Log.d(TAG, "Cannot connect remote Target. Polling loop restarted."); 2328 /* 2329 * The polling loop should have been restarted in failing 2330 * doConnect 2331 */ 2332 } 2333 } else if (device.getMode() == NfcDepEndpoint.MODE_P2P_INITIATOR) { 2334 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_INITIATOR"); 2335 /* Check LLCP compliancy */ 2336 if (mDeviceHost.doCheckLlcp()) { 2337 /* Activate LLCP Link */ 2338 if (mDeviceHost.doActivateLlcp()) { 2339 if (DBG) Log.d(TAG, "Target Activate LLCP OK"); 2340 synchronized (NfcService.this) { 2341 // Register P2P device 2342 mObjectMap.put(device.getHandle(), device); 2343 } 2344 mP2pLinkManager.onLlcpActivated(); 2345 return true; 2346 } 2347 } else { 2348 Log.w(TAG, "checkLlcp failed"); 2349 } 2350 } 2351 2352 return false; 2353 } 2354 2355 private void dispatchTagEndpoint(TagEndpoint tagEndpoint, ReaderModeParams readerParams) { 2356 Tag tag = new Tag(tagEndpoint.getUid(), tagEndpoint.getTechList(), 2357 tagEndpoint.getTechExtras(), tagEndpoint.getHandle(), mNfcTagService); 2358 registerTagObject(tagEndpoint); 2359 if (readerParams != null) { 2360 try { 2361 if ((readerParams.flags & NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS) == 0) { 2362 playSound(SOUND_END); 2363 } 2364 if (readerParams.callback != null) { 2365 readerParams.callback.onTagDiscovered(tag); 2366 return; 2367 } else { 2368 // Follow normal dispatch below 2369 } 2370 } catch (RemoteException e) { 2371 Log.e(TAG, "Reader mode remote has died, falling back."); 2372 // Intentional fall-through 2373 } catch (Exception e) { 2374 // Catch any other exception 2375 Log.e(TAG, "App exception, not dispatching."); 2376 return; 2377 } 2378 } 2379 if (!mNfcDispatcher.dispatchTag(tag)) { 2380 unregisterObject(tagEndpoint.getHandle()); 2381 playSound(SOUND_ERROR); 2382 } else { 2383 playSound(SOUND_END); 2384 } 2385 } 2386 } 2387 2388 private NfcServiceHandler mHandler = new NfcServiceHandler(); 2389 2390 class ApplyRoutingTask extends AsyncTask<Integer, Void, Void> { 2391 @Override 2392 protected Void doInBackground(Integer... params) { 2393 synchronized (NfcService.this) { 2394 if (params == null || params.length != 1) { 2395 // force apply current routing 2396 applyRouting(true); 2397 return null; 2398 } 2399 mScreenState = params[0].intValue(); 2400 2401 mRoutingWakeLock.acquire(); 2402 try { 2403 applyRouting(false); 2404 } finally { 2405 mRoutingWakeLock.release(); 2406 } 2407 return null; 2408 } 2409 } 2410 } 2411 2412 private final BroadcastReceiver mOwnerReceiver = new BroadcastReceiver() { 2413 @Override 2414 public void onReceive(Context context, Intent intent) { 2415 String action = intent.getAction(); 2416 if (action.equals(Intent.ACTION_PACKAGE_REMOVED) || 2417 action.equals(Intent.ACTION_PACKAGE_ADDED) || 2418 action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE) || 2419 action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) { 2420 updatePackageCache(); 2421 2422 if (action.equals(Intent.ACTION_PACKAGE_REMOVED)) { 2423 // Clear the NFCEE access cache in case a UID gets recycled 2424 mNfceeAccessControl.invalidateCache(); 2425 2426 boolean dataRemoved = intent.getBooleanExtra(Intent.EXTRA_DATA_REMOVED, false); 2427 if (dataRemoved) { 2428 Uri data = intent.getData(); 2429 if (data == null) return; 2430 String packageName = data.getSchemeSpecificPart(); 2431 2432 synchronized (NfcService.this) { 2433 if (mSePackages.contains(packageName)) { 2434 new EnableDisableTask().execute(TASK_EE_WIPE); 2435 mSePackages.remove(packageName); 2436 } 2437 } 2438 } 2439 } 2440 } else if (action.equals(ACTION_MASTER_CLEAR_NOTIFICATION)) { 2441 EnableDisableTask eeWipeTask = new EnableDisableTask(); 2442 eeWipeTask.execute(TASK_EE_WIPE); 2443 try { 2444 eeWipeTask.get(); // blocks until EE wipe is complete 2445 } catch (ExecutionException e) { 2446 Log.w(TAG, "failed to wipe NFC-EE"); 2447 } catch (InterruptedException e) { 2448 Log.w(TAG, "failed to wipe NFC-EE"); 2449 } 2450 } 2451 } 2452 }; 2453 2454 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 2455 @Override 2456 public void onReceive(Context context, Intent intent) { 2457 String action = intent.getAction(); 2458 if (action.equals( 2459 NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) { 2460 // Perform applyRouting() in AsyncTask to serialize blocking calls 2461 new ApplyRoutingTask().execute(); 2462 } else if (action.equals(Intent.ACTION_SCREEN_ON) 2463 || action.equals(Intent.ACTION_SCREEN_OFF) 2464 || action.equals(Intent.ACTION_USER_PRESENT)) { 2465 // Perform applyRouting() in AsyncTask to serialize blocking calls 2466 int screenState = SCREEN_STATE_OFF; 2467 if (action.equals(Intent.ACTION_SCREEN_OFF)) { 2468 screenState = SCREEN_STATE_OFF; 2469 } else if (action.equals(Intent.ACTION_SCREEN_ON)) { 2470 screenState = mKeyguard.isKeyguardLocked() ? 2471 SCREEN_STATE_ON_LOCKED : SCREEN_STATE_ON_UNLOCKED; 2472 } else if (action.equals(Intent.ACTION_USER_PRESENT)) { 2473 screenState = SCREEN_STATE_ON_UNLOCKED; 2474 } 2475 new ApplyRoutingTask().execute(Integer.valueOf(screenState)); 2476 } else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) { 2477 boolean isAirplaneModeOn = intent.getBooleanExtra("state", false); 2478 // Query the airplane mode from Settings.System just to make sure that 2479 // some random app is not sending this intent 2480 if (isAirplaneModeOn != isAirplaneModeOn()) { 2481 return; 2482 } 2483 if (!mIsAirplaneSensitive) { 2484 return; 2485 } 2486 mPrefsEditor.putBoolean(PREF_AIRPLANE_OVERRIDE, false); 2487 mPrefsEditor.apply(); 2488 if (isAirplaneModeOn) { 2489 new EnableDisableTask().execute(TASK_DISABLE); 2490 } else if (!isAirplaneModeOn && mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT)) { 2491 new EnableDisableTask().execute(TASK_ENABLE); 2492 } 2493 } else if (action.equals(Intent.ACTION_USER_SWITCHED)) { 2494 mP2pLinkManager.onUserSwitched(); 2495 if (mIsHceCapable) { 2496 mAidCache.invalidateCache(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); 2497 } 2498 } 2499 } 2500 }; 2501 2502 /** Returns true if airplane mode is currently on */ 2503 boolean isAirplaneModeOn() { 2504 return Settings.System.getInt(mContentResolver, 2505 Settings.Global.AIRPLANE_MODE_ON, 0) == 1; 2506 } 2507 2508 /** for debugging only - no i18n */ 2509 static String stateToString(int state) { 2510 switch (state) { 2511 case NfcAdapter.STATE_OFF: 2512 return "off"; 2513 case NfcAdapter.STATE_TURNING_ON: 2514 return "turning on"; 2515 case NfcAdapter.STATE_ON: 2516 return "on"; 2517 case NfcAdapter.STATE_TURNING_OFF: 2518 return "turning off"; 2519 default: 2520 return "<error>"; 2521 } 2522 } 2523 2524 /** For debugging only - no i18n */ 2525 static String screenStateToString(int screenState) { 2526 switch (screenState) { 2527 case SCREEN_STATE_OFF: 2528 return "OFF"; 2529 case SCREEN_STATE_ON_LOCKED: 2530 return "ON_LOCKED"; 2531 case SCREEN_STATE_ON_UNLOCKED: 2532 return "ON_UNLOCKED"; 2533 default: 2534 return "UNKNOWN"; 2535 } 2536 } 2537 2538 void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2539 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 2540 != PackageManager.PERMISSION_GRANTED) { 2541 pw.println("Permission Denial: can't dump nfc from from pid=" 2542 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2543 + " without permission " + android.Manifest.permission.DUMP); 2544 return; 2545 } 2546 2547 synchronized (this) { 2548 pw.println("mState=" + stateToString(mState)); 2549 pw.println("mIsZeroClickRequested=" + mIsNdefPushEnabled); 2550 pw.println("mScreenState=" + screenStateToString(mScreenState)); 2551 pw.println("mNfcPollingEnabled=" + mNfcPollingEnabled); 2552 pw.println("mNfceeRouteEnabled=" + mNfceeRouteEnabled); 2553 pw.println("mIsAirplaneSensitive=" + mIsAirplaneSensitive); 2554 pw.println("mIsAirplaneToggleable=" + mIsAirplaneToggleable); 2555 pw.println("mOpenEe=" + mOpenEe); 2556 mP2pLinkManager.dump(fd, pw, args); 2557 if (mIsHceCapable) { 2558 mAidCache.dump(fd, pw, args); 2559 } 2560 mNfceeAccessControl.dump(fd, pw, args); 2561 mNfcDispatcher.dump(fd, pw, args); 2562 pw.println(mDeviceHost.dump()); 2563 2564 } 2565 } 2566 } 2567