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 static com.android.nfc.NfcStatsLog.NFC_OBSERVE_MODE_STATE_CHANGED__TRIGGER_SOURCE__FOREGROUND_APP; 20 import static com.android.nfc.NfcStatsLog.NFC_OBSERVE_MODE_STATE_CHANGED__TRIGGER_SOURCE__TRIGGER_SOURCE_UNKNOWN; 21 import static com.android.nfc.NfcStatsLog.NFC_OBSERVE_MODE_STATE_CHANGED__TRIGGER_SOURCE__WALLET_ROLE_HOLDER; 22 23 import android.annotation.NonNull; 24 import android.app.ActivityManager; 25 import android.app.AlarmManager; 26 import android.app.Application; 27 import android.app.BroadcastOptions; 28 import android.app.KeyguardManager; 29 import android.app.KeyguardManager.KeyguardLockedStateListener; 30 import android.app.PendingIntent; 31 import android.app.VrManager; 32 import android.app.backup.BackupManager; 33 import android.app.role.RoleManager; 34 import android.content.BroadcastReceiver; 35 import android.content.ContentResolver; 36 import android.content.Context; 37 import android.content.Intent; 38 import android.content.IntentFilter; 39 import android.content.SharedPreferences; 40 import android.content.pm.ApplicationInfo; 41 import android.content.pm.PackageInfo; 42 import android.content.pm.PackageManager; 43 import android.database.ContentObserver; 44 import android.media.AudioAttributes; 45 import android.media.SoundPool; 46 import android.net.Uri; 47 import android.nfc.AvailableNfcAntenna; 48 import android.nfc.Constants; 49 import android.nfc.ErrorCodes; 50 import android.nfc.FormatException; 51 import android.nfc.IAppCallback; 52 import android.nfc.INfcAdapter; 53 import android.nfc.INfcAdapterExtras; 54 import android.nfc.INfcCardEmulation; 55 import android.nfc.INfcControllerAlwaysOnListener; 56 import android.nfc.INfcDta; 57 import android.nfc.INfcFCardEmulation; 58 import android.nfc.INfcOemExtensionCallback; 59 import android.nfc.INfcTag; 60 import android.nfc.INfcUnlockHandler; 61 import android.nfc.INfcVendorNciCallback; 62 import android.nfc.INfcWlcStateListener; 63 import android.nfc.ITagRemovedCallback; 64 import android.nfc.NdefMessage; 65 import android.nfc.NfcAdapter; 66 import android.nfc.NfcAntennaInfo; 67 import android.nfc.Tag; 68 import android.nfc.TechListParcel; 69 import android.nfc.TransceiveResult; 70 import android.nfc.WlcListenerDeviceInfo; 71 import android.nfc.cardemulation.CardEmulation; 72 import android.nfc.cardemulation.PollingFrame; 73 import android.nfc.tech.Ndef; 74 import android.nfc.tech.TagTechnology; 75 import android.os.AsyncTask; 76 import android.os.Binder; 77 import android.os.Build; 78 import android.os.Bundle; 79 import android.os.Handler; 80 import android.os.IBinder; 81 import android.os.Looper; 82 import android.os.Message; 83 import android.os.ParcelFileDescriptor; 84 import android.os.PowerManager; 85 import android.os.PowerManager.OnThermalStatusChangedListener; 86 import android.os.Process; 87 import android.os.RemoteException; 88 import android.os.SystemClock; 89 import android.os.UserHandle; 90 import android.os.UserManager; 91 import android.os.VibrationAttributes; 92 import android.os.VibrationEffect; 93 import android.os.Vibrator; 94 import android.provider.Settings; 95 import android.provider.Settings.SettingNotFoundException; 96 import android.se.omapi.ISecureElementService; 97 import android.sysprop.NfcProperties; 98 import android.util.EventLog; 99 import android.util.Log; 100 import android.util.proto.ProtoOutputStream; 101 import android.widget.Toast; 102 103 import androidx.annotation.VisibleForTesting; 104 105 import com.android.nfc.DeviceHost.DeviceHostListener; 106 import com.android.nfc.DeviceHost.TagEndpoint; 107 import com.android.nfc.cardemulation.CardEmulationManager; 108 import com.android.nfc.cardemulation.util.StatsdUtils; 109 import com.android.nfc.dhimpl.NativeNfcManager; 110 import com.android.nfc.flags.FeatureFlags; 111 import com.android.nfc.handover.HandoverDataParser; 112 import com.android.nfc.proto.NfcEventProto; 113 import com.android.nfc.wlc.NfcCharging; 114 115 import org.json.JSONException; 116 import org.json.JSONObject; 117 118 import java.io.File; 119 import java.io.FileDescriptor; 120 import java.io.FileOutputStream; 121 import java.io.IOException; 122 import java.io.PrintWriter; 123 import java.io.UnsupportedEncodingException; 124 import java.nio.ByteBuffer; 125 import java.nio.file.Files; 126 import java.security.SecureRandom; 127 import java.util.ArrayList; 128 import java.util.Arrays; 129 import java.util.Collections; 130 import java.util.HashMap; 131 import java.util.HashSet; 132 import java.util.HexFormat; 133 import java.util.Iterator; 134 import java.util.List; 135 import java.util.Map; 136 import java.util.NoSuchElementException; 137 import java.util.Scanner; 138 import java.util.Set; 139 import java.util.concurrent.ExecutionException; 140 import java.util.concurrent.ExecutorService; 141 import java.util.concurrent.Executors; 142 import java.util.concurrent.FutureTask; 143 import java.util.concurrent.TimeUnit; 144 import java.util.concurrent.TimeoutException; 145 import java.util.stream.Collectors; 146 147 public class NfcService implements DeviceHostListener, ForegroundUtils.Callback { 148 static final boolean DBG = NfcProperties.debug_enabled().orElse(true); 149 private static final boolean VDBG = false; // turn on for local testing. 150 static final String TAG = "NfcService"; 151 private static final int APP_INFO_FLAGS_SYSTEM_APP = 152 ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 153 154 public static final String SERVICE_NAME = "nfc"; 155 156 private static final String SYSTEM_UI = "com.android.systemui"; 157 158 public static final String PREF = "NfcServicePrefs"; 159 public static final String PREF_TAG_APP_LIST = "TagIntentAppPreferenceListPrefs"; 160 161 static final String PREF_NFC_ON = "nfc_on"; 162 static final boolean NFC_ON_DEFAULT = true; 163 164 static final String PREF_NFC_READER_OPTION_ON = "nfc_reader_on"; 165 static final boolean NFC_READER_OPTION_DEFAULT = true; 166 167 static final String PREF_NFC_CHARGING_ON = "nfc_charging_on"; 168 static final boolean NFC_CHARGING_ON_DEFAULT = true; 169 170 static final String PREF_SECURE_NFC_ON = "secure_nfc_on"; 171 static final boolean SECURE_NFC_ON_DEFAULT = false; 172 static final String PREF_FIRST_BOOT = "first_boot"; 173 174 static final String PREF_ANTENNA_BLOCKED_MESSAGE_SHOWN = "antenna_blocked_message_shown"; 175 static final boolean ANTENNA_BLOCKED_MESSAGE_SHOWN_DEFAULT = false; 176 177 static final String NATIVE_LOG_FILE_NAME = "native_crash_logs"; 178 static final String NATIVE_LOG_FILE_PATH = "/data/misc/nfc/logs"; 179 static final int NATIVE_CRASH_FILE_SIZE = 1024 * 1024; 180 private static final String WAIT_FOR_OEM_ALLOW_BOOT_TIMER_TAG = "NfcWaitForSimTag"; 181 @VisibleForTesting 182 public static final int WAIT_FOR_OEM_ALLOW_BOOT_TIMEOUT_MS = 5_000; 183 184 static final int MSG_NDEF_TAG = 0; 185 // Previously used: MSG_LLCP_LINK_ACTIVATION = 1 186 // Previously used: MSG_LLCP_LINK_DEACTIVATED = 2 187 static final int MSG_MOCK_NDEF = 3; 188 // Previously used: MSG_LLCP_LINK_FIRST_PACKET = 4 189 static final int MSG_ROUTE_AID = 5; 190 static final int MSG_UNROUTE_AID = 6; 191 static final int MSG_COMMIT_ROUTING = 7; 192 // Previously used: MSG_INVOKE_BEAM = 8 193 static final int MSG_RF_FIELD_ACTIVATED = 9; 194 static final int MSG_RF_FIELD_DEACTIVATED = 10; 195 static final int MSG_RESUME_POLLING = 11; 196 static final int MSG_REGISTER_T3T_IDENTIFIER = 12; 197 static final int MSG_DEREGISTER_T3T_IDENTIFIER = 13; 198 static final int MSG_TAG_DEBOUNCE = 14; 199 // Previously used: MSG_UPDATE_STATS = 15 200 static final int MSG_APPLY_SCREEN_STATE = 16; 201 static final int MSG_TRANSACTION_EVENT = 17; 202 static final int MSG_PREFERRED_PAYMENT_CHANGED = 18; 203 static final int MSG_TOAST_DEBOUNCE_EVENT = 19; 204 static final int MSG_DELAY_POLLING = 20; 205 static final int MSG_CLEAR_ROUTING_TABLE = 21; 206 static final int MSG_UPDATE_ISODEP_PROTOCOL_ROUTE = 22; 207 static final int MSG_UPDATE_TECHNOLOGY_AB_ROUTE = 23; 208 209 static final String MSG_ROUTE_AID_PARAM_TAG = "power"; 210 211 // Negative value for NO polling delay 212 static final int NO_POLL_DELAY = -1; 213 214 static final long MAX_POLLING_PAUSE_TIMEOUT = 40000; 215 216 static final int MAX_TOAST_DEBOUNCE_TIME = 10000; 217 218 static final int TASK_ENABLE = 1; 219 static final int TASK_DISABLE = 2; 220 static final int TASK_BOOT = 3; 221 static final int TASK_ENABLE_ALWAYS_ON = 4; 222 static final int TASK_DISABLE_ALWAYS_ON = 5; 223 224 // Polling technology masks 225 static final int NFC_POLL_A = 0x01; 226 static final int NFC_POLL_B = 0x02; 227 static final int NFC_POLL_F = 0x04; 228 static final int NFC_POLL_V = 0x08; 229 static final int NFC_POLL_B_PRIME = 0x10; 230 static final int NFC_POLL_KOVIO = 0x20; 231 232 // Listen technology masks 233 static final int NFC_LISTEN_A = 0x01; 234 static final int NFC_LISTEN_B = 0x02; 235 static final int NFC_LISTEN_F = 0x04; 236 static final int NFC_LISTEN_V = 0x08; 237 238 static final String PREF_POLL_TECH = "polling_tech_dfl"; 239 240 // Default polling tech mask 241 static final int DEFAULT_POLL_TECH = 0x2f; // See: Polling technology masks above 242 243 static final String PREF_LISTEN_TECH = "listen_tech_dfl"; 244 // Default listening tech mask 245 static final int DEFAULT_LISTEN_TECH = 0xf; // See: Listen technology masks above 246 247 // minimum screen state that enables NFC polling 248 static final int NFC_POLLING_MODE = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED; 249 250 // Time to wait for NFC controller to initialize before watchdog 251 // goes off. This time is chosen large, because firmware download 252 // may be a part of initialization. 253 static final int INIT_WATCHDOG_MS = 90000; 254 255 // Time to wait for routing to be applied before watchdog 256 // goes off 257 static final int ROUTING_WATCHDOG_MS = 10000; 258 259 // Default delay used for presence checks 260 static final int DEFAULT_PRESENCE_CHECK_DELAY = 125; 261 262 static final NfcProperties.snoop_log_mode_values NFC_SNOOP_LOG_MODE = 263 NfcProperties.snoop_log_mode().orElse(NfcProperties.snoop_log_mode_values.FILTERED); 264 static final boolean NFC_VENDOR_DEBUG_ENABLED = NfcProperties.vendor_debug_enabled().orElse(false); 265 266 // RF field events as defined in NFC extras 267 public static final String ACTION_RF_FIELD_ON_DETECTED = 268 "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED"; 269 public static final String ACTION_RF_FIELD_OFF_DETECTED = 270 "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED"; 271 272 public static final String APP_NAME_ENABLING_NFC = 273 "com.android.nfc.PACKAGE_NAME_ENABLING_NFC"; 274 275 public static boolean sIsShortRecordLayout = false; 276 277 public static boolean sIsNfcRestore = false; 278 279 // for use with playSound() 280 public static final int SOUND_START = 0; 281 public static final int SOUND_END = 1; 282 public static final int SOUND_ERROR = 2; 283 284 public static final int NCI_VERSION_2_0 = 0x20; 285 286 public static final int NCI_VERSION_1_0 = 0x10; 287 288 // Timeout to re-apply routing if a tag was present and we postponed it 289 private static final int APPLY_ROUTING_RETRY_TIMEOUT_MS = 5000; 290 291 private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES = 292 VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK); 293 294 private static final int NCI_STATUS_OK = 0x00; 295 private static final int NCI_STATUS_REJECTED = 0x01; 296 private static final int NCI_STATUS_MESSAGE_CORRUPTED = 0x02; 297 private static final int NCI_STATUS_FAILED = 0x03; 298 private static final int SEND_VENDOR_CMD_TIMEOUT_MS = 3000; 299 private static final int NCI_GID_PROP = 0x0F; 300 private static final int NCI_MSG_PROP_ANDROID = 0x0C; 301 private static final int NCI_MSG_PROP_ANDROID_POWER_SAVING = 0x01; 302 303 private final Looper mLooper; 304 private final UserManager mUserManager; 305 private final ActivityManager mActivityManager; 306 307 private static int nci_version = NCI_VERSION_1_0; 308 // NFC Execution Environment 309 // fields below are protected by this 310 private final boolean mPollingDisableAllowed; 311 private HashMap<Integer, ReaderModeDeathRecipient> mPollingDisableDeathRecipients = 312 new HashMap<Integer, ReaderModeDeathRecipient>(); 313 private final ReaderModeDeathRecipient mReaderModeDeathRecipient = 314 new ReaderModeDeathRecipient(); 315 private final SeServiceDeathRecipient mSeServiceDeathRecipient = 316 new SeServiceDeathRecipient(); 317 private final DiscoveryTechDeathRecipient mDiscoveryTechDeathRecipient = 318 new DiscoveryTechDeathRecipient(); 319 private final NfcUnlockManager mNfcUnlockManager; 320 321 private final BackupManager mBackupManager; 322 323 private final SecureRandom mCookieGenerator = new SecureRandom(); 324 325 // Tag app preference list for the target UserId. 326 HashMap<Integer, HashMap<String, Boolean>> mTagAppPrefList = 327 new HashMap<Integer, HashMap<String, Boolean>>(); 328 329 // cached version of installed packages requesting Android.permission.NFC_TRANSACTION_EVENTS 330 // for current user and profiles. The Integer part is the userId. 331 HashMap<Integer, List<String>> mNfcEventInstalledPackages = 332 new HashMap<Integer, List<String>>(); 333 334 // cached version of installed packages requesting 335 // Android.permission.NFC_PREFERRED_PAYMENT_INFO for current user and profiles. 336 // The Integer part is the userId. 337 HashMap<Integer, List<String>> mNfcPreferredPaymentChangedInstalledPackages = 338 new HashMap<Integer, List<String>>(); 339 340 // fields below are used in multiple threads and protected by synchronized(this) 341 final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>(); 342 int mScreenState; 343 boolean mInProvisionMode; // whether we're in setup wizard and enabled NFC provisioning 344 boolean mIsSecureNfcEnabled; 345 boolean mSkipNdefRead; 346 NfcDiscoveryParameters mCurrentDiscoveryParameters = 347 NfcDiscoveryParameters.getNfcOffParameters(); 348 349 ReaderModeParams mReaderModeParams; 350 DiscoveryTechParams mDiscoveryTechParams; 351 352 private int mUserId; 353 boolean mPollingPaused; 354 355 // True if nfc notification message already shown 356 boolean mAntennaBlockedMessageShown; 357 private static int mDispatchFailedCount; 358 private static int mDispatchFailedMax; 359 360 static final int INVALID_NATIVE_HANDLE = -1; 361 byte mDebounceTagUid[]; 362 int mDebounceTagDebounceMs; 363 int mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE; 364 ITagRemovedCallback mDebounceTagRemovedCallback; 365 366 // Only accessed on one thread so doesn't need locking 367 NdefMessage mLastReadNdefMessage; 368 369 // mState is protected by this, however it is only modified in onCreate() 370 // and the default AsyncTask thread so it is read unprotected from that 371 // thread 372 int mState; // one of NfcAdapter.STATE_ON, STATE_TURNING_ON, etc 373 // mAlwaysOnState is protected by this, however it is only modified in onCreate() 374 // and the default AsyncTask thread so it is read unprotected from that thread 375 int mAlwaysOnState; // one of NfcAdapter.STATE_ON, STATE_TURNING_ON, etc 376 private boolean mIsPowerSavingModeEnabled = false; 377 378 // fields below are final after onCreate() 379 boolean mIsReaderOptionEnabled = true; 380 boolean mReaderOptionCapable; 381 Context mContext; 382 NfcInjector mNfcInjector; 383 NfcEventLog mNfcEventLog; 384 private DeviceHost mDeviceHost; 385 private SharedPreferences mPrefs; 386 private SharedPreferences.Editor mPrefsEditor; 387 private SharedPreferences mTagAppPrefListPrefs; 388 389 private PowerManager.WakeLock mRoutingWakeLock; 390 private PowerManager.WakeLock mRequireUnlockWakeLock; 391 392 int mStartSound; 393 int mEndSound; 394 int mErrorSound; 395 SoundPool mSoundPool; // playback synchronized on this 396 TagService mNfcTagService; 397 NfcAdapterService mNfcAdapter; 398 NfcDtaService mNfcDtaService; 399 RoutingTableParser mRoutingTableParser; 400 boolean mIsDebugBuild; 401 boolean mIsHceCapable; 402 boolean mIsHceFCapable; 403 boolean mIsSecureNfcCapable; 404 boolean mIsRequestUnlockShowed; 405 boolean mIsRecovering; 406 boolean mIsNfcUserRestricted; 407 boolean mIsNfcUserChangeRestricted; 408 boolean mIsWatchType; 409 boolean mPendingPowerStateUpdate; 410 boolean mIsWlcCapable; 411 boolean mIsWlcEnabled; 412 boolean mIsRWCapable; 413 WlcListenerDeviceInfo mWlcListenerDeviceInfo; 414 public NfcDiagnostics mNfcDiagnostics; 415 416 // polling delay control variables 417 private final int mPollDelayTime; 418 private final int mPollDelayTimeLong; 419 private final int mPollDelayCountMax; 420 private int mPollDelayCount; 421 private int mReadErrorCount; 422 private int mReadErrorCountMax; 423 private boolean mPollDelayed; 424 425 boolean mNotifyDispatchFailed; 426 boolean mNotifyReadFailed; 427 428 // for recording the latest Tag object cookie 429 long mCookieUpToDate = -1; 430 431 private DeviceConfigFacade mDeviceConfigFacade; 432 private NfcDispatcher mNfcDispatcher; 433 private PowerManager mPowerManager; 434 private KeyguardManager mKeyguard; 435 private HandoverDataParser mHandoverDataParser; 436 private ContentResolver mContentResolver; 437 private CardEmulationManager mCardEmulationManager; 438 private NfcCharging mNfcCharging; 439 private Vibrator mVibrator; 440 private VibrationEffect mVibrationEffect; 441 private ISecureElementService mSEService; 442 private VrManager mVrManager; 443 private final AlarmManager mAlarmManager; 444 445 private ScreenStateHelper mScreenStateHelper; 446 private ForegroundUtils mForegroundUtils; 447 448 private final NfcPermissions mNfcPermissions; 449 private static NfcService sService; 450 private static boolean sToast_debounce = false; 451 private static int sToast_debounce_time_ms = 3000; 452 public static boolean sIsDtaMode = false; 453 454 boolean mIsVrModeEnabled; 455 456 private final boolean mIsTagAppPrefSupported; 457 458 private final boolean mIsAlwaysOnSupported; 459 private final Set<INfcControllerAlwaysOnListener> mAlwaysOnListeners = 460 Collections.synchronizedSet(new HashSet<>()); 461 462 private final FeatureFlags mFeatureFlags; 463 private final Set<INfcWlcStateListener> mWlcStateListener = 464 Collections.synchronizedSet(new HashSet<>()); 465 private final StatsdUtils mStatsdUtils; 466 467 private INfcVendorNciCallback mNfcVendorNciCallBack = null; 468 private INfcOemExtensionCallback mNfcOemExtensionCallback = null; 469 getInstance()470 public static NfcService getInstance() { 471 return sService; 472 } 473 474 @Override onRemoteEndpointDiscovered(TagEndpoint tag)475 public void onRemoteEndpointDiscovered(TagEndpoint tag) { 476 sendMessage(NfcService.MSG_NDEF_TAG, tag); 477 } 478 479 /** 480 * Notifies transaction 481 */ 482 @Override onHostCardEmulationActivated(int technology)483 public void onHostCardEmulationActivated(int technology) { 484 if (mCardEmulationManager != null) { 485 mCardEmulationManager.onHostCardEmulationActivated(technology); 486 } 487 } 488 489 @Override onHostCardEmulationData(int technology, byte[] data)490 public void onHostCardEmulationData(int technology, byte[] data) { 491 if (mCardEmulationManager != null) { 492 mCardEmulationManager.onHostCardEmulationData(technology, data); 493 } 494 } 495 496 @Override onHostCardEmulationDeactivated(int technology)497 public void onHostCardEmulationDeactivated(int technology) { 498 if (mCardEmulationManager != null) { 499 mCardEmulationManager.onHostCardEmulationDeactivated(technology); 500 } 501 } 502 503 @Override onRemoteFieldActivated()504 public void onRemoteFieldActivated() { 505 sendMessage(NfcService.MSG_RF_FIELD_ACTIVATED, null); 506 507 if (mStatsdUtils != null) { 508 mStatsdUtils.logFieldChanged(true, 0); 509 } 510 } 511 512 @Override onRemoteFieldDeactivated()513 public void onRemoteFieldDeactivated() { 514 sendMessage(NfcService.MSG_RF_FIELD_DEACTIVATED, null); 515 516 if (mStatsdUtils != null) { 517 mStatsdUtils.logFieldChanged(false, 0); 518 } 519 } 520 521 @Override onPollingLoopDetected(List<PollingFrame> frames)522 public void onPollingLoopDetected(List<PollingFrame> frames) { 523 if (mCardEmulationManager != null && android.nfc.Flags.nfcReadPollingLoop()) { 524 mCardEmulationManager.onPollingLoopDetected(frames); 525 } 526 } 527 528 @Override onNfcTransactionEvent(byte[] aid, byte[] data, String seName)529 public void onNfcTransactionEvent(byte[] aid, byte[] data, String seName) { 530 byte[][] dataObj = {aid, data, seName.getBytes()}; 531 sendMessage(NfcService.MSG_TRANSACTION_EVENT, dataObj); 532 } 533 534 @Override onEeUpdated()535 public void onEeUpdated() { 536 new ApplyRoutingTask().execute(); 537 } 538 restartStack()539 private void restartStack() { 540 try { 541 mContext.unregisterReceiver(mReceiver); 542 } catch (IllegalArgumentException e) { 543 Log.w(TAG, "Failed to unregisterScreenState BroadCastReceiver: " + e); 544 } 545 mIsRecovering = true; 546 new EnableDisableTask().execute(TASK_DISABLE); 547 new EnableDisableTask().execute(TASK_ENABLE); 548 } 549 550 @Override onHwErrorReported()551 public void onHwErrorReported() { 552 restartStack(); 553 } 554 555 @Override onVendorSpecificEvent(int gid, int oid, byte[] payload)556 public void onVendorSpecificEvent(int gid, int oid, byte[] payload) { 557 mHandler.post(() -> mNfcAdapter.sendVendorNciNotification(gid, oid, payload)); 558 } 559 560 /** 561 * Enable or Disable PowerSaving Mode based on flag 562 */ setPowerSavingMode(boolean flag)563 private boolean setPowerSavingMode(boolean flag) { 564 synchronized (NfcService.this) { 565 if ((flag && mState != NfcAdapter.STATE_ON) 566 || (!flag && mState != NfcAdapter.STATE_OFF)) { 567 Log.d(TAG, "Enable Power Saving Mode is allowed in Nfc On state or " 568 + "Disable PowerSaving is allowed only if it is enabled"); 569 return false; 570 } 571 } 572 573 Log.d(TAG, "setPowerSavingMode " + flag); 574 if (flag) { 575 if(mDeviceHost.setPowerSavingMode(flag)) { 576 mIsPowerSavingModeEnabled = true; 577 new EnableDisableTask().execute(TASK_DISABLE); 578 return true; 579 } 580 } else { 581 new EnableDisableTask().execute(TASK_ENABLE); 582 return true; 583 } 584 Log.d(TAG, "Enable PowerSavingMode failed"); 585 return false; 586 } 587 onWlcData(Map<String, Integer> WlcDeviceInfo)588 public void onWlcData(Map<String, Integer> WlcDeviceInfo) { 589 for (String key : WlcDeviceInfo.keySet()) { 590 Log.d(TAG, " onWlcData " + key + " = " + WlcDeviceInfo.get(key)); 591 } 592 synchronized (mWlcStateListener) { 593 mWlcListenerDeviceInfo = new WlcListenerDeviceInfo( 594 WlcDeviceInfo.get(mNfcCharging.VendorId), 595 WlcDeviceInfo.get(mNfcCharging.TemperatureListener), 596 WlcDeviceInfo.get(mNfcCharging.BatteryLevel), 597 WlcDeviceInfo.get(mNfcCharging.State)); 598 for (INfcWlcStateListener listener : mWlcStateListener) { 599 try { 600 listener.onWlcStateChanged(mWlcListenerDeviceInfo); 601 } catch (RemoteException e) { 602 Log.e(TAG, "error in onWlcData"); 603 } 604 } 605 } 606 } 607 608 /** Notifies WLC procedure stopped */ 609 @Override onWlcStopped(int wpt_end_condition)610 public void onWlcStopped(int wpt_end_condition) { 611 Log.d(TAG, "onWlcStopped() - End condition is " + wpt_end_condition); 612 mNfcCharging.onWlcStopped(wpt_end_condition); 613 } 614 615 final class ReaderModeParams { 616 public int flags; 617 public IAppCallback callback; 618 public int presenceCheckDelay; 619 public IBinder binder; 620 public int uid; 621 } 622 623 final class DiscoveryTechParams { 624 public IBinder binder; 625 public int uid; 626 } 627 saveNfcOnSetting(boolean on)628 void saveNfcOnSetting(boolean on) { 629 synchronized (NfcService.this) { 630 mPrefsEditor.putBoolean(PREF_NFC_ON, on); 631 mPrefsEditor.apply(); 632 mBackupManager.dataChanged(); 633 } 634 } 635 getNfcOnSetting()636 boolean getNfcOnSetting() { 637 synchronized (NfcService.this) { 638 return mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT); 639 } 640 } 641 saveNfcListenTech(int tech)642 void saveNfcListenTech(int tech) { 643 synchronized (NfcService.this) { 644 mPrefsEditor.putInt(PREF_LISTEN_TECH, tech); 645 mPrefsEditor.apply(); 646 mBackupManager.dataChanged(); 647 } 648 } 649 getNfcListenTech()650 int getNfcListenTech() { 651 synchronized (NfcService.this) { 652 return mPrefs.getInt(PREF_LISTEN_TECH, DEFAULT_LISTEN_TECH); 653 } 654 } 655 saveNfcPollTech(int tech)656 void saveNfcPollTech(int tech) { 657 synchronized (NfcService.this) { 658 mPrefsEditor.putInt(PREF_POLL_TECH, tech); 659 mPrefsEditor.apply(); 660 mBackupManager.dataChanged(); 661 } 662 } 663 getNfcPollTech()664 int getNfcPollTech() { 665 synchronized (NfcService.this) { 666 return mPrefs.getInt(PREF_POLL_TECH, DEFAULT_POLL_TECH); 667 } 668 } 669 670 671 /** Returns true if NFC has user restriction set. */ isNfcUserRestricted()672 private boolean isNfcUserRestricted() { 673 return mUserManager.getUserRestrictions().getBoolean( 674 UserManager.DISALLOW_NEAR_FIELD_COMMUNICATION_RADIO); 675 } 676 677 /** Returns true if NFC state change by user is restricted. */ isNfcUserChangeRestricted()678 private boolean isNfcUserChangeRestricted() { 679 return mUserManager.getUserRestrictions().getBoolean( 680 UserManager.DISALLOW_CHANGE_NEAR_FIELD_COMMUNICATION_RADIO 681 ); 682 } 683 shouldEnableNfc()684 boolean shouldEnableNfc() { 685 return getNfcOnSetting() && !mNfcInjector.isSatelliteModeOn() && !isNfcUserRestricted(); 686 } 687 registerGlobalBroadcastsReceiver()688 private void registerGlobalBroadcastsReceiver() { 689 IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); 690 filter.addAction(Intent.ACTION_SCREEN_ON); 691 filter.addAction(Intent.ACTION_USER_PRESENT); 692 filter.addAction(Intent.ACTION_USER_SWITCHED); 693 filter.addAction(Intent.ACTION_USER_ADDED); 694 mContext.registerReceiverForAllUsers(mReceiver, filter, null, null); 695 } 696 NfcService(Application nfcApplication, NfcInjector nfcInjector)697 public NfcService(Application nfcApplication, NfcInjector nfcInjector) { 698 mUserId = ActivityManager.getCurrentUser(); 699 mContext = nfcApplication; 700 mNfcInjector = nfcInjector; 701 mLooper = mNfcInjector.getMainLooper(); 702 mHandler = new NfcServiceHandler(mLooper); 703 mNfcEventLog = mNfcInjector.getNfcEventLog(); 704 705 mNfcTagService = new TagService(); 706 mNfcAdapter = new NfcAdapterService(); 707 mRoutingTableParser = mNfcInjector.getRoutingTableParser(); 708 Log.i(TAG, "Starting NFC service"); 709 710 sService = this; 711 712 mScreenStateHelper = mNfcInjector.getScreenStateHelper(); 713 mContentResolver = mContext.getContentResolver(); 714 mDeviceHost = mNfcInjector.makeDeviceHost(this); 715 716 mNfcUnlockManager = mNfcInjector.getNfcUnlockManager(); 717 718 mHandoverDataParser = mNfcInjector.getHandoverDataParser(); 719 mInProvisionMode = mNfcInjector.isInProvisionMode(); 720 mDeviceConfigFacade = mNfcInjector.getDeviceConfigFacade(); 721 722 mNfcDispatcher = mNfcInjector.getNfcDispatcher(); 723 724 mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE); 725 mPrefsEditor = mPrefs.edit(); 726 727 mState = NfcAdapter.STATE_OFF; 728 mAlwaysOnState = NfcAdapter.STATE_OFF; 729 730 mIsDebugBuild = "userdebug".equals(Build.TYPE) || "eng".equals(Build.TYPE); 731 732 mPowerManager = mContext.getSystemService(PowerManager.class); 733 734 mRoutingWakeLock = mPowerManager.newWakeLock( 735 PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mRoutingWakeLock"); 736 737 mRequireUnlockWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK 738 | PowerManager.ACQUIRE_CAUSES_WAKEUP 739 | PowerManager.ON_AFTER_RELEASE, "NfcService:mRequireUnlockWakeLock"); 740 741 mKeyguard = mContext.getSystemService(KeyguardManager.class); 742 mUserManager = mContext.getSystemService(UserManager.class); 743 mActivityManager = mContext.getSystemService(ActivityManager.class); 744 mVibrator = mContext.getSystemService(Vibrator.class); 745 mVibrationEffect = mNfcInjector.getVibrationEffect(); 746 747 PackageManager pm = mContext.getPackageManager(); 748 mIsWatchType = pm.hasSystemFeature(PackageManager.FEATURE_WATCH); 749 750 mNfcDiagnostics = mNfcInjector.getNfcDiagnostics(); 751 752 if (pm.hasSystemFeature(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE) && 753 !mIsWatchType) { 754 mVrManager = mContext.getSystemService(VrManager.class); 755 } else { 756 mVrManager = null; 757 } 758 mAlarmManager = mContext.getSystemService(AlarmManager.class); 759 760 if (mInProvisionMode) { 761 mScreenState = mScreenStateHelper.checkScreenStateProvisionMode(); 762 } else { 763 mScreenState = mScreenStateHelper.checkScreenState(); 764 } 765 766 mBackupManager = mNfcInjector.getBackupManager(); 767 768 mFeatureFlags = mNfcInjector.getFeatureFlags(); 769 mStatsdUtils = mNfcInjector.getStatsdUtils(); 770 771 // Intents for all users 772 registerGlobalBroadcastsReceiver(); 773 774 // Listen for work profile adds or removes. 775 IntentFilter managedProfileFilter = new IntentFilter(); 776 managedProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED); 777 managedProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED); 778 managedProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); 779 managedProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); 780 mContext.registerReceiverForAllUsers(mManagedProfileReceiver, 781 managedProfileFilter, null, null); 782 783 IntentFilter ownerFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); 784 ownerFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 785 ownerFilter.addAction(Intent.ACTION_SHUTDOWN); 786 mContext.registerReceiverForAllUsers(mOwnerReceiver, ownerFilter, null, null); 787 788 ownerFilter = new IntentFilter(); 789 ownerFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 790 ownerFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 791 ownerFilter.addDataScheme("package"); 792 mContext.registerReceiverForAllUsers(mOwnerReceiver, ownerFilter, null, null); 793 794 addKeyguardLockedStateListener(); 795 796 updatePackageCache(); 797 798 mIsRWCapable = pm.hasSystemFeature(PackageManager.FEATURE_NFC); 799 mIsWlcCapable = android.nfc.Flags.enableNfcCharging() && 800 pm.hasSystemFeature(PackageManager.FEATURE_NFC_CHARGING); 801 if (mIsWlcCapable) { 802 mNfcCharging = new NfcCharging(mContext, mDeviceHost); 803 mIsWlcEnabled = mPrefs.getBoolean(PREF_NFC_CHARGING_ON, NFC_CHARGING_ON_DEFAULT); 804 // Register ThermalStatusChangedListener 805 addThermalStatusListener(); 806 } 807 808 mIsHceCapable = 809 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION) || 810 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF); 811 mIsHceFCapable = 812 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF); 813 if (mIsHceCapable) { 814 mCardEmulationManager = new CardEmulationManager(mContext, mNfcInjector); 815 } 816 mForegroundUtils = mNfcInjector.getForegroundUtils(); 817 mIsSecureNfcCapable = mNfcInjector.checkIsSecureNfcCapable(); 818 mIsSecureNfcEnabled = 819 mPrefs.getBoolean(PREF_SECURE_NFC_ON, SECURE_NFC_ON_DEFAULT) && 820 mIsSecureNfcCapable; 821 mDeviceHost.setNfcSecure(mIsSecureNfcEnabled); 822 823 sToast_debounce_time_ms = 824 mContext.getResources().getInteger(R.integer.toast_debounce_time_ms); 825 if(sToast_debounce_time_ms > MAX_TOAST_DEBOUNCE_TIME) { 826 sToast_debounce_time_ms = MAX_TOAST_DEBOUNCE_TIME; 827 } 828 829 // Notification message variables 830 mDispatchFailedCount = 0; 831 if (mDeviceConfigFacade.isAntennaBlockedAlertEnabled() && 832 !mPrefs.getBoolean(PREF_ANTENNA_BLOCKED_MESSAGE_SHOWN, ANTENNA_BLOCKED_MESSAGE_SHOWN_DEFAULT)) { 833 mAntennaBlockedMessageShown = false; 834 mDispatchFailedMax = 835 mContext.getResources().getInteger(R.integer.max_antenna_blocked_failure_count); 836 } else { 837 mAntennaBlockedMessageShown = true; 838 } 839 840 // Polling delay count for switching from stage one to stage two. 841 mPollDelayCountMax = 842 mContext.getResources().getInteger(R.integer.unknown_tag_polling_delay_count_max); 843 // Stage one: polling delay time for the first few unknown tag detections 844 mPollDelayTime = mContext.getResources().getInteger(R.integer.unknown_tag_polling_delay); 845 // Stage two: longer polling delay time after max_poll_delay_count 846 mPollDelayTimeLong = 847 mContext.getResources().getInteger(R.integer.unknown_tag_polling_delay_long); 848 // Polling delay if read error found more than max count. 849 mReadErrorCountMax = 850 mContext.getResources().getInteger(R.integer.unknown_tag_read_error_count_max); 851 852 mNotifyDispatchFailed = mContext.getResources().getBoolean(R.bool.enable_notify_dispatch_failed); 853 mNotifyReadFailed = mContext.getResources().getBoolean(R.bool.enable_notify_read_failed); 854 855 mPollingDisableAllowed = mContext.getResources().getBoolean(R.bool.polling_disable_allowed); 856 857 // Make sure this is only called when object construction is complete. 858 mNfcInjector.getNfcManagerRegisterer().register(mNfcAdapter); 859 860 mIsAlwaysOnSupported = 861 mContext.getResources().getBoolean(R.bool.nfcc_always_on_allowed); 862 863 mIsTagAppPrefSupported = 864 mContext.getResources().getBoolean(R.bool.tag_intent_app_pref_supported); 865 866 Uri uri = Settings.Global.getUriFor(Constants.SETTINGS_SATELLITE_MODE_ENABLED); 867 if (uri == null) { 868 Log.e(TAG, "satellite mode key does not exist in Settings"); 869 } else { 870 mContext.getContentResolver().registerContentObserver( 871 uri, 872 false, 873 new ContentObserver(null) { 874 @Override 875 public void onChange(boolean selfChange) { 876 if (mNfcInjector.isSatelliteModeSensitive()) { 877 Log.i(TAG, "Satellite mode change detected"); 878 if (shouldEnableNfc()) { 879 new EnableDisableTask().execute(TASK_ENABLE); 880 } else { 881 new EnableDisableTask().execute(TASK_DISABLE); 882 } 883 } 884 } 885 }); 886 } 887 888 mIsNfcUserRestricted = isNfcUserRestricted(); 889 mIsNfcUserChangeRestricted = isNfcUserChangeRestricted(); 890 mContext.registerReceiver( 891 new BroadcastReceiver() { 892 @Override 893 public void onReceive(Context context, Intent intent) { 894 if (mIsNfcUserRestricted == isNfcUserRestricted()) { 895 return; 896 } 897 Log.i(TAG, "Disallow NFC user restriction changed from " 898 + mIsNfcUserRestricted + " to " + !mIsNfcUserRestricted + "."); 899 mIsNfcUserRestricted = !mIsNfcUserRestricted; 900 mIsNfcUserChangeRestricted = isNfcUserChangeRestricted(); 901 if (shouldEnableNfc()) { 902 new EnableDisableTask().execute(TASK_ENABLE); 903 } else { 904 new EnableDisableTask().execute(TASK_DISABLE); 905 } 906 } 907 }, 908 new IntentFilter(UserManager.ACTION_USER_RESTRICTIONS_CHANGED) 909 ); 910 911 mNfcPermissions = new NfcPermissions(mContext); 912 mReaderOptionCapable = 913 mContext.getResources().getBoolean(R.bool.enable_reader_option_support); 914 915 if(mReaderOptionCapable) { 916 mIsReaderOptionEnabled = 917 mPrefs.getBoolean(PREF_NFC_READER_OPTION_ON, NFC_READER_OPTION_DEFAULT); 918 } 919 920 executeTaskBoot(); // do blocking boot tasks 921 922 if (NFC_SNOOP_LOG_MODE.equals(NfcProperties.snoop_log_mode_values.FULL) || 923 NFC_VENDOR_DEBUG_ENABLED) { 924 new NfcDeveloperOptionNotification(mContext).startNotification(); 925 } 926 927 connectToSeService(); 928 } 929 930 private AlarmManager.OnAlarmListener mDelayedBootAlarmListener = 931 () -> { 932 Log.i(TAG, "Executing delayed boot"); 933 mDelayedBootAlarmListenerSet = false; 934 new EnableDisableTask().execute(TASK_BOOT); 935 }; 936 private boolean mDelayedBootAlarmListenerSet = false; 937 executeTaskBoot()938 private void executeTaskBoot() { 939 // If overlay is set, delay the NFC boot up until the OEM extension indicates it is ready to 940 // proceed with NFC bootup. 941 if (mContext.getResources().getBoolean(R.bool.enable_oem_extension)) { 942 mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, 943 mNfcInjector.getElapsedSinceBootMillis() + WAIT_FOR_OEM_ALLOW_BOOT_TIMEOUT_MS, 944 WAIT_FOR_OEM_ALLOW_BOOT_TIMER_TAG, mDelayedBootAlarmListener, mHandler); 945 mDelayedBootAlarmListenerSet = true; 946 return; 947 } 948 new EnableDisableTask().execute(TASK_BOOT); 949 } 950 initTagAppPrefList()951 private void initTagAppPrefList() { 952 if (!mIsTagAppPrefSupported) return; 953 mTagAppPrefList.clear(); 954 mTagAppPrefListPrefs = mContext.getSharedPreferences(PREF_TAG_APP_LIST, 955 Context.MODE_PRIVATE); 956 try { 957 if (mTagAppPrefListPrefs != null) { 958 UserManager um = mContext.createContextAsUser( 959 UserHandle.of(ActivityManager.getCurrentUser()), 0) 960 .getSystemService(UserManager.class); 961 List<UserHandle> luh = um.getEnabledProfiles(); 962 for (UserHandle uh : luh) { 963 HashMap<String, Boolean> map = new HashMap<>(); 964 int userId = uh.getIdentifier(); 965 String jsonString = 966 mTagAppPrefListPrefs.getString(Integer.toString(userId), 967 (new JSONObject()).toString()); 968 if (jsonString != null) { 969 JSONObject jsonObject = new JSONObject(jsonString); 970 Iterator<String> keysItr = jsonObject.keys(); 971 while (keysItr.hasNext()) { 972 String key = keysItr.next(); 973 Boolean value = jsonObject.getBoolean(key); 974 map.put(key, value); 975 if (DBG) Log.d(TAG, "uid:" + userId + "key:" + key + ": " + value); 976 } 977 } 978 mTagAppPrefList.put(userId, map); 979 } 980 } else { 981 Log.e(TAG, "Can't get PREF_TAG_APP_LIST"); 982 } 983 } catch (JSONException e) { 984 Log.e(TAG, "JSONException: " + e); 985 } 986 } 987 storeTagAppPrefList()988 private void storeTagAppPrefList() { 989 if (!mIsTagAppPrefSupported) return; 990 mTagAppPrefListPrefs = mContext.getSharedPreferences(PREF_TAG_APP_LIST, 991 Context.MODE_PRIVATE); 992 if (mTagAppPrefListPrefs != null) { 993 UserManager um = mContext.createContextAsUser( 994 UserHandle.of(ActivityManager.getCurrentUser()), 0) 995 .getSystemService(UserManager.class); 996 List<UserHandle> luh = um.getEnabledProfiles(); 997 for (UserHandle uh : luh) { 998 SharedPreferences.Editor editor = mTagAppPrefListPrefs.edit(); 999 int userId = uh.getIdentifier(); 1000 HashMap<String, Boolean> map; 1001 synchronized (NfcService.this) { 1002 map = mTagAppPrefList.getOrDefault(userId, new HashMap<>()); 1003 } 1004 if (map.size() > 0) { 1005 String userIdStr = Integer.toString(userId); 1006 JSONObject jsonObject = new JSONObject(map); 1007 String jsonString = jsonObject.toString(); 1008 editor.remove(userIdStr).putString(userIdStr, jsonString).apply(); 1009 } 1010 } 1011 } else { 1012 Log.e(TAG, "Can't get PREF_TAG_APP_LIST"); 1013 } 1014 } isPackageInstalled(String pkgName, int userId)1015 private boolean isPackageInstalled(String pkgName, int userId) { 1016 final PackageInfo info; 1017 try { 1018 info = mContext.createContextAsUser(UserHandle.of(userId), 0) 1019 .getPackageManager().getPackageInfo(pkgName, PackageManager.MATCH_ALL); 1020 } catch (PackageManager.NameNotFoundException e) { 1021 return false; 1022 } 1023 return info != null; 1024 } 1025 // Remove obsolete entries 1026 // return true if the preference list changed. renewTagAppPrefList()1027 private boolean renewTagAppPrefList() { 1028 if (!mIsTagAppPrefSupported) return false; 1029 boolean changed = false; 1030 UserManager um = mContext.createContextAsUser( 1031 UserHandle.of(ActivityManager.getCurrentUser()), 0) 1032 .getSystemService(UserManager.class); 1033 List<UserHandle> luh = um.getEnabledProfiles(); 1034 for (UserHandle uh : luh) { 1035 int userId = uh.getIdentifier(); 1036 synchronized (NfcService.this) { 1037 changed = mTagAppPrefList.getOrDefault(userId, new HashMap<>()) 1038 .keySet().removeIf(k2 -> !isPackageInstalled(k2, userId)); 1039 } 1040 } 1041 if (DBG) Log.d(TAG, "TagAppPreference changed " + changed); 1042 return changed; 1043 } 1044 isSEServiceAvailable()1045 private boolean isSEServiceAvailable() { 1046 if (mSEService == null) { 1047 connectToSeService(); 1048 } 1049 return (mSEService != null); 1050 } 1051 connectToSeService()1052 private void connectToSeService() { 1053 try { 1054 mSEService = mNfcInjector.connectToSeService(); 1055 if (mSEService != null) { 1056 IBinder seServiceBinder = mSEService.asBinder(); 1057 seServiceBinder.linkToDeath(mSeServiceDeathRecipient, 0); 1058 } 1059 } catch (RemoteException e) { 1060 Log.e(TAG, "Error Registering SE service to linktoDeath : " + e); 1061 } 1062 } 1063 initSoundPool()1064 void initSoundPool() { 1065 synchronized (this) { 1066 if (mSoundPool == null) { 1067 mSoundPool = new SoundPool.Builder() 1068 .setMaxStreams(1) 1069 .setAudioAttributes( 1070 new AudioAttributes.Builder() 1071 .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) 1072 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) 1073 .build()) 1074 .build(); 1075 mStartSound = mSoundPool.load(mContext, R.raw.start, 1); 1076 mEndSound = mSoundPool.load(mContext, R.raw.end, 1); 1077 mErrorSound = mSoundPool.load(mContext, R.raw.error, 1); 1078 } 1079 } 1080 } 1081 releaseSoundPool()1082 void releaseSoundPool() { 1083 synchronized (this) { 1084 if (mSoundPool != null) { 1085 mSoundPool.release(); 1086 mSoundPool = null; 1087 } 1088 } 1089 } 1090 updatePackageCache()1091 void updatePackageCache() { 1092 UserManager um = mContext.createContextAsUser( 1093 UserHandle.of(ActivityManager.getCurrentUser()), /*flags=*/0) 1094 .getSystemService(UserManager.class); 1095 List<UserHandle> luh = um.getEnabledProfiles(); 1096 1097 synchronized (this) { 1098 mNfcEventInstalledPackages.clear(); 1099 mNfcPreferredPaymentChangedInstalledPackages.clear(); 1100 for (UserHandle uh : luh) { 1101 if (um.isQuietModeEnabled(uh)) continue; 1102 1103 PackageManager pm; 1104 try { 1105 pm = mContext.createContextAsUser(uh, /*flags=*/0).getPackageManager(); 1106 } catch (IllegalStateException e) { 1107 Log.d(TAG, "Fail to get PackageManager for user: " + uh); 1108 continue; 1109 } 1110 1111 List<PackageInfo> packagesNfcEvents = pm.getPackagesHoldingPermissions( 1112 new String[] {android.Manifest.permission.NFC_TRANSACTION_EVENT}, 1113 PackageManager.GET_ACTIVITIES); 1114 List<PackageInfo> packagesNfcPreferredPaymentChanged = 1115 pm.getPackagesHoldingPermissions( 1116 new String[] {android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO}, 1117 PackageManager.GET_ACTIVITIES); 1118 List<String> packageListNfcEvent = new ArrayList<String>(); 1119 for (int i = 0; i < packagesNfcEvents.size(); i++) { 1120 packageListNfcEvent.add(packagesNfcEvents.get(i).packageName); 1121 } 1122 mNfcEventInstalledPackages.put(uh.getIdentifier(), packageListNfcEvent); 1123 1124 List<String> packageListNfcPreferredPaymentChanged = new ArrayList<String>(); 1125 for (int i = 0; i < packagesNfcPreferredPaymentChanged.size(); i++) { 1126 packageListNfcPreferredPaymentChanged.add( 1127 packagesNfcPreferredPaymentChanged.get(i).packageName); 1128 } 1129 mNfcPreferredPaymentChangedInstalledPackages.put( 1130 uh.getIdentifier(), packageListNfcPreferredPaymentChanged); 1131 } 1132 } 1133 } 1134 1135 /** 1136 * Manages tasks that involve turning on/off the NFC controller. 1137 * <p/> 1138 * <p>All work that might turn the NFC adapter on or off must be done 1139 * through this task, to keep the handling of mState simple. 1140 * In other words, mState is only modified in these tasks (and we 1141 * don't need a lock to read it in these tasks). 1142 * <p/> 1143 * <p>These tasks are all done on the same AsyncTask background 1144 * thread, so they are serialized. Each task may temporarily transition 1145 * mState to STATE_TURNING_OFF or STATE_TURNING_ON, but must exit in 1146 * either STATE_ON or STATE_OFF. This way each task can be guaranteed 1147 * of starting in either STATE_OFF or STATE_ON, without needing to hold 1148 * NfcService.this for the entire task. 1149 * <p/> 1150 * <p>AsyncTask's are also implicitly queued. This is useful for corner 1151 * cases like turning airplane mode on while TASK_ENABLE is in progress. 1152 * The TASK_DISABLE triggered by airplane mode will be correctly executed 1153 * immediately after TASK_ENABLE is complete. This seems like the most sane 1154 * way to deal with these situations. 1155 * <p/> 1156 * <p>{@link #TASK_ENABLE} enables the NFC adapter, without changing 1157 * preferences 1158 * <p>{@link #TASK_DISABLE} disables the NFC adapter, without changing 1159 * preferences 1160 * <p>{@link #TASK_BOOT} does first boot work and may enable NFC 1161 */ 1162 class EnableDisableTask extends AsyncTask<Integer, Void, Void> { 1163 @Override doInBackground(Integer... params)1164 protected Void doInBackground(Integer... params) { 1165 // Quick check mState 1166 switch (mState) { 1167 case NfcAdapter.STATE_TURNING_OFF: 1168 case NfcAdapter.STATE_TURNING_ON: 1169 Log.e(TAG, "Processing EnableDisable task " + params[0] + " from bad state " + 1170 mState); 1171 return null; 1172 } 1173 1174 /* AsyncTask sets this thread to THREAD_PRIORITY_BACKGROUND, 1175 * override with the default. THREAD_PRIORITY_BACKGROUND causes 1176 * us to service software I2C too slow for firmware download 1177 * with the NXP PN544. 1178 * TODO: move this to the DAL I2C layer in libnfc-nxp, since this 1179 * problem only occurs on I2C platforms using PN544 1180 */ 1181 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1182 1183 switch (params[0].intValue()) { 1184 case TASK_ENABLE: 1185 enableInternal(); 1186 if (sIsNfcRestore && mIsTagAppPrefSupported) { 1187 synchronized (NfcService.this) { 1188 initTagAppPrefList(); 1189 sIsNfcRestore = false; 1190 } 1191 } 1192 break; 1193 case TASK_DISABLE: 1194 disableInternal(); 1195 break; 1196 case TASK_BOOT: 1197 // Initialize the event log cache. 1198 boolean initialized; 1199 if (mPrefs.getBoolean(PREF_FIRST_BOOT, true)) { 1200 Log.i(TAG, "First Boot"); 1201 mPrefsEditor.putBoolean(PREF_FIRST_BOOT, false); 1202 mPrefsEditor.apply(); 1203 mDeviceHost.factoryReset(); 1204 setPaymentForegroundPreference(mUserId); 1205 } 1206 Log.d(TAG, "checking on firmware download"); 1207 boolean enableNfc = shouldEnableNfc(); 1208 if (enableNfc) { 1209 Log.d(TAG, "NFC is on. Doing normal stuff"); 1210 initialized = enableInternal(); 1211 } else { 1212 Log.d(TAG, "NFC is off. Checking firmware version"); 1213 initialized = mDeviceHost.checkFirmware(); 1214 } 1215 mNfcEventLog.logEvent( 1216 NfcEventProto.EventType.newBuilder() 1217 .setBootupState(NfcEventProto.NfcBootupState.newBuilder() 1218 .setEnabled(enableNfc) 1219 .build()) 1220 .build()); 1221 if (initialized) { 1222 // TODO(279846422) The system property will be temporary 1223 // available for vendors that depend on it. 1224 // Remove this code when a replacement API is added. 1225 NfcProperties.initialized(true); 1226 } 1227 if (mIsTagAppPrefSupported) { 1228 synchronized (NfcService.this) { 1229 initTagAppPrefList(); 1230 } 1231 } 1232 break; 1233 case TASK_ENABLE_ALWAYS_ON: 1234 enableAlwaysOnInternal(); 1235 break; 1236 case TASK_DISABLE_ALWAYS_ON: 1237 disableAlwaysOnInternal(); 1238 break; 1239 } 1240 1241 // Restore default AsyncTask priority 1242 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1243 return null; 1244 } 1245 1246 /** 1247 * Enable NFC adapter functions. 1248 * Does not toggle preferences. 1249 */ enableInternal()1250 boolean enableInternal() { 1251 if (mState == NfcAdapter.STATE_ON) { 1252 return true; 1253 } 1254 Log.i(TAG, "Enabling NFC"); 1255 NfcStatsLog.write(NfcStatsLog.NFC_STATE_CHANGED, 1256 mIsSecureNfcEnabled ? NfcStatsLog.NFC_STATE_CHANGED__STATE__ON_LOCKED : 1257 NfcStatsLog.NFC_STATE_CHANGED__STATE__ON); 1258 updateState(NfcAdapter.STATE_TURNING_ON); 1259 1260 WatchDogThread watchDog = new WatchDogThread("enableInternal", INIT_WATCHDOG_MS); 1261 watchDog.start(); 1262 try { 1263 mRoutingWakeLock.acquire(); 1264 try { 1265 if (!mIsAlwaysOnSupported || mIsRecovering 1266 || (mAlwaysOnState != NfcAdapter.STATE_ON 1267 && mAlwaysOnState != NfcAdapter.STATE_TURNING_OFF)) { 1268 if (mIsRecovering) { 1269 // Recovering needs the full init. Put default value 1270 mAlwaysOnState = NfcAdapter.STATE_OFF; 1271 } 1272 if (!mDeviceHost.initialize()) { 1273 Log.w(TAG, "Error enabling NFC"); 1274 updateState(NfcAdapter.STATE_OFF); 1275 return false; 1276 } 1277 } else if (mAlwaysOnState == NfcAdapter.STATE_ON 1278 || mAlwaysOnState == NfcAdapter.STATE_TURNING_OFF) { 1279 Log.i(TAG, "Already initialized"); 1280 } else { 1281 Log.e(TAG, "Unexptected bad state " + mAlwaysOnState); 1282 updateState(NfcAdapter.STATE_OFF); 1283 return false; 1284 } 1285 } finally { 1286 if (mRoutingWakeLock.isHeld()) { 1287 mRoutingWakeLock.release(); 1288 } 1289 } 1290 } finally { 1291 watchDog.cancel(); 1292 } 1293 1294 mSkipNdefRead = NfcProperties.skipNdefRead().orElse(false); 1295 nci_version = getNciVersion(); 1296 Log.d(TAG, "NCI_Version: " + nci_version); 1297 1298 mPendingPowerStateUpdate = false; 1299 1300 synchronized (NfcService.this) { 1301 mObjectMap.clear(); 1302 updateState(NfcAdapter.STATE_ON); 1303 1304 onPreferredPaymentChanged(NfcAdapter.PREFERRED_PAYMENT_LOADED); 1305 } 1306 1307 initSoundPool(); 1308 1309 if (mInProvisionMode) { 1310 mScreenState = mScreenStateHelper.checkScreenStateProvisionMode(); 1311 } else { 1312 mScreenState = mScreenStateHelper.checkScreenState(); 1313 } 1314 int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ? 1315 (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState; 1316 1317 if(mNfcUnlockManager.isLockscreenPollingEnabled()) 1318 applyRouting(false); 1319 1320 mDeviceHost.doSetScreenState(screen_state_mask, mIsWlcEnabled); 1321 1322 sToast_debounce = false; 1323 1324 int pollTech = -1; 1325 if (mPrefs.contains(PREF_POLL_TECH)) { 1326 pollTech = getNfcPollTech(); 1327 } 1328 int listenTech = -1; 1329 if (mPrefs.contains(PREF_LISTEN_TECH)) { 1330 listenTech = getNfcListenTech(); 1331 } 1332 if (listenTech == -1 || listenTech == DEFAULT_LISTEN_TECH) 1333 listenTech = (NfcAdapter.FLAG_LISTEN_KEEP|NfcAdapter.FLAG_USE_ALL_TECH); 1334 1335 if (pollTech == -1 || pollTech == DEFAULT_POLL_TECH) 1336 pollTech = (NfcAdapter.FLAG_READER_KEEP|NfcAdapter.FLAG_USE_ALL_TECH); 1337 1338 mDeviceHost.setDiscoveryTech(pollTech|NfcAdapter.FLAG_SET_DEFAULT_TECH, 1339 listenTech|NfcAdapter.FLAG_SET_DEFAULT_TECH); 1340 1341 /* Skip applyRouting if always on state is switching */ 1342 if (!mIsAlwaysOnSupported 1343 || (mAlwaysOnState != NfcAdapter.STATE_TURNING_ON 1344 && mAlwaysOnState != NfcAdapter.STATE_TURNING_OFF)) { 1345 /* Start polling loop */ 1346 applyRouting(true); 1347 } 1348 1349 if (mIsHceCapable) { 1350 // Generate the initial card emulation routing table 1351 mCardEmulationManager.onNfcEnabled(); 1352 } 1353 1354 if (mIsRecovering) { 1355 // Intents for all users 1356 registerGlobalBroadcastsReceiver(); 1357 mIsRecovering = false; 1358 } 1359 1360 if(mIsPowerSavingModeEnabled) { 1361 mDeviceHost.setPowerSavingMode(false); 1362 mIsPowerSavingModeEnabled = false; 1363 } 1364 1365 return true; 1366 } 1367 1368 /** 1369 * Disable all NFC adapter functions. 1370 * Does not toggle preferences. 1371 */ disableInternal()1372 boolean disableInternal() { 1373 if (mState == NfcAdapter.STATE_OFF) { 1374 return true; 1375 } 1376 Log.i(TAG, "Disabling NFC"); 1377 NfcStatsLog.write( 1378 NfcStatsLog.NFC_STATE_CHANGED, NfcStatsLog.NFC_STATE_CHANGED__STATE__OFF); 1379 updateState(NfcAdapter.STATE_TURNING_OFF); 1380 1381 /* Sometimes mDeviceHost.deinitialize() hangs, use a watch-dog. 1382 * Implemented with a new thread (instead of a Handler or AsyncTask), 1383 * because the UI Thread and AsyncTask thread-pools can also get hung 1384 * when the NFC controller stops responding */ 1385 WatchDogThread watchDog = new WatchDogThread("disableInternal", ROUTING_WATCHDOG_MS); 1386 watchDog.start(); 1387 1388 if (mIsWlcEnabled) { 1389 if (mNfcCharging.NfcChargingOnGoing == true) { 1390 mNfcCharging.disconnectNfcCharging(); 1391 mNfcCharging.NfcChargingOnGoing = false; 1392 } 1393 mNfcCharging.resetInternalValues(); 1394 } 1395 1396 if (mIsHceCapable) { 1397 mCardEmulationManager.onNfcDisabled(); 1398 } 1399 1400 // Stop watchdog if tag present 1401 // A convenient way to stop the watchdog properly consists of 1402 // disconnecting the tag. The polling loop shall be stopped before 1403 // to avoid the tag being discovered again. 1404 maybeDisconnectTarget(); 1405 1406 synchronized (NfcService.this) { 1407 // Disable delay polling when disabling 1408 mPollDelayed = false; 1409 mPollDelayCount = 0; 1410 mReadErrorCount = 0; 1411 mHandler.removeMessages(MSG_DELAY_POLLING); 1412 mPollingDisableDeathRecipients.clear(); 1413 mReaderModeParams = null; 1414 mDiscoveryTechParams = null; 1415 } 1416 mNfcDispatcher.resetForegroundDispatch(); 1417 1418 boolean result; 1419 if (!mIsAlwaysOnSupported || mIsRecovering 1420 || (mAlwaysOnState == NfcAdapter.STATE_OFF) 1421 || (mAlwaysOnState == NfcAdapter.STATE_TURNING_OFF)) { 1422 result = mDeviceHost.deinitialize(); 1423 if (DBG) Log.d(TAG, "mDeviceHost.deinitialize() = " + result); 1424 } else { 1425 mDeviceHost.disableDiscovery(); 1426 result = true; 1427 Log.i(TAG, "AlwaysOn set, disableDiscovery()"); 1428 } 1429 1430 watchDog.cancel(); 1431 1432 synchronized (NfcService.this) { 1433 mCurrentDiscoveryParameters = NfcDiscoveryParameters.getNfcOffParameters(); 1434 updateState(NfcAdapter.STATE_OFF); 1435 } 1436 1437 releaseSoundPool(); 1438 1439 return result; 1440 } 1441 1442 /** 1443 * Enable always on feature. 1444 */ enableAlwaysOnInternal()1445 void enableAlwaysOnInternal() { 1446 if (mAlwaysOnState == NfcAdapter.STATE_ON) { 1447 return; 1448 } else if (mState == NfcAdapter.STATE_TURNING_ON 1449 || mAlwaysOnState == NfcAdapter.STATE_TURNING_OFF) { 1450 Log.e(TAG, "Processing enableAlwaysOnInternal() from bad state"); 1451 return; 1452 } else if (mState == NfcAdapter.STATE_ON) { 1453 updateAlwaysOnState(NfcAdapter.STATE_TURNING_ON); 1454 mDeviceHost.setNfceePowerAndLinkCtrl(true); 1455 updateAlwaysOnState(NfcAdapter.STATE_ON); 1456 } else if (mState == NfcAdapter.STATE_OFF) { 1457 /* Special case when NFCC is OFF without initialize. 1458 * Temperatorily enable NfcAdapter but don't applyRouting. 1459 * Then disable NfcAdapter without deinitialize to keep the NFCC stays initialized. 1460 * mState will switch back to OFF in the end. 1461 * And the NFCC stays initialized. 1462 */ 1463 updateAlwaysOnState(NfcAdapter.STATE_TURNING_ON); 1464 if (!enableInternal()) { 1465 updateAlwaysOnState(NfcAdapter.STATE_OFF); 1466 return; 1467 } 1468 disableInternal(); 1469 mDeviceHost.setNfceePowerAndLinkCtrl(true); 1470 updateAlwaysOnState(NfcAdapter.STATE_ON); 1471 } 1472 } 1473 1474 /** 1475 * Disable always on feature. 1476 */ disableAlwaysOnInternal()1477 void disableAlwaysOnInternal() { 1478 if (mAlwaysOnState == NfcAdapter.STATE_OFF) { 1479 return; 1480 } else if (mState == NfcAdapter.STATE_TURNING_ON 1481 || mAlwaysOnState == NfcAdapter.STATE_TURNING_OFF) { 1482 Log.e(TAG, "Processing disableAlwaysOnInternal() from bad state"); 1483 return; 1484 } else if (mState == NfcAdapter.STATE_ON) { 1485 updateAlwaysOnState(NfcAdapter.STATE_TURNING_OFF); 1486 mDeviceHost.setNfceePowerAndLinkCtrl(false); 1487 updateAlwaysOnState(NfcAdapter.STATE_OFF); 1488 } else if (mState == NfcAdapter.STATE_OFF) { 1489 /* Special case when mState is OFF but NFCC is already initialized. 1490 * Deinitialize mDevicehost directly. 1491 */ 1492 updateAlwaysOnState(NfcAdapter.STATE_TURNING_OFF); 1493 mDeviceHost.setNfceePowerAndLinkCtrl(false); 1494 boolean result = mDeviceHost.deinitialize(); 1495 if (DBG) Log.d(TAG, "mDeviceHost.deinitialize() = " + result); 1496 updateAlwaysOnState(NfcAdapter.STATE_OFF); 1497 } 1498 } 1499 updateState(int newState)1500 void updateState(int newState) { 1501 synchronized (NfcService.this) { 1502 if (newState == mState) { 1503 return; 1504 } 1505 mState = newState; 1506 if (mState == NfcAdapter.STATE_ON && mCardEmulationManager != null) { 1507 mCardEmulationManager.updateForShouldDefaultToObserveMode(getUserId()); 1508 } 1509 if (mAlwaysOnState != NfcAdapter.STATE_TURNING_ON) { 1510 Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED); 1511 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 1512 intent.putExtra(NfcAdapter.EXTRA_ADAPTER_STATE, mState); 1513 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT); 1514 } 1515 } 1516 } 1517 updateAlwaysOnState(int newState)1518 void updateAlwaysOnState(int newState) { 1519 synchronized (NfcService.this) { 1520 if (newState == mAlwaysOnState) { 1521 return; 1522 } 1523 mAlwaysOnState = newState; 1524 if (mAlwaysOnState == NfcAdapter.STATE_OFF 1525 || mAlwaysOnState == NfcAdapter.STATE_ON) { 1526 synchronized (mAlwaysOnListeners) { 1527 for (INfcControllerAlwaysOnListener listener 1528 : mAlwaysOnListeners) { 1529 try { 1530 listener.onControllerAlwaysOnChanged( 1531 mAlwaysOnState == NfcAdapter.STATE_ON); 1532 } catch (RemoteException e) { 1533 Log.e(TAG, "error in updateAlwaysOnState"); 1534 } 1535 } 1536 } 1537 } 1538 } 1539 } 1540 getAlwaysOnState()1541 int getAlwaysOnState() { 1542 synchronized (NfcService.this) { 1543 if (!mIsAlwaysOnSupported) { 1544 return NfcAdapter.STATE_OFF; 1545 } else { 1546 return mAlwaysOnState; 1547 } 1548 } 1549 } 1550 } 1551 playSound(int sound)1552 public void playSound(int sound) { 1553 synchronized (this) { 1554 if (mSoundPool == null) { 1555 Log.w(TAG, "Not playing sound when NFC is disabled"); 1556 return; 1557 } 1558 1559 if (mVrManager != null && mVrManager.isVrModeEnabled()) { 1560 Log.d(TAG, "Not playing NFC sound when Vr Mode is enabled"); 1561 return; 1562 } 1563 switch (sound) { 1564 case SOUND_START: 1565 mSoundPool.play(mStartSound, 1.0f, 1.0f, 0, 0, 1.0f); 1566 break; 1567 case SOUND_END: 1568 mSoundPool.play(mEndSound, 1.0f, 1.0f, 0, 0, 1.0f); 1569 break; 1570 case SOUND_ERROR: 1571 mSoundPool.play(mErrorSound, 1.0f, 1.0f, 0, 0, 1.0f); 1572 break; 1573 } 1574 } 1575 } 1576 getUserId()1577 synchronized int getUserId() { 1578 return mUserId; 1579 } 1580 resetReaderModeParams()1581 private void resetReaderModeParams() { 1582 synchronized (NfcService.this) { 1583 if (mPollingDisableDeathRecipients.size() == 0) { 1584 Log.d(TAG, "Disabling reader mode because app died or moved to background"); 1585 mReaderModeParams = null; 1586 StopPresenceChecking(); 1587 mNfcEventLog.logEvent( 1588 NfcEventProto.EventType.newBuilder() 1589 .setReaderModeChange(NfcEventProto.NfcReaderModeChange.newBuilder() 1590 .setFlags(0) 1591 .build()) 1592 .build()); 1593 if (isNfcEnabled()) { 1594 applyRouting(false); 1595 } 1596 } 1597 } 1598 } 1599 1600 @Override onUidToBackground(int uid)1601 public void onUidToBackground(int uid) { 1602 Log.i(TAG, "Uid " + uid + " switch to background."); 1603 synchronized (NfcService.this) { 1604 if (mReaderModeParams != null && mReaderModeParams.uid == uid) { 1605 mReaderModeParams.binder.unlinkToDeath(mReaderModeDeathRecipient, 0); 1606 resetReaderModeParams(); 1607 } 1608 } 1609 synchronized (NfcService.this) { 1610 if (mDiscoveryTechParams != null && mDiscoveryTechParams.uid == uid) { 1611 mDiscoveryTechParams.binder.unlinkToDeath(mDiscoveryTechDeathRecipient, 0); 1612 mDeviceHost.resetDiscoveryTech(); 1613 mDiscoveryTechParams = null; 1614 if (isNfcEnabled()) { 1615 applyRouting(true); 1616 } 1617 } 1618 } 1619 } 1620 enableNfc()1621 public void enableNfc() { 1622 saveNfcOnSetting(true); 1623 1624 if (shouldEnableNfc()) { 1625 new EnableDisableTask().execute(TASK_ENABLE); 1626 } 1627 } 1628 getAppName(@onNull String packageName, int uid)1629 private @NonNull CharSequence getAppName(@NonNull String packageName, int uid) { 1630 ApplicationInfo applicationInfo = null; 1631 try { 1632 applicationInfo = mContext.getPackageManager().getApplicationInfoAsUser( 1633 packageName, 0, UserHandle.getUserHandleForUid(uid)); 1634 } catch (PackageManager.NameNotFoundException e) { 1635 Log.e(TAG, "Failed to find app name for " + packageName); 1636 return ""; 1637 } 1638 return mContext.getPackageManager().getApplicationLabel(applicationInfo); 1639 } 1640 isSecureNfcEnabled()1641 public boolean isSecureNfcEnabled() { 1642 return mIsSecureNfcEnabled; 1643 } 1644 1645 /** Helper method to check if the entity initiating the binder call is a DO/PO app. */ isDeviceOrProfileOwner(int uid, String packageName)1646 private boolean isDeviceOrProfileOwner(int uid, String packageName) { 1647 return mNfcPermissions.isDeviceOwner(uid, packageName) 1648 || mNfcPermissions.isProfileOwner(uid, packageName); 1649 } 1650 1651 final class NfcAdapterService extends INfcAdapter.Stub { isPrivileged(int callingUid)1652 private boolean isPrivileged(int callingUid) { 1653 // Check for root uid to help invoking privileged APIs from rooted shell only. 1654 return callingUid == Process.SYSTEM_UID 1655 || callingUid == Process.NFC_UID 1656 || callingUid == Process.ROOT_UID; 1657 } 1658 1659 @Override enable(String pkg)1660 public boolean enable(String pkg) throws RemoteException { 1661 boolean isDeviceOrProfileOwner = isDeviceOrProfileOwner(Binder.getCallingUid(), pkg); 1662 if (!NfcPermissions.checkAdminPermissions(mContext) 1663 && !isDeviceOrProfileOwner) { 1664 throw new SecurityException( 1665 "caller is not a system app, device owner or profile owner!"); 1666 } 1667 if (!isDeviceOrProfileOwner && mIsNfcUserChangeRestricted) { 1668 throw new SecurityException("Change nfc state by system app is not allowed!"); 1669 } 1670 1671 Log.i(TAG, "Enabling Nfc service. Package:" + pkg); 1672 List<String> allowlist = new ArrayList<>( 1673 Arrays.asList(mContext.getResources().getStringArray(R.array.nfc_allow_list))); 1674 if (!allowlist.isEmpty() && !allowlist.contains(pkg)) { 1675 Intent allowUsingNfcIntent = new Intent() 1676 .putExtra(APP_NAME_ENABLING_NFC, getAppName(pkg, mUserId)) 1677 .setClass(mContext, NfcEnableAllowlistActivity.class); 1678 1679 mContext.startActivityAsUser(allowUsingNfcIntent, UserHandle.CURRENT); 1680 return true; 1681 } 1682 mNfcEventLog.logEvent( 1683 NfcEventProto.EventType.newBuilder() 1684 .setStateChange(NfcEventProto.NfcStateChange.newBuilder() 1685 .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder() 1686 .setPackageName(pkg) 1687 .setUid(Binder.getCallingUid()) 1688 .build()) 1689 .setEnabled(true) 1690 .build()) 1691 .build()); 1692 enableNfc(); 1693 return true; 1694 } 1695 1696 @Override disable(boolean saveState, String pkg)1697 public boolean disable(boolean saveState, String pkg) throws RemoteException { 1698 boolean isDeviceOrProfileOwner = isDeviceOrProfileOwner(Binder.getCallingUid(), pkg); 1699 if (!NfcPermissions.checkAdminPermissions(mContext) 1700 && !isDeviceOrProfileOwner) { 1701 throw new SecurityException( 1702 "caller is not a system app, device owner or profile owner!"); 1703 } 1704 if (!isDeviceOrProfileOwner && mIsNfcUserChangeRestricted) { 1705 throw new SecurityException("Change nfc state by system app is not allowed!"); 1706 } 1707 1708 Log.i(TAG, "Disabling Nfc service. Package:" + pkg); 1709 if (saveState) { 1710 saveNfcOnSetting(false); 1711 } 1712 1713 mNfcEventLog.logEvent( 1714 NfcEventProto.EventType.newBuilder() 1715 .setStateChange(NfcEventProto.NfcStateChange.newBuilder() 1716 .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder() 1717 .setPackageName(pkg) 1718 .setUid(Binder.getCallingUid()) 1719 .build()) 1720 .setEnabled(false) 1721 .build()) 1722 .build()); 1723 new EnableDisableTask().execute(TASK_DISABLE); 1724 1725 return true; 1726 } 1727 1728 @Override isObserveModeSupported()1729 public boolean isObserveModeSupported() { 1730 if (!isNfcEnabled()) { 1731 Log.e(TAG, "isObserveModeSupported: NFC must be enabled but is: " + mState); 1732 return false; 1733 } 1734 long token = Binder.clearCallingIdentity(); 1735 try { 1736 if (!android.nfc.Flags.nfcObserveMode()) { 1737 return false; 1738 } 1739 } finally { 1740 Binder.restoreCallingIdentity(token); 1741 } 1742 return mDeviceHost.isObserveModeSupported(); 1743 } 1744 1745 @Override isObserveModeEnabled()1746 public synchronized boolean isObserveModeEnabled() { 1747 if (!isNfcEnabled()) { 1748 Log.e(TAG, "isObserveModeEnabled: NFC must be enabled but is: " + mState); 1749 return false; 1750 } 1751 NfcPermissions.enforceUserPermissions(mContext); 1752 return mDeviceHost.isObserveModeEnabled(); 1753 } 1754 1755 @Override setObserveMode(boolean enable, String packageName)1756 public synchronized boolean setObserveMode(boolean enable, String packageName) { 1757 if (!isNfcEnabled()) { 1758 Log.e(TAG, "setObserveMode: NFC must be enabled but is: " + mState); 1759 return false; 1760 } 1761 int callingUid = Binder.getCallingUid(); 1762 int triggerSource = 1763 NFC_OBSERVE_MODE_STATE_CHANGED__TRIGGER_SOURCE__TRIGGER_SOURCE_UNKNOWN; 1764 if (!isPrivileged(callingUid)) { 1765 NfcPermissions.enforceUserPermissions(mContext); 1766 if (packageName == null) { 1767 Log.e(TAG, "no package name associated with non-privileged calling UID"); 1768 } 1769 if (mCardEmulationManager.isPreferredServicePackageNameForUser(packageName, 1770 UserHandle.getUserHandleForUid(callingUid).getIdentifier())) { 1771 if (android.permission.flags.Flags.walletRoleEnabled()) { 1772 UserHandle user = Binder.getCallingUserHandle(); 1773 if (packageName != null) { 1774 triggerSource = packageName.equals(getWalletRoleHolder(user)) 1775 ? NFC_OBSERVE_MODE_STATE_CHANGED__TRIGGER_SOURCE__WALLET_ROLE_HOLDER 1776 : NFC_OBSERVE_MODE_STATE_CHANGED__TRIGGER_SOURCE__FOREGROUND_APP; 1777 } 1778 } else { 1779 if (mForegroundUtils.isInForeground(callingUid)) { 1780 triggerSource = 1781 NFC_OBSERVE_MODE_STATE_CHANGED__TRIGGER_SOURCE__FOREGROUND_APP; 1782 } 1783 } 1784 } else { 1785 Log.e(TAG, "setObserveMode: Caller not preferred NFC service."); 1786 return false; 1787 } 1788 } 1789 1790 if (mCardEmulationManager.isHostCardEmulationActivated()) { 1791 Log.w(TAG, "setObserveMode: Cannot set observe mode during a transaction."); 1792 return false; 1793 } 1794 1795 Log.d(TAG, "setObserveMode: package " + packageName + " with UID (" + callingUid 1796 + ") setting observe mode to " + enable); 1797 1798 long start = SystemClock.elapsedRealtime(); 1799 boolean result = mDeviceHost.setObserveMode(enable); 1800 if (result && mCardEmulationManager != null) { 1801 mCardEmulationManager.onObserveModeStateChange(enable); 1802 } 1803 int latency = Math.toIntExact(SystemClock.elapsedRealtime() - start); 1804 if (mStatsdUtils != null) { 1805 mStatsdUtils.logObserveModeStateChanged(enable, triggerSource, latency); 1806 } 1807 mNfcEventLog.logEvent( 1808 NfcEventProto.EventType.newBuilder() 1809 .setObserveModeChange(NfcEventProto.NfcObserveModeChange.newBuilder() 1810 .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder() 1811 .setPackageName(packageName) 1812 .setUid(callingUid) 1813 .build()) 1814 .setEnable(enable) 1815 .setLatencyMs(latency) 1816 .setResult(result) 1817 .build()) 1818 .build()); 1819 return result; 1820 } 1821 getWalletRoleHolder(UserHandle user)1822 private String getWalletRoleHolder(UserHandle user) { 1823 RoleManager roleManager = mContext.createContextAsUser(user, 0) 1824 .getSystemService(RoleManager.class); 1825 List<String> roleHolders = roleManager.getRoleHolders(RoleManager.ROLE_WALLET); 1826 return roleHolders.isEmpty() ? null : roleHolders.get(0); 1827 } 1828 1829 @Override pausePolling(int timeoutInMs)1830 public void pausePolling(int timeoutInMs) { 1831 NfcPermissions.enforceAdminPermissions(mContext); 1832 1833 if (timeoutInMs <= 0 || timeoutInMs > MAX_POLLING_PAUSE_TIMEOUT) { 1834 Log.e(TAG, "Refusing to pause polling for " + timeoutInMs + "ms."); 1835 return; 1836 } 1837 1838 synchronized (NfcService.this) { 1839 mPollingPaused = true; 1840 mDeviceHost.disableDiscovery(); 1841 mHandler.sendMessageDelayed( 1842 mHandler.obtainMessage(MSG_RESUME_POLLING), timeoutInMs); 1843 } 1844 } 1845 1846 @Override resumePolling()1847 public void resumePolling() { 1848 NfcPermissions.enforceAdminPermissions(mContext); 1849 1850 synchronized (NfcService.this) { 1851 if (!mPollingPaused) { 1852 return; 1853 } 1854 1855 mHandler.removeMessages(MSG_RESUME_POLLING); 1856 mPollingPaused = false; 1857 new ApplyRoutingTask().execute(); 1858 } 1859 if (DBG) Log.d(TAG, "Polling is resumed"); 1860 } 1861 1862 @Override isNfcSecureEnabled()1863 public boolean isNfcSecureEnabled() throws RemoteException { 1864 synchronized (NfcService.this) { 1865 return mIsSecureNfcEnabled; 1866 } 1867 } 1868 1869 @Override setNfcSecure(boolean enable)1870 public boolean setNfcSecure(boolean enable) { 1871 NfcPermissions.enforceAdminPermissions(mContext); 1872 if(mKeyguard.isKeyguardLocked() && !enable) { 1873 Log.i(TAG, "KeyGuard need to be unlocked before setting Secure NFC OFF"); 1874 return false; 1875 } 1876 1877 synchronized (NfcService.this) { 1878 if (mIsSecureNfcEnabled == enable) { 1879 Log.e(TAG, "setNfcSecure error, can't apply the same state twice!"); 1880 return false; 1881 } 1882 Log.i(TAG, "setting Secure NFC " + enable); 1883 mPrefsEditor.putBoolean(PREF_SECURE_NFC_ON, enable); 1884 mPrefsEditor.apply(); 1885 mIsSecureNfcEnabled = enable; 1886 mBackupManager.dataChanged(); 1887 mDeviceHost.setNfcSecure(enable); 1888 if (mIsHceCapable) { 1889 // update HCE/HCEF routing and commitRouting if Nfc is enabled 1890 mCardEmulationManager.onSecureNfcToggled(); 1891 } else if (isNfcEnabled()) { 1892 // commit only tech/protocol route without HCE support 1893 mDeviceHost.commitRouting(); 1894 } 1895 } 1896 1897 NfcStatsLog.write(NfcStatsLog.NFC_STATE_CHANGED, 1898 mIsSecureNfcEnabled ? NfcStatsLog.NFC_STATE_CHANGED__STATE__ON_LOCKED : 1899 NfcStatsLog.NFC_STATE_CHANGED__STATE__ON); 1900 return true; 1901 } 1902 1903 @Override setForegroundDispatch(PendingIntent intent, IntentFilter[] filters, TechListParcel techListsParcel)1904 public void setForegroundDispatch(PendingIntent intent, 1905 IntentFilter[] filters, TechListParcel techListsParcel) { 1906 NfcPermissions.enforceUserPermissions(mContext); 1907 if (!mForegroundUtils.isInForeground(Binder.getCallingUid())) { 1908 Log.e(TAG, "setForegroundDispatch: Caller not in foreground."); 1909 return; 1910 } 1911 // Short-cut the disable path 1912 if (intent == null && filters == null && techListsParcel == null) { 1913 mNfcDispatcher.resetForegroundDispatch(); 1914 return; 1915 } 1916 1917 // Validate the IntentFilters 1918 if (filters != null) { 1919 if (filters.length == 0) { 1920 filters = null; 1921 } else { 1922 for (IntentFilter filter : filters) { 1923 if (filter == null) { 1924 throw new IllegalArgumentException("null IntentFilter"); 1925 } 1926 } 1927 } 1928 } 1929 1930 // Validate the tech lists 1931 String[][] techLists = null; 1932 if (techListsParcel != null) { 1933 techLists = techListsParcel.getTechLists(); 1934 } 1935 1936 mNfcDispatcher.setForegroundDispatch(intent, filters, techLists); 1937 } 1938 1939 1940 @Override setAppCallback(IAppCallback callback)1941 public void setAppCallback(IAppCallback callback) { 1942 NfcPermissions.enforceUserPermissions(mContext); 1943 } 1944 1945 @Override ignore(int nativeHandle, int debounceMs, ITagRemovedCallback callback)1946 public boolean ignore(int nativeHandle, int debounceMs, ITagRemovedCallback callback) 1947 throws RemoteException { 1948 NfcPermissions.enforceUserPermissions(mContext); 1949 1950 if (debounceMs == 0 && mDebounceTagNativeHandle != INVALID_NATIVE_HANDLE 1951 && nativeHandle == mDebounceTagNativeHandle) { 1952 // Remove any previous messages and immediately debounce. 1953 mHandler.removeMessages(MSG_TAG_DEBOUNCE); 1954 mHandler.sendEmptyMessage(MSG_TAG_DEBOUNCE); 1955 return true; 1956 } 1957 1958 TagEndpoint tag = (TagEndpoint) findAndRemoveObject(nativeHandle); 1959 if (tag != null) { 1960 // Store UID and params 1961 int uidLength = tag.getUid().length; 1962 synchronized (NfcService.this) { 1963 mDebounceTagDebounceMs = debounceMs; 1964 mDebounceTagNativeHandle = nativeHandle; 1965 mDebounceTagUid = new byte[uidLength]; 1966 mDebounceTagRemovedCallback = callback; 1967 System.arraycopy(tag.getUid(), 0, mDebounceTagUid, 0, uidLength); 1968 } 1969 1970 // Disconnect from this tag; this should resume the normal 1971 // polling loop (and enter listen mode for a while), before 1972 // we pick up any tags again. 1973 tag.disconnect(); 1974 mHandler.sendEmptyMessageDelayed(MSG_TAG_DEBOUNCE, debounceMs); 1975 return true; 1976 } else { 1977 return false; 1978 } 1979 } 1980 1981 @Override verifyNfcPermission()1982 public void verifyNfcPermission() { 1983 NfcPermissions.enforceUserPermissions(mContext); 1984 } 1985 1986 @Override getNfcTagInterface()1987 public INfcTag getNfcTagInterface() throws RemoteException { 1988 return mNfcTagService; 1989 } 1990 1991 @Override getNfcCardEmulationInterface()1992 public INfcCardEmulation getNfcCardEmulationInterface() { 1993 if (mIsHceCapable) { 1994 return mCardEmulationManager.getNfcCardEmulationInterface(); 1995 } else { 1996 return null; 1997 } 1998 } 1999 2000 @Override getNfcFCardEmulationInterface()2001 public INfcFCardEmulation getNfcFCardEmulationInterface() { 2002 if (mIsHceFCapable) { 2003 return mCardEmulationManager.getNfcFCardEmulationInterface(); 2004 } else { 2005 return null; 2006 } 2007 } 2008 2009 @Override getState()2010 public int getState() throws RemoteException { 2011 synchronized (NfcService.this) { 2012 return mState; 2013 } 2014 } 2015 2016 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)2017 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2018 NfcService.this.dump(fd, pw, args); 2019 } 2020 2021 @Override dispatch(Tag tag)2022 public void dispatch(Tag tag) throws RemoteException { 2023 NfcPermissions.enforceAdminPermissions(mContext); 2024 mNfcDispatcher.dispatchTag(tag); 2025 } 2026 2027 @Override updateDiscoveryTechnology(IBinder binder, int pollTech, int listenTech)2028 public void updateDiscoveryTechnology(IBinder binder, int pollTech, int listenTech) 2029 throws RemoteException { 2030 NfcPermissions.enforceUserPermissions(mContext); 2031 int callingUid = Binder.getCallingUid(); 2032 boolean privilegedCaller = isPrivileged(callingUid) 2033 || NfcPermissions.checkAdminPermissions(mContext); 2034 // Allow non-foreground callers with system uid or systemui 2035 String packageName = getPackageNameFromUid(callingUid); 2036 if (packageName != null) { 2037 privilegedCaller |= packageName.equals(SYSTEM_UI); 2038 } 2039 Log.d(TAG, "updateDiscoveryTechnology: uid=" + callingUid + 2040 ", packageName: " + packageName); 2041 if (!privilegedCaller) { 2042 pollTech &= ~NfcAdapter.FLAG_SET_DEFAULT_TECH; 2043 listenTech &= ~NfcAdapter.FLAG_SET_DEFAULT_TECH; 2044 if (!mForegroundUtils.registerUidToBackgroundCallback( 2045 NfcService.this, callingUid)) { 2046 Log.e(TAG, 2047 "updateDiscoveryTechnology: Unprivileged caller shall be in foreground"); 2048 return; 2049 } 2050 } else if (((pollTech & NfcAdapter.FLAG_SET_DEFAULT_TECH) != 0 2051 || (listenTech & NfcAdapter.FLAG_SET_DEFAULT_TECH) != 0)) { 2052 2053 if ((pollTech & NfcAdapter.FLAG_SET_DEFAULT_TECH) != 0) { 2054 if ((pollTech & NfcAdapter.FLAG_READER_KEEP) == 0 && 2055 (pollTech & NfcAdapter.FLAG_USE_ALL_TECH) 2056 != NfcAdapter.FLAG_USE_ALL_TECH) { 2057 saveNfcPollTech(pollTech & ~NfcAdapter.FLAG_SET_DEFAULT_TECH); 2058 Log.i(TAG, "Default pollTech is set to 0x" + 2059 Integer.toHexString(pollTech)); 2060 } else if ((pollTech 2061 & (NfcAdapter.FLAG_READER_KEEP | NfcAdapter.FLAG_USE_ALL_TECH)) 2062 == (NfcAdapter.FLAG_READER_KEEP | NfcAdapter.FLAG_USE_ALL_TECH)){ 2063 saveNfcPollTech(DEFAULT_POLL_TECH); 2064 } 2065 } 2066 if ((listenTech & NfcAdapter.FLAG_SET_DEFAULT_TECH) != 0) { 2067 if ((listenTech & NfcAdapter.FLAG_LISTEN_KEEP) == 0 && 2068 (listenTech & NfcAdapter.FLAG_USE_ALL_TECH) 2069 != NfcAdapter.FLAG_USE_ALL_TECH) { 2070 saveNfcListenTech(listenTech & ~NfcAdapter.FLAG_SET_DEFAULT_TECH); 2071 Log.i(TAG, "Default listenTech is set to 0x" + 2072 Integer.toHexString(listenTech)); 2073 } else if ((listenTech 2074 & (NfcAdapter.FLAG_LISTEN_KEEP | NfcAdapter.FLAG_USE_ALL_TECH)) 2075 == (NfcAdapter.FLAG_LISTEN_KEEP | NfcAdapter.FLAG_USE_ALL_TECH)) { 2076 saveNfcListenTech(DEFAULT_LISTEN_TECH); 2077 } 2078 } 2079 mDeviceHost.setDiscoveryTech(pollTech, listenTech); 2080 applyRouting(true); 2081 return; 2082 } 2083 synchronized (NfcService.this) { 2084 if (!isNfcEnabled()) { 2085 Log.d(TAG, "updateDiscoveryTechnology: NFC is not enabled."); 2086 return; 2087 } 2088 2089 Log.d(TAG, "updateDiscoveryTechnology: pollTech: 0x" + 2090 Integer.toHexString(pollTech) + 2091 ", listenTech: 0x" + Integer.toHexString(listenTech)); 2092 if (pollTech == NfcAdapter.FLAG_USE_ALL_TECH && 2093 listenTech == NfcAdapter.FLAG_USE_ALL_TECH && 2094 mDiscoveryTechParams != null) { 2095 try { 2096 binder.unlinkToDeath(mDiscoveryTechDeathRecipient, 0); 2097 mDeviceHost.resetDiscoveryTech(); 2098 mDiscoveryTechParams = null; 2099 } catch (NoSuchElementException e) { 2100 Log.e(TAG, "Change Tech Binder was never registered."); 2101 } 2102 } else if (!(pollTech == NfcAdapter.FLAG_USE_ALL_TECH && // Do not call for 2103 // resetDiscoveryTech 2104 listenTech == NfcAdapter.FLAG_USE_ALL_TECH)) { 2105 try { 2106 mDeviceHost.setDiscoveryTech(pollTech, listenTech); 2107 mDiscoveryTechParams = new DiscoveryTechParams(); 2108 mDiscoveryTechParams.uid = callingUid; 2109 mDiscoveryTechParams.binder = binder; 2110 binder.linkToDeath(mDiscoveryTechDeathRecipient, 0); 2111 } catch (RemoteException e) { 2112 Log.e(TAG, "Remote binder has already died."); 2113 return; 2114 } 2115 } else { 2116 return; 2117 } 2118 2119 applyRouting(true); 2120 } 2121 } 2122 2123 @Override setReaderMode(IBinder binder, IAppCallback callback, int flags, Bundle extras)2124 public void setReaderMode(IBinder binder, IAppCallback callback, int flags, Bundle extras) 2125 throws RemoteException { 2126 int callingUid = Binder.getCallingUid(); 2127 int callingPid = Binder.getCallingPid(); 2128 boolean privilegedCaller = isPrivileged(callingUid) 2129 || NfcPermissions.checkAdminPermissions(mContext); 2130 // Allow non-foreground callers with system uid or systemui 2131 String packageName = getPackageNameFromUid(callingUid); 2132 if (packageName != null) { 2133 privilegedCaller |= packageName.equals(SYSTEM_UI); 2134 } 2135 Log.d(TAG, "setReaderMode: uid=" + callingUid + ", packageName: " 2136 + packageName + ", flags: " + flags); 2137 if (!privilegedCaller 2138 && !mForegroundUtils.registerUidToBackgroundCallback( 2139 NfcService.this, callingUid)) { 2140 Log.e(TAG, "setReaderMode: Caller is not in foreground and is not system process."); 2141 return; 2142 } 2143 boolean disablePolling = flags != 0 && getReaderModeTechMask(flags) == 0; 2144 // Only allow to disable polling for specific callers 2145 if (disablePolling && !(privilegedCaller && mPollingDisableAllowed)) { 2146 Log.e(TAG, "setReaderMode() called with invalid flag parameter."); 2147 return; 2148 } 2149 synchronized (NfcService.this) { 2150 if (!isNfcEnabled() && !privilegedCaller) { 2151 Log.e(TAG, "setReaderMode() called while NFC is not enabled."); 2152 return; 2153 } 2154 if (flags != 0) { 2155 try { 2156 if (disablePolling) { 2157 ReaderModeDeathRecipient pollingDisableDeathRecipient = 2158 new ReaderModeDeathRecipient(); 2159 binder.linkToDeath(pollingDisableDeathRecipient, 0); 2160 mPollingDisableDeathRecipients.put( 2161 callingPid, pollingDisableDeathRecipient); 2162 } else { 2163 if (mPollingDisableDeathRecipients.size() != 0) { 2164 Log.e(TAG, "active polling is forced to disable now."); 2165 return; 2166 } 2167 binder.linkToDeath(mReaderModeDeathRecipient, 0); 2168 } 2169 if (mPollDelayed) { 2170 mHandler.removeMessages(MSG_DELAY_POLLING); 2171 mPollDelayCount = 0; 2172 mReadErrorCount = 0; 2173 mPollDelayed = false; 2174 mDeviceHost.startStopPolling(true); 2175 if (DBG) Log.d(TAG, "setReaderMode() polling is started"); 2176 } 2177 updateReaderModeParams(callback, flags, extras, binder, callingUid); 2178 } catch (RemoteException e) { 2179 Log.e(TAG, "Remote binder has already died."); 2180 return; 2181 } 2182 } else { 2183 try { 2184 ReaderModeDeathRecipient pollingDisableDeathRecipient = 2185 mPollingDisableDeathRecipients.get(callingPid); 2186 mPollingDisableDeathRecipients.remove(callingPid); 2187 2188 if (mPollingDisableDeathRecipients.size() == 0) { 2189 mReaderModeParams = null; 2190 StopPresenceChecking(); 2191 } 2192 2193 if (pollingDisableDeathRecipient != null) { 2194 binder.unlinkToDeath(pollingDisableDeathRecipient, 0); 2195 } else { 2196 binder.unlinkToDeath(mReaderModeDeathRecipient, 0); 2197 } 2198 } catch (NoSuchElementException e) { 2199 Log.e(TAG, "Reader mode Binder was never registered."); 2200 } 2201 } 2202 mNfcEventLog.logEvent( 2203 NfcEventProto.EventType.newBuilder() 2204 .setReaderModeChange(NfcEventProto.NfcReaderModeChange.newBuilder() 2205 .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder() 2206 .setPackageName(packageName) 2207 .setUid(callingUid) 2208 .build()) 2209 .setFlags(flags) 2210 .build()) 2211 .build()); 2212 if (isNfcEnabled()) { 2213 applyRouting(false); 2214 } 2215 } 2216 } 2217 2218 @Override getNfcAdapterExtrasInterface(String pkg)2219 public INfcAdapterExtras getNfcAdapterExtrasInterface(String pkg) throws RemoteException { 2220 // nfc-extras implementation is no longer present in AOSP. 2221 return null; 2222 } 2223 2224 @Override getNfcDtaInterface(String pkg)2225 public INfcDta getNfcDtaInterface(String pkg) throws RemoteException { 2226 NfcPermissions.enforceAdminPermissions(mContext); 2227 if (mNfcDtaService == null) { 2228 mNfcDtaService = new NfcDtaService(); 2229 } 2230 return mNfcDtaService; 2231 } 2232 2233 @Override addNfcUnlockHandler(INfcUnlockHandler unlockHandler, int[] techList)2234 public void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, int[] techList) { 2235 NfcPermissions.enforceAdminPermissions(mContext); 2236 2237 int lockscreenPollMask = computeLockscreenPollMask(techList); 2238 synchronized (NfcService.this) { 2239 mNfcUnlockManager.addUnlockHandler(unlockHandler, lockscreenPollMask); 2240 } 2241 2242 applyRouting(false); 2243 } 2244 2245 @Override removeNfcUnlockHandler(INfcUnlockHandler token)2246 public void removeNfcUnlockHandler(INfcUnlockHandler token) throws RemoteException { 2247 synchronized (NfcService.this) { 2248 mNfcUnlockManager.removeUnlockHandler(token.asBinder()); 2249 } 2250 2251 applyRouting(false); 2252 } 2253 2254 @Override deviceSupportsNfcSecure()2255 public boolean deviceSupportsNfcSecure() { 2256 return mIsSecureNfcCapable; 2257 } 2258 2259 @Override getNfcAntennaInfo()2260 public NfcAntennaInfo getNfcAntennaInfo() { 2261 int positionX[] = mContext.getResources().getIntArray( 2262 R.array.antenna_x); 2263 int positionY[] = mContext.getResources().getIntArray( 2264 R.array.antenna_y); 2265 if(positionX.length != positionY.length){ 2266 return null; 2267 } 2268 int width = mContext.getResources().getInteger(R.integer.device_width); 2269 int height = mContext.getResources().getInteger(R.integer.device_height); 2270 List<AvailableNfcAntenna> availableNfcAntennas = new ArrayList<>(); 2271 for(int i = 0; i < positionX.length; i++){ 2272 if(positionX[i] >= width | positionY[i] >= height){ 2273 return null; 2274 } 2275 availableNfcAntennas.add(new AvailableNfcAntenna(positionX[i], positionY[i])); 2276 } 2277 return new NfcAntennaInfo( 2278 width, 2279 height, 2280 mContext.getResources().getBoolean(R.bool.device_foldable), 2281 availableNfcAntennas); 2282 } 2283 2284 @Override setWlcEnabled(boolean enable)2285 public boolean setWlcEnabled(boolean enable) { 2286 if (!mIsWlcCapable) { 2287 return false; 2288 } 2289 NfcPermissions.enforceAdminPermissions(mContext); 2290 // enable or disable WLC 2291 if (DBG) Log.d(TAG, "setWlcEnabled: " + enable); 2292 synchronized (NfcService.this) { 2293 // check whether NFC is enabled 2294 if (!isNfcEnabled()) { 2295 return false; 2296 } 2297 mPrefsEditor.putBoolean(PREF_NFC_CHARGING_ON, enable); 2298 mPrefsEditor.apply(); 2299 mIsWlcEnabled = enable; 2300 mBackupManager.dataChanged(); 2301 } 2302 return true; 2303 } 2304 2305 @Override isWlcEnabled()2306 public boolean isWlcEnabled() throws RemoteException { 2307 if (!mIsWlcCapable) { 2308 return false; 2309 } 2310 // check whether WLC is enabled or disabled 2311 synchronized (NfcService.this) { 2312 return mIsWlcEnabled; 2313 } 2314 } 2315 2316 @Override getWlcListenerDeviceInfo()2317 public WlcListenerDeviceInfo getWlcListenerDeviceInfo() { 2318 if (!mIsWlcCapable) { 2319 return null; 2320 } 2321 synchronized (NfcService.this) { 2322 return mWlcListenerDeviceInfo; 2323 } 2324 } 2325 computeLockscreenPollMask(int[] techList)2326 private int computeLockscreenPollMask(int[] techList) { 2327 2328 Map<Integer, Integer> techCodeToMask = new HashMap<Integer, Integer>(); 2329 2330 techCodeToMask.put(TagTechnology.NFC_A, NfcService.NFC_POLL_A); 2331 techCodeToMask.put(TagTechnology.NFC_B, NfcService.NFC_POLL_B); 2332 techCodeToMask.put(TagTechnology.NFC_V, NfcService.NFC_POLL_V); 2333 techCodeToMask.put(TagTechnology.NFC_F, NfcService.NFC_POLL_F); 2334 techCodeToMask.put(TagTechnology.NFC_BARCODE, NfcService.NFC_POLL_KOVIO); 2335 2336 int mask = 0; 2337 2338 for (int i = 0; i < techList.length; i++) { 2339 if (techCodeToMask.containsKey(techList[i])) { 2340 mask |= techCodeToMask.get(techList[i]).intValue(); 2341 } 2342 } 2343 2344 return mask; 2345 } 2346 getReaderModeTechMask(int flags)2347 private int getReaderModeTechMask(int flags) { 2348 int techMask = 0; 2349 if ((flags & NfcAdapter.FLAG_READER_NFC_A) != 0) { 2350 techMask |= NFC_POLL_A; 2351 } 2352 if ((flags & NfcAdapter.FLAG_READER_NFC_B) != 0) { 2353 techMask |= NFC_POLL_B; 2354 } 2355 if ((flags & NfcAdapter.FLAG_READER_NFC_F) != 0) { 2356 techMask |= NFC_POLL_F; 2357 } 2358 if ((flags & NfcAdapter.FLAG_READER_NFC_V) != 0) { 2359 techMask |= NFC_POLL_V; 2360 } 2361 if ((flags & NfcAdapter.FLAG_READER_NFC_BARCODE) != 0) { 2362 techMask |= NFC_POLL_KOVIO; 2363 } 2364 2365 return techMask; 2366 } 2367 getPackageNameFromUid(int uid)2368 private String getPackageNameFromUid(int uid) { 2369 PackageManager packageManager = mContext.getPackageManager(); 2370 if (packageManager != null) { 2371 String[] packageName = packageManager.getPackagesForUid(uid); 2372 if (packageName != null && packageName.length > 0) { 2373 return packageName[0]; 2374 } 2375 } 2376 return null; 2377 } 2378 updateReaderModeParams( IAppCallback callback, int flags, Bundle extras, IBinder binder, int uid)2379 private void updateReaderModeParams( 2380 IAppCallback callback, int flags, Bundle extras, IBinder binder, int uid) { 2381 synchronized (NfcService.this) { 2382 mReaderModeParams = new ReaderModeParams(); 2383 mReaderModeParams.callback = callback; 2384 mReaderModeParams.flags = flags; 2385 mReaderModeParams.presenceCheckDelay = extras != null 2386 ? (extras.getInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 2387 DEFAULT_PRESENCE_CHECK_DELAY)) 2388 : DEFAULT_PRESENCE_CHECK_DELAY; 2389 mReaderModeParams.binder = binder; 2390 mReaderModeParams.uid = uid; 2391 } 2392 } 2393 setTagAppPreferenceInternal(int userId, String pkg, boolean allow)2394 private int setTagAppPreferenceInternal(int userId, String pkg, boolean allow) { 2395 if (!isPackageInstalled(pkg, userId)) { 2396 return NfcAdapter.TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND; 2397 } 2398 if (DBG) Log.i(TAG, "UserId:" + userId + " pkg:" + pkg + ":" + allow); 2399 synchronized (NfcService.this) { 2400 mTagAppPrefList.computeIfAbsent(userId, key -> new HashMap<String, Boolean>()) 2401 .put(pkg, allow); 2402 } 2403 storeTagAppPrefList(); 2404 return NfcAdapter.TAG_INTENT_APP_PREF_RESULT_SUCCESS; 2405 } 2406 2407 @Override setControllerAlwaysOn(boolean value)2408 public boolean setControllerAlwaysOn(boolean value) throws RemoteException { 2409 NfcPermissions.enforceSetControllerAlwaysOnPermissions(mContext); 2410 if (!mIsAlwaysOnSupported) { 2411 return false; 2412 } 2413 if (value) { 2414 new EnableDisableTask().execute(TASK_ENABLE_ALWAYS_ON); 2415 } else { 2416 new EnableDisableTask().execute(TASK_DISABLE_ALWAYS_ON); 2417 } 2418 return true; 2419 } 2420 2421 @Override isControllerAlwaysOn()2422 public boolean isControllerAlwaysOn() throws RemoteException { 2423 NfcPermissions.enforceSetControllerAlwaysOnPermissions(mContext); 2424 return mIsAlwaysOnSupported && mAlwaysOnState == NfcAdapter.STATE_ON; 2425 } 2426 2427 @Override isControllerAlwaysOnSupported()2428 public boolean isControllerAlwaysOnSupported() throws RemoteException { 2429 NfcPermissions.enforceSetControllerAlwaysOnPermissions(mContext); 2430 return mIsAlwaysOnSupported; 2431 } 2432 2433 @Override registerControllerAlwaysOnListener( INfcControllerAlwaysOnListener listener)2434 public void registerControllerAlwaysOnListener( 2435 INfcControllerAlwaysOnListener listener) throws RemoteException { 2436 NfcPermissions.enforceSetControllerAlwaysOnPermissions(mContext); 2437 if (!mIsAlwaysOnSupported) return; 2438 2439 mAlwaysOnListeners.add(listener); 2440 } 2441 2442 @Override unregisterControllerAlwaysOnListener( INfcControllerAlwaysOnListener listener)2443 public void unregisterControllerAlwaysOnListener( 2444 INfcControllerAlwaysOnListener listener) throws RemoteException { 2445 NfcPermissions.enforceSetControllerAlwaysOnPermissions(mContext); 2446 if (!mIsAlwaysOnSupported) return; 2447 2448 mAlwaysOnListeners.remove(listener); 2449 } 2450 @Override isTagIntentAppPreferenceSupported()2451 public boolean isTagIntentAppPreferenceSupported() throws RemoteException { 2452 NfcPermissions.enforceAdminPermissions(mContext); 2453 return mIsTagAppPrefSupported; 2454 } 2455 @Override getTagIntentAppPreferenceForUser(int userId)2456 public Map getTagIntentAppPreferenceForUser(int userId) throws RemoteException { 2457 NfcPermissions.enforceAdminPermissions(mContext); 2458 if (!mIsTagAppPrefSupported) throw new UnsupportedOperationException(); 2459 synchronized (NfcService.this) { 2460 return mTagAppPrefList.getOrDefault(userId, new HashMap<>()); 2461 } 2462 } 2463 @Override setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)2464 public int setTagIntentAppPreferenceForUser(int userId, 2465 String pkg, boolean allow) throws RemoteException { 2466 NfcPermissions.enforceAdminPermissions(mContext); 2467 if (!mIsTagAppPrefSupported) throw new UnsupportedOperationException(); 2468 return setTagAppPreferenceInternal(userId, pkg, allow); 2469 } 2470 2471 @Override enableReaderOption(boolean enable)2472 public boolean enableReaderOption(boolean enable) { 2473 Log.d(TAG, "enableReaderOption enabled=" + enable); 2474 if (!mReaderOptionCapable) return false; 2475 NfcPermissions.enforceAdminPermissions(mContext); 2476 synchronized (NfcService.this) { 2477 mPrefsEditor.putBoolean(PREF_NFC_READER_OPTION_ON, enable); 2478 mPrefsEditor.apply(); 2479 mIsReaderOptionEnabled = enable; 2480 mBackupManager.dataChanged(); 2481 } 2482 applyRouting(true); 2483 return true; 2484 } 2485 2486 @Override isReaderOptionSupported()2487 public boolean isReaderOptionSupported() { 2488 return mReaderOptionCapable; 2489 } 2490 2491 @Override isReaderOptionEnabled()2492 public boolean isReaderOptionEnabled() { 2493 return mIsReaderOptionEnabled; 2494 } 2495 2496 @Override registerWlcStateListener( INfcWlcStateListener listener)2497 public void registerWlcStateListener( 2498 INfcWlcStateListener listener) throws RemoteException { 2499 if (!mIsWlcCapable) { 2500 return; 2501 } 2502 NfcPermissions.enforceAdminPermissions(mContext); 2503 2504 mWlcStateListener.add(listener); 2505 } 2506 2507 @Override unregisterWlcStateListener( INfcWlcStateListener listener)2508 public void unregisterWlcStateListener( 2509 INfcWlcStateListener listener) throws RemoteException { 2510 if (!mIsWlcCapable) { 2511 return; 2512 } 2513 NfcPermissions.enforceAdminPermissions(mContext); 2514 2515 mWlcStateListener.remove(listener); 2516 } 2517 2518 @Override notifyPollingLoop(PollingFrame frame)2519 public void notifyPollingLoop(PollingFrame frame) { 2520 try { 2521 byte[] data; 2522 int type = frame.getType(); 2523 int gain = frame.getVendorSpecificGain(); 2524 byte[] frame_data = frame.getData(); 2525 2526 long timestamp = frame.getTimestamp(); 2527 HexFormat format = HexFormat.ofDelimiter(" "); 2528 String timestampBytes = format.formatHex(new byte[] { 2529 (byte) (timestamp >>> 24), 2530 (byte) (timestamp >>> 16), 2531 (byte) (timestamp >>> 8), 2532 (byte) timestamp }); 2533 int frame_data_length = frame_data == null ? 0 : frame_data.length; 2534 String frame_data_str = frame_data_length == 0 ? "" : " " + format.formatHex(frame_data); 2535 String type_str = "FF"; 2536 switch (type) { 2537 case PollingFrame.POLLING_LOOP_TYPE_ON: 2538 type_str = "00"; 2539 data = new byte[] { 0x01 }; 2540 break; 2541 case PollingFrame.POLLING_LOOP_TYPE_OFF: 2542 type_str = "00"; 2543 data = new byte[] { 0x00 }; 2544 break; 2545 case PollingFrame.POLLING_LOOP_TYPE_A: 2546 type_str = "01"; 2547 break; 2548 case PollingFrame.POLLING_LOOP_TYPE_B: 2549 type_str = "02"; 2550 break; 2551 case PollingFrame.POLLING_LOOP_TYPE_F: 2552 type_str = "03"; 2553 break; 2554 case PollingFrame.POLLING_LOOP_TYPE_UNKNOWN: 2555 type_str = "07"; 2556 break; 2557 } 2558 data = format.parseHex("6f 0C " + String.format("%02x", 9 + frame_data_length) 2559 + " 03 " + type_str 2560 + " 00 " + String.format("%02x", 5 + frame_data_length) + " " 2561 + timestampBytes + " " + String.format("%02x", gain) + frame_data_str); 2562 ((NativeNfcManager) mDeviceHost).notifyPollingLoopFrame(data.length, data); 2563 } catch (Exception ex) { 2564 Log.e(TAG, "error when notifying polling loop", ex); 2565 } 2566 } 2567 2568 @Override notifyHceDeactivated()2569 public void notifyHceDeactivated() { 2570 try { 2571 mCardEmulationManager.onHostCardEmulationDeactivated(1); 2572 } catch (Exception ex) { 2573 Log.e(TAG, "error when notifying HCE deactivated", ex); 2574 } 2575 } 2576 2577 @Override handleShellCommand(@onNull ParcelFileDescriptor in, @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, @NonNull String[] args)2578 public int handleShellCommand(@NonNull ParcelFileDescriptor in, 2579 @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, 2580 @NonNull String[] args) { 2581 2582 NfcShellCommand shellCommand = new NfcShellCommand(NfcService.this, mContext); 2583 return shellCommand.exec(this, in.getFileDescriptor(), out.getFileDescriptor(), 2584 err.getFileDescriptor(), args); 2585 } 2586 isPowerSavingModeCmd(int gid, int oid, byte[] payload)2587 private static boolean isPowerSavingModeCmd(int gid, int oid, byte[] payload) { 2588 return gid == NCI_GID_PROP && oid == NCI_MSG_PROP_ANDROID && payload.length > 0 2589 && payload[0] == NCI_MSG_PROP_ANDROID_POWER_SAVING; 2590 } 2591 2592 @Override sendVendorNciMessage(int mt, int gid, int oid, byte[] payload)2593 public synchronized int sendVendorNciMessage(int mt, int gid, int oid, byte[] payload) 2594 throws RemoteException { 2595 NfcPermissions.enforceAdminPermissions(mContext); 2596 if ((!isNfcEnabled() && !mIsPowerSavingModeEnabled)) { 2597 Log.e(TAG, "sendRawVendor : Nfc is not enabled"); 2598 return NCI_STATUS_FAILED; 2599 } 2600 2601 FutureTask<Integer> sendVendorCmdTask = new FutureTask<>( 2602 () -> { 2603 if(isPowerSavingModeCmd(gid, oid, payload)) { 2604 boolean status = setPowerSavingMode(payload[1] == 0x01 ? true : false); 2605 return status? NCI_STATUS_OK : NCI_STATUS_FAILED; 2606 } else { 2607 NfcVendorNciResponse response = 2608 mDeviceHost.sendRawVendorCmd(mt, gid, oid, payload); 2609 if (response.status == NCI_STATUS_OK) { 2610 mHandler.post(() -> mNfcAdapter.sendVendorNciResponse( 2611 response.gid, response.oid, response.payload)); 2612 } 2613 return Integer.valueOf(response.status); 2614 } 2615 }); 2616 int status = NCI_STATUS_FAILED; 2617 try { 2618 status = runTaskOnSingleThreadExecutor(sendVendorCmdTask, 2619 SEND_VENDOR_CMD_TIMEOUT_MS); 2620 } catch (TimeoutException e) { 2621 Log.e(TAG, "Failed to send vendor command - status : TIMEOUT", e); 2622 } catch (InterruptedException e) { 2623 e.printStackTrace(); 2624 } catch (ExecutionException e) { 2625 e.printStackTrace(); 2626 } 2627 return status; 2628 } 2629 2630 @Override registerVendorExtensionCallback(INfcVendorNciCallback callbacks)2631 public synchronized void registerVendorExtensionCallback(INfcVendorNciCallback callbacks) 2632 throws RemoteException { 2633 if (DBG) Log.i(TAG, "Register the callback"); 2634 NfcPermissions.enforceAdminPermissions(mContext); 2635 mNfcVendorNciCallBack = callbacks; 2636 mDeviceHost.enableVendorNciNotifications(true); 2637 } 2638 2639 @Override unregisterVendorExtensionCallback(INfcVendorNciCallback callbacks)2640 public synchronized void unregisterVendorExtensionCallback(INfcVendorNciCallback callbacks) 2641 throws RemoteException { 2642 if (DBG) Log.i(TAG, "Unregister the callback"); 2643 NfcPermissions.enforceAdminPermissions(mContext); 2644 mNfcVendorNciCallBack = null; 2645 mDeviceHost.enableVendorNciNotifications(false); 2646 } 2647 2648 @Override registerOemExtensionCallback(INfcOemExtensionCallback callbacks)2649 public void registerOemExtensionCallback(INfcOemExtensionCallback callbacks) 2650 throws RemoteException { 2651 if (DBG) Log.i(TAG, "Register the oem extension callback"); 2652 NfcPermissions.enforceAdminPermissions(mContext); 2653 mNfcOemExtensionCallback = callbacks; 2654 } 2655 2656 @Override unregisterOemExtensionCallback(INfcOemExtensionCallback callbacks)2657 public void unregisterOemExtensionCallback(INfcOemExtensionCallback callbacks) 2658 throws RemoteException { 2659 if (DBG) Log.i(TAG, "Unregister the oem extension callback"); 2660 NfcPermissions.enforceAdminPermissions(mContext); 2661 mNfcOemExtensionCallback = null; 2662 } 2663 2664 @Override clearPreference()2665 public void clearPreference() throws RemoteException { 2666 if (DBG) Log.i(TAG, "clearPreference"); 2667 NfcPermissions.enforceAdminPermissions(mContext); 2668 // TODO: Implement this. 2669 } 2670 2671 @Override setScreenState()2672 public void setScreenState() throws RemoteException { 2673 if (DBG) Log.i(TAG, "setScreenState"); 2674 NfcPermissions.enforceAdminPermissions(mContext); 2675 applyScreenState(mScreenStateHelper.checkScreenState()); 2676 } 2677 2678 @Override checkFirmware()2679 public void checkFirmware() throws RemoteException { 2680 if (DBG) Log.i(TAG, "checkFirmware"); 2681 NfcPermissions.enforceAdminPermissions(mContext); 2682 mDeviceHost.checkFirmware(); 2683 } 2684 2685 // TODO(b/321304762): Add the OEM extension API. allowBoot()2686 public void allowBoot() throws RemoteException { 2687 if (DBG) Log.i(TAG, "allowBoot"); 2688 NfcPermissions.enforceAdminPermissions(mContext); 2689 if (mDelayedBootAlarmListenerSet) { 2690 Log.i(TAG, "OEM executing delayed boot"); 2691 mAlarmManager.cancel(mDelayedBootAlarmListener); 2692 mDelayedBootAlarmListener.onAlarm(); 2693 } 2694 } 2695 sendVendorNciResponse(int gid, int oid, byte[] payload)2696 private synchronized void sendVendorNciResponse(int gid, int oid, byte[] payload) { 2697 if (VDBG) Log.i(TAG, "onVendorNciResponseReceived"); 2698 if (mNfcVendorNciCallBack != null) { 2699 try { 2700 mNfcVendorNciCallBack.onVendorResponseReceived(gid, oid, payload); 2701 } catch (RemoteException e) { 2702 Log.e(TAG, "Failed to send vendor response", e); 2703 } 2704 } 2705 } 2706 sendVendorNciNotification(int gid, int oid, byte[] payload)2707 private synchronized void sendVendorNciNotification(int gid, int oid, byte[] payload) { 2708 if (VDBG) Log.i(TAG, "sendVendorNciNotification"); 2709 if (mNfcVendorNciCallBack != null) { 2710 try { 2711 mNfcVendorNciCallBack.onVendorNotificationReceived(gid, oid, payload); 2712 } catch (RemoteException e) { 2713 Log.e(TAG, "Failed to send vendor notification", e); 2714 } 2715 } 2716 } 2717 } 2718 2719 2720 final class SeServiceDeathRecipient implements IBinder.DeathRecipient { 2721 @Override binderDied()2722 public void binderDied() { 2723 synchronized (NfcService.this) { 2724 Log.i(TAG, "SE Service died"); 2725 mSEService = null; 2726 } 2727 } 2728 } 2729 2730 final class ReaderModeDeathRecipient implements IBinder.DeathRecipient { 2731 @Override binderDied()2732 public void binderDied() { 2733 synchronized (NfcService.this) { 2734 if (mReaderModeParams != null) { 2735 mPollingDisableDeathRecipients.values().remove(this); 2736 resetReaderModeParams(); 2737 } 2738 } 2739 } 2740 } 2741 2742 final class DiscoveryTechDeathRecipient implements IBinder.DeathRecipient { 2743 @Override binderDied()2744 public void binderDied() { 2745 if (DBG) Log.d(TAG, "setDiscoveryTech death recipient"); 2746 synchronized (NfcService.this) { 2747 if (isNfcEnabled() && mDiscoveryTechParams != null) { 2748 mDeviceHost.resetDiscoveryTech(); 2749 mDiscoveryTechParams = null; 2750 } 2751 } 2752 applyRouting(true); 2753 } 2754 } 2755 2756 final class TagService extends INfcTag.Stub { 2757 @Override connect(int nativeHandle, int technology)2758 public int connect(int nativeHandle, int technology) throws RemoteException { 2759 NfcPermissions.enforceUserPermissions(mContext); 2760 2761 TagEndpoint tag = null; 2762 2763 if (!isNfcEnabled()) { 2764 return ErrorCodes.ERROR_NOT_INITIALIZED; 2765 } 2766 2767 if (!isReaderOptionEnabled()) { 2768 return ErrorCodes.ERROR_NOT_INITIALIZED; 2769 } 2770 2771 /* find the tag in the hmap */ 2772 tag = (TagEndpoint) findObject(nativeHandle); 2773 if (tag == null) { 2774 return ErrorCodes.ERROR_DISCONNECT; 2775 } 2776 2777 if (!tag.isPresent()) { 2778 return ErrorCodes.ERROR_DISCONNECT; 2779 } 2780 2781 // Note that on most tags, all technologies are behind a single 2782 // handle. This means that the connect at the lower levels 2783 // will do nothing, as the tag is already connected to that handle. 2784 if (tag.connect(technology)) { 2785 return ErrorCodes.SUCCESS; 2786 } else { 2787 return ErrorCodes.ERROR_DISCONNECT; 2788 } 2789 } 2790 2791 @Override reconnect(int nativeHandle)2792 public int reconnect(int nativeHandle) throws RemoteException { 2793 NfcPermissions.enforceUserPermissions(mContext); 2794 2795 TagEndpoint tag = null; 2796 2797 // Check if NFC is enabled 2798 if (!isNfcEnabled()) { 2799 return ErrorCodes.ERROR_NOT_INITIALIZED; 2800 } 2801 2802 if (!isReaderOptionEnabled()) { 2803 return ErrorCodes.ERROR_NOT_INITIALIZED; 2804 } 2805 2806 /* find the tag in the hmap */ 2807 tag = (TagEndpoint) findObject(nativeHandle); 2808 if (tag != null) { 2809 if (tag.reconnect()) { 2810 return ErrorCodes.SUCCESS; 2811 } else { 2812 return ErrorCodes.ERROR_DISCONNECT; 2813 } 2814 } 2815 return ErrorCodes.ERROR_DISCONNECT; 2816 } 2817 2818 @Override getTechList(int nativeHandle)2819 public int[] getTechList(int nativeHandle) throws RemoteException { 2820 NfcPermissions.enforceUserPermissions(mContext); 2821 2822 // Check if NFC is enabled 2823 if (!isNfcEnabled()) { 2824 return null; 2825 } 2826 2827 if (!isReaderOptionEnabled()) { 2828 return null; 2829 } 2830 2831 /* find the tag in the hmap */ 2832 TagEndpoint tag = (TagEndpoint) findObject(nativeHandle); 2833 if (tag != null) { 2834 return tag.getTechList(); 2835 } 2836 return null; 2837 } 2838 2839 @Override isPresent(int nativeHandle)2840 public boolean isPresent(int nativeHandle) throws RemoteException { 2841 TagEndpoint tag = null; 2842 2843 // Check if NFC is enabled 2844 if (!isNfcEnabled()) { 2845 return false; 2846 } 2847 2848 if (!isReaderOptionEnabled()) { 2849 return false; 2850 } 2851 2852 /* find the tag in the hmap */ 2853 tag = (TagEndpoint) findObject(nativeHandle); 2854 if (tag == null) { 2855 return false; 2856 } 2857 2858 return tag.isPresent(); 2859 } 2860 2861 @Override isNdef(int nativeHandle)2862 public boolean isNdef(int nativeHandle) throws RemoteException { 2863 NfcPermissions.enforceUserPermissions(mContext); 2864 2865 TagEndpoint tag = null; 2866 2867 // Check if NFC is enabled 2868 if (!isNfcEnabled()) { 2869 return false; 2870 } 2871 2872 if (!isReaderOptionEnabled()) { 2873 return false; 2874 } 2875 2876 /* find the tag in the hmap */ 2877 tag = (TagEndpoint) findObject(nativeHandle); 2878 int[] ndefInfo = new int[2]; 2879 if (tag == null) { 2880 return false; 2881 } 2882 return tag.checkNdef(ndefInfo); 2883 } 2884 2885 @Override transceive(int nativeHandle, byte[] data, boolean raw)2886 public TransceiveResult transceive(int nativeHandle, byte[] data, boolean raw) 2887 throws RemoteException { 2888 NfcPermissions.enforceUserPermissions(mContext); 2889 2890 TagEndpoint tag = null; 2891 byte[] response; 2892 2893 // Check if NFC is enabled 2894 if (!isNfcEnabled()) { 2895 return null; 2896 } 2897 2898 if (!isReaderOptionEnabled()) { 2899 return null; 2900 } 2901 2902 /* find the tag in the hmap */ 2903 tag = (TagEndpoint) findObject(nativeHandle); 2904 if (tag != null) { 2905 // Check if length is within limits 2906 if (data.length > getMaxTransceiveLength(tag.getConnectedTechnology())) { 2907 return new TransceiveResult(TransceiveResult.RESULT_EXCEEDED_LENGTH, null); 2908 } 2909 int[] targetLost = new int[1]; 2910 response = tag.transceive(data, raw, targetLost); 2911 int result; 2912 if (response != null) { 2913 result = TransceiveResult.RESULT_SUCCESS; 2914 } else if (targetLost[0] == 1) { 2915 result = TransceiveResult.RESULT_TAGLOST; 2916 } else { 2917 result = TransceiveResult.RESULT_FAILURE; 2918 } 2919 return new TransceiveResult(result, response); 2920 } 2921 return null; 2922 } 2923 2924 @Override ndefRead(int nativeHandle)2925 public NdefMessage ndefRead(int nativeHandle) throws RemoteException { 2926 NfcPermissions.enforceUserPermissions(mContext); 2927 2928 TagEndpoint tag; 2929 2930 // Check if NFC is enabled 2931 if (!isNfcEnabled()) { 2932 return null; 2933 } 2934 2935 if (!isReaderOptionEnabled()) { 2936 return null; 2937 } 2938 2939 /* find the tag in the hmap */ 2940 tag = (TagEndpoint) findObject(nativeHandle); 2941 if (tag != null) { 2942 byte[] buf = tag.readNdef(); 2943 if (buf == null) { 2944 return null; 2945 } 2946 2947 /* Create an NdefMessage */ 2948 try { 2949 return new NdefMessage(buf); 2950 } catch (FormatException e) { 2951 return null; 2952 } 2953 } 2954 return null; 2955 } 2956 2957 @Override ndefWrite(int nativeHandle, NdefMessage msg)2958 public int ndefWrite(int nativeHandle, NdefMessage msg) throws RemoteException { 2959 NfcPermissions.enforceUserPermissions(mContext); 2960 2961 TagEndpoint tag; 2962 2963 // Check if NFC is enabled 2964 if (!isNfcEnabled()) { 2965 return ErrorCodes.ERROR_NOT_INITIALIZED; 2966 } 2967 2968 if (!isReaderOptionEnabled()) { 2969 return ErrorCodes.ERROR_NOT_INITIALIZED; 2970 } 2971 2972 /* find the tag in the hmap */ 2973 tag = (TagEndpoint) findObject(nativeHandle); 2974 if (tag == null) { 2975 return ErrorCodes.ERROR_IO; 2976 } 2977 2978 if (msg == null) return ErrorCodes.ERROR_INVALID_PARAM; 2979 2980 if (tag.writeNdef(msg.toByteArray())) { 2981 return ErrorCodes.SUCCESS; 2982 } else { 2983 return ErrorCodes.ERROR_IO; 2984 } 2985 2986 } 2987 2988 @Override ndefIsWritable(int nativeHandle)2989 public boolean ndefIsWritable(int nativeHandle) throws RemoteException { 2990 throw new UnsupportedOperationException(); 2991 } 2992 2993 @Override ndefMakeReadOnly(int nativeHandle)2994 public int ndefMakeReadOnly(int nativeHandle) throws RemoteException { 2995 NfcPermissions.enforceUserPermissions(mContext); 2996 2997 TagEndpoint tag; 2998 2999 // Check if NFC is enabled 3000 if (!isNfcEnabled()) { 3001 return ErrorCodes.ERROR_NOT_INITIALIZED; 3002 } 3003 3004 if (!isReaderOptionEnabled()) { 3005 return ErrorCodes.ERROR_NOT_INITIALIZED; 3006 } 3007 3008 /* find the tag in the hmap */ 3009 tag = (TagEndpoint) findObject(nativeHandle); 3010 if (tag == null) { 3011 return ErrorCodes.ERROR_IO; 3012 } 3013 3014 if (tag.makeReadOnly()) { 3015 return ErrorCodes.SUCCESS; 3016 } else { 3017 return ErrorCodes.ERROR_IO; 3018 } 3019 } 3020 3021 @Override formatNdef(int nativeHandle, byte[] key)3022 public int formatNdef(int nativeHandle, byte[] key) throws RemoteException { 3023 NfcPermissions.enforceUserPermissions(mContext); 3024 3025 TagEndpoint tag; 3026 3027 // Check if NFC is enabled 3028 if (!isNfcEnabled()) { 3029 return ErrorCodes.ERROR_NOT_INITIALIZED; 3030 } 3031 3032 if (!isReaderOptionEnabled()) { 3033 return ErrorCodes.ERROR_NOT_INITIALIZED; 3034 } 3035 3036 /* find the tag in the hmap */ 3037 tag = (TagEndpoint) findObject(nativeHandle); 3038 if (tag == null) { 3039 return ErrorCodes.ERROR_IO; 3040 } 3041 3042 if (tag.formatNdef(key)) { 3043 return ErrorCodes.SUCCESS; 3044 } else { 3045 return ErrorCodes.ERROR_IO; 3046 } 3047 } 3048 3049 @Override rediscover(int nativeHandle)3050 public Tag rediscover(int nativeHandle) throws RemoteException { 3051 NfcPermissions.enforceUserPermissions(mContext); 3052 3053 TagEndpoint tag = null; 3054 3055 // Check if NFC is enabled 3056 if (!isNfcEnabled()) { 3057 return null; 3058 } 3059 3060 if (!isReaderOptionEnabled()) { 3061 return null; 3062 } 3063 3064 /* find the tag in the hmap */ 3065 tag = (TagEndpoint) findObject(nativeHandle); 3066 if (tag != null) { 3067 // For now the prime usecase for rediscover() is to be able 3068 // to access the NDEF technology after formatting without 3069 // having to remove the tag from the field, or similar 3070 // to have access to NdefFormatable in case low-level commands 3071 // were used to remove NDEF. So instead of doing a full stack 3072 // rediscover (which is poorly supported at the moment anyway), 3073 // we simply remove these two technologies and detect them 3074 // again. 3075 tag.removeTechnology(TagTechnology.NDEF); 3076 tag.removeTechnology(TagTechnology.NDEF_FORMATABLE); 3077 tag.findAndReadNdef(); 3078 // Build a new Tag object to return 3079 try { 3080 /* Avoid setting mCookieUpToDate to negative values */ 3081 mCookieUpToDate = mCookieGenerator.nextLong() >>> 1; 3082 Tag newTag = new Tag(tag.getUid(), tag.getTechList(), 3083 tag.getTechExtras(), tag.getHandle(), mCookieUpToDate, this); 3084 return newTag; 3085 } catch (Exception e) { 3086 Log.e(TAG, "Tag creation exception.", e); 3087 return null; 3088 } 3089 } 3090 return null; 3091 } 3092 3093 @Override setTimeout(int tech, int timeout)3094 public int setTimeout(int tech, int timeout) throws RemoteException { 3095 NfcPermissions.enforceUserPermissions(mContext); 3096 boolean success = mDeviceHost.setTimeout(tech, timeout); 3097 if (success) { 3098 return ErrorCodes.SUCCESS; 3099 } else { 3100 return ErrorCodes.ERROR_INVALID_PARAM; 3101 } 3102 } 3103 3104 @Override getTimeout(int tech)3105 public int getTimeout(int tech) throws RemoteException { 3106 NfcPermissions.enforceUserPermissions(mContext); 3107 3108 return mDeviceHost.getTimeout(tech); 3109 } 3110 3111 @Override resetTimeouts()3112 public void resetTimeouts() throws RemoteException { 3113 NfcPermissions.enforceUserPermissions(mContext); 3114 3115 mDeviceHost.resetTimeouts(); 3116 } 3117 3118 @Override canMakeReadOnly(int ndefType)3119 public boolean canMakeReadOnly(int ndefType) throws RemoteException { 3120 return mDeviceHost.canMakeReadOnly(ndefType); 3121 } 3122 3123 @Override getMaxTransceiveLength(int tech)3124 public int getMaxTransceiveLength(int tech) throws RemoteException { 3125 return mDeviceHost.getMaxTransceiveLength(tech); 3126 } 3127 3128 @Override getExtendedLengthApdusSupported()3129 public boolean getExtendedLengthApdusSupported() throws RemoteException { 3130 return mDeviceHost.getExtendedLengthApdusSupported(); 3131 } 3132 3133 @Override isTagUpToDate(long cookie)3134 public boolean isTagUpToDate(long cookie) throws RemoteException { 3135 if (mCookieUpToDate != -1 && mCookieUpToDate == cookie) { 3136 if (DBG) Log.d(TAG, "Tag " + Long.toString(cookie) + " is up to date"); 3137 return true; 3138 } 3139 3140 if (DBG) Log.d(TAG, "Tag " + Long.toString(cookie) + " is out of date"); 3141 EventLog.writeEvent(0x534e4554, "199291025", -1, 3142 "The obsolete tag was attempted to be accessed"); 3143 return false; 3144 } 3145 } 3146 3147 final class NfcDtaService extends INfcDta.Stub { enableDta()3148 public void enableDta() throws RemoteException { 3149 NfcPermissions.enforceAdminPermissions(mContext); 3150 if(!sIsDtaMode) { 3151 mDeviceHost.enableDtaMode(); 3152 sIsDtaMode = true; 3153 Log.d(TAG, "DTA Mode is Enabled "); 3154 } 3155 } 3156 disableDta()3157 public void disableDta() throws RemoteException { 3158 NfcPermissions.enforceAdminPermissions(mContext); 3159 if(sIsDtaMode) { 3160 mDeviceHost.disableDtaMode(); 3161 sIsDtaMode = false; 3162 } 3163 } 3164 enableServer(String serviceName, int serviceSap, int miu, int rwSize,int testCaseId)3165 public boolean enableServer(String serviceName, int serviceSap, int miu, 3166 int rwSize,int testCaseId) throws RemoteException { 3167 NfcPermissions.enforceAdminPermissions(mContext); 3168 return false; 3169 } 3170 disableServer()3171 public void disableServer() throws RemoteException { 3172 } 3173 enableClient(String serviceName, int miu, int rwSize, int testCaseId)3174 public boolean enableClient(String serviceName, int miu, int rwSize, 3175 int testCaseId) throws RemoteException { 3176 NfcPermissions.enforceAdminPermissions(mContext); 3177 return false; 3178 } 3179 disableClient()3180 public void disableClient() throws RemoteException { 3181 return; 3182 } 3183 registerMessageService(String msgServiceName)3184 public boolean registerMessageService(String msgServiceName) 3185 throws RemoteException { 3186 NfcPermissions.enforceAdminPermissions(mContext); 3187 if(msgServiceName == null) 3188 return false; 3189 3190 DtaServiceConnector.setMessageService(msgServiceName); 3191 return true; 3192 } 3193 3194 }; 3195 isNfcEnabledOrShuttingDown()3196 boolean isNfcEnabledOrShuttingDown() { 3197 synchronized (this) { 3198 return (mState == NfcAdapter.STATE_ON || mState == NfcAdapter.STATE_TURNING_OFF); 3199 } 3200 } 3201 isNfcEnabled()3202 boolean isNfcEnabled() { 3203 synchronized (this) { 3204 return mState == NfcAdapter.STATE_ON; 3205 } 3206 } 3207 isReaderOptionEnabled()3208 boolean isReaderOptionEnabled() { 3209 synchronized (this) { 3210 return mIsReaderOptionEnabled || mReaderModeParams != null; 3211 } 3212 } 3213 3214 class WatchDogThread extends Thread { 3215 final Object mCancelWaiter = new Object(); 3216 final int mTimeout; 3217 boolean mCanceled = false; 3218 WatchDogThread(String threadName, int timeout)3219 public WatchDogThread(String threadName, int timeout) { 3220 super(threadName); 3221 mTimeout = timeout; 3222 } 3223 3224 @Override run()3225 public void run() { 3226 try { 3227 synchronized (mCancelWaiter) { 3228 mCancelWaiter.wait(mTimeout); 3229 if (mCanceled) { 3230 return; 3231 } 3232 } 3233 } catch (InterruptedException e) { 3234 // Should not happen; fall-through to abort. 3235 Log.w(TAG, "Watchdog thread interruped."); 3236 interrupt(); 3237 } 3238 if(mRoutingWakeLock.isHeld()){ 3239 Log.e(TAG, "Watchdog triggered, release lock before aborting."); 3240 mRoutingWakeLock.release(); 3241 } 3242 Log.e(TAG, "Watchdog triggered, aborting."); 3243 NfcStatsLog.write(NfcStatsLog.NFC_STATE_CHANGED, 3244 NfcStatsLog.NFC_STATE_CHANGED__STATE__CRASH_RESTART); 3245 storeNativeCrashLogs(); 3246 mDeviceHost.doAbort(getName()); 3247 } 3248 cancel()3249 public synchronized void cancel() { 3250 synchronized (mCancelWaiter) { 3251 mCanceled = true; 3252 mCancelWaiter.notify(); 3253 } 3254 } 3255 } 3256 hexStringToBytes(String s)3257 static byte[] hexStringToBytes(String s) { 3258 if (s == null || s.length() == 0) return null; 3259 int len = s.length(); 3260 if (len % 2 != 0) { 3261 s = '0' + s; 3262 len++; 3263 } 3264 byte[] data = new byte[len / 2]; 3265 for (int i = 0; i < len; i += 2) { 3266 data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 3267 + Character.digit(s.charAt(i + 1), 16)); 3268 } 3269 return data; 3270 } 3271 addKeyguardLockedStateListener()3272 private void addKeyguardLockedStateListener() { 3273 try { 3274 mKeyguard.addKeyguardLockedStateListener(mContext.getMainExecutor(), 3275 mIKeyguardLockedStateListener); 3276 } catch (Exception e) { 3277 Log.e(TAG, "Exception in addKeyguardLockedStateListener " + e); 3278 } 3279 } 3280 3281 /** 3282 * Receives KeyGuard lock state updates 3283 */ 3284 private KeyguardLockedStateListener mIKeyguardLockedStateListener = 3285 new KeyguardLockedStateListener() { 3286 @Override 3287 public void onKeyguardLockedStateChanged(boolean isKeyguardLocked) { 3288 if (!mIsWlcCapable || !mNfcCharging.NfcChargingOnGoing) { 3289 applyScreenState(mScreenStateHelper.checkScreenState()); 3290 } 3291 } 3292 }; 3293 addThermalStatusListener()3294 private void addThermalStatusListener() { 3295 try { 3296 if (mPowerManager != null) { 3297 mPowerManager.addThermalStatusListener(mContext.getMainExecutor(), 3298 mOnThermalStatusChangedListener); 3299 } 3300 } catch (Exception e) { 3301 Log.e(TAG, "Exception in addThermalStatusListener " + e); 3302 } 3303 } 3304 3305 /** 3306 * Receives Thermal state updates 3307 */ 3308 private OnThermalStatusChangedListener mOnThermalStatusChangedListener = 3309 new OnThermalStatusChangedListener() { 3310 @Override 3311 public void onThermalStatusChanged(int status) { 3312 switch (status) { 3313 case PowerManager.THERMAL_STATUS_MODERATE: 3314 Log.d(TAG, "Thermal status changed to MODERATE"); 3315 break; 3316 case PowerManager.THERMAL_STATUS_SEVERE: 3317 Log.d(TAG, "Thermal status changed to SEVERE"); 3318 break; 3319 case PowerManager.THERMAL_STATUS_CRITICAL: 3320 Log.d(TAG, "Thermal status changed to CRITICAL"); 3321 break; 3322 default: 3323 Log.d(TAG, "Unknown thermal status: " + status); 3324 break; 3325 } 3326 } 3327 }; 3328 3329 3330 /** 3331 * Read mScreenState and apply NFC-C polling and NFC-EE routing 3332 */ applyRouting(boolean force)3333 void applyRouting(boolean force) { 3334 synchronized (this) { 3335 if (!isNfcEnabledOrShuttingDown()) { 3336 return; 3337 } 3338 WatchDogThread watchDog = new WatchDogThread("applyRouting", ROUTING_WATCHDOG_MS); 3339 if (mInProvisionMode) { 3340 mInProvisionMode = Settings.Global.getInt(mContentResolver, 3341 Settings.Global.DEVICE_PROVISIONED, 0) == 0; 3342 if (!mInProvisionMode) { 3343 // Notify dispatcher it's fine to dispatch to any package now 3344 // and allow handover transfers. 3345 mNfcDispatcher.disableProvisioningMode(); 3346 } 3347 } 3348 // Special case: if we're transitioning to unlocked state while 3349 // still talking to a tag, postpone re-configuration. 3350 if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED && isTagPresent()) { 3351 Log.d(TAG, "Not updating discovery parameters, tag connected."); 3352 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESUME_POLLING), 3353 APPLY_ROUTING_RETRY_TIMEOUT_MS); 3354 return; 3355 } 3356 3357 try { 3358 watchDog.start(); 3359 // Compute new polling parameters 3360 NfcDiscoveryParameters newParams = computeDiscoveryParameters(mScreenState); 3361 if (force || !newParams.equals(mCurrentDiscoveryParameters)) { 3362 if (newParams.shouldEnableDiscovery()) { 3363 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery(); 3364 mDeviceHost.enableDiscovery(newParams, shouldRestart); 3365 } else { 3366 mDeviceHost.disableDiscovery(); 3367 } 3368 mCurrentDiscoveryParameters = newParams; 3369 } else { 3370 Log.d(TAG, "Discovery configuration equal, not updating."); 3371 } 3372 } finally { 3373 watchDog.cancel(); 3374 } 3375 } 3376 } 3377 computeDiscoveryParameters(int screenState)3378 private NfcDiscoveryParameters computeDiscoveryParameters(int screenState) { 3379 // Recompute discovery parameters based on screen state 3380 NfcDiscoveryParameters.Builder paramsBuilder = NfcDiscoveryParameters.newBuilder(); 3381 // Polling 3382 if (screenState >= NFC_POLLING_MODE && isReaderOptionEnabled()) { 3383 // Check if reader-mode is enabled 3384 if (mReaderModeParams != null) { 3385 int techMask = 0; 3386 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_A) != 0) 3387 techMask |= NFC_POLL_A; 3388 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_B) != 0) 3389 techMask |= NFC_POLL_B; 3390 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_F) != 0) 3391 techMask |= NFC_POLL_F; 3392 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_V) != 0) 3393 techMask |= NFC_POLL_V; 3394 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_BARCODE) != 0) 3395 techMask |= NFC_POLL_KOVIO; 3396 3397 paramsBuilder.setTechMask(techMask); 3398 paramsBuilder.setEnableReaderMode(true); 3399 if (mReaderModeParams.flags != 0 && techMask == 0) { 3400 paramsBuilder.setEnableHostRouting(true); 3401 } 3402 } else { 3403 paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT); 3404 } 3405 } else if (screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mInProvisionMode) { 3406 paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT); 3407 } else if (screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && 3408 mNfcUnlockManager.isLockscreenPollingEnabled() && isReaderOptionEnabled()) { 3409 int techMask = 0; 3410 if (mNfcUnlockManager.isLockscreenPollingEnabled()) 3411 techMask |= mNfcUnlockManager.getLockscreenPollMask(); 3412 paramsBuilder.setTechMask(techMask); 3413 paramsBuilder.setEnableLowPowerDiscovery(false); 3414 } 3415 3416 if (mIsHceCapable && mReaderModeParams == null) { 3417 // Host routing is always enabled, provided we aren't in reader mode 3418 paramsBuilder.setEnableHostRouting(true); 3419 } 3420 3421 return paramsBuilder.build(); 3422 } 3423 isTagPresent()3424 private boolean isTagPresent() { 3425 for (Object object : mObjectMap.values()) { 3426 if (object instanceof TagEndpoint) { 3427 return ((TagEndpoint) object).isPresent(); 3428 } 3429 } 3430 return false; 3431 } 3432 StopPresenceChecking()3433 private void StopPresenceChecking() { 3434 Object[] objectValues = mObjectMap.values().toArray(); 3435 for (Object object : objectValues) { 3436 if (object instanceof TagEndpoint) { 3437 TagEndpoint tag = (TagEndpoint)object; 3438 ((TagEndpoint) object).stopPresenceChecking(); 3439 } 3440 } 3441 } 3442 3443 /** 3444 * Disconnect any target if present 3445 */ maybeDisconnectTarget()3446 void maybeDisconnectTarget() { 3447 if (!isNfcEnabledOrShuttingDown()) { 3448 return; 3449 } 3450 Object[] objectsToDisconnect; 3451 synchronized (this) { 3452 Object[] objectValues = mObjectMap.values().toArray(); 3453 // Copy the array before we clear mObjectMap, 3454 // just in case the HashMap values are backed by the same array 3455 objectsToDisconnect = Arrays.copyOf(objectValues, objectValues.length); 3456 mObjectMap.clear(); 3457 } 3458 for (Object o : objectsToDisconnect) { 3459 if (DBG) Log.d(TAG, "disconnecting " + o.getClass().getName()); 3460 if (o instanceof TagEndpoint) { 3461 // Disconnect from tags 3462 TagEndpoint tag = (TagEndpoint) o; 3463 tag.disconnect(); 3464 } 3465 } 3466 } 3467 findObject(int key)3468 Object findObject(int key) { 3469 synchronized (this) { 3470 Object device = mObjectMap.get(key); 3471 if (device == null) { 3472 Log.w(TAG, "Handle not found"); 3473 } 3474 return device; 3475 } 3476 } 3477 findAndRemoveObject(int handle)3478 Object findAndRemoveObject(int handle) { 3479 synchronized (this) { 3480 Object device = mObjectMap.get(handle); 3481 if (device == null) { 3482 Log.w(TAG, "Handle not found"); 3483 } else { 3484 mObjectMap.remove(handle); 3485 } 3486 return device; 3487 } 3488 } 3489 registerTagObject(TagEndpoint tag)3490 void registerTagObject(TagEndpoint tag) { 3491 synchronized (this) { 3492 mObjectMap.put(tag.getHandle(), tag); 3493 } 3494 } 3495 unregisterObject(int handle)3496 void unregisterObject(int handle) { 3497 synchronized (this) { 3498 mObjectMap.remove(handle); 3499 } 3500 } 3501 getAidRoutingTableSize()3502 public int getAidRoutingTableSize () 3503 { 3504 int aidTableSize = 0x00; 3505 aidTableSize = mDeviceHost.getAidTableSize(); 3506 return aidTableSize; 3507 } 3508 sendMockNdefTag(NdefMessage msg)3509 public void sendMockNdefTag(NdefMessage msg) { 3510 sendMessage(MSG_MOCK_NDEF, msg); 3511 } 3512 routeAids(String aid, int route, int aidInfo, int power)3513 public void routeAids(String aid, int route, int aidInfo, int power) { 3514 Message msg = mHandler.obtainMessage(); 3515 msg.what = MSG_ROUTE_AID; 3516 msg.arg1 = route; 3517 msg.obj = aid; 3518 msg.arg2 = aidInfo; 3519 3520 Bundle aidPowerState = new Bundle(); 3521 aidPowerState.putInt(MSG_ROUTE_AID_PARAM_TAG, power); 3522 msg.setData(aidPowerState); 3523 3524 mHandler.sendMessage(msg); 3525 } 3526 unrouteAids(String aid)3527 public void unrouteAids(String aid) { 3528 sendMessage(MSG_UNROUTE_AID, aid); 3529 } 3530 getNciVersion()3531 public int getNciVersion() { 3532 return mDeviceHost.getNciVersion(); 3533 } 3534 getT3tIdentifierBytes(String systemCode, String nfcId2, String t3tPmm)3535 private byte[] getT3tIdentifierBytes(String systemCode, String nfcId2, String t3tPmm) { 3536 ByteBuffer buffer = ByteBuffer.allocate(2 + 8 + 8); /* systemcode + nfcid2 + t3tpmm */ 3537 buffer.put(hexStringToBytes(systemCode)); 3538 buffer.put(hexStringToBytes(nfcId2)); 3539 buffer.put(hexStringToBytes(t3tPmm)); 3540 byte[] t3tIdBytes = new byte[buffer.position()]; 3541 buffer.position(0); 3542 buffer.get(t3tIdBytes); 3543 3544 return t3tIdBytes; 3545 } 3546 registerT3tIdentifier(String systemCode, String nfcId2, String t3tPmm)3547 public void registerT3tIdentifier(String systemCode, String nfcId2, String t3tPmm) { 3548 Log.d(TAG, "request to register LF_T3T_IDENTIFIER"); 3549 3550 byte[] t3tIdentifier = getT3tIdentifierBytes(systemCode, nfcId2, t3tPmm); 3551 sendMessage(MSG_REGISTER_T3T_IDENTIFIER, t3tIdentifier); 3552 } 3553 deregisterT3tIdentifier(String systemCode, String nfcId2, String t3tPmm)3554 public void deregisterT3tIdentifier(String systemCode, String nfcId2, String t3tPmm) { 3555 Log.d(TAG, "request to deregister LF_T3T_IDENTIFIER"); 3556 3557 byte[] t3tIdentifier = getT3tIdentifierBytes(systemCode, nfcId2, t3tPmm); 3558 sendMessage(MSG_DEREGISTER_T3T_IDENTIFIER, t3tIdentifier); 3559 } 3560 clearT3tIdentifiersCache()3561 public void clearT3tIdentifiersCache() { 3562 Log.d(TAG, "clear T3t Identifiers Cache"); 3563 mDeviceHost.clearT3tIdentifiersCache(); 3564 } 3565 getLfT3tMax()3566 public int getLfT3tMax() { 3567 return mDeviceHost.getLfT3tMax(); 3568 } 3569 commitRouting()3570 public void commitRouting() { 3571 mHandler.sendEmptyMessage(MSG_COMMIT_ROUTING); 3572 } 3573 sendScreenMessageAfterNfcCharging()3574 public boolean sendScreenMessageAfterNfcCharging() { 3575 if (DBG) Log.d(TAG, "sendScreenMessageAfterNfcCharging() "); 3576 3577 if (mPendingPowerStateUpdate == true) { 3578 int screenState = mScreenStateHelper.checkScreenState(); 3579 if (DBG) Log.d(TAG, 3580 "sendScreenMessageAfterNfcCharging - applying postponed screen state " 3581 + screenState); 3582 NfcService.getInstance().sendMessage(NfcService.MSG_APPLY_SCREEN_STATE, screenState); 3583 mPendingPowerStateUpdate = false; 3584 return true; 3585 } 3586 return false; 3587 } 3588 sendData(byte[] data)3589 public boolean sendData(byte[] data) { 3590 return mDeviceHost.sendRawFrame(data); 3591 } 3592 onPreferredPaymentChanged(int reason)3593 public void onPreferredPaymentChanged(int reason) { 3594 sendMessage(MSG_PREFERRED_PAYMENT_CHANGED, reason); 3595 } 3596 clearRoutingTable(int clearFlags)3597 public void clearRoutingTable(int clearFlags) { 3598 sendMessage(MSG_CLEAR_ROUTING_TABLE, clearFlags); 3599 } 3600 setIsoDepProtocolRoute(int route)3601 public void setIsoDepProtocolRoute(int route) { 3602 sendMessage(MSG_UPDATE_ISODEP_PROTOCOL_ROUTE, route); 3603 } 3604 setTechnologyABRoute(int route)3605 public void setTechnologyABRoute(int route) { 3606 sendMessage(MSG_UPDATE_TECHNOLOGY_AB_ROUTE, route); 3607 } 3608 sendMessage(int what, Object obj)3609 void sendMessage(int what, Object obj) { 3610 Message msg = mHandler.obtainMessage(); 3611 msg.what = what; 3612 msg.obj = obj; 3613 mHandler.sendMessage(msg); 3614 } 3615 3616 /** 3617 * Send require device unlock for NFC intent to system UI. 3618 */ sendRequireUnlockIntent()3619 public void sendRequireUnlockIntent() { 3620 if (!mIsRequestUnlockShowed && mKeyguard.isKeyguardLocked()) { 3621 if (DBG) Log.d(TAG, "Request unlock"); 3622 mIsRequestUnlockShowed = true; 3623 mRequireUnlockWakeLock.acquire(); 3624 Intent requireUnlockIntent = 3625 new Intent(NfcAdapter.ACTION_REQUIRE_UNLOCK_FOR_NFC); 3626 requireUnlockIntent.setPackage(SYSTEM_UI); 3627 mContext.sendBroadcast(requireUnlockIntent); 3628 mRequireUnlockWakeLock.release(); 3629 } 3630 } 3631 3632 final class NfcServiceHandler extends Handler { NfcServiceHandler(Looper looper)3633 public NfcServiceHandler(Looper looper) { 3634 super(looper); 3635 } 3636 3637 @Override handleMessage(Message msg)3638 public void handleMessage(Message msg) { 3639 switch (msg.what) { 3640 case MSG_ROUTE_AID: { 3641 int route = msg.arg1; 3642 int aidInfo = msg.arg2; 3643 String aid = (String) msg.obj; 3644 3645 int power = 0x00; 3646 Bundle bundle = msg.getData(); 3647 if (bundle != null) { 3648 power = bundle.getInt(MSG_ROUTE_AID_PARAM_TAG); 3649 } 3650 3651 mDeviceHost.routeAid(hexStringToBytes(aid), route, aidInfo, power); 3652 // Restart polling config 3653 break; 3654 } 3655 case MSG_UNROUTE_AID: { 3656 String aid = (String) msg.obj; 3657 mDeviceHost.unrouteAid(hexStringToBytes(aid)); 3658 break; 3659 } 3660 case MSG_REGISTER_T3T_IDENTIFIER: { 3661 Log.d(TAG, "message to register LF_T3T_IDENTIFIER"); 3662 mDeviceHost.disableDiscovery(); 3663 3664 byte[] t3tIdentifier = (byte[]) msg.obj; 3665 mDeviceHost.registerT3tIdentifier(t3tIdentifier); 3666 3667 NfcDiscoveryParameters params = computeDiscoveryParameters(mScreenState); 3668 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery(); 3669 mDeviceHost.enableDiscovery(params, shouldRestart); 3670 break; 3671 } 3672 case MSG_DEREGISTER_T3T_IDENTIFIER: { 3673 Log.d(TAG, "message to deregister LF_T3T_IDENTIFIER"); 3674 mDeviceHost.disableDiscovery(); 3675 3676 byte[] t3tIdentifier = (byte[]) msg.obj; 3677 mDeviceHost.deregisterT3tIdentifier(t3tIdentifier); 3678 3679 NfcDiscoveryParameters params = computeDiscoveryParameters(mScreenState); 3680 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery(); 3681 mDeviceHost.enableDiscovery(params, shouldRestart); 3682 break; 3683 } 3684 case MSG_COMMIT_ROUTING: { 3685 synchronized (NfcService.this) { 3686 if (mState == NfcAdapter.STATE_OFF 3687 || mState == NfcAdapter.STATE_TURNING_OFF) { 3688 Log.d(TAG, "Skip commit routing when NFCC is off or turning off"); 3689 return; 3690 } 3691 if (mCurrentDiscoveryParameters.shouldEnableDiscovery()) { 3692 mDeviceHost.commitRouting(); 3693 } else { 3694 Log.d(TAG, "Not committing routing because discovery is disabled."); 3695 } 3696 } 3697 break; 3698 } 3699 case MSG_MOCK_NDEF: { 3700 NdefMessage ndefMsg = (NdefMessage) msg.obj; 3701 Bundle extras = new Bundle(); 3702 extras.putParcelable(Ndef.EXTRA_NDEF_MSG, ndefMsg); 3703 extras.putInt(Ndef.EXTRA_NDEF_MAXLENGTH, 0); 3704 extras.putInt(Ndef.EXTRA_NDEF_CARDSTATE, Ndef.NDEF_MODE_READ_ONLY); 3705 extras.putInt(Ndef.EXTRA_NDEF_TYPE, Ndef.TYPE_OTHER); 3706 /* Avoid setting mCookieUpToDate to negative values */ 3707 mCookieUpToDate = mCookieGenerator.nextLong() >>> 1; 3708 Tag tag = Tag.createMockTag(new byte[]{0x00}, 3709 new int[]{TagTechnology.NDEF}, 3710 new Bundle[]{extras}, mCookieUpToDate); 3711 Log.d(TAG, "mock NDEF tag, starting corresponding activity"); 3712 Log.d(TAG, tag.toString()); 3713 int dispatchStatus = mNfcDispatcher.dispatchTag(tag); 3714 if (dispatchStatus == NfcDispatcher.DISPATCH_SUCCESS) { 3715 playSound(SOUND_END); 3716 } else if (dispatchStatus == NfcDispatcher.DISPATCH_FAIL) { 3717 playSound(SOUND_ERROR); 3718 } 3719 break; 3720 } 3721 3722 case MSG_NDEF_TAG: 3723 if (DBG) Log.d(TAG, "Tag detected, notifying applications"); 3724 TagEndpoint tag = (TagEndpoint) msg.obj; 3725 byte[] debounceTagUid; 3726 int debounceTagMs; 3727 ITagRemovedCallback debounceTagRemovedCallback; 3728 synchronized (NfcService.this) { 3729 debounceTagUid = mDebounceTagUid; 3730 debounceTagMs = mDebounceTagDebounceMs; 3731 debounceTagRemovedCallback = mDebounceTagRemovedCallback; 3732 } 3733 ReaderModeParams readerParams = null; 3734 int presenceCheckDelay = DEFAULT_PRESENCE_CHECK_DELAY; 3735 DeviceHost.TagDisconnectedCallback callback = 3736 new DeviceHost.TagDisconnectedCallback() { 3737 @Override 3738 public void onTagDisconnected() { 3739 mCookieUpToDate = -1; 3740 applyRouting(false); 3741 } 3742 }; 3743 synchronized (NfcService.this) { 3744 readerParams = mReaderModeParams; 3745 } 3746 if (readerParams != null) { 3747 presenceCheckDelay = readerParams.presenceCheckDelay; 3748 if ((readerParams.flags & NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK) != 0) { 3749 if (DBG) Log.d(TAG, "Skipping NDEF detection in reader mode"); 3750 tag.startPresenceChecking(presenceCheckDelay, callback); 3751 dispatchTagEndpoint(tag, readerParams); 3752 break; 3753 } 3754 3755 if (mIsDebugBuild && mSkipNdefRead) { 3756 if (DBG) Log.d(TAG, "Only NDEF detection in reader mode"); 3757 tag.findNdef(); 3758 tag.startPresenceChecking(presenceCheckDelay, callback); 3759 dispatchTagEndpoint(tag, readerParams); 3760 break; 3761 } 3762 } 3763 3764 if (tag.getConnectedTechnology() == TagTechnology.NFC_BARCODE) { 3765 // When these tags start containing NDEF, they will require 3766 // the stack to deal with them in a different way, since 3767 // they are activated only really shortly. 3768 // For now, don't consider NDEF on these. 3769 if (DBG) Log.d(TAG, "Skipping NDEF detection for NFC Barcode"); 3770 tag.startPresenceChecking(presenceCheckDelay, callback); 3771 dispatchTagEndpoint(tag, readerParams); 3772 break; 3773 } 3774 NdefMessage ndefMsg = tag.findAndReadNdef(); 3775 3776 if (ndefMsg == null) { 3777 // First try to see if this was a bad tag read 3778 if (!tag.reconnect()) { 3779 tag.disconnect(); 3780 if (DBG) Log.d(TAG, "Read NDEF error"); 3781 if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) { 3782 if (mReadErrorCount < mReadErrorCountMax) { 3783 mReadErrorCount++; 3784 } else { 3785 pollingDelay(); 3786 } 3787 if (!sToast_debounce && mNotifyReadFailed) { 3788 Toast.makeText(mContext, R.string.tag_read_error, 3789 Toast.LENGTH_SHORT).show(); 3790 sToast_debounce = true; 3791 mHandler.sendEmptyMessageDelayed(MSG_TOAST_DEBOUNCE_EVENT, 3792 sToast_debounce_time_ms); 3793 } 3794 } 3795 break; 3796 } 3797 } 3798 3799 if (debounceTagUid != null) { 3800 // If we're debouncing and the UID or the NDEF message of the tag match, 3801 // don't dispatch but drop it. 3802 if (Arrays.equals(debounceTagUid, tag.getUid()) || 3803 (ndefMsg != null && ndefMsg.equals(mLastReadNdefMessage))) { 3804 mHandler.removeMessages(MSG_TAG_DEBOUNCE); 3805 mHandler.sendEmptyMessageDelayed(MSG_TAG_DEBOUNCE, debounceTagMs); 3806 tag.disconnect(); 3807 return; 3808 } else { 3809 synchronized (NfcService.this) { 3810 mDebounceTagUid = null; 3811 mDebounceTagRemovedCallback = null; 3812 mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE; 3813 } 3814 if (debounceTagRemovedCallback != null) { 3815 try { 3816 debounceTagRemovedCallback.onTagRemoved(); 3817 } catch (RemoteException e) { 3818 // Ignore 3819 } 3820 } 3821 } 3822 } 3823 3824 mLastReadNdefMessage = ndefMsg; 3825 3826 if (mIsWlcEnabled) { 3827 if (DBG) Log.d(TAG, "Wlc enabled, check for WLC_CAP record"); 3828 3829 if (!mNfcCharging.NfcChargingMode 3830 && (mNfcCharging.checkWlcCapMsg(ndefMsg) == true)) { 3831 if (DBG) Log.d(TAG, "checkWlcCapMsg returned true"); 3832 if (mNfcCharging.startNfcCharging(tag)) { 3833 mNfcCharging.NfcChargingMode = true; 3834 if (DBG) Log.d(TAG, "Nfc charging mode started successfully"); 3835 } else { 3836 if (DBG) Log.d(TAG, "Nfc charging mode not detected"); 3837 } 3838 } else if (mIsRWCapable) { 3839 tag.startPresenceChecking(presenceCheckDelay, callback); 3840 dispatchTagEndpoint(tag, readerParams); 3841 } else { 3842 tag.startPresenceChecking(presenceCheckDelay, callback); 3843 } 3844 } else if (mIsRWCapable) { 3845 tag.startPresenceChecking(presenceCheckDelay, callback); 3846 dispatchTagEndpoint(tag, readerParams); 3847 } else { 3848 tag.startPresenceChecking(presenceCheckDelay, callback); 3849 } 3850 break; 3851 3852 case MSG_RF_FIELD_ACTIVATED: 3853 if (mCardEmulationManager != null) { 3854 mCardEmulationManager.onFieldChangeDetected(true); 3855 } 3856 Intent fieldOnIntent = new Intent(ACTION_RF_FIELD_ON_DETECTED); 3857 sendNfcPermissionProtectedBroadcast(fieldOnIntent); 3858 if (mIsSecureNfcEnabled) { 3859 sendRequireUnlockIntent(); 3860 } 3861 break; 3862 case MSG_RF_FIELD_DEACTIVATED: 3863 if (mCardEmulationManager != null) { 3864 mCardEmulationManager.onFieldChangeDetected(false); 3865 } 3866 Intent fieldOffIntent = new Intent(ACTION_RF_FIELD_OFF_DETECTED); 3867 sendNfcPermissionProtectedBroadcast(fieldOffIntent); 3868 break; 3869 case MSG_RESUME_POLLING: 3870 mNfcAdapter.resumePolling(); 3871 break; 3872 case MSG_TAG_DEBOUNCE: 3873 // Didn't see the tag again, tag is gone 3874 ITagRemovedCallback tagRemovedCallback; 3875 synchronized (NfcService.this) { 3876 mDebounceTagUid = null; 3877 tagRemovedCallback = mDebounceTagRemovedCallback; 3878 mDebounceTagRemovedCallback = null; 3879 mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE; 3880 } 3881 if (tagRemovedCallback != null) { 3882 try { 3883 tagRemovedCallback.onTagRemoved(); 3884 } catch (RemoteException e) { 3885 // Ignore 3886 } 3887 } 3888 break; 3889 3890 case MSG_APPLY_SCREEN_STATE: 3891 mScreenState = (Integer)msg.obj; 3892 Log.d(TAG, "MSG_APPLY_SCREEN_STATE " + mScreenState); 3893 3894 synchronized (NfcService.this) { 3895 // Disable delay polling when screen state changed 3896 mPollDelayed = false; 3897 mHandler.removeMessages(MSG_DELAY_POLLING); 3898 // If NFC is turning off, we shouldn't need any changes here 3899 if (mState == NfcAdapter.STATE_TURNING_OFF) 3900 return; 3901 } 3902 3903 mRoutingWakeLock.acquire(); 3904 try { 3905 if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) { 3906 applyRouting(false); 3907 mIsRequestUnlockShowed = false; 3908 } 3909 int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) 3910 ? (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : 3911 mScreenState; 3912 3913 if (mNfcUnlockManager.isLockscreenPollingEnabled()) { 3914 applyRouting(false); 3915 } 3916 3917 mDeviceHost.doSetScreenState(screen_state_mask, mIsWlcEnabled); 3918 } finally { 3919 mRoutingWakeLock.release(); 3920 } 3921 break; 3922 3923 case MSG_TRANSACTION_EVENT: 3924 if (mCardEmulationManager != null) { 3925 mCardEmulationManager.onOffHostAidSelected(); 3926 } 3927 byte[][] data = (byte[][]) msg.obj; 3928 sendOffHostTransactionEvent(data[0], data[1], data[2]); 3929 break; 3930 3931 case MSG_PREFERRED_PAYMENT_CHANGED: 3932 Intent preferredPaymentChangedIntent = 3933 new Intent(NfcAdapter.ACTION_PREFERRED_PAYMENT_CHANGED); 3934 preferredPaymentChangedIntent.putExtra( 3935 NfcAdapter.EXTRA_PREFERRED_PAYMENT_CHANGED_REASON, (int)msg.obj); 3936 sendPreferredPaymentChangedEvent(preferredPaymentChangedIntent); 3937 break; 3938 3939 case MSG_TOAST_DEBOUNCE_EVENT: 3940 sToast_debounce = false; 3941 break; 3942 3943 case MSG_DELAY_POLLING: 3944 synchronized (NfcService.this) { 3945 if (!mPollDelayed) { 3946 return; 3947 } 3948 mPollDelayed = false; 3949 mDeviceHost.startStopPolling(true); 3950 } 3951 if (DBG) Log.d(TAG, "Polling is started"); 3952 break; 3953 case MSG_CLEAR_ROUTING_TABLE: 3954 if (DBG) Log.d(TAG, "Clear routing table"); 3955 int clearFlags = (Integer)msg.obj; 3956 mDeviceHost.clearRoutingEntry(clearFlags); 3957 break; 3958 case MSG_UPDATE_ISODEP_PROTOCOL_ROUTE: 3959 if (DBG) Log.d(TAG, "Update IsoDep Protocol Route"); 3960 mDeviceHost.setIsoDepProtocolRoute((Integer)msg.obj); 3961 break; 3962 case MSG_UPDATE_TECHNOLOGY_AB_ROUTE: 3963 if (DBG) Log.d(TAG, "Update technology A&B route"); 3964 mDeviceHost.setTechnologyABRoute((Integer)msg.obj); 3965 break; 3966 default: 3967 Log.e(TAG, "Unknown message received"); 3968 break; 3969 } 3970 } 3971 sendOffHostTransactionEvent(byte[] aid, byte[] data, byte[] readerByteArray)3972 private void sendOffHostTransactionEvent(byte[] aid, byte[] data, byte[] readerByteArray) { 3973 String reader = ""; 3974 int uid = -1; 3975 int offhostCategory = NfcStatsLog.NFC_CARDEMULATION_OCCURRED__CATEGORY__OFFHOST; 3976 try { 3977 StringBuilder aidString = new StringBuilder(aid.length); 3978 for (byte b : aid) { 3979 aidString.append(String.format("%02X", b)); 3980 } 3981 3982 String aidCategory = mCardEmulationManager 3983 .getRegisteredAidCategory(aidString.toString()); 3984 if (DBG) Log.d(TAG, "aid cateogry: " + aidCategory); 3985 if (mStatsdUtils != null) { 3986 mStatsdUtils.setCardEmulationEventCategory(aidCategory); 3987 } else { 3988 switch (aidCategory) { 3989 case CardEmulation.CATEGORY_PAYMENT: 3990 offhostCategory = NfcStatsLog 3991 .NFC_CARDEMULATION_OCCURRED__CATEGORY__OFFHOST_PAYMENT; 3992 break; 3993 case CardEmulation.CATEGORY_OTHER: 3994 offhostCategory = NfcStatsLog 3995 .NFC_CARDEMULATION_OCCURRED__CATEGORY__OFFHOST_OTHER; 3996 break; 3997 default: 3998 offhostCategory = NfcStatsLog 3999 .NFC_CARDEMULATION_OCCURRED__CATEGORY__OFFHOST; 4000 }; 4001 } 4002 4003 reader = new String(readerByteArray, "UTF-8"); 4004 4005 if (!isSEServiceAvailable() || mNfcEventInstalledPackages.isEmpty()) { 4006 return; 4007 } 4008 4009 for (int userId : mNfcEventInstalledPackages.keySet()) { 4010 List<String> packagesOfUser = mNfcEventInstalledPackages.get(userId); 4011 String[] installedPackages = new String[packagesOfUser.size()]; 4012 boolean[] nfcAccess = mSEService.isNfcEventAllowed(reader, aid, 4013 packagesOfUser.toArray(installedPackages), userId); 4014 if (nfcAccess == null) { 4015 continue; 4016 } 4017 Intent intent = new Intent(NfcAdapter.ACTION_TRANSACTION_DETECTED); 4018 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 4019 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 4020 intent.putExtra(NfcAdapter.EXTRA_AID, aid); 4021 intent.putExtra(NfcAdapter.EXTRA_DATA, data); 4022 intent.putExtra(NfcAdapter.EXTRA_SECURE_ELEMENT_NAME, reader); 4023 String url = 4024 new String("nfc://secure:0/" + reader + "/" + aidString.toString()); 4025 intent.setData(Uri.parse(url)); 4026 4027 final BroadcastOptions options = BroadcastOptions.makeBasic(); 4028 options.setBackgroundActivityStartsAllowed(true); 4029 4030 Map<String, Integer> hasIntentPackages = mContext 4031 .getPackageManager() 4032 .queryBroadcastReceiversAsUser(intent, 0, UserHandle.of(userId)) 4033 .stream() 4034 .collect(Collectors.toMap( 4035 activity -> activity.activityInfo.applicationInfo.packageName, 4036 activity -> activity.activityInfo.applicationInfo.uid, 4037 (packageName1, packageName2) -> { 4038 if (DBG) { 4039 Log.d(TAG, 4040 "queryBroadcastReceiversAsUser duplicate: " + 4041 packageName1 + ", " + packageName2); 4042 } 4043 return packageName1; 4044 })); 4045 if (DBG) { 4046 String[] packageNames = hasIntentPackages 4047 .keySet().toArray(new String[hasIntentPackages.size()]); 4048 Log.d(TAG, 4049 "queryBroadcastReceiversAsUser: " + Arrays.toString(packageNames)); 4050 } 4051 4052 boolean foundFirstPackage = false; 4053 for (int i = 0; i < nfcAccess.length; i++) { 4054 if (nfcAccess[i]) { 4055 String packageName = packagesOfUser.get(i); 4056 if (DBG) { 4057 Log.d(TAG, "sendOffHostTransactionEvent to " + packageName); 4058 } 4059 if (!foundFirstPackage && hasIntentPackages.containsKey(packageName)) { 4060 uid = hasIntentPackages.get(packageName); 4061 if (mStatsdUtils != null) { 4062 mStatsdUtils.setCardEmulationEventUid(uid); 4063 } 4064 foundFirstPackage = true; 4065 } 4066 intent.setPackage(packagesOfUser.get(i)); 4067 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId), null, 4068 options.toBundle()); 4069 } 4070 } 4071 } 4072 } catch (RemoteException e) { 4073 Log.e(TAG, "Error in isNfcEventAllowed() " + e); 4074 } catch (UnsupportedEncodingException e) { 4075 Log.e(TAG, "Incorrect format for Secure Element name" + e); 4076 } catch (IllegalArgumentException e) { 4077 Log.e(TAG, "Error " + e); 4078 } finally { 4079 if (mStatsdUtils != null) { 4080 mStatsdUtils.logCardEmulationOffhostEvent(reader); 4081 } else { 4082 NfcStatsLog.write(NfcStatsLog.NFC_CARDEMULATION_OCCURRED, 4083 offhostCategory, 4084 reader, 4085 uid); 4086 } 4087 } 4088 } 4089 sendNfcPermissionProtectedBroadcast(Intent intent)4090 private void sendNfcPermissionProtectedBroadcast(Intent intent) { 4091 if (mNfcEventInstalledPackages.isEmpty()) { 4092 return; 4093 } 4094 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 4095 for (int userId : mNfcEventInstalledPackages.keySet()) { 4096 for (String packageName : mNfcEventInstalledPackages.get(userId)) { 4097 intent.setPackage(packageName); 4098 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); 4099 } 4100 } 4101 } 4102 4103 /* Returns the list of packages request for nfc preferred payment service changed and 4104 * have access to NFC Events on any SE */ getNfcPreferredPaymentChangedSEAccessAllowedPackages(int userId)4105 private ArrayList<String> getNfcPreferredPaymentChangedSEAccessAllowedPackages(int userId) { 4106 if (!isSEServiceAvailable() 4107 || mNfcPreferredPaymentChangedInstalledPackages.get(userId).isEmpty()) { 4108 return null; 4109 } 4110 String[] readers = null; 4111 try { 4112 readers = mSEService.getReaders(); 4113 } catch (RemoteException e) { 4114 Log.e(TAG, "Error in getReaders() " + e); 4115 return null; 4116 } 4117 4118 if (readers == null || readers.length == 0) { 4119 return null; 4120 } 4121 boolean[] nfcAccessFinal = null; 4122 List<String> packagesOfUser = mNfcPreferredPaymentChangedInstalledPackages.get(userId); 4123 String[] installedPackages = new String[packagesOfUser.size()]; 4124 4125 for (String reader : readers) { 4126 try { 4127 boolean[] accessList = mSEService.isNfcEventAllowed(reader, null, 4128 packagesOfUser.toArray(installedPackages), userId 4129 ); 4130 if (accessList == null) { 4131 continue; 4132 } 4133 if (nfcAccessFinal == null) { 4134 nfcAccessFinal = accessList; 4135 } 4136 for (int i = 0; i < accessList.length; i++) { 4137 if (accessList[i]) { 4138 nfcAccessFinal[i] = true; 4139 } 4140 } 4141 } catch (RemoteException e) { 4142 Log.e(TAG, "Error in isNfcEventAllowed() " + e); 4143 } catch (IllegalArgumentException e) { 4144 Log.e(TAG, "Error " + e); 4145 } 4146 } 4147 if (nfcAccessFinal == null) { 4148 return null; 4149 } 4150 ArrayList<String> packages = new ArrayList<String>(); 4151 for (int i = 0; i < nfcAccessFinal.length; i++) { 4152 if (nfcAccessFinal[i]) { 4153 packages.add(packagesOfUser.get(i)); 4154 } 4155 } 4156 return packages; 4157 } 4158 isSystemApp(ApplicationInfo applicationInfo)4159 private boolean isSystemApp(ApplicationInfo applicationInfo) { 4160 return ((applicationInfo.flags & APP_INFO_FLAGS_SYSTEM_APP) != 0); 4161 } 4162 sendPreferredPaymentChangedEvent(Intent intent)4163 private void sendPreferredPaymentChangedEvent(Intent intent) { 4164 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 4165 // Resume app switches so the receivers can start activities without delay 4166 mNfcDispatcher.resumeAppSwitches(); 4167 synchronized (this) { 4168 for (int userId : mNfcPreferredPaymentChangedInstalledPackages.keySet()) { 4169 ArrayList<String> SEPackages = 4170 getNfcPreferredPaymentChangedSEAccessAllowedPackages(userId); 4171 UserHandle userHandle = UserHandle.of(userId); 4172 if (SEPackages != null && !SEPackages.isEmpty()) { 4173 for (String packageName : SEPackages) { 4174 intent.setPackage(packageName); 4175 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 4176 mContext.sendBroadcastAsUser(intent, userHandle); 4177 } 4178 } 4179 PackageManager pm; 4180 try { 4181 pm = mContext.createContextAsUser(userHandle, /*flags=*/0) 4182 .getPackageManager(); 4183 } catch (IllegalStateException e) { 4184 Log.d(TAG, "Fail to get PackageManager for user: " + userHandle); 4185 continue; 4186 } 4187 for (String pkgName : 4188 mNfcPreferredPaymentChangedInstalledPackages.get(userId)) { 4189 try { 4190 PackageInfo info = pm.getPackageInfo(pkgName, 0); 4191 if (SEPackages != null && SEPackages.contains(pkgName)) { 4192 continue; 4193 } 4194 if (info.applicationInfo != null 4195 && (isSystemApp(info.applicationInfo) 4196 || info.applicationInfo.isPrivilegedApp())) { 4197 intent.setPackage(pkgName); 4198 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 4199 mContext.sendBroadcastAsUser(intent, userHandle); 4200 } 4201 } catch (Exception e) { 4202 Log.e(TAG, "Exception in getPackageInfo " + e); 4203 } 4204 } 4205 } 4206 } 4207 } 4208 pollingDelay()4209 private void pollingDelay() { 4210 if (mPollDelayTime <= NO_POLL_DELAY) return; 4211 synchronized (NfcService.this) { 4212 if (!mPollDelayed) { 4213 mPollDelayed = true; 4214 mDeviceHost.startStopPolling(false); 4215 int delayTime = mPollDelayTime; 4216 if (mPollDelayCount < mPollDelayCountMax) { 4217 mPollDelayCount++; 4218 } else { 4219 delayTime = mPollDelayTimeLong; 4220 } 4221 if (DBG) Log.d(TAG, "Polling delayed " + delayTime); 4222 mHandler.sendMessageDelayed( 4223 mHandler.obtainMessage(MSG_DELAY_POLLING), delayTime); 4224 } else { 4225 if (DBG) Log.d(TAG, "Keep waiting for polling delay"); 4226 } 4227 } 4228 } 4229 dispatchTagEndpoint(TagEndpoint tagEndpoint, ReaderModeParams readerParams)4230 private void dispatchTagEndpoint(TagEndpoint tagEndpoint, ReaderModeParams readerParams) { 4231 try { 4232 /* Avoid setting mCookieUpToDate to negative values */ 4233 mCookieUpToDate = mCookieGenerator.nextLong() >>> 1; 4234 Tag tag = new Tag(tagEndpoint.getUid(), tagEndpoint.getTechList(), 4235 tagEndpoint.getTechExtras(), tagEndpoint.getHandle(), 4236 mCookieUpToDate, mNfcTagService); 4237 registerTagObject(tagEndpoint); 4238 if (readerParams != null) { 4239 try { 4240 if ((readerParams.flags & NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS) == 0) { 4241 mVibrator.vibrate(mVibrationEffect, 4242 HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES); 4243 playSound(SOUND_END); 4244 } 4245 if (readerParams.callback != null) { 4246 if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) { 4247 mPowerManager.userActivity(SystemClock.uptimeMillis(), 4248 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0); 4249 } 4250 readerParams.callback.onTagDiscovered(tag); 4251 return; 4252 } else { 4253 // Follow normal dispatch below 4254 } 4255 } catch (RemoteException e) { 4256 Log.e(TAG, "Reader mode remote has died, falling back.", e); 4257 // Intentional fall-through 4258 } catch (Exception e) { 4259 // Catch any other exception 4260 Log.e(TAG, "App exception, not dispatching.", e); 4261 return; 4262 } 4263 } 4264 int dispatchResult = mNfcDispatcher.dispatchTag(tag); 4265 if (dispatchResult == NfcDispatcher.DISPATCH_FAIL && !mInProvisionMode) { 4266 if (DBG) Log.d(TAG, "Tag dispatch failed"); 4267 unregisterObject(tagEndpoint.getHandle()); 4268 if (mPollDelayTime > NO_POLL_DELAY) { 4269 tagEndpoint.stopPresenceChecking(); 4270 pollingDelay(); 4271 } else { 4272 Log.d(TAG, "Keep presence checking."); 4273 } 4274 if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED && mNotifyDispatchFailed) { 4275 if (!sToast_debounce) { 4276 Toast.makeText(mContext, R.string.tag_dispatch_failed, 4277 Toast.LENGTH_SHORT).show(); 4278 sToast_debounce = true; 4279 mHandler.sendEmptyMessageDelayed(MSG_TOAST_DEBOUNCE_EVENT, 4280 sToast_debounce_time_ms); 4281 } 4282 playSound(SOUND_ERROR); 4283 } 4284 if (!mAntennaBlockedMessageShown && mDispatchFailedCount++ > mDispatchFailedMax) { 4285 new NfcBlockedNotification(mContext).startNotification(); 4286 synchronized (NfcService.this) { 4287 mPrefsEditor.putBoolean(PREF_ANTENNA_BLOCKED_MESSAGE_SHOWN, true); 4288 mPrefsEditor.apply(); 4289 } 4290 mBackupManager.dataChanged(); 4291 mAntennaBlockedMessageShown = true; 4292 mDispatchFailedCount = 0; 4293 if (DBG) Log.d(TAG, "Tag dispatch failed notification"); 4294 } 4295 } else if (dispatchResult == NfcDispatcher.DISPATCH_SUCCESS) { 4296 synchronized (NfcService.this) { 4297 mPollDelayCount = 0; 4298 mReadErrorCount = 0; 4299 } 4300 if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) { 4301 mPowerManager.userActivity(SystemClock.uptimeMillis(), 4302 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0); 4303 } 4304 mDispatchFailedCount = 0; 4305 mVibrator.vibrate(mVibrationEffect, HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES); 4306 playSound(SOUND_END); 4307 } 4308 } catch (Exception e) { 4309 Log.e(TAG, "Tag creation exception, not dispatching.", e); 4310 return; 4311 } 4312 } 4313 } 4314 4315 private NfcServiceHandler mHandler; 4316 4317 class ApplyRoutingTask extends AsyncTask<Integer, Void, Void> { 4318 @Override doInBackground(Integer... params)4319 protected Void doInBackground(Integer... params) { 4320 synchronized (NfcService.this) { 4321 if (params == null || params.length != 1) { 4322 // force apply current routing 4323 applyRouting(true); 4324 return null; 4325 } 4326 mScreenState = params[0].intValue(); 4327 4328 mRoutingWakeLock.acquire(); 4329 try { 4330 applyRouting(false); 4331 } finally { 4332 mRoutingWakeLock.release(); 4333 } 4334 return null; 4335 } 4336 } 4337 } 4338 4339 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 4340 @Override 4341 public void onReceive(Context context, Intent intent) { 4342 String action = intent.getAction(); 4343 if (action.equals(Intent.ACTION_SCREEN_ON) 4344 || action.equals(Intent.ACTION_SCREEN_OFF) 4345 || action.equals(Intent.ACTION_USER_PRESENT)) { 4346 // Perform applyRouting() in AsyncTask to serialize blocking calls 4347 4348 if (mIsWlcCapable && mNfcCharging.NfcChargingOnGoing) { 4349 Log.d(TAG, 4350 "MSG_APPLY_SCREEN_STATE postponing due to a charging pier device"); 4351 mPendingPowerStateUpdate = true; 4352 return; 4353 } 4354 if (action.equals(Intent.ACTION_SCREEN_ON)) { 4355 synchronized (NfcService.this) { 4356 mPollDelayCount = 0; 4357 mReadErrorCount = 0; 4358 } 4359 } 4360 applyScreenState(mScreenStateHelper.checkScreenState()); 4361 } else if (action.equals(Intent.ACTION_USER_SWITCHED)) { 4362 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 4363 mUserId = userId; 4364 updatePackageCache(); 4365 if (DBG) Log.d(TAG, action + " received with UserId: " + userId); 4366 if (mIsHceCapable) { 4367 mCardEmulationManager.onUserSwitched(getUserId()); 4368 } 4369 applyScreenState(mScreenStateHelper.checkScreenState()); 4370 4371 if (NFC_SNOOP_LOG_MODE.equals(NfcProperties.snoop_log_mode_values.FULL) || 4372 NFC_VENDOR_DEBUG_ENABLED) { 4373 new NfcDeveloperOptionNotification(mContext.createContextAsUser( 4374 UserHandle.of(ActivityManager.getCurrentUser()), /*flags=*/0)) 4375 .startNotification(); 4376 } 4377 } else if (action.equals(Intent.ACTION_USER_ADDED)) { 4378 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 4379 setPaymentForegroundPreference(userId); 4380 4381 if (NFC_SNOOP_LOG_MODE.equals(NfcProperties.snoop_log_mode_values.FULL) || 4382 NFC_VENDOR_DEBUG_ENABLED) { 4383 new NfcDeveloperOptionNotification(mContext.createContextAsUser( 4384 UserHandle.of(ActivityManager.getCurrentUser()), /*flags=*/0)) 4385 .startNotification(); 4386 } 4387 } 4388 } 4389 }; 4390 4391 private final BroadcastReceiver mManagedProfileReceiver = new BroadcastReceiver() { 4392 @Override 4393 public void onReceive(Context context, Intent intent) { 4394 String action = intent.getAction(); 4395 UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER); 4396 4397 // User should be filled for below intents, check the existence. 4398 if (user == null) { 4399 Log.d(TAG, intent.getAction() + " broadcast without EXTRA_USER."); 4400 return; 4401 } 4402 4403 if (mCardEmulationManager == null) { 4404 return; 4405 } 4406 if (action.equals(Intent.ACTION_MANAGED_PROFILE_ADDED) || 4407 action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) || 4408 action.equals(Intent.ACTION_MANAGED_PROFILE_REMOVED) || 4409 action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)) { 4410 if (DBG) Log.d(TAG, action + " received with UserId: " + user.getIdentifier()); 4411 mCardEmulationManager.onManagedProfileChanged(); 4412 setPaymentForegroundPreference(user.getIdentifier()); 4413 } 4414 } 4415 }; 4416 4417 private final BroadcastReceiver mOwnerReceiver = new BroadcastReceiver() { 4418 @Override 4419 public void onReceive(Context context, Intent intent) { 4420 String action = intent.getAction(); 4421 if (action.equals(Intent.ACTION_PACKAGE_REMOVED) || 4422 action.equals(Intent.ACTION_PACKAGE_ADDED) || 4423 action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE) || 4424 action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) { 4425 updatePackageCache(); 4426 if (action.equals(Intent.ACTION_PACKAGE_REMOVED) 4427 && renewTagAppPrefList()) storeTagAppPrefList(); 4428 } else if (action.equals(Intent.ACTION_SHUTDOWN)) { 4429 if (DBG) Log.d(TAG, "Shutdown received with UserId: " + 4430 getSendingUser().getIdentifier()); 4431 if (!getSendingUser().equals(UserHandle.ALL)) { 4432 return; 4433 } 4434 if (DBG) Log.d(TAG, "Device is shutting down."); 4435 if (mIsAlwaysOnSupported && mAlwaysOnState == NfcAdapter.STATE_ON) { 4436 new EnableDisableTask().execute(TASK_DISABLE_ALWAYS_ON); 4437 } 4438 if (isNfcEnabled()) { 4439 mDeviceHost.shutdown(); 4440 } 4441 } 4442 } 4443 }; 4444 applyScreenState(int screenState)4445 private void applyScreenState(int screenState) { 4446 if(mFeatureFlags.reduceStateTransition() && 4447 mIsWatchType && !mCardEmulationManager.isRequiresScreenOnServiceExist()) { 4448 if (screenState == ScreenStateHelper.SCREEN_STATE_OFF_LOCKED) { 4449 screenState = ScreenStateHelper.SCREEN_STATE_ON_LOCKED; 4450 } else if (screenState == ScreenStateHelper.SCREEN_STATE_OFF_UNLOCKED) { 4451 screenState = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED; 4452 } 4453 } 4454 if (DBG) Log.d(TAG, "applyScreenState(): screenState=" + screenState ); 4455 if (mScreenState != screenState) { 4456 if (nci_version != NCI_VERSION_2_0) { 4457 new ApplyRoutingTask().execute(Integer.valueOf(screenState)); 4458 } 4459 if (DBG) Log.d(TAG, "applyScreenState(): screenState != mScreenState=" + mScreenState ); 4460 sendMessage(NfcService.MSG_APPLY_SCREEN_STATE, screenState); 4461 } 4462 } 4463 setPaymentForegroundPreference(int user)4464 private void setPaymentForegroundPreference(int user) { 4465 Context uc; 4466 try { 4467 uc = mContext.createContextAsUser(UserHandle.of(user), 0); 4468 } catch (IllegalStateException e) { 4469 Log.d(TAG, "Fail to get user context for user: " + user); 4470 return; 4471 } 4472 try { 4473 // Check whether the Settings.Secure.NFC_PAYMENT_FOREGROUND exists or not. 4474 Settings.Secure.getInt(uc.getContentResolver(), 4475 Constants.SETTINGS_SECURE_NFC_PAYMENT_FOREGROUND); 4476 } catch (SettingNotFoundException e) { 4477 boolean foregroundPreference = 4478 mContext.getResources().getBoolean(R.bool.payment_foreground_preference); 4479 Settings.Secure.putInt(uc.getContentResolver(), 4480 Constants.SETTINGS_SECURE_NFC_PAYMENT_FOREGROUND, foregroundPreference ? 1 : 0); 4481 Log.d(TAG, "Set NFC_PAYMENT_FOREGROUND preference:" + foregroundPreference); 4482 } 4483 } 4484 4485 /** 4486 * for debugging only - no i18n 4487 */ stateToString(int state)4488 static String stateToString(int state) { 4489 switch (state) { 4490 case NfcAdapter.STATE_OFF: 4491 return "off"; 4492 case NfcAdapter.STATE_TURNING_ON: 4493 return "turning on"; 4494 case NfcAdapter.STATE_ON: 4495 return "on"; 4496 case NfcAdapter.STATE_TURNING_OFF: 4497 return "turning off"; 4498 default: 4499 return "<error>"; 4500 } 4501 } 4502 stateToProtoEnum(int state)4503 static int stateToProtoEnum(int state) { 4504 switch (state) { 4505 case NfcAdapter.STATE_OFF: 4506 return NfcServiceDumpProto.STATE_OFF; 4507 case NfcAdapter.STATE_TURNING_ON: 4508 return NfcServiceDumpProto.STATE_TURNING_ON; 4509 case NfcAdapter.STATE_ON: 4510 return NfcServiceDumpProto.STATE_ON; 4511 case NfcAdapter.STATE_TURNING_OFF: 4512 return NfcServiceDumpProto.STATE_TURNING_OFF; 4513 default: 4514 return NfcServiceDumpProto.STATE_UNKNOWN; 4515 } 4516 } 4517 copyNativeCrashLogsIfAny(PrintWriter pw)4518 private void copyNativeCrashLogsIfAny(PrintWriter pw) { 4519 try { 4520 File file = new File(NATIVE_LOG_FILE_PATH, NATIVE_LOG_FILE_NAME); 4521 if (!file.exists()) { 4522 return; 4523 } 4524 pw.println("---BEGIN: NATIVE CRASH LOG----"); 4525 Scanner sc = new Scanner(file); 4526 while(sc.hasNextLine()) { 4527 String s = sc.nextLine(); 4528 pw.println(s); 4529 } 4530 pw.println("---END: NATIVE CRASH LOG----"); 4531 sc.close(); 4532 } catch (IOException e) { 4533 Log.e(TAG, "Exception in copyNativeCrashLogsIfAny " + e); 4534 } 4535 } 4536 storeNativeCrashLogs()4537 public void storeNativeCrashLogs() { 4538 FileOutputStream fos = null; 4539 try { 4540 File file = new File(NATIVE_LOG_FILE_PATH, NATIVE_LOG_FILE_NAME); 4541 if (file.length() >= NATIVE_CRASH_FILE_SIZE) { 4542 file.createNewFile(); 4543 } 4544 4545 fos = new FileOutputStream(file, true); 4546 mDeviceHost.dump(fos.getFD()); 4547 fos.flush(); 4548 } catch (IOException e) { 4549 Log.e(TAG, "Exception in storeNativeCrashLogs " + e); 4550 } finally { 4551 if (fos != null) { 4552 try { 4553 fos.close(); 4554 } catch (IOException e) { 4555 Log.e(TAG, "Exception in storeNativeCrashLogs: file close " + e); 4556 } 4557 } 4558 } 4559 } 4560 dumpTagAppPreference(PrintWriter pw)4561 private void dumpTagAppPreference(PrintWriter pw) { 4562 pw.println("mIsTagAppPrefSupported =" + mIsTagAppPrefSupported); 4563 if (mIsTagAppPrefSupported) { 4564 pw.println("TagAppPreference:"); 4565 UserManager um = mContext.createContextAsUser( 4566 UserHandle.of(ActivityManager.getCurrentUser()), 0) 4567 .getSystemService(UserManager.class); 4568 List<UserHandle> luh = um.getEnabledProfiles(); 4569 for (UserHandle uh : luh) { 4570 int userId = uh.getIdentifier(); 4571 HashMap<String, Boolean> map; 4572 synchronized (NfcService.this) { 4573 map = mTagAppPrefList.getOrDefault(userId, new HashMap<>()); 4574 } 4575 if (map.size() > 0) pw.println("userId=" + userId); 4576 for (Map.Entry<String, Boolean> entry : map.entrySet()) { 4577 pw.println("pkg: " + entry.getKey() + " : " + entry.getValue()); 4578 } 4579 } 4580 } 4581 } 4582 dump(FileDescriptor fd, PrintWriter pw, String[] args)4583 void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 4584 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 4585 != PackageManager.PERMISSION_GRANTED) { 4586 pw.println("Permission Denial: can't dump nfc from from pid=" 4587 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 4588 + " without permission " + android.Manifest.permission.DUMP); 4589 return; 4590 } 4591 4592 for (String arg : args) { 4593 if ("--proto".equals(arg)) { 4594 FileOutputStream fos = null; 4595 try { 4596 fos = new FileOutputStream(fd); 4597 ProtoOutputStream proto = new ProtoOutputStream(fos); 4598 synchronized (this) { 4599 dumpDebug(proto); 4600 } 4601 proto.flush(); 4602 } catch (Exception e) { 4603 Log.e(TAG, "Exception in dump nfc --proto " + e); 4604 } finally { 4605 if (fos != null) { 4606 try { 4607 fos.close(); 4608 } catch (IOException e) { 4609 Log.e(TAG, "Exception in storeNativeCrashLogs " + e); 4610 } 4611 } 4612 } 4613 return; 4614 } 4615 } 4616 4617 synchronized (this) { 4618 pw.println("mState=" + stateToString(mState)); 4619 pw.println("mAlwaysOnState=" + stateToString(mAlwaysOnState)); 4620 pw.println("mScreenState=" + ScreenStateHelper.screenStateToString(mScreenState)); 4621 pw.println("mIsSecureNfcEnabled=" + mIsSecureNfcEnabled); 4622 pw.println("mIsReaderOptionEnabled=" + mIsReaderOptionEnabled); 4623 pw.println("mIsAlwaysOnSupported=" + mIsAlwaysOnSupported); 4624 if(mIsWlcCapable) { 4625 pw.println("WlcEnabled=" + mIsWlcEnabled); 4626 } 4627 pw.println("SnoopLogMode=" + NFC_SNOOP_LOG_MODE); 4628 pw.println("VendorDebugEnabled=" + NFC_VENDOR_DEBUG_ENABLED); 4629 pw.println("mIsPowerSavingModeEnabled=" + mIsPowerSavingModeEnabled); 4630 pw.println(mCurrentDiscoveryParameters); 4631 if (mIsHceCapable) { 4632 mCardEmulationManager.dump(fd, pw, args); 4633 } 4634 mNfcDispatcher.dump(fd, pw, args); 4635 if (mState == NfcAdapter.STATE_ON) { 4636 mRoutingTableParser.dump(mDeviceHost, pw); 4637 } 4638 dumpTagAppPreference(pw); 4639 mNfcInjector.getNfcEventLog().dump(fd, pw, args); 4640 copyNativeCrashLogsIfAny(pw); 4641 pw.flush(); 4642 mDeviceHost.dump(fd); 4643 } 4644 } 4645 4646 /** 4647 * Dump debugging information as a NfcServiceDumpProto 4648 * 4649 * Note: 4650 * See proto definition in frameworks/base/core/proto/android/nfc/nfc_service.proto 4651 * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and 4652 * {@link ProtoOutputStream#end(long)} after. 4653 * Never reuse a proto field number. When removing a field, mark it as reserved. 4654 */ dumpDebug(ProtoOutputStream proto)4655 private void dumpDebug(ProtoOutputStream proto) { 4656 proto.write(NfcServiceDumpProto.STATE, stateToProtoEnum(mState)); 4657 proto.write(NfcServiceDumpProto.IN_PROVISION_MODE, mInProvisionMode); 4658 proto.write(NfcServiceDumpProto.SCREEN_STATE, 4659 ScreenStateHelper.screenStateToProtoEnum(mScreenState)); 4660 proto.write(NfcServiceDumpProto.SECURE_NFC_ENABLED, mIsSecureNfcEnabled); 4661 proto.write(NfcServiceDumpProto.POLLING_PAUSED, mPollingPaused); 4662 proto.write(NfcServiceDumpProto.HCE_CAPABLE, mIsHceCapable); 4663 proto.write(NfcServiceDumpProto.HCE_F_CAPABLE, mIsHceFCapable); 4664 proto.write(NfcServiceDumpProto.SECURE_NFC_CAPABLE, mIsSecureNfcCapable); 4665 proto.write(NfcServiceDumpProto.VR_MODE_ENABLED, 4666 (mVrManager != null) ? mVrManager.isVrModeEnabled() : false); 4667 4668 long token = proto.start(NfcServiceDumpProto.DISCOVERY_PARAMS); 4669 mCurrentDiscoveryParameters.dumpDebug(proto); 4670 proto.end(token); 4671 4672 if (mIsHceCapable) { 4673 token = proto.start(NfcServiceDumpProto.CARD_EMULATION_MANAGER); 4674 mCardEmulationManager.dumpDebug(proto); 4675 proto.end(token); 4676 } 4677 4678 token = proto.start(NfcServiceDumpProto.NFC_DISPATCHER); 4679 mNfcDispatcher.dumpDebug(proto); 4680 proto.end(token); 4681 4682 // Dump native crash logs if any 4683 File file = new File(NATIVE_LOG_FILE_PATH, NATIVE_LOG_FILE_NAME); 4684 if (!file.exists()) { 4685 return; 4686 } 4687 try { 4688 String logs = Files.lines(file.toPath()).collect(Collectors.joining("\n")); 4689 proto.write(NfcServiceDumpProto.NATIVE_CRASH_LOGS, logs); 4690 } catch (IOException e) { 4691 Log.e(TAG, "IOException in dumpDebug(ProtoOutputStream): " + e); 4692 } 4693 } 4694 runTaskOnSingleThreadExecutor(FutureTask<Integer> task, int timeoutMs)4695 private int runTaskOnSingleThreadExecutor(FutureTask<Integer> task, int timeoutMs) 4696 throws InterruptedException, TimeoutException, ExecutionException { 4697 ExecutorService executor = Executors.newSingleThreadExecutor(); 4698 executor.submit(task); 4699 try { 4700 return task.get(timeoutMs, TimeUnit.MILLISECONDS); 4701 } catch (TimeoutException e) { 4702 executor.shutdownNow(); 4703 throw e; 4704 } 4705 } 4706 } 4707