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