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.dhimpl.NativeNfcManager; 27 import com.android.nfc.dhimpl.NativeNfcSecureElement; 28 29 import android.app.Application; 30 import android.app.KeyguardManager; 31 import android.app.PendingIntent; 32 import android.content.BroadcastReceiver; 33 import android.content.ContentResolver; 34 import android.content.Context; 35 import android.content.Intent; 36 import android.content.IntentFilter; 37 import android.content.SharedPreferences; 38 import android.content.pm.PackageInfo; 39 import android.content.pm.PackageManager; 40 import android.media.AudioManager; 41 import android.media.SoundPool; 42 import android.net.Uri; 43 import android.nfc.ErrorCodes; 44 import android.nfc.FormatException; 45 import android.nfc.INdefPushCallback; 46 import android.nfc.INfcAdapter; 47 import android.nfc.INfcAdapterExtras; 48 import android.nfc.INfcTag; 49 import android.nfc.NdefMessage; 50 import android.nfc.NfcAdapter; 51 import android.nfc.Tag; 52 import android.nfc.TechListParcel; 53 import android.nfc.TransceiveResult; 54 import android.nfc.tech.Ndef; 55 import android.nfc.tech.TagTechnology; 56 import android.os.AsyncTask; 57 import android.os.Binder; 58 import android.os.Bundle; 59 import android.os.Handler; 60 import android.os.IBinder; 61 import android.os.Message; 62 import android.os.PowerManager; 63 import android.os.Process; 64 import android.os.RemoteException; 65 import android.os.ServiceManager; 66 import android.os.UserHandle; 67 import android.provider.Settings; 68 import android.util.Log; 69 70 import java.io.FileDescriptor; 71 import java.io.IOException; 72 import java.io.PrintWriter; 73 import java.util.Arrays; 74 import java.util.HashMap; 75 import java.util.HashSet; 76 import java.util.List; 77 import java.util.concurrent.ExecutionException; 78 79 public class NfcService implements DeviceHostListener { 80 private static final String ACTION_MASTER_CLEAR_NOTIFICATION = "android.intent.action.MASTER_CLEAR_NOTIFICATION"; 81 82 static final boolean DBG = false; 83 static final String TAG = "NfcService"; 84 85 public static final String SERVICE_NAME = "nfc"; 86 87 /** Regular NFC permission */ 88 private static final String NFC_PERM = android.Manifest.permission.NFC; 89 private static final String NFC_PERM_ERROR = "NFC permission required"; 90 91 /** NFC ADMIN permission - only for system apps */ 92 private static final String ADMIN_PERM = android.Manifest.permission.WRITE_SECURE_SETTINGS; 93 private static final String ADMIN_PERM_ERROR = "WRITE_SECURE_SETTINGS permission required"; 94 95 public static final String PREF = "NfcServicePrefs"; 96 97 static final String PREF_NFC_ON = "nfc_on"; 98 static final boolean NFC_ON_DEFAULT = true; 99 static final String PREF_NDEF_PUSH_ON = "ndef_push_on"; 100 static final boolean NDEF_PUSH_ON_DEFAULT = true; 101 static final String PREF_FIRST_BEAM = "first_beam"; 102 static final String PREF_FIRST_BOOT = "first_boot"; 103 static final String PREF_AIRPLANE_OVERRIDE = "airplane_override"; 104 105 static final int MSG_NDEF_TAG = 0; 106 static final int MSG_CARD_EMULATION = 1; 107 static final int MSG_LLCP_LINK_ACTIVATION = 2; 108 static final int MSG_LLCP_LINK_DEACTIVATED = 3; 109 static final int MSG_TARGET_DESELECTED = 4; 110 static final int MSG_MOCK_NDEF = 7; 111 static final int MSG_SE_FIELD_ACTIVATED = 8; 112 static final int MSG_SE_FIELD_DEACTIVATED = 9; 113 static final int MSG_SE_APDU_RECEIVED = 10; 114 static final int MSG_SE_EMV_CARD_REMOVAL = 11; 115 static final int MSG_SE_MIFARE_ACCESS = 12; 116 static final int MSG_SE_LISTEN_ACTIVATED = 13; 117 static final int MSG_SE_LISTEN_DEACTIVATED = 14; 118 119 static final int TASK_ENABLE = 1; 120 static final int TASK_DISABLE = 2; 121 static final int TASK_BOOT = 3; 122 static final int TASK_EE_WIPE = 4; 123 124 // Screen state, used by mScreenState 125 static final int SCREEN_STATE_UNKNOWN = 0; 126 static final int SCREEN_STATE_OFF = 1; 127 static final int SCREEN_STATE_ON_LOCKED = 2; 128 static final int SCREEN_STATE_ON_UNLOCKED = 3; 129 130 // Copied from com.android.nfc_extras to avoid library dependency 131 // Must keep in sync with com.android.nfc_extras 132 static final int ROUTE_OFF = 1; 133 static final int ROUTE_ON_WHEN_SCREEN_ON = 2; 134 135 /** minimum screen state that enables NFC polling (discovery) */ 136 static final int POLLING_MODE = SCREEN_STATE_ON_UNLOCKED; 137 138 // Time to wait for NFC controller to initialize before watchdog 139 // goes off. This time is chosen large, because firmware download 140 // may be a part of initialization. 141 static final int INIT_WATCHDOG_MS = 90000; 142 143 // Time to wait for routing to be applied before watchdog 144 // goes off 145 static final int ROUTING_WATCHDOG_MS = 10000; 146 147 // for use with playSound() 148 public static final int SOUND_START = 0; 149 public static final int SOUND_END = 1; 150 public static final int SOUND_ERROR = 2; 151 152 public static final String ACTION_RF_FIELD_ON_DETECTED = 153 "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED"; 154 public static final String ACTION_RF_FIELD_OFF_DETECTED = 155 "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED"; 156 public static final String ACTION_AID_SELECTED = 157 "com.android.nfc_extras.action.AID_SELECTED"; 158 public static final String EXTRA_AID = "com.android.nfc_extras.extra.AID"; 159 160 public static final String ACTION_APDU_RECEIVED = 161 "com.android.nfc_extras.action.APDU_RECEIVED"; 162 public static final String EXTRA_APDU_BYTES = 163 "com.android.nfc_extras.extra.APDU_BYTES"; 164 165 public static final String ACTION_EMV_CARD_REMOVAL = 166 "com.android.nfc_extras.action.EMV_CARD_REMOVAL"; 167 168 public static final String ACTION_MIFARE_ACCESS_DETECTED = 169 "com.android.nfc_extras.action.MIFARE_ACCESS_DETECTED"; 170 public static final String EXTRA_MIFARE_BLOCK = 171 "com.android.nfc_extras.extra.MIFARE_BLOCK"; 172 173 public static final String ACTION_SE_LISTEN_ACTIVATED = 174 "com.android.nfc_extras.action.SE_LISTEN_ACTIVATED"; 175 public static final String ACTION_SE_LISTEN_DEACTIVATED = 176 "com.android.nfc_extras.action.SE_LISTEN_DEACTIVATED"; 177 178 // NFC Execution Environment 179 // fields below are protected by this 180 private NativeNfcSecureElement mSecureElement; 181 private OpenSecureElement mOpenEe; // null when EE closed 182 private int mEeRoutingState; // contactless interface routing 183 184 // fields below must be used only on the UI thread and therefore aren't synchronized 185 boolean mP2pStarted = false; 186 187 // fields below are used in multiple threads and protected by synchronized(this) 188 final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>(); 189 // mSePackages holds packages that accessed the SE, but only for the owner user, 190 // as SE access is not granted for non-owner users. 191 HashSet<String> mSePackages = new HashSet<String>(); 192 int mScreenState; 193 boolean mIsNdefPushEnabled; 194 boolean mNfceeRouteEnabled; // current Device Host state of NFC-EE routing 195 boolean mNfcPollingEnabled; // current Device Host state of NFC-C polling 196 List<PackageInfo> mInstalledPackages; // cached version of installed packages 197 198 // mState is protected by this, however it is only modified in onCreate() 199 // and the default AsyncTask thread so it is read unprotected from that 200 // thread 201 int mState; // one of NfcAdapter.STATE_ON, STATE_TURNING_ON, etc 202 203 // fields below are final after onCreate() 204 Context mContext; 205 private DeviceHost mDeviceHost; 206 private SharedPreferences mPrefs; 207 private SharedPreferences.Editor mPrefsEditor; 208 private PowerManager.WakeLock mRoutingWakeLock; 209 private PowerManager.WakeLock mEeWakeLock; 210 211 int mStartSound; 212 int mEndSound; 213 int mErrorSound; 214 SoundPool mSoundPool; // playback synchronized on this 215 P2pLinkManager mP2pLinkManager; 216 TagService mNfcTagService; 217 NfcAdapterService mNfcAdapter; 218 NfcAdapterExtrasService mExtrasService; 219 boolean mIsAirplaneSensitive; 220 boolean mIsAirplaneToggleable; 221 NfceeAccessControl mNfceeAccessControl; 222 223 private NfcDispatcher mNfcDispatcher; 224 private PowerManager mPowerManager; 225 private KeyguardManager mKeyguard; 226 227 private static NfcService sService; 228 229 public static void enforceAdminPerm(Context context) { 230 context.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 231 } 232 233 public void enforceNfceeAdminPerm(String pkg) { 234 if (pkg == null) { 235 throw new SecurityException("caller must pass a package name"); 236 } 237 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 238 if (!mNfceeAccessControl.check(Binder.getCallingUid(), pkg)) { 239 throw new SecurityException(NfceeAccessControl.NFCEE_ACCESS_PATH + 240 " denies NFCEE access to " + pkg); 241 } 242 if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) { 243 throw new SecurityException("only the owner is allowed to call SE APIs"); 244 } 245 } 246 247 public static NfcService getInstance() { 248 return sService; 249 } 250 251 @Override 252 public void onRemoteEndpointDiscovered(TagEndpoint tag) { 253 sendMessage(NfcService.MSG_NDEF_TAG, tag); 254 } 255 256 /** 257 * Notifies transaction 258 */ 259 @Override 260 public void onCardEmulationDeselected() { 261 sendMessage(NfcService.MSG_TARGET_DESELECTED, null); 262 } 263 264 /** 265 * Notifies transaction 266 */ 267 @Override 268 public void onCardEmulationAidSelected(byte[] aid) { 269 sendMessage(NfcService.MSG_CARD_EMULATION, aid); 270 } 271 272 /** 273 * Notifies P2P Device detected, to activate LLCP link 274 */ 275 @Override 276 public void onLlcpLinkActivated(NfcDepEndpoint device) { 277 sendMessage(NfcService.MSG_LLCP_LINK_ACTIVATION, device); 278 } 279 280 /** 281 * Notifies P2P Device detected, to activate LLCP link 282 */ 283 @Override 284 public void onLlcpLinkDeactivated(NfcDepEndpoint device) { 285 sendMessage(NfcService.MSG_LLCP_LINK_DEACTIVATED, device); 286 } 287 288 @Override 289 public void onRemoteFieldActivated() { 290 sendMessage(NfcService.MSG_SE_FIELD_ACTIVATED, null); 291 } 292 293 @Override 294 public void onRemoteFieldDeactivated() { 295 sendMessage(NfcService.MSG_SE_FIELD_DEACTIVATED, null); 296 } 297 298 @Override 299 public void onSeListenActivated() { 300 sendMessage(NfcService.MSG_SE_LISTEN_ACTIVATED, null); 301 } 302 303 @Override 304 public void onSeListenDeactivated() { 305 sendMessage(NfcService.MSG_SE_LISTEN_DEACTIVATED, null); 306 } 307 308 309 @Override 310 public void onSeApduReceived(byte[] apdu) { 311 sendMessage(NfcService.MSG_SE_APDU_RECEIVED, apdu); 312 } 313 314 @Override 315 public void onSeEmvCardRemoval() { 316 sendMessage(NfcService.MSG_SE_EMV_CARD_REMOVAL, null); 317 } 318 319 @Override 320 public void onSeMifareAccess(byte[] block) { 321 sendMessage(NfcService.MSG_SE_MIFARE_ACCESS, block); 322 } 323 324 public NfcService(Application nfcApplication) { 325 mNfcTagService = new TagService(); 326 mNfcAdapter = new NfcAdapterService(); 327 mExtrasService = new NfcAdapterExtrasService(); 328 329 Log.i(TAG, "Starting NFC service"); 330 331 sService = this; 332 333 mContext = nfcApplication; 334 mDeviceHost = new NativeNfcManager(mContext, this); 335 336 HandoverManager handoverManager = new HandoverManager(mContext); 337 mNfcDispatcher = new NfcDispatcher(mContext, handoverManager); 338 339 mP2pLinkManager = new P2pLinkManager(mContext, handoverManager, 340 mDeviceHost.getDefaultLlcpMiu(), mDeviceHost.getDefaultLlcpRwSize()); 341 342 mSecureElement = new NativeNfcSecureElement(mContext); 343 mEeRoutingState = ROUTE_OFF; 344 345 mNfceeAccessControl = new NfceeAccessControl(mContext); 346 347 mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE); 348 mPrefsEditor = mPrefs.edit(); 349 350 mState = NfcAdapter.STATE_OFF; 351 mIsNdefPushEnabled = mPrefs.getBoolean(PREF_NDEF_PUSH_ON, NDEF_PUSH_ON_DEFAULT); 352 353 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 354 355 mRoutingWakeLock = mPowerManager.newWakeLock( 356 PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mRoutingWakeLock"); 357 mEeWakeLock = mPowerManager.newWakeLock( 358 PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mEeWakeLock"); 359 360 mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); 361 mScreenState = checkScreenState(); 362 363 ServiceManager.addService(SERVICE_NAME, mNfcAdapter); 364 365 // Intents only for owner 366 IntentFilter ownerFilter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION); 367 ownerFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); 368 ownerFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 369 ownerFilter.addAction(ACTION_MASTER_CLEAR_NOTIFICATION); 370 371 mContext.registerReceiver(mOwnerReceiver, ownerFilter); 372 373 ownerFilter = new IntentFilter(); 374 ownerFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 375 ownerFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 376 ownerFilter.addDataScheme("package"); 377 378 mContext.registerReceiver(mOwnerReceiver, ownerFilter); 379 380 // Intents for all users 381 IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION); 382 filter.addAction(Intent.ACTION_SCREEN_OFF); 383 filter.addAction(Intent.ACTION_SCREEN_ON); 384 filter.addAction(Intent.ACTION_USER_PRESENT); 385 registerForAirplaneMode(filter); 386 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null); 387 388 updatePackageCache(); 389 390 new EnableDisableTask().execute(TASK_BOOT); // do blocking boot tasks 391 } 392 393 void initSoundPool() { 394 synchronized(this) { 395 if (mSoundPool == null) { 396 mSoundPool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0); 397 mStartSound = mSoundPool.load(mContext, R.raw.start, 1); 398 mEndSound = mSoundPool.load(mContext, R.raw.end, 1); 399 mErrorSound = mSoundPool.load(mContext, R.raw.error, 1); 400 } 401 } 402 } 403 404 void releaseSoundPool() { 405 synchronized(this) { 406 if (mSoundPool != null) { 407 mSoundPool.release(); 408 mSoundPool = null; 409 } 410 } 411 } 412 413 void registerForAirplaneMode(IntentFilter filter) { 414 final ContentResolver resolver = mContext.getContentResolver(); 415 final String airplaneModeRadios = Settings.System.getString(resolver, 416 Settings.System.AIRPLANE_MODE_RADIOS); 417 final String toggleableRadios = Settings.System.getString(resolver, 418 Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS); 419 420 mIsAirplaneSensitive = airplaneModeRadios == null ? true : 421 airplaneModeRadios.contains(Settings.System.RADIO_NFC); 422 mIsAirplaneToggleable = toggleableRadios == null ? false : 423 toggleableRadios.contains(Settings.System.RADIO_NFC); 424 425 if (mIsAirplaneSensitive) { 426 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); 427 } 428 } 429 430 void updatePackageCache() { 431 PackageManager pm = mContext.getPackageManager(); 432 List<PackageInfo> packages = pm.getInstalledPackages(0, UserHandle.USER_OWNER); 433 synchronized (this) { 434 mInstalledPackages = packages; 435 } 436 } 437 438 int checkScreenState() { 439 if (!mPowerManager.isScreenOn()) { 440 return SCREEN_STATE_OFF; 441 } else if (mKeyguard.isKeyguardLocked()) { 442 return SCREEN_STATE_ON_LOCKED; 443 } else { 444 return SCREEN_STATE_ON_UNLOCKED; 445 } 446 } 447 448 int doOpenSecureElementConnection() { 449 mEeWakeLock.acquire(); 450 try { 451 return mSecureElement.doOpenSecureElementConnection(); 452 } finally { 453 mEeWakeLock.release(); 454 } 455 } 456 457 byte[] doTransceive(int handle, byte[] cmd) { 458 mEeWakeLock.acquire(); 459 try { 460 return doTransceiveNoLock(handle, cmd); 461 } finally { 462 mEeWakeLock.release(); 463 } 464 } 465 466 byte[] doTransceiveNoLock(int handle, byte[] cmd) { 467 return mSecureElement.doTransceive(handle, cmd); 468 } 469 470 void doDisconnect(int handle) { 471 mEeWakeLock.acquire(); 472 try { 473 mSecureElement.doDisconnect(handle); 474 } finally { 475 mEeWakeLock.release(); 476 } 477 } 478 479 /** 480 * Manages tasks that involve turning on/off the NFC controller. 481 * 482 * <p>All work that might turn the NFC adapter on or off must be done 483 * through this task, to keep the handling of mState simple. 484 * In other words, mState is only modified in these tasks (and we 485 * don't need a lock to read it in these tasks). 486 * 487 * <p>These tasks are all done on the same AsyncTask background 488 * thread, so they are serialized. Each task may temporarily transition 489 * mState to STATE_TURNING_OFF or STATE_TURNING_ON, but must exit in 490 * either STATE_ON or STATE_OFF. This way each task can be guaranteed 491 * of starting in either STATE_OFF or STATE_ON, without needing to hold 492 * NfcService.this for the entire task. 493 * 494 * <p>AsyncTask's are also implicitly queued. This is useful for corner 495 * cases like turning airplane mode on while TASK_ENABLE is in progress. 496 * The TASK_DISABLE triggered by airplane mode will be correctly executed 497 * immediately after TASK_ENABLE is complete. This seems like the most sane 498 * way to deal with these situations. 499 * 500 * <p>{@link #TASK_ENABLE} enables the NFC adapter, without changing 501 * preferences 502 * <p>{@link #TASK_DISABLE} disables the NFC adapter, without changing 503 * preferences 504 * <p>{@link #TASK_BOOT} does first boot work and may enable NFC 505 * <p>{@link #TASK_EE_WIPE} wipes the Execution Environment, and in the 506 * process may temporarily enable the NFC adapter 507 */ 508 class EnableDisableTask extends AsyncTask<Integer, Void, Void> { 509 @Override 510 protected Void doInBackground(Integer... params) { 511 // Sanity check mState 512 switch (mState) { 513 case NfcAdapter.STATE_TURNING_OFF: 514 case NfcAdapter.STATE_TURNING_ON: 515 Log.e(TAG, "Processing EnableDisable task " + params[0] + " from bad state " + 516 mState); 517 return null; 518 } 519 520 /* AsyncTask sets this thread to THREAD_PRIORITY_BACKGROUND, 521 * override with the default. THREAD_PRIORITY_BACKGROUND causes 522 * us to service software I2C too slow for firmware download 523 * with the NXP PN544. 524 * TODO: move this to the DAL I2C layer in libnfc-nxp, since this 525 * problem only occurs on I2C platforms using PN544 526 */ 527 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 528 529 switch (params[0].intValue()) { 530 case TASK_ENABLE: 531 enableInternal(); 532 break; 533 case TASK_DISABLE: 534 disableInternal(); 535 break; 536 case TASK_BOOT: 537 Log.d(TAG,"checking on firmware download"); 538 boolean airplaneOverride = mPrefs.getBoolean(PREF_AIRPLANE_OVERRIDE, false); 539 if (mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT) && 540 (!mIsAirplaneSensitive || !isAirplaneModeOn() || airplaneOverride)) { 541 Log.d(TAG,"NFC is on. Doing normal stuff"); 542 enableInternal(); 543 } else { 544 Log.d(TAG,"NFC is off. Checking firmware version"); 545 mDeviceHost.checkFirmware(); 546 } 547 if (mPrefs.getBoolean(PREF_FIRST_BOOT, true)) { 548 Log.i(TAG, "First Boot"); 549 mPrefsEditor.putBoolean(PREF_FIRST_BOOT, false); 550 mPrefsEditor.apply(); 551 executeEeWipe(); 552 } 553 break; 554 case TASK_EE_WIPE: 555 executeEeWipe(); 556 break; 557 } 558 559 // Restore default AsyncTask priority 560 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 561 return null; 562 } 563 564 /** 565 * Enable NFC adapter functions. 566 * Does not toggle preferences. 567 */ 568 boolean enableInternal() { 569 if (mState == NfcAdapter.STATE_ON) { 570 return true; 571 } 572 Log.i(TAG, "Enabling NFC"); 573 updateState(NfcAdapter.STATE_TURNING_ON); 574 575 WatchDogThread watchDog = new WatchDogThread("enableInternal", INIT_WATCHDOG_MS); 576 watchDog.start(); 577 try { 578 mRoutingWakeLock.acquire(); 579 try { 580 if (!mDeviceHost.initialize()) { 581 Log.w(TAG, "Error enabling NFC"); 582 updateState(NfcAdapter.STATE_OFF); 583 return false; 584 } 585 } finally { 586 mRoutingWakeLock.release(); 587 } 588 } finally { 589 watchDog.cancel(); 590 } 591 592 synchronized(NfcService.this) { 593 mObjectMap.clear(); 594 595 mP2pLinkManager.enableDisable(mIsNdefPushEnabled, true); 596 updateState(NfcAdapter.STATE_ON); 597 } 598 599 initSoundPool(); 600 601 /* Start polling loop */ 602 603 applyRouting(true); 604 return true; 605 } 606 607 /** 608 * Disable all NFC adapter functions. 609 * Does not toggle preferences. 610 */ 611 boolean disableInternal() { 612 if (mState == NfcAdapter.STATE_OFF) { 613 return true; 614 } 615 Log.i(TAG, "Disabling NFC"); 616 updateState(NfcAdapter.STATE_TURNING_OFF); 617 618 /* Sometimes mDeviceHost.deinitialize() hangs, use a watch-dog. 619 * Implemented with a new thread (instead of a Handler or AsyncTask), 620 * because the UI Thread and AsyncTask thread-pools can also get hung 621 * when the NFC controller stops responding */ 622 WatchDogThread watchDog = new WatchDogThread("disableInternal", ROUTING_WATCHDOG_MS); 623 watchDog.start(); 624 625 mP2pLinkManager.enableDisable(false, false); 626 627 synchronized (NfcService.this) { 628 if (mOpenEe != null) { 629 try { 630 _nfcEeClose(-1, mOpenEe.binder); 631 } catch (IOException e) { } 632 } 633 } 634 635 // Stop watchdog if tag present 636 // A convenient way to stop the watchdog properly consists of 637 // disconnecting the tag. The polling loop shall be stopped before 638 // to avoid the tag being discovered again. 639 maybeDisconnectTarget(); 640 641 mNfcDispatcher.setForegroundDispatch(null, null, null); 642 643 boolean result = mDeviceHost.deinitialize(); 644 if (DBG) Log.d(TAG, "mDeviceHost.deinitialize() = " + result); 645 646 watchDog.cancel(); 647 648 updateState(NfcAdapter.STATE_OFF); 649 650 releaseSoundPool(); 651 652 return result; 653 } 654 655 void executeEeWipe() { 656 // TODO: read SE reset list from /system/etc 657 byte[][]apdus = mDeviceHost.getWipeApdus(); 658 659 if (apdus == null) { 660 Log.d(TAG, "No wipe APDUs found"); 661 return; 662 } 663 664 boolean tempEnable = mState == NfcAdapter.STATE_OFF; 665 // Hold a wake-lock over the entire wipe procedure 666 mEeWakeLock.acquire(); 667 try { 668 if (tempEnable && !enableInternal()) { 669 Log.w(TAG, "Could not enable NFC to wipe NFC-EE"); 670 return; 671 } 672 try { 673 // NFC enabled 674 int handle = 0; 675 try { 676 Log.i(TAG, "Executing SE wipe"); 677 handle = doOpenSecureElementConnection(); 678 if (handle == 0) { 679 Log.w(TAG, "Could not open the secure element"); 680 return; 681 } 682 // TODO: remove this hack 683 try { 684 Thread.sleep(1000); 685 } catch (InterruptedException e) { 686 // Ignore 687 } 688 689 mDeviceHost.setTimeout(TagTechnology.ISO_DEP, 10000); 690 try { 691 for (byte[] cmd : apdus) { 692 byte[] resp = doTransceiveNoLock(handle, cmd); 693 if (resp == null) { 694 Log.w(TAG, "Transceive failed, could not wipe NFC-EE"); 695 break; 696 } 697 } 698 } finally { 699 mDeviceHost.resetTimeouts(); 700 } 701 } finally { 702 if (handle != 0) { 703 doDisconnect(handle); 704 } 705 } 706 } finally { 707 if (tempEnable) { 708 disableInternal(); 709 } 710 } 711 } finally { 712 mEeWakeLock.release(); 713 } 714 Log.i(TAG, "SE wipe done"); 715 } 716 717 void updateState(int newState) { 718 synchronized (NfcService.this) { 719 if (newState == mState) { 720 return; 721 } 722 mState = newState; 723 Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED); 724 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 725 intent.putExtra(NfcAdapter.EXTRA_ADAPTER_STATE, mState); 726 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT); 727 } 728 } 729 } 730 731 void saveNfcOnSetting(boolean on) { 732 synchronized (NfcService.this) { 733 mPrefsEditor.putBoolean(PREF_NFC_ON, on); 734 mPrefsEditor.apply(); 735 } 736 } 737 738 public void playSound(int sound) { 739 synchronized (this) { 740 if (mSoundPool == null) { 741 Log.w(TAG, "Not playing sound when NFC is disabled"); 742 return; 743 } 744 switch (sound) { 745 case SOUND_START: 746 mSoundPool.play(mStartSound, 1.0f, 1.0f, 0, 0, 1.0f); 747 break; 748 case SOUND_END: 749 mSoundPool.play(mEndSound, 1.0f, 1.0f, 0, 0, 1.0f); 750 break; 751 case SOUND_ERROR: 752 mSoundPool.play(mErrorSound, 1.0f, 1.0f, 0, 0, 1.0f); 753 break; 754 } 755 } 756 } 757 758 759 final class NfcAdapterService extends INfcAdapter.Stub { 760 @Override 761 public boolean enable() throws RemoteException { 762 NfcService.enforceAdminPerm(mContext); 763 764 saveNfcOnSetting(true); 765 766 if (mIsAirplaneSensitive && isAirplaneModeOn()) { 767 if (!mIsAirplaneToggleable) { 768 Log.i(TAG, "denying enable() request (airplane mode)"); 769 return false; 770 } 771 // Make sure the override survives a reboot 772 mPrefsEditor.putBoolean(PREF_AIRPLANE_OVERRIDE, true); 773 mPrefsEditor.apply(); 774 } 775 new EnableDisableTask().execute(TASK_ENABLE); 776 777 return true; 778 } 779 780 @Override 781 public boolean disable(boolean saveState) throws RemoteException { 782 NfcService.enforceAdminPerm(mContext); 783 784 if (saveState) { 785 saveNfcOnSetting(false); 786 } 787 788 new EnableDisableTask().execute(TASK_DISABLE); 789 790 return true; 791 } 792 793 @Override 794 public boolean isNdefPushEnabled() throws RemoteException { 795 synchronized (NfcService.this) { 796 return mState == NfcAdapter.STATE_ON && mIsNdefPushEnabled; 797 } 798 } 799 800 @Override 801 public boolean enableNdefPush() throws RemoteException { 802 NfcService.enforceAdminPerm(mContext); 803 synchronized(NfcService.this) { 804 if (mIsNdefPushEnabled) { 805 return true; 806 } 807 Log.i(TAG, "enabling NDEF Push"); 808 mPrefsEditor.putBoolean(PREF_NDEF_PUSH_ON, true); 809 mPrefsEditor.apply(); 810 mIsNdefPushEnabled = true; 811 if (isNfcEnabled()) { 812 mP2pLinkManager.enableDisable(true, true); 813 } 814 } 815 return true; 816 } 817 818 @Override 819 public boolean disableNdefPush() throws RemoteException { 820 NfcService.enforceAdminPerm(mContext); 821 synchronized(NfcService.this) { 822 if (!mIsNdefPushEnabled) { 823 return true; 824 } 825 Log.i(TAG, "disabling NDEF Push"); 826 mPrefsEditor.putBoolean(PREF_NDEF_PUSH_ON, false); 827 mPrefsEditor.apply(); 828 mIsNdefPushEnabled = false; 829 if (isNfcEnabled()) { 830 mP2pLinkManager.enableDisable(false, true); 831 } 832 } 833 return true; 834 } 835 836 @Override 837 public void setForegroundDispatch(PendingIntent intent, 838 IntentFilter[] filters, TechListParcel techListsParcel) { 839 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 840 841 // Short-cut the disable path 842 if (intent == null && filters == null && techListsParcel == null) { 843 mNfcDispatcher.setForegroundDispatch(null, null, null); 844 return; 845 } 846 847 // Validate the IntentFilters 848 if (filters != null) { 849 if (filters.length == 0) { 850 filters = null; 851 } else { 852 for (IntentFilter filter : filters) { 853 if (filter == null) { 854 throw new IllegalArgumentException("null IntentFilter"); 855 } 856 } 857 } 858 } 859 860 // Validate the tech lists 861 String[][] techLists = null; 862 if (techListsParcel != null) { 863 techLists = techListsParcel.getTechLists(); 864 } 865 866 mNfcDispatcher.setForegroundDispatch(intent, filters, techLists); 867 } 868 869 @Override 870 public void setNdefPushCallback(INdefPushCallback callback) { 871 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 872 mP2pLinkManager.setNdefCallback(callback); 873 } 874 875 @Override 876 public INfcTag getNfcTagInterface() throws RemoteException { 877 return mNfcTagService; 878 } 879 880 @Override 881 public INfcAdapterExtras getNfcAdapterExtrasInterface(String pkg) { 882 NfcService.this.enforceNfceeAdminPerm(pkg); 883 return mExtrasService; 884 } 885 886 @Override 887 public int getState() throws RemoteException { 888 synchronized (NfcService.this) { 889 return mState; 890 } 891 } 892 893 @Override 894 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 895 NfcService.this.dump(fd, pw, args); 896 } 897 898 @Override 899 public void dispatch(Tag tag) throws RemoteException { 900 enforceAdminPerm(mContext); 901 mNfcDispatcher.dispatchTag(tag); 902 } 903 904 @Override 905 public void setP2pModes(int initiatorModes, int targetModes) throws RemoteException { 906 enforceAdminPerm(mContext); 907 908 mDeviceHost.setP2pInitiatorModes(initiatorModes); 909 mDeviceHost.setP2pTargetModes(targetModes); 910 mDeviceHost.disableDiscovery(); 911 mDeviceHost.enableDiscovery(); 912 } 913 } 914 915 final class TagService extends INfcTag.Stub { 916 @Override 917 public int close(int nativeHandle) throws RemoteException { 918 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 919 920 TagEndpoint tag = null; 921 922 if (!isNfcEnabled()) { 923 return ErrorCodes.ERROR_NOT_INITIALIZED; 924 } 925 926 /* find the tag in the hmap */ 927 tag = (TagEndpoint) findObject(nativeHandle); 928 if (tag != null) { 929 /* Remove the device from the hmap */ 930 unregisterObject(nativeHandle); 931 tag.disconnect(); 932 return ErrorCodes.SUCCESS; 933 } 934 /* Restart polling loop for notification */ 935 applyRouting(true); 936 return ErrorCodes.ERROR_DISCONNECT; 937 } 938 939 @Override 940 public int connect(int nativeHandle, int technology) throws RemoteException { 941 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 942 943 TagEndpoint tag = null; 944 945 if (!isNfcEnabled()) { 946 return ErrorCodes.ERROR_NOT_INITIALIZED; 947 } 948 949 /* find the tag in the hmap */ 950 tag = (TagEndpoint) findObject(nativeHandle); 951 if (tag == null) { 952 return ErrorCodes.ERROR_DISCONNECT; 953 } 954 955 if (!tag.isPresent()) { 956 return ErrorCodes.ERROR_DISCONNECT; 957 } 958 959 // Note that on most tags, all technologies are behind a single 960 // handle. This means that the connect at the lower levels 961 // will do nothing, as the tag is already connected to that handle. 962 if (tag.connect(technology)) { 963 return ErrorCodes.SUCCESS; 964 } else { 965 return ErrorCodes.ERROR_DISCONNECT; 966 } 967 } 968 969 @Override 970 public int reconnect(int nativeHandle) throws RemoteException { 971 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 972 973 TagEndpoint tag = null; 974 975 // Check if NFC is enabled 976 if (!isNfcEnabled()) { 977 return ErrorCodes.ERROR_NOT_INITIALIZED; 978 } 979 980 /* find the tag in the hmap */ 981 tag = (TagEndpoint) findObject(nativeHandle); 982 if (tag != null) { 983 if (tag.reconnect()) { 984 return ErrorCodes.SUCCESS; 985 } else { 986 return ErrorCodes.ERROR_DISCONNECT; 987 } 988 } 989 return ErrorCodes.ERROR_DISCONNECT; 990 } 991 992 @Override 993 public int[] getTechList(int nativeHandle) throws RemoteException { 994 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 995 996 // Check if NFC is enabled 997 if (!isNfcEnabled()) { 998 return null; 999 } 1000 1001 /* find the tag in the hmap */ 1002 TagEndpoint tag = (TagEndpoint) findObject(nativeHandle); 1003 if (tag != null) { 1004 return tag.getTechList(); 1005 } 1006 return null; 1007 } 1008 1009 @Override 1010 public boolean isPresent(int nativeHandle) throws RemoteException { 1011 TagEndpoint tag = null; 1012 1013 // Check if NFC is enabled 1014 if (!isNfcEnabled()) { 1015 return false; 1016 } 1017 1018 /* find the tag in the hmap */ 1019 tag = (TagEndpoint) findObject(nativeHandle); 1020 if (tag == null) { 1021 return false; 1022 } 1023 1024 return tag.isPresent(); 1025 } 1026 1027 @Override 1028 public boolean isNdef(int nativeHandle) throws RemoteException { 1029 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1030 1031 TagEndpoint tag = null; 1032 1033 // Check if NFC is enabled 1034 if (!isNfcEnabled()) { 1035 return false; 1036 } 1037 1038 /* find the tag in the hmap */ 1039 tag = (TagEndpoint) findObject(nativeHandle); 1040 int[] ndefInfo = new int[2]; 1041 if (tag == null) { 1042 return false; 1043 } 1044 return tag.checkNdef(ndefInfo); 1045 } 1046 1047 @Override 1048 public TransceiveResult transceive(int nativeHandle, byte[] data, boolean raw) 1049 throws RemoteException { 1050 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1051 1052 TagEndpoint tag = null; 1053 byte[] response; 1054 1055 // Check if NFC is enabled 1056 if (!isNfcEnabled()) { 1057 return null; 1058 } 1059 1060 /* find the tag in the hmap */ 1061 tag = (TagEndpoint) findObject(nativeHandle); 1062 if (tag != null) { 1063 // Check if length is within limits 1064 if (data.length > getMaxTransceiveLength(tag.getConnectedTechnology())) { 1065 return new TransceiveResult(TransceiveResult.RESULT_EXCEEDED_LENGTH, null); 1066 } 1067 int[] targetLost = new int[1]; 1068 response = tag.transceive(data, raw, targetLost); 1069 int result; 1070 if (response != null) { 1071 result = TransceiveResult.RESULT_SUCCESS; 1072 } else if (targetLost[0] == 1) { 1073 result = TransceiveResult.RESULT_TAGLOST; 1074 } else { 1075 result = TransceiveResult.RESULT_FAILURE; 1076 } 1077 return new TransceiveResult(result, response); 1078 } 1079 return null; 1080 } 1081 1082 @Override 1083 public NdefMessage ndefRead(int nativeHandle) throws RemoteException { 1084 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1085 1086 TagEndpoint tag; 1087 1088 // Check if NFC is enabled 1089 if (!isNfcEnabled()) { 1090 return null; 1091 } 1092 1093 /* find the tag in the hmap */ 1094 tag = (TagEndpoint) findObject(nativeHandle); 1095 if (tag != null) { 1096 byte[] buf = tag.readNdef(); 1097 if (buf == null) { 1098 return null; 1099 } 1100 1101 /* Create an NdefMessage */ 1102 try { 1103 return new NdefMessage(buf); 1104 } catch (FormatException e) { 1105 return null; 1106 } 1107 } 1108 return null; 1109 } 1110 1111 @Override 1112 public int ndefWrite(int nativeHandle, NdefMessage msg) throws RemoteException { 1113 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1114 1115 TagEndpoint tag; 1116 1117 // Check if NFC is enabled 1118 if (!isNfcEnabled()) { 1119 return ErrorCodes.ERROR_NOT_INITIALIZED; 1120 } 1121 1122 /* find the tag in the hmap */ 1123 tag = (TagEndpoint) findObject(nativeHandle); 1124 if (tag == null) { 1125 return ErrorCodes.ERROR_IO; 1126 } 1127 1128 if (msg == null) return ErrorCodes.ERROR_INVALID_PARAM; 1129 1130 if (tag.writeNdef(msg.toByteArray())) { 1131 return ErrorCodes.SUCCESS; 1132 } else { 1133 return ErrorCodes.ERROR_IO; 1134 } 1135 1136 } 1137 1138 @Override 1139 public boolean ndefIsWritable(int nativeHandle) throws RemoteException { 1140 throw new UnsupportedOperationException(); 1141 } 1142 1143 @Override 1144 public int ndefMakeReadOnly(int nativeHandle) throws RemoteException { 1145 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1146 1147 TagEndpoint tag; 1148 1149 // Check if NFC is enabled 1150 if (!isNfcEnabled()) { 1151 return ErrorCodes.ERROR_NOT_INITIALIZED; 1152 } 1153 1154 /* find the tag in the hmap */ 1155 tag = (TagEndpoint) findObject(nativeHandle); 1156 if (tag == null) { 1157 return ErrorCodes.ERROR_IO; 1158 } 1159 1160 if (tag.makeReadOnly()) { 1161 return ErrorCodes.SUCCESS; 1162 } else { 1163 return ErrorCodes.ERROR_IO; 1164 } 1165 } 1166 1167 @Override 1168 public int formatNdef(int nativeHandle, byte[] key) throws RemoteException { 1169 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1170 1171 TagEndpoint tag; 1172 1173 // Check if NFC is enabled 1174 if (!isNfcEnabled()) { 1175 return ErrorCodes.ERROR_NOT_INITIALIZED; 1176 } 1177 1178 /* find the tag in the hmap */ 1179 tag = (TagEndpoint) findObject(nativeHandle); 1180 if (tag == null) { 1181 return ErrorCodes.ERROR_IO; 1182 } 1183 1184 if (tag.formatNdef(key)) { 1185 return ErrorCodes.SUCCESS; 1186 } else { 1187 return ErrorCodes.ERROR_IO; 1188 } 1189 } 1190 1191 @Override 1192 public Tag rediscover(int nativeHandle) throws RemoteException { 1193 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1194 1195 TagEndpoint tag = null; 1196 1197 // Check if NFC is enabled 1198 if (!isNfcEnabled()) { 1199 return null; 1200 } 1201 1202 /* find the tag in the hmap */ 1203 tag = (TagEndpoint) findObject(nativeHandle); 1204 if (tag != null) { 1205 // For now the prime usecase for rediscover() is to be able 1206 // to access the NDEF technology after formatting without 1207 // having to remove the tag from the field, or similar 1208 // to have access to NdefFormatable in case low-level commands 1209 // were used to remove NDEF. So instead of doing a full stack 1210 // rediscover (which is poorly supported at the moment anyway), 1211 // we simply remove these two technologies and detect them 1212 // again. 1213 tag.removeTechnology(TagTechnology.NDEF); 1214 tag.removeTechnology(TagTechnology.NDEF_FORMATABLE); 1215 tag.findAndReadNdef(); 1216 // Build a new Tag object to return 1217 Tag newTag = new Tag(tag.getUid(), tag.getTechList(), 1218 tag.getTechExtras(), tag.getHandle(), this); 1219 return newTag; 1220 } 1221 return null; 1222 } 1223 1224 @Override 1225 public int setTimeout(int tech, int timeout) throws RemoteException { 1226 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1227 boolean success = mDeviceHost.setTimeout(tech, timeout); 1228 if (success) { 1229 return ErrorCodes.SUCCESS; 1230 } else { 1231 return ErrorCodes.ERROR_INVALID_PARAM; 1232 } 1233 } 1234 1235 @Override 1236 public int getTimeout(int tech) throws RemoteException { 1237 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1238 1239 return mDeviceHost.getTimeout(tech); 1240 } 1241 1242 @Override 1243 public void resetTimeouts() throws RemoteException { 1244 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1245 1246 mDeviceHost.resetTimeouts(); 1247 } 1248 1249 @Override 1250 public boolean canMakeReadOnly(int ndefType) throws RemoteException { 1251 return mDeviceHost.canMakeReadOnly(ndefType); 1252 } 1253 1254 @Override 1255 public int getMaxTransceiveLength(int tech) throws RemoteException { 1256 return mDeviceHost.getMaxTransceiveLength(tech); 1257 } 1258 1259 @Override 1260 public boolean getExtendedLengthApdusSupported() throws RemoteException { 1261 return mDeviceHost.getExtendedLengthApdusSupported(); 1262 } 1263 } 1264 1265 void _nfcEeClose(int callingPid, IBinder binder) throws IOException { 1266 // Blocks until a pending open() or transceive() times out. 1267 //TODO: This is incorrect behavior - the close should interrupt pending 1268 // operations. However this is not supported by current hardware. 1269 1270 synchronized (NfcService.this) { 1271 if (!isNfcEnabledOrShuttingDown()) { 1272 throw new IOException("NFC adapter is disabled"); 1273 } 1274 if (mOpenEe == null) { 1275 throw new IOException("NFC EE closed"); 1276 } 1277 if (callingPid != -1 && callingPid != mOpenEe.pid) { 1278 throw new SecurityException("Wrong PID"); 1279 } 1280 if (mOpenEe.binder != binder) { 1281 throw new SecurityException("Wrong binder handle"); 1282 } 1283 1284 binder.unlinkToDeath(mOpenEe, 0); 1285 mDeviceHost.resetTimeouts(); 1286 doDisconnect(mOpenEe.handle); 1287 mOpenEe = null; 1288 1289 applyRouting(true); 1290 } 1291 } 1292 1293 final class NfcAdapterExtrasService extends INfcAdapterExtras.Stub { 1294 private Bundle writeNoException() { 1295 Bundle p = new Bundle(); 1296 p.putInt("e", 0); 1297 return p; 1298 } 1299 private Bundle writeIoException(IOException e) { 1300 Bundle p = new Bundle(); 1301 p.putInt("e", -1); 1302 p.putString("m", e.getMessage()); 1303 return p; 1304 } 1305 1306 @Override 1307 public Bundle open(String pkg, IBinder b) throws RemoteException { 1308 NfcService.this.enforceNfceeAdminPerm(pkg); 1309 1310 Bundle result; 1311 try { 1312 _open(b); 1313 result = writeNoException(); 1314 } catch (IOException e) { 1315 result = writeIoException(e); 1316 } 1317 return result; 1318 } 1319 1320 private void _open(IBinder b) throws IOException { 1321 synchronized(NfcService.this) { 1322 if (!isNfcEnabled()) { 1323 throw new IOException("NFC adapter is disabled"); 1324 } 1325 if (mOpenEe != null) { 1326 throw new IOException("NFC EE already open"); 1327 } 1328 1329 int handle = doOpenSecureElementConnection(); 1330 if (handle == 0) { 1331 throw new IOException("NFC EE failed to open"); 1332 } 1333 mDeviceHost.setTimeout(TagTechnology.ISO_DEP, 30000); 1334 1335 mOpenEe = new OpenSecureElement(getCallingPid(), handle, b); 1336 try { 1337 b.linkToDeath(mOpenEe, 0); 1338 } catch (RemoteException e) { 1339 mOpenEe.binderDied(); 1340 } 1341 1342 // Add the calling package to the list of packages that have accessed 1343 // the secure element. 1344 for (String packageName : mContext.getPackageManager().getPackagesForUid(getCallingUid())) { 1345 mSePackages.add(packageName); 1346 } 1347 } 1348 } 1349 1350 @Override 1351 public Bundle close(String pkg, IBinder binder) throws RemoteException { 1352 NfcService.this.enforceNfceeAdminPerm(pkg); 1353 1354 Bundle result; 1355 try { 1356 _nfcEeClose(getCallingPid(), binder); 1357 result = writeNoException(); 1358 } catch (IOException e) { 1359 result = writeIoException(e); 1360 } 1361 return result; 1362 } 1363 1364 @Override 1365 public Bundle transceive(String pkg, byte[] in) throws RemoteException { 1366 NfcService.this.enforceNfceeAdminPerm(pkg); 1367 1368 Bundle result; 1369 byte[] out; 1370 try { 1371 out = _transceive(in); 1372 result = writeNoException(); 1373 result.putByteArray("out", out); 1374 } catch (IOException e) { 1375 result = writeIoException(e); 1376 } 1377 return result; 1378 } 1379 1380 private byte[] _transceive(byte[] data) throws IOException { 1381 synchronized(NfcService.this) { 1382 if (!isNfcEnabled()) { 1383 throw new IOException("NFC is not enabled"); 1384 } 1385 if (mOpenEe == null) { 1386 throw new IOException("NFC EE is not open"); 1387 } 1388 if (getCallingPid() != mOpenEe.pid) { 1389 throw new SecurityException("Wrong PID"); 1390 } 1391 } 1392 1393 return doTransceive(mOpenEe.handle, data); 1394 } 1395 1396 @Override 1397 public int getCardEmulationRoute(String pkg) throws RemoteException { 1398 NfcService.this.enforceNfceeAdminPerm(pkg); 1399 return mEeRoutingState; 1400 } 1401 1402 @Override 1403 public void setCardEmulationRoute(String pkg, int route) throws RemoteException { 1404 NfcService.this.enforceNfceeAdminPerm(pkg); 1405 mEeRoutingState = route; 1406 ApplyRoutingTask applyRoutingTask = new ApplyRoutingTask(); 1407 applyRoutingTask.execute(); 1408 try { 1409 // Block until route is set 1410 applyRoutingTask.get(); 1411 } catch (ExecutionException e) { 1412 Log.e(TAG, "failed to set card emulation mode"); 1413 } catch (InterruptedException e) { 1414 Log.e(TAG, "failed to set card emulation mode"); 1415 } 1416 } 1417 1418 @Override 1419 public void authenticate(String pkg, byte[] token) throws RemoteException { 1420 NfcService.this.enforceNfceeAdminPerm(pkg); 1421 } 1422 1423 @Override 1424 public String getDriverName(String pkg) throws RemoteException { 1425 NfcService.this.enforceNfceeAdminPerm(pkg); 1426 return mDeviceHost.getName(); 1427 } 1428 } 1429 1430 /** resources kept while secure element is open */ 1431 private class OpenSecureElement implements IBinder.DeathRecipient { 1432 public int pid; // pid that opened SE 1433 // binder handle used for DeathReceipient. Must keep 1434 // a reference to this, otherwise it can get GC'd and 1435 // the binder stub code might create a different BinderProxy 1436 // for the same remote IBinder, causing mismatched 1437 // link()/unlink() 1438 public IBinder binder; 1439 public int handle; // low-level handle 1440 public OpenSecureElement(int pid, int handle, IBinder binder) { 1441 this.pid = pid; 1442 this.handle = handle; 1443 this.binder = binder; 1444 } 1445 @Override 1446 public void binderDied() { 1447 synchronized (NfcService.this) { 1448 Log.i(TAG, "Tracked app " + pid + " died"); 1449 pid = -1; 1450 try { 1451 _nfcEeClose(-1, binder); 1452 } catch (IOException e) { /* already closed */ } 1453 } 1454 } 1455 @Override 1456 public String toString() { 1457 return new StringBuilder('@').append(Integer.toHexString(hashCode())).append("[pid=") 1458 .append(pid).append(" handle=").append(handle).append("]").toString(); 1459 } 1460 } 1461 1462 boolean isNfcEnabledOrShuttingDown() { 1463 synchronized (this) { 1464 return (mState == NfcAdapter.STATE_ON || mState == NfcAdapter.STATE_TURNING_OFF); 1465 } 1466 } 1467 1468 boolean isNfcEnabled() { 1469 synchronized (this) { 1470 return mState == NfcAdapter.STATE_ON; 1471 } 1472 } 1473 1474 class WatchDogThread extends Thread { 1475 boolean mWatchDogCanceled = false; 1476 final int mTimeout; 1477 1478 public WatchDogThread(String threadName, int timeout) { 1479 super(threadName); 1480 mTimeout = timeout; 1481 } 1482 1483 @Override 1484 public void run() { 1485 boolean slept = false; 1486 while (!slept) { 1487 try { 1488 Thread.sleep(mTimeout); 1489 slept = true; 1490 } catch (InterruptedException e) { } 1491 } 1492 synchronized (this) { 1493 if (!mWatchDogCanceled) { 1494 // Trigger watch-dog 1495 Log.e(TAG, "Watchdog fired: name=" + getName() + " threadId=" + 1496 getId() + " timeout=" + mTimeout); 1497 mDeviceHost.doAbort(); 1498 } 1499 } 1500 } 1501 public synchronized void cancel() { 1502 mWatchDogCanceled = true; 1503 } 1504 } 1505 1506 /** 1507 * Read mScreenState and apply NFC-C polling and NFC-EE routing 1508 */ 1509 void applyRouting(boolean force) { 1510 synchronized (this) { 1511 if (!isNfcEnabledOrShuttingDown() || mOpenEe != null) { 1512 // PN544 cannot be reconfigured while EE is open 1513 return; 1514 } 1515 WatchDogThread watchDog = new WatchDogThread("applyRouting", ROUTING_WATCHDOG_MS); 1516 1517 try { 1518 watchDog.start(); 1519 1520 if (mDeviceHost.enablePN544Quirks() && mScreenState == SCREEN_STATE_OFF) { 1521 /* TODO undo this after the LLCP stack is fixed. 1522 * Use a different sequence when turning the screen off to 1523 * workaround race conditions in pn544 libnfc. The race occurs 1524 * when we change routing while there is a P2P target connect. 1525 * The async LLCP callback will crash since the routing code 1526 * is overwriting globals it relies on. 1527 */ 1528 if (POLLING_MODE > SCREEN_STATE_OFF) { 1529 if (force || mNfcPollingEnabled) { 1530 Log.d(TAG, "NFC-C OFF, disconnect"); 1531 mNfcPollingEnabled = false; 1532 mDeviceHost.disableDiscovery(); 1533 maybeDisconnectTarget(); 1534 } 1535 } 1536 if (mEeRoutingState == ROUTE_ON_WHEN_SCREEN_ON) { 1537 if (force || mNfceeRouteEnabled) { 1538 Log.d(TAG, "NFC-EE OFF"); 1539 mNfceeRouteEnabled = false; 1540 mDeviceHost.doDeselectSecureElement(); 1541 } 1542 } 1543 return; 1544 } 1545 1546 // configure NFC-EE routing 1547 if (mScreenState >= SCREEN_STATE_ON_LOCKED && 1548 mEeRoutingState == ROUTE_ON_WHEN_SCREEN_ON) { 1549 if (force || !mNfceeRouteEnabled) { 1550 Log.d(TAG, "NFC-EE ON"); 1551 mNfceeRouteEnabled = true; 1552 mDeviceHost.doSelectSecureElement(); 1553 } 1554 } else { 1555 if (force || mNfceeRouteEnabled) { 1556 Log.d(TAG, "NFC-EE OFF"); 1557 mNfceeRouteEnabled = false; 1558 mDeviceHost.doDeselectSecureElement(); 1559 } 1560 } 1561 1562 // configure NFC-C polling 1563 if (mScreenState >= POLLING_MODE) { 1564 if (force || !mNfcPollingEnabled) { 1565 Log.d(TAG, "NFC-C ON"); 1566 mNfcPollingEnabled = true; 1567 mDeviceHost.enableDiscovery(); 1568 } 1569 } else { 1570 if (force || mNfcPollingEnabled) { 1571 Log.d(TAG, "NFC-C OFF"); 1572 mNfcPollingEnabled = false; 1573 mDeviceHost.disableDiscovery(); 1574 } 1575 } 1576 } finally { 1577 watchDog.cancel(); 1578 } 1579 } 1580 } 1581 1582 /** Disconnect any target if present */ 1583 void maybeDisconnectTarget() { 1584 if (!isNfcEnabledOrShuttingDown()) { 1585 return; 1586 } 1587 Object[] objectsToDisconnect; 1588 synchronized (this) { 1589 Object[] objectValues = mObjectMap.values().toArray(); 1590 // Copy the array before we clear mObjectMap, 1591 // just in case the HashMap values are backed by the same array 1592 objectsToDisconnect = Arrays.copyOf(objectValues, objectValues.length); 1593 mObjectMap.clear(); 1594 } 1595 for (Object o : objectsToDisconnect) { 1596 if (DBG) Log.d(TAG, "disconnecting " + o.getClass().getName()); 1597 if (o instanceof TagEndpoint) { 1598 // Disconnect from tags 1599 TagEndpoint tag = (TagEndpoint) o; 1600 tag.disconnect(); 1601 } else if (o instanceof NfcDepEndpoint) { 1602 // Disconnect from P2P devices 1603 NfcDepEndpoint device = (NfcDepEndpoint) o; 1604 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) { 1605 // Remote peer is target, request disconnection 1606 device.disconnect(); 1607 } else { 1608 // Remote peer is initiator, we cannot disconnect 1609 // Just wait for field removal 1610 } 1611 } 1612 } 1613 } 1614 1615 Object findObject(int key) { 1616 synchronized (this) { 1617 Object device = mObjectMap.get(key); 1618 if (device == null) { 1619 Log.w(TAG, "Handle not found"); 1620 } 1621 return device; 1622 } 1623 } 1624 1625 void registerTagObject(TagEndpoint tag) { 1626 synchronized (this) { 1627 mObjectMap.put(tag.getHandle(), tag); 1628 } 1629 } 1630 1631 void unregisterObject(int handle) { 1632 synchronized (this) { 1633 mObjectMap.remove(handle); 1634 } 1635 } 1636 1637 /** For use by code in this process */ 1638 public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) 1639 throws LlcpException { 1640 return mDeviceHost.createLlcpSocket(sap, miu, rw, linearBufferLength); 1641 } 1642 1643 /** For use by code in this process */ 1644 public LlcpConnectionlessSocket createLlcpConnectionLessSocket(int sap, String sn) 1645 throws LlcpException { 1646 return mDeviceHost.createLlcpConnectionlessSocket(sap, sn); 1647 } 1648 1649 /** For use by code in this process */ 1650 public LlcpServerSocket createLlcpServerSocket(int sap, String sn, int miu, int rw, 1651 int linearBufferLength) throws LlcpException { 1652 return mDeviceHost.createLlcpServerSocket(sap, sn, miu, rw, linearBufferLength); 1653 } 1654 1655 public void sendMockNdefTag(NdefMessage msg) { 1656 sendMessage(MSG_MOCK_NDEF, msg); 1657 } 1658 1659 void sendMessage(int what, Object obj) { 1660 Message msg = mHandler.obtainMessage(); 1661 msg.what = what; 1662 msg.obj = obj; 1663 mHandler.sendMessage(msg); 1664 } 1665 1666 final class NfcServiceHandler extends Handler { 1667 @Override 1668 public void handleMessage(Message msg) { 1669 switch (msg.what) { 1670 case MSG_MOCK_NDEF: { 1671 NdefMessage ndefMsg = (NdefMessage) msg.obj; 1672 Bundle extras = new Bundle(); 1673 extras.putParcelable(Ndef.EXTRA_NDEF_MSG, ndefMsg); 1674 extras.putInt(Ndef.EXTRA_NDEF_MAXLENGTH, 0); 1675 extras.putInt(Ndef.EXTRA_NDEF_CARDSTATE, Ndef.NDEF_MODE_READ_ONLY); 1676 extras.putInt(Ndef.EXTRA_NDEF_TYPE, Ndef.TYPE_OTHER); 1677 Tag tag = Tag.createMockTag(new byte[] { 0x00 }, 1678 new int[] { TagTechnology.NDEF }, 1679 new Bundle[] { extras }); 1680 Log.d(TAG, "mock NDEF tag, starting corresponding activity"); 1681 Log.d(TAG, tag.toString()); 1682 boolean delivered = mNfcDispatcher.dispatchTag(tag); 1683 if (delivered) { 1684 playSound(SOUND_END); 1685 } else { 1686 playSound(SOUND_ERROR); 1687 } 1688 break; 1689 } 1690 1691 case MSG_NDEF_TAG: 1692 if (DBG) Log.d(TAG, "Tag detected, notifying applications"); 1693 TagEndpoint tag = (TagEndpoint) msg.obj; 1694 playSound(SOUND_START); 1695 NdefMessage ndefMsg = tag.findAndReadNdef(); 1696 1697 if (ndefMsg != null) { 1698 tag.startPresenceChecking(); 1699 dispatchTagEndpoint(tag); 1700 } else { 1701 if (tag.reconnect()) { 1702 tag.startPresenceChecking(); 1703 dispatchTagEndpoint(tag); 1704 } else { 1705 tag.disconnect(); 1706 playSound(SOUND_ERROR); 1707 } 1708 } 1709 break; 1710 1711 case MSG_CARD_EMULATION: 1712 if (DBG) Log.d(TAG, "Card Emulation message"); 1713 byte[] aid = (byte[]) msg.obj; 1714 /* Send broadcast */ 1715 Intent aidIntent = new Intent(); 1716 aidIntent.setAction(ACTION_AID_SELECTED); 1717 aidIntent.putExtra(EXTRA_AID, aid); 1718 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_AID_SELECTED); 1719 sendSeBroadcast(aidIntent); 1720 break; 1721 1722 case MSG_SE_EMV_CARD_REMOVAL: 1723 if (DBG) Log.d(TAG, "Card Removal message"); 1724 /* Send broadcast */ 1725 Intent cardRemovalIntent = new Intent(); 1726 cardRemovalIntent.setAction(ACTION_EMV_CARD_REMOVAL); 1727 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_EMV_CARD_REMOVAL); 1728 sendSeBroadcast(cardRemovalIntent); 1729 break; 1730 1731 case MSG_SE_APDU_RECEIVED: 1732 if (DBG) Log.d(TAG, "APDU Received message"); 1733 byte[] apduBytes = (byte[]) msg.obj; 1734 /* Send broadcast */ 1735 Intent apduReceivedIntent = new Intent(); 1736 apduReceivedIntent.setAction(ACTION_APDU_RECEIVED); 1737 if (apduBytes != null && apduBytes.length > 0) { 1738 apduReceivedIntent.putExtra(EXTRA_APDU_BYTES, apduBytes); 1739 } 1740 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_APDU_RECEIVED); 1741 sendSeBroadcast(apduReceivedIntent); 1742 break; 1743 1744 case MSG_SE_MIFARE_ACCESS: 1745 if (DBG) Log.d(TAG, "MIFARE access message"); 1746 /* Send broadcast */ 1747 byte[] mifareCmd = (byte[]) msg.obj; 1748 Intent mifareAccessIntent = new Intent(); 1749 mifareAccessIntent.setAction(ACTION_MIFARE_ACCESS_DETECTED); 1750 if (mifareCmd != null && mifareCmd.length > 1) { 1751 int mifareBlock = mifareCmd[1] & 0xff; 1752 if (DBG) Log.d(TAG, "Mifare Block=" + mifareBlock); 1753 mifareAccessIntent.putExtra(EXTRA_MIFARE_BLOCK, mifareBlock); 1754 } 1755 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_MIFARE_ACCESS_DETECTED); 1756 sendSeBroadcast(mifareAccessIntent); 1757 break; 1758 1759 case MSG_LLCP_LINK_ACTIVATION: 1760 llcpActivated((NfcDepEndpoint) msg.obj); 1761 break; 1762 1763 case MSG_LLCP_LINK_DEACTIVATED: 1764 NfcDepEndpoint device = (NfcDepEndpoint) msg.obj; 1765 boolean needsDisconnect = false; 1766 1767 Log.d(TAG, "LLCP Link Deactivated message. Restart polling loop."); 1768 synchronized (NfcService.this) { 1769 /* Check if the device has been already unregistered */ 1770 if (mObjectMap.remove(device.getHandle()) != null) { 1771 /* Disconnect if we are initiator */ 1772 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) { 1773 if (DBG) Log.d(TAG, "disconnecting from target"); 1774 needsDisconnect = true; 1775 } else { 1776 if (DBG) Log.d(TAG, "not disconnecting from initiator"); 1777 } 1778 } 1779 } 1780 if (needsDisconnect) { 1781 device.disconnect(); // restarts polling loop 1782 } 1783 1784 mP2pLinkManager.onLlcpDeactivated(); 1785 break; 1786 1787 case MSG_TARGET_DESELECTED: 1788 /* Broadcast Intent Target Deselected */ 1789 if (DBG) Log.d(TAG, "Target Deselected"); 1790 Intent intent = new Intent(); 1791 intent.setAction(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION); 1792 if (DBG) Log.d(TAG, "Broadcasting Intent"); 1793 mContext.sendOrderedBroadcast(intent, NFC_PERM); 1794 break; 1795 1796 case MSG_SE_FIELD_ACTIVATED: { 1797 if (DBG) Log.d(TAG, "SE FIELD ACTIVATED"); 1798 Intent eventFieldOnIntent = new Intent(); 1799 eventFieldOnIntent.setAction(ACTION_RF_FIELD_ON_DETECTED); 1800 sendSeBroadcast(eventFieldOnIntent); 1801 break; 1802 } 1803 1804 case MSG_SE_FIELD_DEACTIVATED: { 1805 if (DBG) Log.d(TAG, "SE FIELD DEACTIVATED"); 1806 Intent eventFieldOffIntent = new Intent(); 1807 eventFieldOffIntent.setAction(ACTION_RF_FIELD_OFF_DETECTED); 1808 sendSeBroadcast(eventFieldOffIntent); 1809 break; 1810 } 1811 1812 case MSG_SE_LISTEN_ACTIVATED: { 1813 if (DBG) Log.d(TAG, "SE LISTEN MODE ACTIVATED"); 1814 Intent listenModeActivated = new Intent(); 1815 listenModeActivated.setAction(ACTION_SE_LISTEN_ACTIVATED); 1816 sendSeBroadcast(listenModeActivated); 1817 break; 1818 } 1819 1820 case MSG_SE_LISTEN_DEACTIVATED: { 1821 if (DBG) Log.d(TAG, "SE LISTEN MODE DEACTIVATED"); 1822 Intent listenModeDeactivated = new Intent(); 1823 listenModeDeactivated.setAction(ACTION_SE_LISTEN_DEACTIVATED); 1824 sendSeBroadcast(listenModeDeactivated); 1825 break; 1826 } 1827 1828 default: 1829 Log.e(TAG, "Unknown message received"); 1830 break; 1831 } 1832 } 1833 1834 private void sendSeBroadcast(Intent intent) { 1835 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 1836 // Resume app switches so the receivers can start activites without delay 1837 mNfcDispatcher.resumeAppSwitches(); 1838 1839 synchronized(this) { 1840 for (PackageInfo pkg : mInstalledPackages) { 1841 if (pkg != null && pkg.applicationInfo != null) { 1842 if (mNfceeAccessControl.check(pkg.applicationInfo)) { 1843 intent.setPackage(pkg.packageName); 1844 mContext.sendBroadcast(intent); 1845 } 1846 } 1847 } 1848 } 1849 } 1850 1851 private boolean llcpActivated(NfcDepEndpoint device) { 1852 Log.d(TAG, "LLCP Activation message"); 1853 1854 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) { 1855 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_TARGET"); 1856 if (device.connect()) { 1857 /* Check LLCP compliancy */ 1858 if (mDeviceHost.doCheckLlcp()) { 1859 /* Activate LLCP Link */ 1860 if (mDeviceHost.doActivateLlcp()) { 1861 if (DBG) Log.d(TAG, "Initiator Activate LLCP OK"); 1862 synchronized (NfcService.this) { 1863 // Register P2P device 1864 mObjectMap.put(device.getHandle(), device); 1865 } 1866 mP2pLinkManager.onLlcpActivated(); 1867 return true; 1868 } else { 1869 /* should not happen */ 1870 Log.w(TAG, "Initiator LLCP activation failed. Disconnect."); 1871 device.disconnect(); 1872 } 1873 } else { 1874 if (DBG) Log.d(TAG, "Remote Target does not support LLCP. Disconnect."); 1875 device.disconnect(); 1876 } 1877 } else { 1878 if (DBG) Log.d(TAG, "Cannot connect remote Target. Polling loop restarted."); 1879 /* 1880 * The polling loop should have been restarted in failing 1881 * doConnect 1882 */ 1883 } 1884 } else if (device.getMode() == NfcDepEndpoint.MODE_P2P_INITIATOR) { 1885 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_INITIATOR"); 1886 /* Check LLCP compliancy */ 1887 if (mDeviceHost.doCheckLlcp()) { 1888 /* Activate LLCP Link */ 1889 if (mDeviceHost.doActivateLlcp()) { 1890 if (DBG) Log.d(TAG, "Target Activate LLCP OK"); 1891 synchronized (NfcService.this) { 1892 // Register P2P device 1893 mObjectMap.put(device.getHandle(), device); 1894 } 1895 mP2pLinkManager.onLlcpActivated(); 1896 return true; 1897 } 1898 } else { 1899 Log.w(TAG, "checkLlcp failed"); 1900 } 1901 } 1902 1903 return false; 1904 } 1905 1906 private void dispatchTagEndpoint(TagEndpoint tagEndpoint) { 1907 Tag tag = new Tag(tagEndpoint.getUid(), tagEndpoint.getTechList(), 1908 tagEndpoint.getTechExtras(), tagEndpoint.getHandle(), mNfcTagService); 1909 registerTagObject(tagEndpoint); 1910 if (!mNfcDispatcher.dispatchTag(tag)) { 1911 unregisterObject(tagEndpoint.getHandle()); 1912 playSound(SOUND_ERROR); 1913 } else { 1914 playSound(SOUND_END); 1915 } 1916 } 1917 } 1918 1919 private NfcServiceHandler mHandler = new NfcServiceHandler(); 1920 1921 class ApplyRoutingTask extends AsyncTask<Integer, Void, Void> { 1922 @Override 1923 protected Void doInBackground(Integer... params) { 1924 synchronized (NfcService.this) { 1925 if (params == null || params.length != 1) { 1926 // force apply current routing 1927 applyRouting(true); 1928 return null; 1929 } 1930 mScreenState = params[0].intValue(); 1931 1932 mRoutingWakeLock.acquire(); 1933 try { 1934 applyRouting(false); 1935 } finally { 1936 mRoutingWakeLock.release(); 1937 } 1938 return null; 1939 } 1940 } 1941 } 1942 1943 private final BroadcastReceiver mOwnerReceiver = new BroadcastReceiver() { 1944 @Override 1945 public void onReceive(Context context, Intent intent) { 1946 String action = intent.getAction(); 1947 if (action.equals(Intent.ACTION_PACKAGE_REMOVED) || 1948 action.equals(Intent.ACTION_PACKAGE_ADDED) || 1949 action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE) || 1950 action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) { 1951 updatePackageCache(); 1952 1953 if (action.equals(Intent.ACTION_PACKAGE_REMOVED)) { 1954 // Clear the NFCEE access cache in case a UID gets recycled 1955 mNfceeAccessControl.invalidateCache(); 1956 1957 boolean dataRemoved = intent.getBooleanExtra(Intent.EXTRA_DATA_REMOVED, false); 1958 if (dataRemoved) { 1959 Uri data = intent.getData(); 1960 if (data == null) return; 1961 String packageName = data.getSchemeSpecificPart(); 1962 1963 synchronized (NfcService.this) { 1964 if (mSePackages.contains(packageName)) { 1965 new EnableDisableTask().execute(TASK_EE_WIPE); 1966 mSePackages.remove(packageName); 1967 } 1968 } 1969 } 1970 } 1971 } else if (action.equals(ACTION_MASTER_CLEAR_NOTIFICATION)) { 1972 EnableDisableTask eeWipeTask = new EnableDisableTask(); 1973 eeWipeTask.execute(TASK_EE_WIPE); 1974 try { 1975 eeWipeTask.get(); // blocks until EE wipe is complete 1976 } catch (ExecutionException e) { 1977 Log.w(TAG, "failed to wipe NFC-EE"); 1978 } catch (InterruptedException e) { 1979 Log.w(TAG, "failed to wipe NFC-EE"); 1980 } 1981 } 1982 } 1983 }; 1984 1985 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 1986 @Override 1987 public void onReceive(Context context, Intent intent) { 1988 String action = intent.getAction(); 1989 if (action.equals( 1990 NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) { 1991 // Perform applyRouting() in AsyncTask to serialize blocking calls 1992 new ApplyRoutingTask().execute(); 1993 } else if (action.equals(Intent.ACTION_SCREEN_ON) 1994 || action.equals(Intent.ACTION_SCREEN_OFF) 1995 || action.equals(Intent.ACTION_USER_PRESENT)) { 1996 // Perform applyRouting() in AsyncTask to serialize blocking calls 1997 int screenState = SCREEN_STATE_OFF; 1998 if (action.equals(Intent.ACTION_SCREEN_OFF)) { 1999 screenState = SCREEN_STATE_OFF; 2000 } else if (action.equals(Intent.ACTION_SCREEN_ON)) { 2001 screenState = mKeyguard.isKeyguardLocked() ? 2002 SCREEN_STATE_ON_LOCKED : SCREEN_STATE_ON_UNLOCKED; 2003 } else if (action.equals(Intent.ACTION_USER_PRESENT)) { 2004 screenState = SCREEN_STATE_ON_UNLOCKED; 2005 } 2006 new ApplyRoutingTask().execute(Integer.valueOf(screenState)); 2007 } else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) { 2008 boolean isAirplaneModeOn = intent.getBooleanExtra("state", false); 2009 // Query the airplane mode from Settings.System just to make sure that 2010 // some random app is not sending this intent 2011 if (isAirplaneModeOn != isAirplaneModeOn()) { 2012 return; 2013 } 2014 if (!mIsAirplaneSensitive) { 2015 return; 2016 } 2017 mPrefsEditor.putBoolean(PREF_AIRPLANE_OVERRIDE, false); 2018 mPrefsEditor.apply(); 2019 if (isAirplaneModeOn) { 2020 new EnableDisableTask().execute(TASK_DISABLE); 2021 } else if (!isAirplaneModeOn && mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT)) { 2022 new EnableDisableTask().execute(TASK_ENABLE); 2023 } 2024 } 2025 } 2026 }; 2027 2028 /** Returns true if airplane mode is currently on */ 2029 boolean isAirplaneModeOn() { 2030 return Settings.System.getInt(mContext.getContentResolver(), 2031 Settings.System.AIRPLANE_MODE_ON, 0) == 1; 2032 } 2033 2034 /** for debugging only - no i18n */ 2035 static String stateToString(int state) { 2036 switch (state) { 2037 case NfcAdapter.STATE_OFF: 2038 return "off"; 2039 case NfcAdapter.STATE_TURNING_ON: 2040 return "turning on"; 2041 case NfcAdapter.STATE_ON: 2042 return "on"; 2043 case NfcAdapter.STATE_TURNING_OFF: 2044 return "turning off"; 2045 default: 2046 return "<error>"; 2047 } 2048 } 2049 2050 /** For debugging only - no i18n */ 2051 static String screenStateToString(int screenState) { 2052 switch (screenState) { 2053 case SCREEN_STATE_OFF: 2054 return "OFF"; 2055 case SCREEN_STATE_ON_LOCKED: 2056 return "ON_LOCKED"; 2057 case SCREEN_STATE_ON_UNLOCKED: 2058 return "ON_UNLOCKED"; 2059 default: 2060 return "UNKNOWN"; 2061 } 2062 } 2063 2064 void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2065 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 2066 != PackageManager.PERMISSION_GRANTED) { 2067 pw.println("Permission Denial: can't dump nfc from from pid=" 2068 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2069 + " without permission " + android.Manifest.permission.DUMP); 2070 return; 2071 } 2072 2073 synchronized (this) { 2074 pw.println("mState=" + stateToString(mState)); 2075 pw.println("mIsZeroClickRequested=" + mIsNdefPushEnabled); 2076 pw.println("mScreenState=" + screenStateToString(mScreenState)); 2077 pw.println("mNfcPollingEnabled=" + mNfcPollingEnabled); 2078 pw.println("mNfceeRouteEnabled=" + mNfceeRouteEnabled); 2079 pw.println("mIsAirplaneSensitive=" + mIsAirplaneSensitive); 2080 pw.println("mIsAirplaneToggleable=" + mIsAirplaneToggleable); 2081 pw.println("mOpenEe=" + mOpenEe); 2082 mP2pLinkManager.dump(fd, pw, args); 2083 mNfceeAccessControl.dump(fd, pw, args); 2084 mNfcDispatcher.dump(fd, pw, args); 2085 pw.println(mDeviceHost.dump()); 2086 2087 } 2088 } 2089 } 2090