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