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