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