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