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