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