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