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