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