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