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 android.Manifest.permission.BIND_NFC_SERVICE; 20 import static android.nfc.OemLogItems.EVENT_DISABLE; 21 import static android.nfc.OemLogItems.EVENT_ENABLE; 22 23 import static com.android.nfc.ScreenStateHelper.SCREEN_STATE_ON_LOCKED; 24 import static com.android.nfc.ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED; 25 26 import android.annotation.FlaggedApi; 27 import android.annotation.NonNull; 28 import android.annotation.Nullable; 29 import android.app.ActivityManager; 30 import android.app.AlarmManager; 31 import android.app.Application; 32 import android.app.BroadcastOptions; 33 import android.app.KeyguardManager; 34 import android.app.KeyguardManager.DeviceLockedStateListener; 35 import android.app.KeyguardManager.KeyguardLockedStateListener; 36 import android.app.PendingIntent; 37 import android.app.admin.SecurityLog; 38 import android.app.backup.BackupManager; 39 import android.app.role.RoleManager; 40 import android.content.BroadcastReceiver; 41 import android.content.ContentResolver; 42 import android.content.Context; 43 import android.content.Intent; 44 import android.content.IntentFilter; 45 import android.content.SharedPreferences; 46 import android.content.pm.ApplicationInfo; 47 import android.content.pm.PackageInfo; 48 import android.content.pm.PackageManager; 49 import android.database.ContentObserver; 50 import android.hardware.display.DisplayManager; 51 import android.hardware.display.DisplayManager.DisplayListener; 52 import android.media.AudioAttributes; 53 import android.media.SoundPool; 54 import android.media.SoundPool.OnLoadCompleteListener; 55 import android.net.Uri; 56 import android.nfc.AvailableNfcAntenna; 57 import android.nfc.Constants; 58 import android.nfc.Entry; 59 import android.nfc.ErrorCodes; 60 import android.nfc.FormatException; 61 import android.nfc.IAppCallback; 62 import android.nfc.INfcAdapter; 63 import android.nfc.INfcAdapterExtras; 64 import android.nfc.INfcCardEmulation; 65 import android.nfc.INfcControllerAlwaysOnListener; 66 import android.nfc.INfcDta; 67 import android.nfc.INfcFCardEmulation; 68 import android.nfc.INfcOemExtensionCallback; 69 import android.nfc.INfcTag; 70 import android.nfc.INfcUnlockHandler; 71 import android.nfc.INfcVendorNciCallback; 72 import android.nfc.INfcWlcStateListener; 73 import android.nfc.IT4tNdefNfcee; 74 import android.nfc.ITagRemovedCallback; 75 import android.nfc.NdefMessage; 76 import android.nfc.NfcAdapter; 77 import android.nfc.NfcAntennaInfo; 78 import android.nfc.NfcOemExtension; 79 import android.nfc.OemLogItems; 80 import android.nfc.T4tNdefNfcee; 81 import android.nfc.T4tNdefNfceeCcFileInfo; 82 import android.nfc.Tag; 83 import android.nfc.TechListParcel; 84 import android.nfc.TransceiveResult; 85 import android.nfc.WlcListenerDeviceInfo; 86 import android.nfc.cardemulation.CardEmulation; 87 import android.nfc.cardemulation.PollingFrame; 88 import android.nfc.tech.Ndef; 89 import android.nfc.tech.TagTechnology; 90 import android.os.AsyncTask; 91 import android.os.Binder; 92 import android.os.Build; 93 import android.os.Bundle; 94 import android.os.Handler; 95 import android.os.IBinder; 96 import android.os.Looper; 97 import android.os.Message; 98 import android.os.ParcelFileDescriptor; 99 import android.os.PowerManager; 100 import android.os.PowerManager.OnThermalStatusChangedListener; 101 import android.os.Process; 102 import android.os.RemoteException; 103 import android.os.ResultReceiver; 104 import android.os.SystemClock; 105 import android.os.Trace; 106 import android.os.UserHandle; 107 import android.os.UserManager; 108 import android.os.VibrationAttributes; 109 import android.os.VibrationEffect; 110 import android.os.Vibrator; 111 import android.provider.Settings; 112 import android.provider.Settings.SettingNotFoundException; 113 import android.se.omapi.ISecureElementService; 114 import android.sysprop.NfcProperties; 115 import android.util.EventLog; 116 import android.util.Log; 117 import android.util.proto.ProtoOutputStream; 118 import android.view.Display; 119 import android.widget.Toast; 120 121 import androidx.annotation.VisibleForTesting; 122 123 import com.android.nfc.DeviceHost.DeviceHostListener; 124 import com.android.nfc.DeviceHost.TagEndpoint; 125 import com.android.nfc.cardemulation.CardEmulationManager; 126 import com.android.nfc.cardemulation.util.StatsdUtils; 127 import com.android.nfc.dhimpl.NativeNfcManager; 128 import com.android.nfc.flags.FeatureFlags; 129 import com.android.nfc.flags.Flags; 130 import com.android.nfc.handover.HandoverDataParser; 131 import com.android.nfc.proto.NfcEventProto; 132 import com.android.nfc.wlc.NfcCharging; 133 134 import com.google.protobuf.ByteString; 135 136 import org.json.JSONException; 137 import org.json.JSONObject; 138 139 import java.io.File; 140 import java.io.FileDescriptor; 141 import java.io.FileOutputStream; 142 import java.io.IOException; 143 import java.io.PrintWriter; 144 import java.io.StringWriter; 145 import java.io.UnsupportedEncodingException; 146 import java.nio.ByteBuffer; 147 import java.nio.file.Files; 148 import java.security.SecureRandom; 149 import java.time.Instant; 150 import java.util.ArrayList; 151 import java.util.Arrays; 152 import java.util.Collections; 153 import java.util.HashMap; 154 import java.util.HashSet; 155 import java.util.HexFormat; 156 import java.util.Iterator; 157 import java.util.List; 158 import java.util.Map; 159 import java.util.NoSuchElementException; 160 import java.util.Scanner; 161 import java.util.Set; 162 import java.util.Timer; 163 import java.util.TimerTask; 164 import java.util.concurrent.CountDownLatch; 165 import java.util.concurrent.ExecutionException; 166 import java.util.concurrent.ExecutorService; 167 import java.util.concurrent.Executors; 168 import java.util.concurrent.FutureTask; 169 import java.util.concurrent.ScheduledExecutorService; 170 import java.util.concurrent.ScheduledFuture; 171 import java.util.concurrent.TimeUnit; 172 import java.util.concurrent.TimeoutException; 173 import java.util.stream.Collectors; 174 175 public class NfcService implements DeviceHostListener, ForegroundUtils.Callback { 176 static final boolean DBG = NfcProperties.debug_enabled().orElse(true); 177 private static final boolean VDBG = false; // turn on for local testing. 178 static final String TAG = "NfcService"; 179 private static final int APP_INFO_FLAGS_SYSTEM_APP = 180 ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 181 182 public static final String SERVICE_NAME = "nfc"; 183 184 private static final String SYSTEM_UI = "com.android.systemui"; 185 186 public static final String PREF = "NfcServicePrefs"; 187 public static final String PREF_TAG_APP_LIST = "TagIntentAppPreferenceListPrefs"; 188 189 static final String PREF_NFC_ON = "nfc_on"; 190 191 static final String PREF_NFC_READER_OPTION_ON = "nfc_reader_on"; 192 193 static final String PREF_NFC_CHARGING_ON = "nfc_charging_on"; 194 static final boolean NFC_CHARGING_ON_DEFAULT = true; 195 196 static final String PREF_MIGRATE_TO_DE_COMPLETE = "migrate_to_de_complete"; 197 static final String PREF_SECURE_NFC_ON = "secure_nfc_on"; 198 static final String PREF_FIRST_BOOT = "first_boot"; 199 200 static final String PREF_ANTENNA_BLOCKED_MESSAGE_SHOWN = "antenna_blocked_message_shown"; 201 static final boolean ANTENNA_BLOCKED_MESSAGE_SHOWN_DEFAULT = false; 202 203 static final String NATIVE_LOG_FILE_NAME = "native_crash_logs"; 204 static final String NATIVE_LOG_FILE_PATH = "/data/misc/nfc/logs"; 205 static final int NATIVE_CRASH_FILE_SIZE = 1024 * 1024; 206 private static final String WAIT_FOR_OEM_ALLOW_BOOT_TIMER_TAG = "NfcWaitForSimTag"; 207 static final byte[] T4T_NFCEE_CC_FILE_ID = {(byte) (0xE1), (byte) (0x03)}; 208 public static final int T4T_NFCEE_MAPPING_VERSION_2_0 = 0x20; 209 @VisibleForTesting 210 public static final int WAIT_FOR_OEM_ALLOW_BOOT_TIMEOUT_MS = 5_000; 211 212 static final int MSG_NDEF_TAG = 0; 213 // Previously used: MSG_LLCP_LINK_ACTIVATION = 1 214 // Previously used: MSG_LLCP_LINK_DEACTIVATED = 2 215 static final int MSG_MOCK_NDEF = 3; 216 // Previously used: MSG_LLCP_LINK_FIRST_PACKET = 4 217 static final int MSG_ROUTE_AID = 5; 218 static final int MSG_UNROUTE_AID = 6; 219 static final int MSG_COMMIT_ROUTING = 7; 220 // Previously used: MSG_INVOKE_BEAM = 8 221 static final int MSG_RF_FIELD_ACTIVATED = 9; 222 static final int MSG_RF_FIELD_DEACTIVATED = 10; 223 static final int MSG_RESUME_POLLING = 11; 224 static final int MSG_REGISTER_T3T_IDENTIFIER = 12; 225 static final int MSG_DEREGISTER_T3T_IDENTIFIER = 13; 226 static final int MSG_TAG_DEBOUNCE = 14; 227 // Previously used: MSG_UPDATE_STATS = 15 228 static final int MSG_APPLY_SCREEN_STATE = 16; 229 static final int MSG_TRANSACTION_EVENT = 17; 230 static final int MSG_PREFERRED_PAYMENT_CHANGED = 18; 231 static final int MSG_TOAST_DEBOUNCE_EVENT = 19; 232 static final int MSG_DELAY_POLLING = 20; 233 static final int MSG_CLEAR_ROUTING_TABLE = 21; 234 static final int MSG_UPDATE_ISODEP_PROTOCOL_ROUTE = 22; 235 static final int MSG_UPDATE_TECHNOLOGY_ABF_ROUTE = 23; 236 static final int MSG_WATCHDOG_PING = 24; 237 static final int MSG_SE_SELECTED_EVENT = 25; 238 static final int MSG_UPDATE_SYSTEM_CODE_ROUTE = 26; 239 static final int MSG_PREFERRED_SIM_CHANGED = 27; 240 static final String MSG_ROUTE_AID_PARAM_TAG = "power"; 241 static final int MSG_RESTART_DISCOVERY = 28; 242 243 // Negative value for NO polling delay 244 static final int NO_POLL_DELAY = -1; 245 246 static final long MAX_POLLING_PAUSE_TIMEOUT = 40000; 247 248 static final int MAX_TOAST_DEBOUNCE_TIME = 10000; 249 250 static final int DISABLE_POLLING_FLAGS = 0x1000; 251 252 static final int RF_COALESCING_WINDOW = 50; 253 254 static final int TASK_ENABLE = 1; 255 static final int TASK_DISABLE = 2; 256 static final int TASK_BOOT = 3; 257 static final int TASK_ENABLE_ALWAYS_ON = 4; 258 static final int TASK_DISABLE_ALWAYS_ON = 5; 259 260 // SE selected types 261 public static final int SE_SELECTED_AID = 0x01; 262 public static final int SE_SELECTED_TECH = 0x02; 263 public static final int SE_SELECTED_PROTOCOL = 0x04; 264 265 // Polling technology masks 266 static final int NFC_POLL_A = 0x01; 267 static final int NFC_POLL_B = 0x02; 268 static final int NFC_POLL_F = 0x04; 269 static final int NFC_POLL_V = 0x08; 270 static final int NFC_POLL_B_PRIME = 0x10; 271 static final int NFC_POLL_KOVIO = 0x20; 272 273 // Listen technology masks 274 static final int NFC_LISTEN_A = 0x01; 275 static final int NFC_LISTEN_B = 0x02; 276 static final int NFC_LISTEN_F = 0x04; 277 static final int NFC_LISTEN_V = 0x08; 278 279 static final String PREF_POLL_TECH = "polling_tech_dfl"; 280 281 // Default polling tech mask 282 static final int DEFAULT_POLL_TECH = 0x2f; // See: Polling technology masks above 283 284 static final String PREF_LISTEN_TECH = "listen_tech_dfl"; 285 // Default listening tech mask 286 static final int DEFAULT_LISTEN_TECH = 0xf; // See: Listen technology masks above 287 288 // minimum screen state that enables NFC polling 289 static final int NFC_POLLING_MODE = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED; 290 291 // Time to wait for NFC controller to initialize before watchdog 292 // goes off. This time is chosen large, because firmware download 293 // may be a part of initialization. 294 static final int INIT_WATCHDOG_MS = 90000; 295 296 // Time to wait for routing to be applied before watchdog 297 // goes off 298 static final int ROUTING_WATCHDOG_MS = 6000; 299 300 // Default delay used for presence checks 301 static final int DEFAULT_PRESENCE_CHECK_DELAY = 125; 302 303 // Removal Detection Wait Time Range 304 static final int MIN_RF_REMOVAL_DETECTION_TIMEOUT = 0x00; 305 static final int MAX_RF_REMOVAL_DETECTION_TIMEOUT = 0x13; 306 307 static final NfcProperties.snoop_log_mode_values NFC_SNOOP_LOG_MODE = 308 NfcProperties.snoop_log_mode().orElse(NfcProperties.snoop_log_mode_values.FILTERED); 309 static final boolean NFC_VENDOR_DEBUG_ENABLED = NfcProperties.vendor_debug_enabled().orElse(false); 310 311 // RF field events as defined in NFC extras 312 public static final String ACTION_RF_FIELD_ON_DETECTED = 313 "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED"; 314 public static final String ACTION_RF_FIELD_OFF_DETECTED = 315 "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED"; 316 317 public static final String APP_NAME_ENABLING_NFC = 318 "com.android.nfc.PACKAGE_NAME_ENABLING_NFC"; 319 320 public static boolean sIsShortRecordLayout = false; 321 322 public static boolean sIsNfcRestore = false; 323 324 // for use with playSound() 325 public static final int SOUND_END = 1; 326 public static final int SOUND_ERROR = 2; 327 328 public static final int NCI_VERSION_2_0 = 0x20; 329 330 public static final int NCI_VERSION_1_0 = 0x10; 331 332 // Timeout to re-apply routing if a tag was present and we postponed it 333 private static final int APPLY_ROUTING_RETRY_TIMEOUT_MS = 5000; 334 335 private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES = 336 VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK); 337 338 private static final int NCI_STATUS_OK = 0x00; 339 private static final int NCI_STATUS_REJECTED = 0x01; 340 private static final int NCI_STATUS_MESSAGE_CORRUPTED = 0x02; 341 private static final int NCI_STATUS_FAILED = 0x03; 342 private static final int SEND_VENDOR_CMD_TIMEOUT_MS = 3_000; 343 private static final int CHECK_FIRMWARE_TIMEOUT_MS = 60_000; 344 private static final int NCI_GID_PROP = 0x0F; 345 private static final int NCI_MSG_PROP_ANDROID = 0x0C; 346 private static final int NCI_MSG_PROP_ANDROID_POWER_SAVING = 0x01; 347 private static final int NCI_PROP_ANDROID_QUERY_POWER_SAVING_STATUS_CMD = 0x0A; 348 private static final int POWER_STATE_SWITCH_ON = 0x01; 349 350 public static final int WAIT_FOR_OEM_CALLBACK_TIMEOUT_MS = 3000; 351 352 public static final int WAIT_FOR_COMMIT_ROUTING_TIMEOUT_MS = 10000; 353 354 private static final long TIME_TO_MONITOR_AFTER_FIELD_ON_MS = 10000L; 355 356 private final Looper mLooper; 357 private final UserManager mUserManager; 358 private final ActivityManager mActivityManager; 359 360 private static int nci_version = NCI_VERSION_1_0; 361 // NFC Execution Environment 362 // fields below are protected by this 363 private final boolean mPollingDisableAllowed; 364 private HashMap<Integer, ReaderModeDeathRecipient> mPollingDisableDeathRecipients = 365 new HashMap<Integer, ReaderModeDeathRecipient>(); 366 private final ReaderModeDeathRecipient mReaderModeDeathRecipient = 367 new ReaderModeDeathRecipient(); 368 private final SeServiceDeathRecipient mSeServiceDeathRecipient = 369 new SeServiceDeathRecipient(); 370 private final DiscoveryTechDeathRecipient mDiscoveryTechDeathRecipient = 371 new DiscoveryTechDeathRecipient(); 372 private final NfcUnlockManager mNfcUnlockManager; 373 374 private final BackupManager mBackupManager; 375 376 private final SecureRandom mCookieGenerator = new SecureRandom(); 377 378 // Tag app preference list for the target UserId. 379 HashMap<Integer, HashMap<String, Boolean>> mTagAppPrefList = 380 new HashMap<Integer, HashMap<String, Boolean>>(); 381 382 // Tag app blocklist hash 383 static final String PREF_TAG_APP_BLOCK_LIST_HASH = "tag_app_block_list_hash"; 384 // Tag app blocklist hash default 385 static final int PREF_TAG_APP_BLOCK_LIST_HASH_DEFAULT = 0; 386 // Tag app preference blocked list. 387 static final List<String> TAG_APP_BLOCKLIST = new ArrayList<String>(); 388 389 // cached version of installed packages requesting Android.permission.NFC_TRANSACTION_EVENTS 390 // for current user and profiles. The Integer part is the userId. 391 HashMap<Integer, List<String>> mNfcEventInstalledPackages = 392 new HashMap<Integer, List<String>>(); 393 394 // cached version of installed packages requesting 395 // Android.permission.NFC_PREFERRED_PAYMENT_INFO for current user and profiles. 396 // The Integer part is the userId. 397 HashMap<Integer, List<String>> mNfcPreferredPaymentChangedInstalledPackages = 398 new HashMap<Integer, List<String>>(); 399 400 // fields below are used in multiple threads and protected by synchronized(this) 401 final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>(); 402 int mScreenState; 403 boolean mInProvisionMode; // whether we're in setup wizard and enabled NFC provisioning 404 boolean mIsSecureNfcEnabled; 405 boolean mSkipNdefRead; 406 NfcDiscoveryParameters mCurrentDiscoveryParameters = 407 NfcDiscoveryParameters.getNfcOffParameters(); 408 409 ReaderModeParams mReaderModeParams; 410 DiscoveryTechParams mDiscoveryTechParams; 411 412 private int mUserId; 413 boolean mPollingPaused; 414 415 // True if nfc notification message already shown 416 boolean mAntennaBlockedMessageShown; 417 private static int mDispatchFailedCount; 418 private static int mDispatchFailedMax; 419 420 static final int INVALID_NATIVE_HANDLE = -1; 421 static final int MOCK_NATIVE_HANDLE = 0; 422 byte mDebounceTagUid[]; 423 int mDebounceTagDebounceMs; 424 int mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE; 425 ITagRemovedCallback mDebounceTagRemovedCallback; 426 427 // Only accessed on one thread so doesn't need locking 428 NdefMessage mLastReadNdefMessage; 429 430 // mState is protected by this, however it is only modified in onCreate() 431 // and the default AsyncTask thread so it is read unprotected from that 432 // thread 433 int mState; // one of NfcAdapter.STATE_ON, STATE_TURNING_ON, etc 434 // mAlwaysOnState is protected by this, however it is only modified in onCreate() 435 // and the default AsyncTask thread so it is read unprotected from that thread 436 int mAlwaysOnState; // one of NfcAdapter.STATE_ON, STATE_TURNING_ON, etc 437 int mAlwaysOnMode; // one of NfcOemExtension.ENABLE_DEFAULT, ENABLE_TRANSPARENT, etc 438 private boolean mIsPowerSavingModeEnabled = false; 439 440 // fields below are final after onCreate() 441 boolean mIsReaderOptionEnabled = true; 442 boolean mReaderOptionCapable; 443 Context mContext; 444 NfcInjector mNfcInjector; 445 NfcEventLog mNfcEventLog; 446 private DeviceHost mDeviceHost; 447 private SharedPreferences mPrefs; 448 private SharedPreferences.Editor mPrefsEditor; 449 private SharedPreferences mTagAppPrefListPrefs; 450 451 private PowerManager.WakeLock mRoutingWakeLock; 452 private PowerManager.WakeLock mRequireUnlockWakeLock; 453 454 private long mLastFieldOnTimestamp = 0; 455 456 int mEndSound; 457 int mErrorSound; 458 SoundPool mSoundPool; // playback synchronized on this 459 TagService mNfcTagService; 460 T4tNdefNfceeService mT4tNdefNfceeService; 461 NfcAdapterService mNfcAdapter; 462 NfcDtaService mNfcDtaService; 463 RoutingTableParser mRoutingTableParser; 464 boolean mIsDebugBuild; 465 boolean mIsHceCapable; 466 boolean mIsHceFCapable; 467 boolean mIsSecureNfcCapable; 468 boolean mIsRequestUnlockShowed; 469 boolean mIsRecovering; 470 boolean mIsNfcUserRestricted; 471 boolean mIsNfcUserChangeRestricted; 472 boolean mIsWatchType; 473 boolean mPendingPowerStateUpdate; 474 boolean mIsWlcCapable; 475 boolean mIsWlcEnabled; 476 boolean mIsRWCapable; 477 boolean mIsRDCapable; 478 WlcListenerDeviceInfo mWlcListenerDeviceInfo; 479 public NfcDiagnostics mNfcDiagnostics; 480 481 // polling delay control variables 482 private final int mPollDelayTime; 483 private final int mPollDelayTimeLong; 484 private final int mAppInActivityDetectionTime; 485 private final int mTagRemovalDetectionWaitTime; 486 private Timer mAppInActivityDetectionTimer; 487 private final int mPollDelayCountMax; 488 private int mPollDelayCount; 489 private int mReadErrorCount; 490 private int mReadErrorCountMax; 491 private boolean mPollDelayed; 492 493 boolean mNotifyDispatchFailed; 494 boolean mNotifyReadFailed; 495 496 // for recording the latest Tag object cookie 497 long mCookieUpToDate = -1; 498 499 private DeviceConfigFacade mDeviceConfigFacade; 500 private NfcDispatcher mNfcDispatcher; 501 private PowerManager mPowerManager; 502 private KeyguardManager mKeyguard; 503 private HandoverDataParser mHandoverDataParser; 504 private ContentResolver mContentResolver; 505 506 @VisibleForTesting 507 CardEmulationManager mCardEmulationManager; 508 private NfcCharging mNfcCharging; 509 private Vibrator mVibrator; 510 private VibrationEffect mVibrationEffect; 511 private ISecureElementService mSEService; 512 private final AlarmManager mAlarmManager; 513 514 private ScreenStateHelper mScreenStateHelper; 515 private ForegroundUtils mForegroundUtils; 516 517 private final NfcPermissions mNfcPermissions; 518 private static NfcService sService; 519 private static boolean sToast_debounce = false; 520 private static int sToast_debounce_time_ms = 3000; 521 public static boolean sIsDtaMode = false; 522 523 private final boolean mIsTagAppPrefSupported; 524 private int mTagAppBlockListHash; 525 526 private final boolean mIsAlwaysOnSupported; 527 private final Set<INfcControllerAlwaysOnListener> mAlwaysOnListeners = 528 Collections.synchronizedSet(new HashSet<>()); 529 530 private int mAidMatchingExactOnly = 0x02; 531 public static final int T4TNFCEE_STATUS_FAILED = -1; 532 private Object mT4tNdefNfcEeObj = new Object(); 533 private Bundle mT4tNdefNfceeReturnBundle = new Bundle(); 534 private final FeatureFlags mFeatureFlags; 535 private final Set<INfcWlcStateListener> mWlcStateListener = 536 Collections.synchronizedSet(new HashSet<>()); 537 @Nullable 538 private final StatsdUtils mStatsdUtils; 539 private final boolean mCheckDisplayStateForScreenState; 540 541 private INfcVendorNciCallback mNfcVendorNciCallBack = null; 542 private INfcOemExtensionCallback mNfcOemExtensionCallback = null; 543 544 private CountDownLatch mCommitRoutingCountDownLatch = null; 545 private int mCommitRoutingStatus; 546 private final DisplayListener mDisplayListener = new DisplayListener() { 547 @Override 548 public void onDisplayAdded(int displayId) { 549 } 550 551 @Override 552 public void onDisplayRemoved(int displayId) { 553 } 554 555 @Override 556 public void onDisplayChanged(int displayId) { 557 if (displayId == Display.DEFAULT_DISPLAY) { 558 handleScreenStateChanged(); 559 } 560 } 561 }; 562 563 private Object mDiscoveryLock = new Object(); 564 565 private boolean mCardEmulationActivated = false; 566 private boolean mRfFieldActivated = false; 567 private boolean mRfDiscoveryStarted = false; 568 private boolean mEeListenActivated = false; 569 // Scheduled executor for routing table update 570 private final ScheduledExecutorService mRtUpdateScheduler = Executors.newScheduledThreadPool(1); 571 private ScheduledFuture<?> mRtUpdateScheduledTask = null; 572 573 private static final int STATUS_OK = NfcOemExtension.STATUS_OK; 574 private static final int STATUS_UNKNOWN_ERROR = NfcOemExtension.STATUS_UNKNOWN_ERROR; 575 576 private static final int ACTION_ON_ENABLE = 0; 577 private static final int ACTION_ON_DISABLE = 1; 578 private static final int ACTION_ON_TAG_DISPATCH = 2; 579 private static final int ACTION_ON_READ_NDEF = 3; 580 private static final int ACTION_ON_APPLY_ROUTING = 4; 581 private static final int ACTION_ON_ROUTING_CHANGED = 5; 582 getInstance()583 public static NfcService getInstance() { 584 return sService; 585 } 586 587 @Override onRemoteEndpointDiscovered(TagEndpoint tag)588 public void onRemoteEndpointDiscovered(TagEndpoint tag) { 589 Log.d(TAG, "onRemoteEndpointDiscovered"); 590 sendMessage(MSG_NDEF_TAG, tag); 591 } 592 593 /** 594 * Notifies transaction 595 */ 596 @Override onHostCardEmulationActivated(int technology)597 public void onHostCardEmulationActivated(int technology) { 598 mCardEmulationActivated = true; 599 try { 600 if (mNfcOemExtensionCallback != null) { 601 mNfcOemExtensionCallback.onCardEmulationActivated(mCardEmulationActivated); 602 } 603 } catch (RemoteException e) { 604 Log.e(TAG, "onHostCardEmulationActivated: error: ", e); 605 } 606 if (mCardEmulationManager != null) { 607 mCardEmulationManager.onHostCardEmulationActivated(technology); 608 if (android.nfc.Flags.nfcPersistLog()) { 609 mNfcEventLog.logEvent( 610 NfcEventProto.EventType.newBuilder() 611 .setHostCardEmulationStateChange( 612 NfcEventProto.NfcHostCardEmulationStateChange.newBuilder() 613 .setTechnology(technology) 614 .setEnable(true) 615 .build()) 616 .build()); 617 } 618 } 619 } 620 621 @Override onHostCardEmulationData(int technology, byte[] data)622 public void onHostCardEmulationData(int technology, byte[] data) { 623 if (mCardEmulationManager != null) { 624 mCardEmulationManager.onHostCardEmulationData(technology, data); 625 if (android.nfc.Flags.nfcPersistLog() && NFC_VENDOR_DEBUG_ENABLED) { 626 mNfcEventLog.logEvent( 627 NfcEventProto.EventType.newBuilder() 628 .setHostCardEmulationData( 629 NfcEventProto.NfcHostCardEmulationData.newBuilder() 630 .setTechnology(technology) 631 .setData(ByteString.copyFrom(data)) 632 .build()) 633 .build()); 634 } 635 } 636 } 637 638 @Override onHostCardEmulationDeactivated(int technology)639 public void onHostCardEmulationDeactivated(int technology) { 640 mCardEmulationActivated = false; 641 try { 642 if (mNfcOemExtensionCallback != null) { 643 mNfcOemExtensionCallback.onCardEmulationActivated(mCardEmulationActivated); 644 } 645 } catch (RemoteException e) { 646 Log.e(TAG, "onHostCardEmulationDeactivated: e=", e); 647 } 648 if (mCardEmulationManager != null) { 649 mCardEmulationManager.onHostCardEmulationDeactivated(technology); 650 if (android.nfc.Flags.nfcPersistLog()) { 651 mNfcEventLog.logEvent( 652 NfcEventProto.EventType.newBuilder() 653 .setHostCardEmulationStateChange( 654 NfcEventProto.NfcHostCardEmulationStateChange.newBuilder() 655 .setTechnology(technology) 656 .setEnable(false) 657 .build()) 658 .build()); 659 } 660 } 661 } 662 663 664 /** Notifies Removal Detection procedure completed, 665 endpoint deactivation reason returned by NFCC */ onEndpointRemoved(int reason)666 public void onEndpointRemoved(int reason) { 667 Log.d(TAG, "onEndpointRemoved: Deactivation reason is " + reason); 668 if (mIsWlcEnabled && mNfcCharging.NfcChargingMode) { 669 mNfcCharging.onEndpointRemoved(reason); 670 } 671 /* else send intent to notify other applications */ 672 } 673 startRemovalDetection(int waiting_time_int)674 public boolean startRemovalDetection(int waiting_time_int) { 675 return mDeviceHost.detectEpRemoval(waiting_time_int); 676 } 677 678 @Override onRemoteFieldActivated()679 public void onRemoteFieldActivated() { 680 mRfFieldActivated = true; 681 mLastFieldOnTimestamp = mNfcInjector.getWallClockMillis(); 682 mNfcInjector.ensureWatchdogMonitoring(); 683 try { 684 if (mNfcOemExtensionCallback != null) { 685 mNfcOemExtensionCallback.onRfFieldDetected(mRfFieldActivated); 686 } 687 } catch (RemoteException e) { 688 Log.e(TAG, "onRemoteFieldActivated: e=", e); 689 } 690 if (Flags.coalesceRfEvents() && mHandler.hasMessages(MSG_RF_FIELD_DEACTIVATED)) { 691 mHandler.removeMessages(MSG_RF_FIELD_DEACTIVATED); 692 } else { 693 sendMessage(MSG_RF_FIELD_ACTIVATED, null); 694 } 695 if (mStatsdUtils != null) { 696 mStatsdUtils.logFieldChanged(true, 0); 697 } 698 if (android.nfc.Flags.nfcPersistLog() && NFC_VENDOR_DEBUG_ENABLED) { 699 mNfcEventLog.logEvent( 700 NfcEventProto.EventType.newBuilder() 701 .setRemoteFieldStateChange( 702 NfcEventProto.NfcRemoteFieldStateChange.newBuilder() 703 .setFieldOn(true) 704 .build()) 705 .build()); 706 } 707 if (android.nfc.Flags.nfcEventListener() && mCardEmulationManager != null) { 708 mCardEmulationManager.onRemoteFieldChanged(true); 709 } 710 } 711 712 @Override onRemoteFieldDeactivated()713 public void onRemoteFieldDeactivated() { 714 mRfFieldActivated = false; 715 try { 716 if (mNfcOemExtensionCallback != null) { 717 mNfcOemExtensionCallback.onRfFieldDetected(mRfFieldActivated); 718 } 719 } catch (RemoteException e) { 720 Log.e(TAG, "onRemoteFieldDeactivated: e=", e); 721 } 722 if (Flags.coalesceRfEvents()) { 723 mHandler.sendMessageDelayed( 724 mHandler.obtainMessage(MSG_RF_FIELD_DEACTIVATED), 725 RF_COALESCING_WINDOW); 726 } else { 727 sendMessage(MSG_RF_FIELD_DEACTIVATED, null); 728 } 729 if (mStatsdUtils != null) { 730 mStatsdUtils.logFieldChanged(false, 0); 731 } 732 if (android.nfc.Flags.nfcPersistLog() && NFC_VENDOR_DEBUG_ENABLED) { 733 mNfcEventLog.logEvent( 734 NfcEventProto.EventType.newBuilder() 735 .setRemoteFieldStateChange( 736 NfcEventProto.NfcRemoteFieldStateChange.newBuilder() 737 .setFieldOn(false) 738 .build()) 739 .build()); 740 } 741 742 if (android.nfc.Flags.nfcEventListener() && mCardEmulationManager != null) { 743 mCardEmulationManager.onRemoteFieldChanged(false); 744 } 745 } 746 747 List<PollingFrame> mPollingFramesToBeSent = new ArrayList<>(); 748 final Runnable mPollingLoopsDetectedRunnable = new Runnable() { 749 public void run() { 750 List<PollingFrame> frames; 751 synchronized (mPollingLoopsDetectedRunnable) { 752 frames = mPollingFramesToBeSent; 753 mPollingFramesToBeSent = new ArrayList<>(); 754 } 755 if (mCardEmulationManager != null) { 756 mCardEmulationManager.onPollingLoopDetected(new ArrayList<>(frames)); 757 } 758 } 759 }; 760 761 @Override onPollingLoopDetected(List<PollingFrame> frames)762 public void onPollingLoopDetected(List<PollingFrame> frames) { 763 if (mCardEmulationManager != null) { 764 if (Flags.postCallbacks()) { 765 synchronized (mPollingLoopsDetectedRunnable) { 766 mPollingFramesToBeSent.addAll(frames); 767 if (!mHandler.hasCallbacks(mPollingLoopsDetectedRunnable)) { 768 mHandler.post(mPollingLoopsDetectedRunnable); 769 } 770 } 771 } else { 772 mCardEmulationManager.onPollingLoopDetected((frames)); 773 } 774 } 775 } 776 777 @Override onNfcTransactionEvent(byte[] aid, byte[] data, String seName)778 public void onNfcTransactionEvent(byte[] aid, byte[] data, String seName) { 779 byte[][] dataObj = {aid, data, seName.getBytes()}; 780 sendMessage(MSG_TRANSACTION_EVENT, dataObj); 781 } 782 783 @Override onEeUpdated()784 public void onEeUpdated() { 785 if (mNfcOemExtensionCallback != null) { 786 try { 787 mNfcOemExtensionCallback.onEeUpdated(); 788 } catch (RemoteException e) { 789 Log.e(TAG, "onEeUpdated: e=", e); 790 } 791 } 792 if (mRtUpdateScheduledTask != null && !mRtUpdateScheduledTask.isDone()) { 793 mRtUpdateScheduledTask.cancel(false); 794 } 795 // Delay routing table update to allow remove useless operations when several 796 // ntf are received 797 mRtUpdateScheduledTask = 798 mRtUpdateScheduler.schedule( 799 () -> { 800 if (mIsHceCapable) { 801 if (DBG) Log.d(TAG, "onEeUpdated: trigger routing table update"); 802 mCardEmulationManager.onTriggerRoutingTableUpdate(); 803 } 804 }, 805 50, 806 TimeUnit.MILLISECONDS); 807 } 808 restartStack()809 private void restartStack() { 810 synchronized (NfcService.this) { 811 if (DBG) { 812 Log.d(TAG, "restartStack: mIsRecovering=" + mIsRecovering); 813 } 814 if (!mIsRecovering) { 815 mIsRecovering = true; 816 } else { 817 return; 818 } 819 } 820 821 if (DBG) { 822 Log.d(TAG, "restartStack: Restarting NFC Service"); 823 } 824 try { 825 mContext.unregisterReceiver(mReceiver); 826 } catch (IllegalArgumentException e) { 827 Log.w(TAG, "restartStack: Failed to unregisterScreenState BroadCastReceiver: " + e); 828 } 829 new EnableDisableTask().execute(TASK_DISABLE); 830 new EnableDisableTask().execute(TASK_ENABLE); 831 } 832 833 @Override onHwErrorReported()834 public void onHwErrorReported() { 835 if (android.nfc.Flags.nfcEventListener() && mCardEmulationManager != null) { 836 mCardEmulationManager.onInternalErrorReported( 837 CardEmulation.NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR); 838 } 839 restartStack(); 840 } 841 842 @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) 843 @Override onCommandTimeout()844 public void onCommandTimeout() { 845 if (android.nfc.Flags.nfcEventListener() && mCardEmulationManager != null) { 846 mCardEmulationManager.onInternalErrorReported( 847 CardEmulation.NFC_INTERNAL_ERROR_COMMAND_TIMEOUT); 848 } 849 } 850 851 @Override onVendorSpecificEvent(int gid, int oid, byte[] payload)852 public void onVendorSpecificEvent(int gid, int oid, byte[] payload) { 853 mHandler.post(() -> mNfcAdapter.sendVendorNciNotification(gid, oid, payload)); 854 } 855 856 @Override onObserveModeStateChanged(boolean enable)857 public void onObserveModeStateChanged(boolean enable) { 858 if (Flags.postCallbacks()) { 859 mHandler.post(() -> { 860 if (mCardEmulationManager != null) { 861 mCardEmulationManager.onObserveModeStateChange(enable); 862 } 863 }); 864 } else { 865 if (mCardEmulationManager != null) { 866 mCardEmulationManager.onObserveModeStateChange(enable); 867 } 868 } 869 } 870 871 @Override onObserveModeDisabledInFirmware(PollingFrame exitFrame)872 public void onObserveModeDisabledInFirmware(PollingFrame exitFrame) { 873 mCardEmulationManager.onObserveModeDisabledInFirmware(exitFrame); 874 onObserveModeStateChanged(false); 875 } 876 877 @Override onObserveModeEnabledInFirmware()878 public void onObserveModeEnabledInFirmware() { 879 onObserveModeStateChanged(true); 880 } 881 882 @Override onEeListenActivated(boolean isActivated)883 public void onEeListenActivated(boolean isActivated) { 884 mEeListenActivated = isActivated; 885 mCardEmulationManager.onEeListenActivated(isActivated); 886 try { 887 if (mNfcOemExtensionCallback != null) { 888 mNfcOemExtensionCallback.onEeListenActivated(isActivated); 889 } 890 } catch (RemoteException e) { 891 Log.e(TAG, "onEeListenActivated: e=", e); 892 } 893 } 894 895 @Override onRfDiscoveryEvent(boolean isDiscoveryStarted)896 public void onRfDiscoveryEvent(boolean isDiscoveryStarted) { 897 synchronized (mDiscoveryLock) { 898 mRfDiscoveryStarted = isDiscoveryStarted; 899 } 900 try { 901 if (mNfcOemExtensionCallback != null) { 902 mNfcOemExtensionCallback.onRfDiscoveryStarted(mRfDiscoveryStarted); 903 } 904 } catch (RemoteException e) { 905 Log.e(TAG, "onRfDiscoveryEvent: e=", e); 906 } 907 } 908 909 @Override onSeSelected(int type)910 public void onSeSelected(int type) { 911 sendMessage(MSG_SE_SELECTED_EVENT, type); 912 } 913 914 @Override onRestartRfDiscovery()915 public void onRestartRfDiscovery() { 916 sendMessage(NfcService.MSG_RESTART_DISCOVERY, null); 917 } 918 919 /** 920 * Enable or Disable PowerSaving Mode based on flag 921 */ setPowerSavingMode(boolean flag)922 private boolean setPowerSavingMode(boolean flag) { 923 synchronized (NfcService.this) { 924 if ((flag && mState != NfcAdapter.STATE_ON) 925 || (!flag && mState != NfcAdapter.STATE_OFF)) { 926 Log.d(TAG, 927 "setPowerSavingMode: Enable Power Saving Mode is allowed in " 928 + "Nfc On state or " 929 + "Disable PowerSaving is allowed only if it is enabled"); 930 return false; 931 } 932 } 933 934 Log.d(TAG, "setPowerSavingMode: " + flag); 935 if (flag) { 936 if (mDeviceHost.setPowerSavingMode(flag)) { 937 mIsPowerSavingModeEnabled = true; 938 new EnableDisableTask().execute(TASK_DISABLE); 939 return true; 940 } 941 } else { 942 new EnableDisableTask().execute(TASK_ENABLE); 943 return true; 944 } 945 Log.d(TAG, "PowerSavingMode: failed"); 946 return false; 947 } 948 onWlcData(Map<String, Integer> WlcDeviceInfo)949 public void onWlcData(Map<String, Integer> WlcDeviceInfo) { 950 for (String key : WlcDeviceInfo.keySet()) { 951 Log.d(TAG, "onWlcData: " + key + " = " + WlcDeviceInfo.get(key)); 952 } 953 synchronized (mWlcStateListener) { 954 mWlcListenerDeviceInfo = new WlcListenerDeviceInfo( 955 WlcDeviceInfo.get(mNfcCharging.VendorId), 956 WlcDeviceInfo.get(mNfcCharging.TemperatureListener), 957 WlcDeviceInfo.get(mNfcCharging.BatteryLevel), 958 WlcDeviceInfo.get(mNfcCharging.State)); 959 for (INfcWlcStateListener listener : mWlcStateListener) { 960 try { 961 listener.onWlcStateChanged(mWlcListenerDeviceInfo); 962 } catch (RemoteException e) { 963 Log.e(TAG, "onWlcData: error"); 964 } 965 } 966 } 967 } 968 969 /** Notifies WLC procedure stopped */ 970 @Override onWlcStopped(int wpt_end_condition)971 public void onWlcStopped(int wpt_end_condition) { 972 Log.d(TAG, "onWlcStopped: End condition is " + wpt_end_condition); 973 mNfcCharging.onWlcStopped(wpt_end_condition); 974 } 975 onTagRfDiscovered(boolean discovered)976 public void onTagRfDiscovered(boolean discovered) { 977 Log.d(TAG, "onTagRfDiscovered: " + discovered); 978 executeOemOnTagConnectedCallback(discovered); 979 } 980 981 final class ReaderModeParams { 982 public int flags; 983 public IAppCallback callback; 984 public int presenceCheckDelay; 985 public IBinder binder; 986 public int uid; 987 public byte[] annotation; 988 } 989 990 final class DiscoveryTechParams { 991 public IBinder binder; 992 public int uid; 993 } 994 saveNfcOnSetting(boolean on)995 void saveNfcOnSetting(boolean on) { 996 synchronized (NfcService.this) { 997 mPrefsEditor.putBoolean(PREF_NFC_ON, on); 998 mPrefsEditor.apply(); 999 mBackupManager.dataChanged(); 1000 } 1001 } 1002 getNfcOnSetting()1003 boolean getNfcOnSetting() { 1004 synchronized (NfcService.this) { 1005 return mPrefs.getBoolean(PREF_NFC_ON, mDeviceConfigFacade.getNfcDefaultState()); 1006 } 1007 } 1008 saveNfcListenTech(int tech)1009 void saveNfcListenTech(int tech) { 1010 synchronized (NfcService.this) { 1011 mPrefsEditor.putInt(PREF_LISTEN_TECH, tech); 1012 mPrefsEditor.apply(); 1013 mBackupManager.dataChanged(); 1014 } 1015 } 1016 getNfcListenTech()1017 int getNfcListenTech() { 1018 synchronized (NfcService.this) { 1019 return mPrefs.getInt(PREF_LISTEN_TECH, DEFAULT_LISTEN_TECH); 1020 } 1021 } 1022 saveNfcPollTech(int tech)1023 void saveNfcPollTech(int tech) { 1024 synchronized (NfcService.this) { 1025 mPrefsEditor.putInt(PREF_POLL_TECH, tech); 1026 mPrefsEditor.apply(); 1027 mBackupManager.dataChanged(); 1028 } 1029 } 1030 getNfcPollTech()1031 int getNfcPollTech() { 1032 synchronized (NfcService.this) { 1033 return mPrefs.getInt(PREF_POLL_TECH, DEFAULT_POLL_TECH); 1034 } 1035 } 1036 1037 1038 /** Returns true if NFC has user restriction set. */ isNfcUserRestricted()1039 private boolean isNfcUserRestricted() { 1040 return mUserManager.getUserRestrictions().getBoolean( 1041 UserManager.DISALLOW_NEAR_FIELD_COMMUNICATION_RADIO); 1042 } 1043 1044 /** Returns true if NFC state change by user is restricted. */ isNfcUserChangeRestricted()1045 private boolean isNfcUserChangeRestricted() { 1046 return mUserManager.getUserRestrictions().getBoolean( 1047 UserManager.DISALLOW_CHANGE_NEAR_FIELD_COMMUNICATION_RADIO 1048 ); 1049 } 1050 shouldEnableNfc()1051 boolean shouldEnableNfc() { 1052 return getNfcOnSetting() && !mNfcInjector.isSatelliteModeOn() 1053 && !isNfcUserRestricted() && allowOemEnable(); 1054 } 1055 allowOemEnable()1056 boolean allowOemEnable() { 1057 if (mNfcOemExtensionCallback == null) return true; 1058 return receiveOemCallbackResult(ACTION_ON_ENABLE); 1059 } 1060 allowOemDisable()1061 boolean allowOemDisable() { 1062 if (mNfcOemExtensionCallback == null) return true; 1063 return receiveOemCallbackResult(ACTION_ON_DISABLE); 1064 } 1065 receiveOemCallbackResult(int action)1066 boolean receiveOemCallbackResult(int action) { 1067 CountDownLatch latch = new CountDownLatch(1); 1068 NfcCallbackResultReceiver.OnReceiveResultListener listener = 1069 new NfcCallbackResultReceiver.OnReceiveResultListener(); 1070 ResultReceiver receiver = new NfcCallbackResultReceiver(latch, listener); 1071 try { 1072 switch (action) { 1073 case ACTION_ON_ENABLE: 1074 mNfcOemExtensionCallback.onEnable(receiver); 1075 break; 1076 case ACTION_ON_DISABLE: 1077 mNfcOemExtensionCallback.onDisable(receiver); 1078 break; 1079 case ACTION_ON_TAG_DISPATCH: 1080 mNfcOemExtensionCallback.onTagDispatch(receiver); 1081 break; 1082 case ACTION_ON_READ_NDEF: 1083 mNfcOemExtensionCallback.onNdefRead(receiver); 1084 break; 1085 case ACTION_ON_APPLY_ROUTING: 1086 mNfcOemExtensionCallback.onApplyRouting(receiver); 1087 break; 1088 case ACTION_ON_ROUTING_CHANGED: 1089 mNfcOemExtensionCallback.onRoutingChanged(receiver); 1090 break; 1091 } 1092 } catch (RemoteException remoteException) { 1093 return false; 1094 } 1095 try { 1096 boolean success = latch.await(WAIT_FOR_OEM_CALLBACK_TIMEOUT_MS, TimeUnit.MILLISECONDS); 1097 if (!success) { 1098 return false; 1099 } else { 1100 return listener.getResultCode() == 1; 1101 } 1102 } catch (InterruptedException ie) { 1103 return false; 1104 } 1105 } 1106 registerGlobalBroadcastsReceiver()1107 private void registerGlobalBroadcastsReceiver() { 1108 IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); 1109 filter.addAction(Intent.ACTION_SCREEN_ON); 1110 filter.addAction(Intent.ACTION_USER_PRESENT); 1111 filter.addAction(Intent.ACTION_USER_SWITCHED); 1112 filter.addAction(Intent.ACTION_USER_ADDED); 1113 filter.addAction(Intent.ACTION_BOOT_COMPLETED); 1114 if (mFeatureFlags.enableDirectBootAware()) filter.addAction(Intent.ACTION_USER_UNLOCKED); 1115 mContext.registerReceiverForAllUsers(mReceiver, filter, null, null); 1116 } 1117 NfcService(Application nfcApplication, NfcInjector nfcInjector)1118 public NfcService(Application nfcApplication, NfcInjector nfcInjector) { 1119 mUserId = ActivityManager.getCurrentUser(); 1120 mContext = nfcApplication; 1121 mNfcInjector = nfcInjector; 1122 mLooper = mNfcInjector.getMainLooper(); 1123 mHandler = new NfcServiceHandler(mLooper); 1124 mNfcEventLog = mNfcInjector.getNfcEventLog(); 1125 1126 mNfcTagService = new TagService(); 1127 mNfcAdapter = new NfcAdapterService(); 1128 mRoutingTableParser = mNfcInjector.getRoutingTableParser(); 1129 mT4tNdefNfceeService = new T4tNdefNfceeService(); 1130 Log.i(TAG, "Starting NFC service"); 1131 1132 sService = this; 1133 1134 mScreenStateHelper = mNfcInjector.getScreenStateHelper(); 1135 mContentResolver = mContext.getContentResolver(); 1136 mDeviceHost = mNfcInjector.makeDeviceHost(this); 1137 1138 mNfcUnlockManager = mNfcInjector.getNfcUnlockManager(); 1139 1140 mHandoverDataParser = mNfcInjector.getHandoverDataParser(); 1141 mInProvisionMode = mNfcInjector.isInProvisionMode(); 1142 mDeviceConfigFacade = mNfcInjector.getDeviceConfigFacade(); 1143 1144 mNfcDispatcher = mNfcInjector.getNfcDispatcher(); 1145 1146 mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE); 1147 mPrefsEditor = mPrefs.edit(); 1148 1149 mState = NfcAdapter.STATE_OFF; 1150 mAlwaysOnState = NfcAdapter.STATE_OFF; 1151 mAlwaysOnMode = NfcOemExtension.ENABLE_DEFAULT; 1152 1153 mIsDebugBuild = "userdebug".equals(Build.TYPE) || "eng".equals(Build.TYPE); 1154 1155 mPowerManager = mContext.getSystemService(PowerManager.class); 1156 1157 mRoutingWakeLock = mPowerManager.newWakeLock( 1158 PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mRoutingWakeLock"); 1159 1160 mRequireUnlockWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK 1161 | PowerManager.ACQUIRE_CAUSES_WAKEUP 1162 | PowerManager.ON_AFTER_RELEASE, "NfcService:mRequireUnlockWakeLock"); 1163 1164 mKeyguard = mContext.getSystemService(KeyguardManager.class); 1165 mUserManager = mContext.getSystemService(UserManager.class); 1166 mActivityManager = mContext.getSystemService(ActivityManager.class); 1167 mVibrator = mContext.getSystemService(Vibrator.class); 1168 mVibrationEffect = mNfcInjector.getVibrationEffect(); 1169 1170 PackageManager pm = mContext.getPackageManager(); 1171 mIsWatchType = pm.hasSystemFeature(PackageManager.FEATURE_WATCH); 1172 1173 mNfcDiagnostics = mNfcInjector.getNfcDiagnostics(); 1174 1175 mAlarmManager = mContext.getSystemService(AlarmManager.class); 1176 1177 mCheckDisplayStateForScreenState = mDeviceConfigFacade.getCheckDisplayStateForScreenState(); 1178 if (mInProvisionMode) { 1179 mScreenState = mScreenStateHelper.checkScreenStateProvisionMode(); 1180 } else { 1181 mScreenState = mScreenStateHelper.checkScreenState(mCheckDisplayStateForScreenState); 1182 } 1183 if (mCheckDisplayStateForScreenState) { 1184 DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); 1185 displayManager.registerDisplayListener(mDisplayListener, mHandler); 1186 } 1187 1188 mBackupManager = mNfcInjector.getBackupManager(); 1189 1190 mFeatureFlags = mNfcInjector.getFeatureFlags(); 1191 mStatsdUtils = mNfcInjector.getStatsdUtils(); 1192 1193 // Intents for all users 1194 registerGlobalBroadcastsReceiver(); 1195 1196 // Listen for work profile adds or removes. 1197 IntentFilter managedProfileFilter = new IntentFilter(); 1198 managedProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED); 1199 managedProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED); 1200 managedProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); 1201 managedProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); 1202 mContext.registerReceiverForAllUsers(mManagedProfileReceiver, 1203 managedProfileFilter, null, null); 1204 1205 IntentFilter ownerFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); 1206 ownerFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 1207 ownerFilter.addAction(Intent.ACTION_SHUTDOWN); 1208 mContext.registerReceiverForAllUsers(mOwnerReceiver, ownerFilter, null, null); 1209 1210 ownerFilter = new IntentFilter(); 1211 ownerFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 1212 ownerFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 1213 ownerFilter.addDataScheme("package"); 1214 mContext.registerReceiverForAllUsers(mOwnerReceiver, ownerFilter, null, null); 1215 1216 addDeviceLockedStateListener(); 1217 1218 updatePackageCache(); 1219 1220 mIsRWCapable = pm.hasSystemFeature(PackageManager.FEATURE_NFC); 1221 mIsWlcCapable = android.nfc.Flags.enableNfcCharging() && 1222 pm.hasSystemFeature(PackageManager.FEATURE_NFC_CHARGING); 1223 if (mIsWlcCapable) { 1224 mNfcCharging = mNfcInjector.getNfcCharging(mDeviceHost); 1225 mIsWlcEnabled = mPrefs.getBoolean(PREF_NFC_CHARGING_ON, NFC_CHARGING_ON_DEFAULT); 1226 // Register ThermalStatusChangedListener 1227 addThermalStatusListener(); 1228 } 1229 1230 mIsRDCapable = mContext.getResources().getBoolean(R.bool.removal_detection_default); 1231 1232 mIsHceCapable = 1233 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION) || 1234 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF); 1235 mIsHceFCapable = 1236 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF); 1237 if (mIsHceCapable) { 1238 mCardEmulationManager = mNfcInjector.getCardEmulationManager(); 1239 } 1240 mForegroundUtils = mNfcInjector.getForegroundUtils(); 1241 mIsSecureNfcCapable = mDeviceConfigFacade.isSecureNfcCapable(); 1242 mIsSecureNfcEnabled = mPrefs.getBoolean(PREF_SECURE_NFC_ON, 1243 mDeviceConfigFacade.getDefaultSecureNfcState()) 1244 && mIsSecureNfcCapable; 1245 mDeviceHost.setNfcSecure(mIsSecureNfcEnabled); 1246 1247 sToast_debounce_time_ms = 1248 mContext.getResources().getInteger(R.integer.toast_debounce_time_ms); 1249 if (sToast_debounce_time_ms > MAX_TOAST_DEBOUNCE_TIME) { 1250 sToast_debounce_time_ms = MAX_TOAST_DEBOUNCE_TIME; 1251 } 1252 1253 // Notification message variables 1254 mDispatchFailedCount = 0; 1255 if (mDeviceConfigFacade.isAntennaBlockedAlertEnabled() && 1256 !mPrefs.getBoolean(PREF_ANTENNA_BLOCKED_MESSAGE_SHOWN, ANTENNA_BLOCKED_MESSAGE_SHOWN_DEFAULT)) { 1257 mAntennaBlockedMessageShown = false; 1258 mDispatchFailedMax = 1259 mContext.getResources().getInteger(R.integer.max_antenna_blocked_failure_count); 1260 } else { 1261 mAntennaBlockedMessageShown = true; 1262 } 1263 1264 // Polling delay count for switching from stage one to stage two. 1265 mPollDelayCountMax = mDeviceConfigFacade.getUnknownTagPollingDelayMax(); 1266 // Stage one: polling delay time for the first few unknown tag detections 1267 mPollDelayTime = mDeviceConfigFacade.getUnknownTagPollingDelay(); 1268 // Stage two: longer polling delay time after max_poll_delay_count 1269 mPollDelayTimeLong = mDeviceConfigFacade.getUnknownTagPollingDelayLong(); 1270 // Polling delay if read error found more than max count. 1271 mReadErrorCountMax = 1272 mContext.getResources().getInteger(R.integer.unknown_tag_read_error_count_max); 1273 1274 mNotifyDispatchFailed = mContext.getResources().getBoolean(R.bool.enable_notify_dispatch_failed); 1275 mNotifyReadFailed = mContext.getResources().getBoolean(R.bool.enable_notify_read_failed); 1276 1277 mPollingDisableAllowed = mDeviceConfigFacade.getPollingDisableAllowed(); 1278 mAppInActivityDetectionTime = 1279 mContext.getResources().getInteger(R.integer.inactive_presence_check_allowed_time); 1280 mTagRemovalDetectionWaitTime = 1281 mContext.getResources().getInteger(R.integer.removal_detection_waiting_time); 1282 // Make sure this is only called when object construction is complete. 1283 mNfcInjector.getNfcManagerRegisterer().register(mNfcAdapter); 1284 1285 mIsAlwaysOnSupported = mDeviceConfigFacade.getNfccAlwaysOnAllowed(); 1286 1287 mIsTagAppPrefSupported = 1288 mContext.getResources().getBoolean(R.bool.tag_intent_app_pref_supported); 1289 mTagAppBlockListHash = mPrefs.getInt(PREF_TAG_APP_BLOCK_LIST_HASH, 1290 PREF_TAG_APP_BLOCK_LIST_HASH_DEFAULT); 1291 1292 // Get default blocked package list from resource file 1293 TAG_APP_BLOCKLIST.addAll( 1294 Arrays.asList(mContext.getResources().getStringArray( 1295 R.array.tag_intent_blocked_app_list))); 1296 1297 Uri uri = Settings.Global.getUriFor(Constants.SETTINGS_SATELLITE_MODE_ENABLED); 1298 if (uri == null) { 1299 Log.e(TAG, "NfcService(constructor): satellite mode key does not exist in Settings"); 1300 } else { 1301 mContext.getContentResolver().registerContentObserver( 1302 uri, 1303 false, 1304 new ContentObserver(null) { 1305 @Override 1306 public void onChange(boolean selfChange) { 1307 if (mNfcInjector.isSatelliteModeSensitive()) { 1308 Log.i(TAG, 1309 "NfcService(constructor): Satellite mode change detected"); 1310 if (isTaskBootCompleted()) { 1311 if (shouldEnableNfc()) { 1312 new EnableDisableTask().execute(TASK_ENABLE); 1313 } else { 1314 new EnableDisableTask().execute(TASK_DISABLE); 1315 } 1316 } else { 1317 Log.i(TAG, 1318 "NfcService(constructor): Satellite mode change " 1319 + "detected, skip NFC init is not completed"); 1320 } 1321 } 1322 } 1323 }); 1324 } 1325 1326 mIsNfcUserRestricted = isNfcUserRestricted(); 1327 mIsNfcUserChangeRestricted = isNfcUserChangeRestricted(); 1328 mContext.registerReceiver( 1329 new BroadcastReceiver() { 1330 @Override 1331 public void onReceive(Context context, Intent intent) { 1332 mIsNfcUserChangeRestricted = isNfcUserChangeRestricted(); 1333 if (mIsNfcUserRestricted == isNfcUserRestricted()) { 1334 return; 1335 } 1336 Log.i(TAG, 1337 "NfcService(constructor): Disallow NFC user restriction " 1338 + "changed from " + mIsNfcUserRestricted + " to " 1339 + !mIsNfcUserRestricted + "."); 1340 mIsNfcUserRestricted = !mIsNfcUserRestricted; 1341 if (isTaskBootCompleted()) { 1342 if (shouldEnableNfc()) { 1343 new EnableDisableTask().execute(TASK_ENABLE); 1344 } else { 1345 new EnableDisableTask().execute(TASK_DISABLE); 1346 } 1347 } else { 1348 Log.i(TAG, "restriction change detected - skip NFC init is not completed"); 1349 } 1350 } 1351 }, 1352 new IntentFilter(UserManager.ACTION_USER_RESTRICTIONS_CHANGED) 1353 ); 1354 1355 mNfcPermissions = new NfcPermissions(mContext); 1356 mReaderOptionCapable = mDeviceConfigFacade.isReaderOptionCapable(); 1357 1358 if (mReaderOptionCapable) { 1359 mIsReaderOptionEnabled = 1360 mPrefs.getBoolean(PREF_NFC_READER_OPTION_ON, 1361 mDeviceConfigFacade.getDefaultReaderOption() || mInProvisionMode); 1362 } 1363 1364 executeTaskBoot(); // do blocking boot tasks 1365 1366 if ((NFC_SNOOP_LOG_MODE.equals(NfcProperties.snoop_log_mode_values.FULL) || 1367 NFC_VENDOR_DEBUG_ENABLED) && 1368 mDeviceConfigFacade.getEnableDeveloperNotification()) { 1369 new NfcDeveloperOptionNotification(mContext).startNotification(); 1370 } 1371 1372 connectToSeService(); 1373 } 1374 isTaskBootCompleted()1375 private static Boolean isTaskBootCompleted() { 1376 return NfcProperties.initialized().orElse(Boolean.FALSE); 1377 } 1378 executeTaskBoot()1379 private void executeTaskBoot() { 1380 // If overlay is set, delay the NFC boot up until the OEM extension indicates it is ready to 1381 // proceed with NFC bootup. 1382 if (mDeviceConfigFacade.getEnableOemExtension()) { 1383 // Send intent for OEM extension to initialize. 1384 Intent intent = new Intent(NfcOemExtension.ACTION_OEM_EXTENSION_INIT); 1385 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT, BIND_NFC_SERVICE); 1386 Log.i(TAG, "executeTaskBoot: Sent intent for OEM extension to initialize"); 1387 return; 1388 } 1389 new EnableDisableTask().execute(TASK_BOOT); 1390 } 1391 getEnabledUserIds()1392 private List<Integer> getEnabledUserIds() { 1393 List<Integer> userIds = new ArrayList<Integer>(); 1394 UserManager um = 1395 mContext.createContextAsUser(UserHandle.of(ActivityManager.getCurrentUser()), 0) 1396 .getSystemService(UserManager.class); 1397 List<UserHandle> luh = um.getEnabledProfiles(); 1398 for (UserHandle uh : luh) { 1399 userIds.add(uh.getIdentifier()); 1400 } 1401 return userIds; 1402 } 1403 initTagAppPrefList()1404 private void initTagAppPrefList() { 1405 if (!mIsTagAppPrefSupported) return; 1406 boolean force = mTagAppBlockListHash != TAG_APP_BLOCKLIST.hashCode(); 1407 if (force) { 1408 mTagAppBlockListHash = TAG_APP_BLOCKLIST.hashCode(); 1409 mPrefsEditor.putInt(PREF_TAG_APP_BLOCK_LIST_HASH, 1410 mTagAppBlockListHash); 1411 mPrefsEditor.apply(); 1412 } 1413 mTagAppPrefList.clear(); 1414 mTagAppPrefListPrefs = mContext.getSharedPreferences(PREF_TAG_APP_LIST, 1415 Context.MODE_PRIVATE); 1416 boolean changed = false; 1417 if (mTagAppPrefListPrefs == null) { 1418 Log.e(TAG, "initTagAppPrefList: Can't get PREF_TAG_APP_LIST"); 1419 return; 1420 } 1421 try { 1422 for (Integer userId : getEnabledUserIds()) { 1423 HashMap<String, Boolean> map = new HashMap<>(); 1424 String jsonString = 1425 mTagAppPrefListPrefs.getString(Integer.toString(userId), 1426 (new JSONObject()).toString()); 1427 if (jsonString != null) { 1428 JSONObject jsonObject = new JSONObject(jsonString); 1429 Iterator<String> keysItr = jsonObject.keys(); 1430 while (keysItr.hasNext()) { 1431 String key = keysItr.next(); 1432 Boolean value = jsonObject.getBoolean(key); 1433 map.put(key, value); 1434 if (DBG) { 1435 Log.d(TAG, "initTagAppPrefList: uid:" + userId + "key:" + key + ": " 1436 + value); 1437 } 1438 } 1439 } 1440 // Put default blocked pkgs 1441 for (String pkg : TAG_APP_BLOCKLIST) { 1442 if ((force || !map.containsKey(pkg)) 1443 && isPackageInstalled(pkg, userId)) { 1444 map.put(pkg, false); 1445 changed = true; 1446 } 1447 } 1448 mTagAppPrefList.put(userId, map); 1449 } 1450 } catch (JSONException e) { 1451 Log.e(TAG, "initTagAppPrefList: JSONException=" + e); 1452 } 1453 if (changed) storeTagAppPrefList(); 1454 } 1455 storeTagAppPrefList()1456 private void storeTagAppPrefList() { 1457 if (!mIsTagAppPrefSupported) return; 1458 mTagAppPrefListPrefs = mContext.getSharedPreferences(PREF_TAG_APP_LIST, 1459 Context.MODE_PRIVATE); 1460 if (mTagAppPrefListPrefs != null) { 1461 for (Integer userId : getEnabledUserIds()) { 1462 SharedPreferences.Editor editor = mTagAppPrefListPrefs.edit(); 1463 HashMap<String, Boolean> map; 1464 synchronized (NfcService.this) { 1465 map = mTagAppPrefList.getOrDefault(userId, new HashMap<>()); 1466 } 1467 if (map.size() > 0) { 1468 String userIdStr = Integer.toString(userId); 1469 JSONObject jsonObject = new JSONObject(map); 1470 String jsonString = jsonObject.toString(); 1471 editor.remove(userIdStr).putString(userIdStr, jsonString).apply(); 1472 } 1473 } 1474 } else { 1475 Log.e(TAG, "storeTagAppPrefList: Can't get PREF_TAG_APP_LIST"); 1476 } 1477 } isPackageInstalled(String pkgName, int userId)1478 private boolean isPackageInstalled(String pkgName, int userId) { 1479 final PackageInfo info; 1480 try { 1481 info = mContext.createContextAsUser(UserHandle.of(userId), 0) 1482 .getPackageManager().getPackageInfo(pkgName, PackageManager.MATCH_ALL); 1483 } catch (PackageManager.NameNotFoundException e) { 1484 return false; 1485 } 1486 return info != null; 1487 } 1488 // Remove obsolete entries renewTagAppPrefList(String action)1489 private void renewTagAppPrefList(String action) { 1490 if (!mIsTagAppPrefSupported) return; 1491 if (!action.equals(Intent.ACTION_PACKAGE_ADDED) 1492 && !action.equals(Intent.ACTION_PACKAGE_REMOVED)) return; 1493 boolean changed = false; 1494 for (Integer userId : getEnabledUserIds()) { 1495 synchronized (NfcService.this) { 1496 if (action.equals(Intent.ACTION_PACKAGE_ADDED)) { 1497 HashMap<String, Boolean> map = 1498 mTagAppPrefList.getOrDefault(userId, new HashMap<>()); 1499 for (String pkg : TAG_APP_BLOCKLIST) { 1500 if (!map.containsKey(pkg) && isPackageInstalled(pkg, userId)) { 1501 map.put(pkg, false); 1502 changed = true; 1503 mTagAppPrefList.put(userId, map); 1504 } 1505 } 1506 } else if (action.equals(Intent.ACTION_PACKAGE_REMOVED)) { 1507 changed |= mTagAppPrefList.getOrDefault(userId, new HashMap<>()) 1508 .keySet().removeIf(k2 -> !isPackageInstalled(k2, userId)); 1509 } 1510 } 1511 } 1512 if (DBG) Log.d(TAG, "renewTagAppPrefList: TagAppPreference changed " + changed); 1513 if (changed) storeTagAppPrefList(); 1514 } 1515 isSEServiceAvailable()1516 private boolean isSEServiceAvailable() { 1517 if (mSEService == null) { 1518 connectToSeService(); 1519 } 1520 return (mSEService != null); 1521 } 1522 connectToSeService()1523 private void connectToSeService() { 1524 try { 1525 mSEService = mNfcInjector.connectToSeService(); 1526 if (mSEService != null) { 1527 IBinder seServiceBinder = mSEService.asBinder(); 1528 seServiceBinder.linkToDeath(mSeServiceDeathRecipient, 0); 1529 } 1530 } catch (RemoteException e) { 1531 Log.e(TAG, "connectToSeService: e=" + e); 1532 } 1533 } 1534 initSoundPoolIfNeededAndPlaySound(Runnable playSoundRunnable)1535 void initSoundPoolIfNeededAndPlaySound(Runnable playSoundRunnable) { 1536 if (mSoundPool == null) { 1537 // For the first sound play which triggers the sound pool initialization, play the 1538 // sound after sound pool load is complete. 1539 OnLoadCompleteListener onLoadCompleteListener = new OnLoadCompleteListener() { 1540 private int mNumLoadComplete = 0; 1541 @Override 1542 public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { 1543 // Check that both end/error sounds are loaded before playing the sound. 1544 if (++mNumLoadComplete == 2) { 1545 Log.d(TAG, "initSoundPoolIfNeededAndPlaySound: playing sound"); 1546 playSoundRunnable.run(); 1547 } 1548 } 1549 }; 1550 mSoundPool = new SoundPool.Builder() 1551 .setMaxStreams(1) 1552 .setAudioAttributes( 1553 new AudioAttributes.Builder() 1554 .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) 1555 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) 1556 .build()) 1557 .build(); 1558 mSoundPool.setOnLoadCompleteListener(onLoadCompleteListener); 1559 mEndSound = mSoundPool.load(mContext, R.raw.end, 1); 1560 mErrorSound = mSoundPool.load(mContext, R.raw.error, 1); 1561 } else { 1562 // sound pool already loaded, play the sound. 1563 Log.d(TAG, "initSoundPoolIfNeededAndPlaySound: Sound pool is already loaded, " 1564 + "playing sound"); 1565 playSoundRunnable.run(); 1566 } 1567 } 1568 releaseSoundPool()1569 void releaseSoundPool() { 1570 synchronized (this) { 1571 if (mSoundPool != null) { 1572 mSoundPool.release(); 1573 mSoundPool = null; 1574 } 1575 } 1576 } 1577 updatePackageCache()1578 void updatePackageCache() { 1579 UserManager um = mContext.createContextAsUser( 1580 UserHandle.of(ActivityManager.getCurrentUser()), /*flags=*/0) 1581 .getSystemService(UserManager.class); 1582 List<UserHandle> luh = um.getEnabledProfiles(); 1583 1584 synchronized (this) { 1585 mNfcEventInstalledPackages.clear(); 1586 mNfcPreferredPaymentChangedInstalledPackages.clear(); 1587 for (UserHandle uh : luh) { 1588 if (um.isQuietModeEnabled(uh)) continue; 1589 1590 PackageManager pm; 1591 try { 1592 pm = mContext.createContextAsUser(uh, /*flags=*/0).getPackageManager(); 1593 } catch (IllegalStateException e) { 1594 Log.d(TAG, "updatePackageCache: Fail to get PackageManager for user: " + uh); 1595 continue; 1596 } 1597 1598 List<PackageInfo> packagesNfcEvents = pm.getPackagesHoldingPermissions( 1599 new String[] {android.Manifest.permission.NFC_TRANSACTION_EVENT}, 1600 PackageManager.GET_ACTIVITIES); 1601 List<PackageInfo> packagesNfcPreferredPaymentChanged = 1602 pm.getPackagesHoldingPermissions( 1603 new String[] {android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO}, 1604 PackageManager.GET_ACTIVITIES); 1605 List<String> packageListNfcEvent = new ArrayList<String>(); 1606 for (int i = 0; i < packagesNfcEvents.size(); i++) { 1607 packageListNfcEvent.add(packagesNfcEvents.get(i).packageName); 1608 } 1609 mNfcEventInstalledPackages.put(uh.getIdentifier(), packageListNfcEvent); 1610 1611 List<String> packageListNfcPreferredPaymentChanged = new ArrayList<String>(); 1612 for (int i = 0; i < packagesNfcPreferredPaymentChanged.size(); i++) { 1613 packageListNfcPreferredPaymentChanged.add( 1614 packagesNfcPreferredPaymentChanged.get(i).packageName); 1615 } 1616 mNfcPreferredPaymentChangedInstalledPackages.put( 1617 uh.getIdentifier(), packageListNfcPreferredPaymentChanged); 1618 } 1619 } 1620 } 1621 1622 /** 1623 * Manages tasks that involve turning on/off the NFC controller. 1624 * <p/> 1625 * <p>All work that might turn the NFC adapter on or off must be done 1626 * through this task, to keep the handling of mState simple. 1627 * In other words, mState is only modified in these tasks (and we 1628 * don't need a lock to read it in these tasks). 1629 * <p/> 1630 * <p>These tasks are all done on the same AsyncTask background 1631 * thread, so they are serialized. Each task may temporarily transition 1632 * mState to STATE_TURNING_OFF or STATE_TURNING_ON, but must exit in 1633 * either STATE_ON or STATE_OFF. This way each task can be guaranteed 1634 * of starting in either STATE_OFF or STATE_ON, without needing to hold 1635 * NfcService.this for the entire task. 1636 * <p/> 1637 * <p>AsyncTask's are also implicitly queued. This is useful for corner 1638 * cases like turning airplane mode on while TASK_ENABLE is in progress. 1639 * The TASK_DISABLE triggered by airplane mode will be correctly executed 1640 * immediately after TASK_ENABLE is complete. This seems like the most sane 1641 * way to deal with these situations. 1642 * <p/> 1643 * <p>{@link #TASK_ENABLE} enables the NFC adapter, without changing 1644 * preferences 1645 * <p>{@link #TASK_DISABLE} disables the NFC adapter, without changing 1646 * preferences 1647 * <p>{@link #TASK_BOOT} does first boot work and may enable NFC 1648 */ 1649 class EnableDisableTask extends AsyncTask<Integer, Void, Boolean> { 1650 int action; 1651 @Override doInBackground(Integer... params)1652 protected Boolean doInBackground(Integer... params) { 1653 // Quick check mState 1654 switch (mState) { 1655 case NfcAdapter.STATE_TURNING_OFF: 1656 case NfcAdapter.STATE_TURNING_ON: 1657 Log.e(TAG, "Processing EnableDisable task " + params[0] + " from bad state " + 1658 mState); 1659 return false; 1660 } 1661 1662 action = params[0].intValue(); 1663 boolean result = true; 1664 /* AsyncTask sets this thread to THREAD_PRIORITY_BACKGROUND, 1665 * override with the default. THREAD_PRIORITY_BACKGROUND causes 1666 * us to service software I2C too slow for firmware download 1667 * with the NXP PN544. 1668 * TODO: move this to the DAL I2C layer in libnfc-nxp, since this 1669 * problem only occurs on I2C platforms using PN544 1670 */ 1671 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1672 switch (action) { 1673 case TASK_ENABLE: 1674 if (shouldEnableNfc()) { 1675 onOemPreExecute(); 1676 result = enableInternal(); 1677 if (sIsNfcRestore && mIsTagAppPrefSupported) { 1678 synchronized (NfcService.this) { 1679 initTagAppPrefList(); 1680 sIsNfcRestore = false; 1681 } 1682 } 1683 } else { 1684 result = false; 1685 } 1686 break; 1687 case TASK_DISABLE: 1688 if (allowOemDisable()) { 1689 onOemPreExecute(); 1690 result = disableInternal(); 1691 } else { 1692 result = false; 1693 } 1694 break; 1695 case TASK_BOOT: 1696 // Initialize the event log cache. 1697 boolean initialized; 1698 if (mPrefs.getBoolean(PREF_FIRST_BOOT, true)) { 1699 Log.i(TAG, "First Boot"); 1700 mPrefsEditor.putBoolean(PREF_FIRST_BOOT, false); 1701 mPrefsEditor.apply(); 1702 mDeviceHost.factoryReset(); 1703 setPaymentForegroundPreference(mUserId); 1704 } 1705 Log.d(TAG, "checking on firmware download"); 1706 boolean enableNfc = shouldEnableNfc(); 1707 onOemPreExecute(); 1708 if (enableNfc) { 1709 Log.d(TAG, "NFC is on. Doing normal stuff"); 1710 initialized = enableInternal(); 1711 } else { 1712 Log.d(TAG, "NFC is off. Checking firmware version"); 1713 initialized = mDeviceHost.checkFirmware(); 1714 } 1715 mNfcEventLog.logEvent( 1716 NfcEventProto.EventType.newBuilder() 1717 .setBootupState(NfcEventProto.NfcBootupState.newBuilder() 1718 .setEnabled(enableNfc) 1719 .build()) 1720 .build()); 1721 if (initialized) { 1722 // TODO(279846422) The system property will be temporary 1723 // available for vendors that depend on it. 1724 // Remove this code when a replacement API is added. 1725 NfcProperties.initialized(true); 1726 } 1727 synchronized (NfcService.this) { 1728 initTagAppPrefList(); 1729 } 1730 result = initialized; 1731 break; 1732 case TASK_ENABLE_ALWAYS_ON: 1733 /* Get mode from AsyncTask params */ 1734 result = enableAlwaysOnInternal(params[1]); 1735 break; 1736 case TASK_DISABLE_ALWAYS_ON: 1737 result = disableAlwaysOnInternal(); 1738 break; 1739 default: 1740 break; 1741 } 1742 1743 // Restore default AsyncTask priority 1744 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1745 return result; 1746 } 1747 1748 @Override onPostExecute(Boolean result)1749 protected void onPostExecute(Boolean result) { 1750 Log.d(TAG, "onPostExecute: result - " + result); 1751 if (mNfcOemExtensionCallback != null) { 1752 try { 1753 if (action == TASK_BOOT) 1754 mNfcOemExtensionCallback 1755 .onBootFinished(result ? STATUS_OK : STATUS_UNKNOWN_ERROR); 1756 else if (action == TASK_ENABLE) 1757 mNfcOemExtensionCallback 1758 .onEnableFinished(result ? STATUS_OK : STATUS_UNKNOWN_ERROR); 1759 else if (action == TASK_DISABLE) 1760 mNfcOemExtensionCallback 1761 .onDisableFinished(result ? STATUS_OK : STATUS_UNKNOWN_ERROR); 1762 } catch (RemoteException remoteException) { 1763 Log.e(TAG, "onPostExecute: Failed to call remote oem extension callback"); 1764 } 1765 } 1766 } 1767 onOemPreExecute()1768 void onOemPreExecute() { 1769 if (mNfcOemExtensionCallback != null) { 1770 try { 1771 if (action == TASK_BOOT) 1772 mNfcOemExtensionCallback.onBootStarted(); 1773 else if (action == TASK_ENABLE) 1774 mNfcOemExtensionCallback.onEnableStarted(); 1775 else if (action == TASK_DISABLE) 1776 mNfcOemExtensionCallback.onDisableStarted(); 1777 } catch (RemoteException remoteException) { 1778 Log.e(TAG, "onOemPreExecute: Failed to call remote oem extension callback"); 1779 } 1780 } 1781 } 1782 isAlwaysOnInDefaultMode()1783 boolean isAlwaysOnInDefaultMode() { 1784 return mAlwaysOnMode == NfcOemExtension.ENABLE_DEFAULT; 1785 } 1786 1787 /** 1788 * Enable NFC adapter functions. 1789 * Does not toggle preferences. 1790 */ enableInternal()1791 boolean enableInternal() { 1792 if (DBG) Log.d(TAG, "EnableDisableTask.enableInternal: begin"); 1793 if (mState == NfcAdapter.STATE_ON) { 1794 return true; 1795 } else if (mAlwaysOnState == NfcAdapter.STATE_ON) { 1796 if (!isAlwaysOnInDefaultMode()) { 1797 Log.i(TAG, "enableInternal: ControllerAlwaysOn Not In DEFAULT_MODE " 1798 + "- disableAlwaysOn!"); 1799 disableAlwaysOnInternal(); 1800 } 1801 } 1802 Log.i(TAG, "Enabling NFC"); 1803 NfcStatsLog.write(NfcStatsLog.NFC_STATE_CHANGED, 1804 mIsSecureNfcEnabled ? NfcStatsLog.NFC_STATE_CHANGED__STATE__ON_LOCKED : 1805 NfcStatsLog.NFC_STATE_CHANGED__STATE__ON); 1806 updateState(NfcAdapter.STATE_TURNING_ON); 1807 1808 WatchDogThread watchDog = new WatchDogThread("enableInternal", INIT_WATCHDOG_MS); 1809 watchDog.start(); 1810 1811 mCardEmulationManager.updateForDefaultSwpToEuicc(); 1812 try { 1813 mRoutingWakeLock.acquire(); 1814 try { 1815 if (!mIsAlwaysOnSupported || mIsRecovering 1816 || (mAlwaysOnState != NfcAdapter.STATE_ON 1817 && mAlwaysOnState != NfcAdapter.STATE_TURNING_OFF)) { 1818 if (mIsRecovering) { 1819 // Recovering needs the full init. Put default value 1820 mAlwaysOnState = NfcAdapter.STATE_OFF; 1821 } 1822 if (!mDeviceHost.initialize()) { 1823 Log.w(TAG, "enableInternal: Error enabling NFC"); 1824 updateState(NfcAdapter.STATE_OFF); 1825 return false; 1826 } 1827 } else if (mAlwaysOnState == NfcAdapter.STATE_ON 1828 || mAlwaysOnState == NfcAdapter.STATE_TURNING_OFF) { 1829 Log.i(TAG, "enableInternal: Already initialized"); 1830 } else { 1831 Log.e(TAG, "enableInternal: Unexpected bad state " + mAlwaysOnState); 1832 updateState(NfcAdapter.STATE_OFF); 1833 return false; 1834 } 1835 } finally { 1836 if (mRoutingWakeLock.isHeld()) { 1837 mRoutingWakeLock.release(); 1838 } 1839 } 1840 } finally { 1841 watchDog.cancel(); 1842 } 1843 1844 mSkipNdefRead = NfcProperties.skipNdefRead().orElse(false); 1845 nci_version = getNciVersion(); 1846 Log.d(TAG, "enableInternal: NCI_Version: " + nci_version); 1847 1848 mPendingPowerStateUpdate = false; 1849 1850 synchronized (NfcService.this) { 1851 mObjectMap.clear(); 1852 updateState(NfcAdapter.STATE_ON); 1853 1854 onPreferredPaymentChanged(NfcAdapter.PREFERRED_PAYMENT_LOADED); 1855 } 1856 1857 if (mInProvisionMode) { 1858 mScreenState = mScreenStateHelper.checkScreenStateProvisionMode(); 1859 } else { 1860 mScreenState = mScreenStateHelper.checkScreenState(mCheckDisplayStateForScreenState); 1861 } 1862 int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ? 1863 (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState; 1864 1865 if (mNfcUnlockManager.isLockscreenPollingEnabled()) applyRouting(false); 1866 1867 mDeviceHost.doSetScreenState(screen_state_mask, mIsWlcEnabled); 1868 1869 sToast_debounce = false; 1870 1871 restoreSavedTech(); 1872 1873 /* Skip applyRouting if always on state is switching */ 1874 if (!mIsAlwaysOnSupported 1875 || (mAlwaysOnState != NfcAdapter.STATE_TURNING_ON 1876 && mAlwaysOnState != NfcAdapter.STATE_TURNING_OFF)) { 1877 /* Start polling loop */ 1878 applyRouting(true); 1879 } 1880 1881 if (mIsHceCapable) { 1882 // Generate the initial card emulation routing table 1883 mCardEmulationManager.onNfcEnabled(); 1884 } 1885 1886 if (mIsRecovering) { 1887 // Intents for all users 1888 registerGlobalBroadcastsReceiver(); 1889 mIsRecovering = false; 1890 } 1891 1892 if (mIsPowerSavingModeEnabled) { 1893 mDeviceHost.setPowerSavingMode(false); 1894 mIsPowerSavingModeEnabled = false; 1895 } 1896 1897 if (DBG) Log.d(TAG, "EnableDisableTask.enableInternal: end"); 1898 return true; 1899 } 1900 1901 /** 1902 * Disable all NFC adapter functions. 1903 * Does not toggle preferences. 1904 */ disableInternal()1905 boolean disableInternal() { 1906 if (DBG) Log.d(TAG, "EnableDisableTask.disableInternal: beging"); 1907 if (mState == NfcAdapter.STATE_OFF) { 1908 return true; 1909 } 1910 Log.i(TAG, "Disabling NFC"); 1911 NfcStatsLog.write( 1912 NfcStatsLog.NFC_STATE_CHANGED, NfcStatsLog.NFC_STATE_CHANGED__STATE__OFF); 1913 updateState(NfcAdapter.STATE_TURNING_OFF); 1914 1915 /* Sometimes mDeviceHost.deinitialize() hangs, use a watch-dog. 1916 * Implemented with a new thread (instead of a Handler or AsyncTask), 1917 * because the UI Thread and AsyncTask thread-pools can also get hung 1918 * when the NFC controller stops responding */ 1919 WatchDogThread watchDog = new WatchDogThread("disableInternal", ROUTING_WATCHDOG_MS); 1920 watchDog.start(); 1921 1922 if (mIsWlcEnabled) { 1923 if (mNfcCharging.NfcChargingOnGoing == true) { 1924 mNfcCharging.disconnectNfcCharging(); 1925 mNfcCharging.NfcChargingOnGoing = false; 1926 } 1927 mNfcCharging.resetInternalValues(); 1928 } 1929 1930 if (mIsHceCapable) { 1931 mCardEmulationManager.onNfcDisabled(); 1932 } 1933 1934 // Stop watchdog if tag present 1935 // A convenient way to stop the watchdog properly consists of 1936 // disconnecting the tag. The polling loop shall be stopped before 1937 // to avoid the tag being discovered again. 1938 maybeDisconnectTarget(); 1939 1940 synchronized (NfcService.this) { 1941 // Disable delay polling when disabling 1942 mPollDelayed = false; 1943 mPollDelayCount = 0; 1944 mReadErrorCount = 0; 1945 mHandler.removeMessages(MSG_DELAY_POLLING); 1946 mPollingDisableDeathRecipients.clear(); 1947 mReaderModeParams = null; 1948 mDiscoveryTechParams = null; 1949 } 1950 mNfcDispatcher.resetForegroundDispatch(); 1951 1952 boolean result; 1953 if (!mIsAlwaysOnSupported || mIsRecovering 1954 || (mAlwaysOnState == NfcAdapter.STATE_OFF) 1955 || (mAlwaysOnState == NfcAdapter.STATE_TURNING_OFF)) { 1956 result = mDeviceHost.deinitialize(); 1957 if (DBG) Log.d(TAG, "disableInternal: mDeviceHost.deinitialize() = " + result); 1958 } else { 1959 mDeviceHost.disableDiscovery(); 1960 result = true; 1961 Log.i(TAG, "disableInternal: AlwaysOn set, disableDiscovery()"); 1962 } 1963 1964 watchDog.cancel(); 1965 1966 synchronized (NfcService.this) { 1967 mCurrentDiscoveryParameters = NfcDiscoveryParameters.getNfcOffParameters(); 1968 updateState(NfcAdapter.STATE_OFF); 1969 } 1970 1971 releaseSoundPool(); 1972 if (DBG) Log.d(TAG, "EnableDisableTask.disableInternal: end"); 1973 return result; 1974 } 1975 1976 /** 1977 * Enable always on feature. 1978 */ enableAlwaysOnInternal(int mode)1979 boolean enableAlwaysOnInternal(int mode) { 1980 if (mAlwaysOnState == NfcAdapter.STATE_ON) { 1981 return true; 1982 } else if (mState == NfcAdapter.STATE_TURNING_ON 1983 || mAlwaysOnState == NfcAdapter.STATE_TURNING_OFF) { 1984 Log.e(TAG, "enableAlwaysOnInternal: Processing from bad state"); 1985 return false; 1986 } else if (mState == NfcAdapter.STATE_ON) { 1987 updateAlwaysOnState(NfcAdapter.STATE_TURNING_ON); 1988 mDeviceHost.setNfceePowerAndLinkCtrl(true); 1989 updateAlwaysOnState(NfcAdapter.STATE_ON); 1990 } else if (mState == NfcAdapter.STATE_OFF) { 1991 /* Special case when NFCC is OFF without initialize. 1992 * Temporarily enable NfcAdapter but don't applyRouting. 1993 * Then disable NfcAdapter without deinitialize to keep the NFCC stays initialized. 1994 * mState will switch back to OFF in the end. 1995 * And the NFCC stays initialized. 1996 */ 1997 updateAlwaysOnState(NfcAdapter.STATE_TURNING_ON); 1998 if (mode != NfcOemExtension.ENABLE_DEFAULT) { 1999 mDeviceHost.setPartialInitMode(mode); 2000 mAlwaysOnMode = mode; 2001 } 2002 if (!enableInternal()) { 2003 updateAlwaysOnState(NfcAdapter.STATE_OFF); 2004 return false; 2005 } 2006 disableInternal(); 2007 mDeviceHost.setNfceePowerAndLinkCtrl(true); 2008 updateAlwaysOnState(NfcAdapter.STATE_ON); 2009 } 2010 return true; 2011 } 2012 2013 /** 2014 * Disable always on feature. 2015 */ disableAlwaysOnInternal()2016 boolean disableAlwaysOnInternal() { 2017 if (mAlwaysOnState == NfcAdapter.STATE_OFF) { 2018 return true; 2019 } else if ((mState == NfcAdapter.STATE_TURNING_ON 2020 || mAlwaysOnState == NfcAdapter.STATE_TURNING_OFF) 2021 && (!(mAlwaysOnState == NfcAdapter.STATE_ON))) { 2022 if (!isAlwaysOnInDefaultMode()) { 2023 Log.e(TAG, "disableAlwaysOnInternal: Processing from bad state"); 2024 return false; 2025 } 2026 } else if (mState == NfcAdapter.STATE_ON) { 2027 updateAlwaysOnState(NfcAdapter.STATE_TURNING_OFF); 2028 mDeviceHost.setNfceePowerAndLinkCtrl(false); 2029 updateAlwaysOnState(NfcAdapter.STATE_OFF); 2030 } else if (mState == NfcAdapter.STATE_OFF 2031 || (mAlwaysOnState == NfcAdapter.STATE_ON)) { 2032 /* Special case when mState is OFF but NFCC is already initialized. 2033 * Deinitialize mDevicehost directly. 2034 */ 2035 updateAlwaysOnState(NfcAdapter.STATE_TURNING_OFF); 2036 mDeviceHost.setNfceePowerAndLinkCtrl(false); 2037 boolean result = mDeviceHost.deinitialize(); 2038 if (DBG) { 2039 Log.d(TAG, "disableAlwaysOnInternal: mDeviceHost.deinitialize() = " + result); 2040 } 2041 updateAlwaysOnState(NfcAdapter.STATE_OFF); 2042 return result; 2043 } 2044 return true; 2045 } 2046 updateState(int newState)2047 void updateState(int newState) { 2048 synchronized (NfcService.this) { 2049 if (newState == mState) { 2050 return; 2051 } 2052 mState = newState; 2053 if (android.nfc.Flags.nfcEventListener() && mCardEmulationManager != null) { 2054 mCardEmulationManager.onNfcStateChanged(newState); 2055 } 2056 if (mState == NfcAdapter.STATE_ON && mCardEmulationManager != null) { 2057 mCardEmulationManager.updateForShouldDefaultToObserveMode(getUserId()); 2058 mCardEmulationManager.updateFirmwareExitFramesForWalletRole(getUserId()); 2059 } 2060 if (mAlwaysOnState != NfcAdapter.STATE_TURNING_ON) { 2061 Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED); 2062 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 2063 intent.putExtra(NfcAdapter.EXTRA_ADAPTER_STATE, mState); 2064 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT); 2065 if (mNfcOemExtensionCallback != null) { 2066 try { 2067 mNfcOemExtensionCallback.onStateUpdated(mState); 2068 } catch (RemoteException remoteException) { 2069 Log.e(TAG, "updateState: Failed to invoke onStateUpdated " 2070 + "oem callback"); 2071 } 2072 } 2073 } 2074 } 2075 } 2076 updateAlwaysOnState(int newState)2077 void updateAlwaysOnState(int newState) { 2078 synchronized (NfcService.this) { 2079 if (newState == mAlwaysOnState) { 2080 return; 2081 } 2082 if (newState == NfcAdapter.STATE_OFF) { 2083 mAlwaysOnMode = NfcOemExtension.ENABLE_DEFAULT; 2084 mDeviceHost.setPartialInitMode(NfcOemExtension.ENABLE_DEFAULT); 2085 } 2086 mAlwaysOnState = newState; 2087 if (mAlwaysOnState == NfcAdapter.STATE_OFF 2088 || mAlwaysOnState == NfcAdapter.STATE_ON) { 2089 synchronized (mAlwaysOnListeners) { 2090 for (INfcControllerAlwaysOnListener listener 2091 : mAlwaysOnListeners) { 2092 try { 2093 listener.onControllerAlwaysOnChanged( 2094 mAlwaysOnState == NfcAdapter.STATE_ON); 2095 } catch (RemoteException e) { 2096 Log.e(TAG, "updateAlwaysOnState: error"); 2097 } 2098 } 2099 } 2100 } 2101 } 2102 } 2103 } 2104 clearListenTech(boolean keepListenTech)2105 private void clearListenTech(boolean keepListenTech) { 2106 if (getNfcListenTech() != DEFAULT_LISTEN_TECH) { 2107 int listenTech = -1; 2108 if (keepListenTech) { 2109 Log.d(TAG, "clearListenTech: keep listenTech"); 2110 listenTech = NfcAdapter.FLAG_LISTEN_KEEP; 2111 } else { 2112 Log.d(TAG, "clearListenTech: clear listenTech"); 2113 listenTech = (NfcAdapter.FLAG_LISTEN_KEEP | NfcAdapter.FLAG_USE_ALL_TECH 2114 | NfcAdapter.FLAG_SET_DEFAULT_TECH); 2115 } 2116 mDeviceHost.setDiscoveryTech(NfcAdapter.FLAG_READER_KEEP, listenTech); 2117 } 2118 } 2119 restoreSavedTech()2120 private void restoreSavedTech() { 2121 Log.i(TAG, "restoreSavedTech"); 2122 int pollTech = -1; 2123 if (mPrefs.contains(PREF_POLL_TECH)) { 2124 pollTech = getNfcPollTech(); 2125 } 2126 int listenTech = -1; 2127 if (mPrefs.contains(PREF_LISTEN_TECH)) { 2128 listenTech = getNfcListenTech(); 2129 } 2130 if (listenTech == -1 || listenTech == DEFAULT_LISTEN_TECH) 2131 listenTech = (NfcAdapter.FLAG_LISTEN_KEEP|NfcAdapter.FLAG_USE_ALL_TECH); 2132 2133 if (pollTech == -1 || pollTech == DEFAULT_POLL_TECH) 2134 pollTech = (NfcAdapter.FLAG_READER_KEEP|NfcAdapter.FLAG_USE_ALL_TECH); 2135 2136 mDeviceHost.setDiscoveryTech(pollTech|NfcAdapter.FLAG_SET_DEFAULT_TECH, 2137 listenTech|NfcAdapter.FLAG_SET_DEFAULT_TECH); 2138 } 2139 playSound(int sound)2140 public void playSound(int sound) { 2141 synchronized (this) { 2142 switch (sound) { 2143 case SOUND_END: 2144 // Lazy init sound pool when needed. 2145 initSoundPoolIfNeededAndPlaySound(() -> { 2146 int playReturn = mSoundPool.play(mEndSound, 1.0f, 1.0f, 0, 0, 1.0f); 2147 Log.d(TAG, "playSound: Sound pool play return: " + playReturn); 2148 }); 2149 break; 2150 case SOUND_ERROR: 2151 // Lazy init sound pool when needed. 2152 initSoundPoolIfNeededAndPlaySound(() -> { 2153 int playReturn = mSoundPool.play(mErrorSound, 1.0f, 1.0f, 0, 0, 1.0f); 2154 Log.d(TAG, "playSound: Sound pool play return: " + playReturn); 2155 }); 2156 break; 2157 } 2158 } 2159 } 2160 getUserId()2161 synchronized int getUserId() { 2162 return mUserId; 2163 } 2164 resetReaderModeParams()2165 private void resetReaderModeParams() { 2166 synchronized (NfcService.this) { 2167 if (mPollingDisableDeathRecipients.size() == 0) { 2168 Log.d(TAG, "resetReaderModeParams: Disabling reader mode because app died" 2169 + " or moved to background"); 2170 mReaderModeParams = null; 2171 StopPresenceChecking(); 2172 // listenTech is different from the default value, the stored listenTech will be included. 2173 // When using enableReaderMode, change listenTech to default & restore to the previous value. 2174 if (isNfcEnabled()) { 2175 restoreSavedTech(); 2176 } 2177 mNfcEventLog.logEvent( 2178 NfcEventProto.EventType.newBuilder() 2179 .setReaderModeChange(NfcEventProto.NfcReaderModeChange.newBuilder() 2180 .setFlags(0) 2181 .build()) 2182 .build()); 2183 if (isNfcEnabled()) { 2184 applyRouting(false); 2185 } 2186 } 2187 } 2188 } 2189 2190 @Override onUidToBackground(int uid)2191 public void onUidToBackground(int uid) { 2192 Log.i(TAG, "onUidToBackground: Uid " + uid); 2193 synchronized (NfcService.this) { 2194 if (mReaderModeParams != null && mReaderModeParams.uid == uid) { 2195 mReaderModeParams.binder.unlinkToDeath(mReaderModeDeathRecipient, 0); 2196 resetReaderModeParams(); 2197 } 2198 if (mDiscoveryTechParams != null && mDiscoveryTechParams.uid == uid) { 2199 mDiscoveryTechParams.binder.unlinkToDeath(mDiscoveryTechDeathRecipient, 0); 2200 mDeviceHost.resetDiscoveryTech(); 2201 mDiscoveryTechParams = null; 2202 if (isNfcEnabled()) { 2203 applyRouting(true); 2204 } 2205 } 2206 } 2207 } 2208 enableNfc()2209 public void enableNfc() { 2210 saveNfcOnSetting(true); 2211 2212 new EnableDisableTask().execute(TASK_ENABLE); 2213 } 2214 getAppName(@onNull String packageName, int uid)2215 private @NonNull CharSequence getAppName(@NonNull String packageName, int uid) { 2216 ApplicationInfo applicationInfo = null; 2217 try { 2218 applicationInfo = mContext.getPackageManager().getApplicationInfoAsUser( 2219 packageName, 0, UserHandle.getUserHandleForUid(uid)); 2220 } catch (PackageManager.NameNotFoundException e) { 2221 Log.e(TAG, "getAppName: Failed for " + packageName); 2222 return ""; 2223 } 2224 return mContext.getPackageManager().getApplicationLabel(applicationInfo); 2225 } 2226 isSecureNfcEnabled()2227 public boolean isSecureNfcEnabled() { 2228 return mIsSecureNfcEnabled; 2229 } 2230 2231 /** Helper method to check if the entity initiating the binder call is a DO/PO app. */ isDeviceOrProfileOwner(int uid, String packageName)2232 private boolean isDeviceOrProfileOwner(int uid, String packageName) { 2233 return mNfcPermissions.isDeviceOwner(uid, packageName) 2234 || mNfcPermissions.isProfileOwner(uid, packageName); 2235 } 2236 2237 final class NfcAdapterService extends INfcAdapter.Stub { 2238 @Override enable(String pkg)2239 public boolean enable(String pkg) throws RemoteException { 2240 if (Flags.checkPassedInPackage()) { 2241 mNfcPermissions.checkPackage(Binder.getCallingUid(), pkg); 2242 } 2243 boolean isDeviceOrProfileOwner = isDeviceOrProfileOwner(Binder.getCallingUid(), pkg); 2244 if (!NfcPermissions.checkAdminPermissions(mContext) 2245 && !isDeviceOrProfileOwner) { 2246 throw new SecurityException( 2247 "caller is not a system app, device owner or profile owner!"); 2248 } 2249 if (!isDeviceOrProfileOwner && mIsNfcUserChangeRestricted) { 2250 throw new SecurityException("Change nfc state by system app is not allowed!"); 2251 } 2252 2253 if (!isTaskBootCompleted()) { 2254 Log.e(TAG, "enable: NFC is not initialized yet:" + isTaskBootCompleted()); 2255 return false; 2256 } 2257 2258 notifyOemLogEvent(new OemLogItems.Builder(OemLogItems.LOG_ACTION_NFC_TOGGLE) 2259 .setCallingPid(Binder.getCallingPid()) 2260 .setCallingEvent(EVENT_ENABLE) 2261 .build()); 2262 2263 Log.i(TAG, "enable: enabling, package:" + pkg); 2264 List<String> allowlist = new ArrayList<>( 2265 Arrays.asList(mContext.getResources().getStringArray(R.array.nfc_allow_list))); 2266 if (!allowlist.isEmpty() && !allowlist.contains(pkg)) { 2267 Intent allowUsingNfcIntent = new Intent() 2268 .putExtra(APP_NAME_ENABLING_NFC, getAppName(pkg, getUserId())) 2269 .setClass(mContext, NfcEnableAllowlistActivity.class); 2270 2271 mContext.startActivityAsUser(allowUsingNfcIntent, UserHandle.CURRENT); 2272 return true; 2273 } 2274 mNfcEventLog.logEvent( 2275 NfcEventProto.EventType.newBuilder() 2276 .setStateChange(NfcEventProto.NfcStateChange.newBuilder() 2277 .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder() 2278 .setPackageName(pkg) 2279 .setUid(Binder.getCallingUid()) 2280 .build()) 2281 .setEnabled(true) 2282 .build()) 2283 .build()); 2284 if (android.nfc.Flags.nfcStateChangeSecurityLogEventEnabled()) { 2285 SecurityLog.writeEvent(SecurityLog.TAG_NFC_ENABLED); 2286 } 2287 enableNfc(); 2288 return true; 2289 } 2290 2291 @Override disable(boolean saveState, String pkg)2292 public boolean disable(boolean saveState, String pkg) throws RemoteException { 2293 if (Flags.checkPassedInPackage()) { 2294 mNfcPermissions.checkPackage(Binder.getCallingUid(), pkg); 2295 } 2296 2297 boolean isDeviceOrProfileOwner = isDeviceOrProfileOwner(Binder.getCallingUid(), pkg); 2298 if (!NfcPermissions.checkAdminPermissions(mContext) 2299 && !isDeviceOrProfileOwner) { 2300 throw new SecurityException( 2301 "caller is not a system app, device owner or profile owner!"); 2302 } 2303 if (!isDeviceOrProfileOwner && mIsNfcUserChangeRestricted) { 2304 throw new SecurityException("Change nfc state by system app is not allowed!"); 2305 } 2306 2307 notifyOemLogEvent(new OemLogItems.Builder(OemLogItems.LOG_ACTION_NFC_TOGGLE) 2308 .setCallingPid(Binder.getCallingPid()) 2309 .setCallingEvent(EVENT_DISABLE) 2310 .build()); 2311 2312 Log.i(TAG, "disable: disabling, package:" + pkg); 2313 if (saveState) { 2314 saveNfcOnSetting(false); 2315 } 2316 2317 mNfcEventLog.logEvent( 2318 NfcEventProto.EventType.newBuilder() 2319 .setStateChange(NfcEventProto.NfcStateChange.newBuilder() 2320 .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder() 2321 .setPackageName(pkg) 2322 .setUid(Binder.getCallingUid()) 2323 .build()) 2324 .setEnabled(false) 2325 .build()) 2326 .build()); 2327 if (android.nfc.Flags.nfcStateChangeSecurityLogEventEnabled()) { 2328 SecurityLog.writeEvent(SecurityLog.TAG_NFC_DISABLED); 2329 } 2330 new EnableDisableTask().execute(TASK_DISABLE); 2331 2332 return true; 2333 } 2334 2335 @Override isReaderModeAnnotationSupported()2336 public boolean isReaderModeAnnotationSupported() { 2337 return mDeviceHost.isReaderModeAnnotationSupported(); 2338 } 2339 2340 @Override isObserveModeSupported()2341 public boolean isObserveModeSupported() { 2342 if (!isNfcEnabled()) { 2343 Log.e(TAG, "isObserveModeSupported: NFC must be enabled but is: " + mState); 2344 return false; 2345 } 2346 return mDeviceHost.isObserveModeSupported(); 2347 } 2348 2349 @Override isObserveModeEnabled()2350 public boolean isObserveModeEnabled() { 2351 synchronized (NfcService.this) { 2352 if (!isNfcEnabled()) { 2353 Log.e(TAG, "isObserveModeEnabled: NFC must be enabled but is: " + mState); 2354 return false; 2355 } 2356 NfcPermissions.enforceUserPermissions(mContext); 2357 return mDeviceHost.isObserveModeEnabled(); 2358 } 2359 } 2360 2361 @Override setObserveMode(boolean enable, String packageName)2362 public boolean setObserveMode(boolean enable, String packageName) { 2363 synchronized (NfcService.this) { 2364 if (Flags.checkPassedInPackage()) { 2365 mNfcPermissions.checkPackage(Binder.getCallingUid(), packageName); 2366 } 2367 if (!isNfcEnabled()) { 2368 Log.e(TAG, "setObserveMode: NFC must be enabled but is: " + mState); 2369 return false; 2370 } 2371 int callingUid = Binder.getCallingUid(); 2372 UserHandle callingUser = Binder.getCallingUserHandle(); 2373 int triggerSource = StatsdUtils.TRIGGER_SOURCE_UNKNOWN; 2374 2375 if (!NfcInjector.isPrivileged(callingUid)) { 2376 NfcPermissions.enforceUserPermissions(mContext); 2377 if (packageName == null) { 2378 Log.e(TAG, "setObserveMode: no package name associated with " 2379 + "non-privileged calling UID"); 2380 } 2381 if (mCardEmulationManager.isPreferredServicePackageNameForUser( 2382 packageName, callingUser.getIdentifier())) { 2383 if (android.permission.flags.Flags.walletRoleEnabled()) { 2384 if (packageName != null) { 2385 triggerSource = 2386 packageName.equals(getWalletRoleHolder(callingUser)) 2387 ? StatsdUtils.TRIGGER_SOURCE_WALLET_ROLE_HOLDER 2388 : StatsdUtils.TRIGGER_SOURCE_FOREGROUND_APP; 2389 } 2390 } else { 2391 if (mForegroundUtils.isInForeground(callingUid)) { 2392 triggerSource = StatsdUtils.TRIGGER_SOURCE_FOREGROUND_APP; 2393 } 2394 } 2395 } else { 2396 Log.e(TAG, "setObserveMode: Caller not preferred NFC service."); 2397 return false; 2398 } 2399 } 2400 2401 if (mCardEmulationManager.isHostCardEmulationActivated()) { 2402 Log.w(TAG, "setObserveMode: Cannot set observe mode during a transaction."); 2403 return false; 2404 } 2405 2406 Log.d( 2407 TAG, 2408 "setObserveMode: package " 2409 + packageName 2410 + " with UID (" 2411 + callingUid 2412 + ") setting observe mode to " 2413 + enable); 2414 2415 long start = SystemClock.elapsedRealtime(); 2416 Trace.beginSection("setObserveMode: " + enable); 2417 boolean result = mDeviceHost.setObserveMode(enable); 2418 Trace.endSection(); 2419 int latency = Math.toIntExact(SystemClock.elapsedRealtime() - start); 2420 if (mStatsdUtils != null) { 2421 mStatsdUtils.logObserveModeStateChanged(enable, triggerSource, latency); 2422 } 2423 mNfcEventLog.logEvent( 2424 NfcEventProto.EventType.newBuilder() 2425 .setObserveModeChange( 2426 NfcEventProto.NfcObserveModeChange.newBuilder() 2427 .setAppInfo( 2428 NfcEventProto.NfcAppInfo.newBuilder() 2429 .setPackageName(packageName) 2430 .setUid(callingUid) 2431 .build()) 2432 .setEnable(enable) 2433 .setLatencyMs(latency) 2434 .setResult(result) 2435 .build()) 2436 .build()); 2437 return result; 2438 } 2439 } 2440 getWalletRoleHolder(UserHandle user)2441 private String getWalletRoleHolder(UserHandle user) { 2442 RoleManager roleManager = mContext.createContextAsUser(user, 0) 2443 .getSystemService(RoleManager.class); 2444 List<String> roleHolders = roleManager.getRoleHolders(RoleManager.ROLE_WALLET); 2445 return roleHolders.isEmpty() ? null : roleHolders.get(0); 2446 } 2447 2448 @Override pausePolling(long timeoutInMs)2449 public int pausePolling(long timeoutInMs) { 2450 NfcPermissions.enforceAdminPermissions(mContext); 2451 2452 checkAndHandleRemovalDetectionMode(false); 2453 synchronized (mDiscoveryLock) { 2454 if (!mRfDiscoveryStarted) { 2455 if (DBG) Log.d(TAG, "pausePolling: already disabled!"); 2456 return NfcOemExtension.POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE; 2457 } 2458 } 2459 synchronized (NfcService.this) { 2460 mPollingPaused = true; 2461 mDeviceHost.disableDiscovery(); 2462 /* timeoutInMs 0 will stop discovery without any timeout 2463 * polling will not auto resume */ 2464 if (timeoutInMs == 0) { 2465 if (DBG) Log.d(TAG, "pausePolling: without timeout"); 2466 return NfcOemExtension.POLLING_STATE_CHANGE_SUCCEEDED; 2467 } 2468 if (timeoutInMs < 0 || timeoutInMs > this.getMaxPausePollingTimeoutMs()) { 2469 throw new IllegalArgumentException( 2470 "Invalid timeout " + timeoutInMs + " ms!"); 2471 } 2472 mHandler.sendMessageDelayed( 2473 mHandler.obtainMessage(MSG_RESUME_POLLING), timeoutInMs); 2474 return NfcOemExtension.POLLING_STATE_CHANGE_SUCCEEDED; 2475 } 2476 } 2477 2478 @Override resumePolling()2479 public int resumePolling() { 2480 NfcPermissions.enforceAdminPermissions(mContext); 2481 boolean rfDiscoveryStarted; 2482 synchronized (mDiscoveryLock) { 2483 rfDiscoveryStarted = mRfDiscoveryStarted; 2484 } 2485 synchronized (NfcService.this) { 2486 if (!mPollingPaused) { 2487 if (rfDiscoveryStarted) { 2488 if (DBG) Log.d(TAG, "resumePolling: already enabled!"); 2489 return NfcOemExtension.POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE; 2490 } else { 2491 if (DBG) Log.d(TAG, "resumePolling: Enable explicitly!"); 2492 } 2493 } 2494 mHandler.removeMessages(MSG_RESUME_POLLING); 2495 mPollingPaused = false; 2496 new ApplyRoutingTask().execute(); 2497 if (DBG) Log.d(TAG, "resumePolling: done"); 2498 return NfcOemExtension.POLLING_STATE_CHANGE_SUCCEEDED; 2499 } 2500 } 2501 2502 @Override isNfcSecureEnabled()2503 public boolean isNfcSecureEnabled() throws RemoteException { 2504 synchronized (NfcService.this) { 2505 return mIsSecureNfcEnabled; 2506 } 2507 } 2508 2509 @Override setNfcSecure(boolean enable)2510 public boolean setNfcSecure(boolean enable) { 2511 NfcPermissions.enforceAdminPermissions(mContext); 2512 if (mNfcInjector.isDeviceLocked() && !enable) { 2513 Log.i(TAG, 2514 "setNfcSecure: Device need to be unlocked before setting Secure NFC OFF"); 2515 return false; 2516 } 2517 2518 synchronized (NfcService.this) { 2519 if (mIsSecureNfcEnabled == enable) { 2520 Log.e(TAG, "setNfcSecure: error, can't apply the same state twice!"); 2521 return false; 2522 } 2523 Log.i(TAG, "setNfcSecure: " + enable); 2524 mPrefsEditor.putBoolean(PREF_SECURE_NFC_ON, enable); 2525 mPrefsEditor.apply(); 2526 mIsSecureNfcEnabled = enable; 2527 mBackupManager.dataChanged(); 2528 mDeviceHost.setNfcSecure(enable); 2529 if (android.nfc.Flags.nfcPersistLog()) { 2530 mNfcEventLog.logEvent( 2531 NfcEventProto.EventType.newBuilder() 2532 .setSecureChange( 2533 NfcEventProto.NfcSecureChange.newBuilder() 2534 .setEnable(enable) 2535 .build()) 2536 .build()); 2537 } 2538 if (mIsHceCapable) { 2539 // update HCE/HCEF routing and commitRouting if Nfc is enabled 2540 mCardEmulationManager.onTriggerRoutingTableUpdate(); 2541 } else if (isNfcEnabled()) { 2542 // commit only tech/protocol route without HCE support 2543 mDeviceHost.commitRouting(); 2544 } 2545 } 2546 2547 NfcStatsLog.write(NfcStatsLog.NFC_STATE_CHANGED, 2548 mIsSecureNfcEnabled ? NfcStatsLog.NFC_STATE_CHANGED__STATE__ON_LOCKED : 2549 NfcStatsLog.NFC_STATE_CHANGED__STATE__ON); 2550 return true; 2551 } 2552 2553 @Override setForegroundDispatch(PendingIntent intent, IntentFilter[] filters, TechListParcel techListsParcel)2554 public void setForegroundDispatch(PendingIntent intent, 2555 IntentFilter[] filters, TechListParcel techListsParcel) { 2556 NfcPermissions.enforceUserPermissions(mContext); 2557 if (!mForegroundUtils.isInForeground(Binder.getCallingUid())) { 2558 Log.e(TAG, "setForegroundDispatch: Caller not in foreground."); 2559 return; 2560 } 2561 // Short-cut the disable path 2562 if (intent == null && filters == null && techListsParcel == null) { 2563 mNfcDispatcher.resetForegroundDispatch(); 2564 return; 2565 } 2566 2567 // Validate the IntentFilters 2568 if (filters != null) { 2569 if (filters.length == 0) { 2570 filters = null; 2571 } else { 2572 for (IntentFilter filter : filters) { 2573 if (filter == null) { 2574 throw new IllegalArgumentException("null IntentFilter"); 2575 } 2576 } 2577 } 2578 } 2579 2580 // Validate the tech lists 2581 String[][] techLists = null; 2582 if (techListsParcel != null) { 2583 techLists = techListsParcel.getTechLists(); 2584 } 2585 2586 mNfcDispatcher.setForegroundDispatch(intent, filters, techLists); 2587 } 2588 2589 2590 @Override setAppCallback(IAppCallback callback)2591 public void setAppCallback(IAppCallback callback) { 2592 NfcPermissions.enforceUserPermissions(mContext); 2593 } 2594 2595 @Override ignore(int nativeHandle, int debounceMs, ITagRemovedCallback callback)2596 public boolean ignore(int nativeHandle, int debounceMs, ITagRemovedCallback callback) 2597 throws RemoteException { 2598 NfcPermissions.enforceUserPermissions(mContext); 2599 2600 if (nativeHandle == MOCK_NATIVE_HANDLE 2601 || (debounceMs == 0 && mDebounceTagNativeHandle != INVALID_NATIVE_HANDLE 2602 && nativeHandle == mDebounceTagNativeHandle)) { 2603 // Remove any previous messages and immediately debounce. 2604 mHandler.removeMessages(MSG_TAG_DEBOUNCE); 2605 synchronized (NfcService.this) { 2606 mDebounceTagRemovedCallback = callback; 2607 } 2608 mHandler.sendEmptyMessage(MSG_TAG_DEBOUNCE); 2609 return true; 2610 } 2611 2612 TagEndpoint tag = (TagEndpoint) findAndRemoveObject(nativeHandle); 2613 if (tag != null) { 2614 // Store UID and params 2615 int uidLength = tag.getUid().length; 2616 synchronized (NfcService.this) { 2617 mDebounceTagDebounceMs = debounceMs; 2618 mDebounceTagNativeHandle = nativeHandle; 2619 mDebounceTagUid = new byte[uidLength]; 2620 mDebounceTagRemovedCallback = callback; 2621 System.arraycopy(tag.getUid(), 0, mDebounceTagUid, 0, uidLength); 2622 } 2623 2624 // Disconnect from this tag; this should resume the normal 2625 // polling loop (and enter listen mode for a while), before 2626 // we pick up any tags again. 2627 tag.disconnect(); 2628 mHandler.sendEmptyMessageDelayed(MSG_TAG_DEBOUNCE, debounceMs); 2629 return true; 2630 } else { 2631 return false; 2632 } 2633 } 2634 2635 @Override verifyNfcPermission()2636 public void verifyNfcPermission() { 2637 NfcPermissions.enforceUserPermissions(mContext); 2638 } 2639 2640 @Override getNfcTagInterface()2641 public INfcTag getNfcTagInterface() throws RemoteException { 2642 return mNfcTagService; 2643 } 2644 2645 @Override getNfcCardEmulationInterface()2646 public INfcCardEmulation getNfcCardEmulationInterface() { 2647 if (mIsHceCapable) { 2648 return mCardEmulationManager.getNfcCardEmulationInterface(); 2649 } else { 2650 return null; 2651 } 2652 } 2653 2654 @Override getNfcFCardEmulationInterface()2655 public INfcFCardEmulation getNfcFCardEmulationInterface() { 2656 if (mIsHceFCapable) { 2657 return mCardEmulationManager.getNfcFCardEmulationInterface(); 2658 } else { 2659 return null; 2660 } 2661 } 2662 2663 @Override getState()2664 public int getState() throws RemoteException { 2665 synchronized (NfcService.this) { 2666 return mState; 2667 } 2668 } 2669 2670 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)2671 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2672 NfcService.this.dump(fd, pw, args); 2673 } 2674 2675 @Override dispatch(Tag tag)2676 public void dispatch(Tag tag) throws RemoteException { 2677 NfcPermissions.enforceAdminPermissions(mContext); 2678 mNfcDispatcher.dispatchTag(tag); 2679 } 2680 2681 @Override updateDiscoveryTechnology( IBinder binder, int pollTech, int listenTech, String packageName)2682 public void updateDiscoveryTechnology( 2683 IBinder binder, int pollTech, int listenTech, String packageName) 2684 throws RemoteException { 2685 if (Flags.checkPassedInPackage()) { 2686 mNfcPermissions.checkPackage(Binder.getCallingUid(), packageName); 2687 } 2688 NfcPermissions.enforceUserPermissions(mContext); 2689 int callingUid = Binder.getCallingUid(); 2690 boolean privilegedCaller = NfcInjector.isPrivileged(callingUid) 2691 || NfcPermissions.checkAdminPermissions(mContext); 2692 // Allow non-foreground callers with system uid or systemui 2693 privilegedCaller |= packageName.equals(SYSTEM_UI); 2694 Log.d(TAG, "updateDiscoveryTechnology: uid=" + callingUid + 2695 ", packageName: " + packageName); 2696 if (!privilegedCaller) { 2697 pollTech &= ~NfcAdapter.FLAG_SET_DEFAULT_TECH; 2698 listenTech &= ~NfcAdapter.FLAG_SET_DEFAULT_TECH; 2699 if (!mForegroundUtils.registerUidToBackgroundCallback( 2700 NfcService.this, callingUid)) { 2701 Log.e(TAG, 2702 "updateDiscoveryTechnology: Unprivileged caller shall be in foreground"); 2703 return; 2704 } 2705 } else if (((pollTech & NfcAdapter.FLAG_SET_DEFAULT_TECH) != 0 2706 || (listenTech & NfcAdapter.FLAG_SET_DEFAULT_TECH) != 0)) { 2707 2708 if (!isNfcEnabled()) { 2709 Log.d(TAG, "updateDiscoveryTechnology: NFC is not enabled."); 2710 return; 2711 } 2712 if ((pollTech & NfcAdapter.FLAG_SET_DEFAULT_TECH) != 0) { 2713 if ((pollTech & NfcAdapter.FLAG_READER_KEEP) == 0 && 2714 (pollTech & NfcAdapter.FLAG_USE_ALL_TECH) 2715 != NfcAdapter.FLAG_USE_ALL_TECH) { 2716 pollTech = getReaderModeTechMask(pollTech); 2717 saveNfcPollTech(pollTech & ~NfcAdapter.FLAG_SET_DEFAULT_TECH); 2718 Log.i(TAG, "updateDiscoveryTechnology: Default pollTech is set to 0x" 2719 + Integer.toHexString(pollTech)); 2720 } else if ((pollTech 2721 & (NfcAdapter.FLAG_READER_KEEP | NfcAdapter.FLAG_USE_ALL_TECH)) 2722 == (NfcAdapter.FLAG_READER_KEEP | NfcAdapter.FLAG_USE_ALL_TECH)) { 2723 saveNfcPollTech(DEFAULT_POLL_TECH); 2724 } 2725 } 2726 if ((listenTech & NfcAdapter.FLAG_SET_DEFAULT_TECH) != 0) { 2727 if ((listenTech & NfcAdapter.FLAG_LISTEN_KEEP) == 0 && 2728 (listenTech & NfcAdapter.FLAG_USE_ALL_TECH) 2729 != NfcAdapter.FLAG_USE_ALL_TECH) { 2730 saveNfcListenTech(listenTech & ~NfcAdapter.FLAG_SET_DEFAULT_TECH); 2731 Log.i(TAG, "updateDiscoveryTechnology: Default listenTech is set to 0x" 2732 + Integer.toHexString(listenTech)); 2733 } else if ((listenTech 2734 & (NfcAdapter.FLAG_LISTEN_KEEP | NfcAdapter.FLAG_USE_ALL_TECH)) 2735 == (NfcAdapter.FLAG_LISTEN_KEEP | NfcAdapter.FLAG_USE_ALL_TECH)) { 2736 saveNfcListenTech(DEFAULT_LISTEN_TECH); 2737 } 2738 } 2739 if ((pollTech & NfcAdapter.FLAG_READER_KEEP) != 0) { 2740 pollTech = getNfcPollTech(); 2741 } 2742 if ((listenTech & NfcAdapter.FLAG_LISTEN_KEEP) != 0) { 2743 listenTech = getNfcListenTech(); 2744 } 2745 2746 mDeviceHost.setDiscoveryTech(pollTech, listenTech); 2747 applyRouting(true); 2748 return; 2749 } 2750 checkAndHandleRemovalDetectionMode(false); 2751 synchronized (NfcService.this) { 2752 if (!isNfcEnabled()) { 2753 Log.d(TAG, "updateDiscoveryTechnology: NFC is not enabled."); 2754 return; 2755 } 2756 2757 Log.d(TAG, "updateDiscoveryTechnology: pollTech=0x" + Integer.toHexString(pollTech) 2758 + ", listenTech=0x" + Integer.toHexString(listenTech)); 2759 if (pollTech == NfcAdapter.FLAG_USE_ALL_TECH && 2760 listenTech == NfcAdapter.FLAG_USE_ALL_TECH && 2761 mDiscoveryTechParams != null) { 2762 try { 2763 binder.unlinkToDeath(mDiscoveryTechDeathRecipient, 0); 2764 mDeviceHost.resetDiscoveryTech(); 2765 mDiscoveryTechParams = null; 2766 } catch (NoSuchElementException e) { 2767 Log.e(TAG, "updateDiscoveryTechnology: Change Tech Binder was never " 2768 + "registered"); 2769 } 2770 } else if (!(pollTech == NfcAdapter.FLAG_USE_ALL_TECH && // Do not call for 2771 // resetDiscoveryTech 2772 listenTech == NfcAdapter.FLAG_USE_ALL_TECH)) { 2773 if ((pollTech & NfcAdapter.FLAG_READER_KEEP) != 0) { 2774 pollTech = getNfcPollTech(); 2775 } else { 2776 pollTech = getReaderModeTechMask(pollTech); 2777 } 2778 if ((listenTech & NfcAdapter.FLAG_LISTEN_KEEP) != 0) { 2779 listenTech = getNfcListenTech(); 2780 } 2781 try { 2782 mDeviceHost.setDiscoveryTech(pollTech, listenTech); 2783 mDiscoveryTechParams = new DiscoveryTechParams(); 2784 mDiscoveryTechParams.uid = callingUid; 2785 mDiscoveryTechParams.binder = binder; 2786 binder.linkToDeath(mDiscoveryTechDeathRecipient, 0); 2787 if (android.nfc.Flags.nfcPersistLog()) { 2788 mNfcEventLog.logEvent( 2789 NfcEventProto.EventType.newBuilder() 2790 .setDiscoveryTechnologyUpdate(NfcEventProto 2791 .NfcDiscoveryTechnologyUpdate.newBuilder() 2792 .setAppInfo(NfcEventProto.NfcAppInfo 2793 .newBuilder() 2794 .setPackageName(packageName) 2795 .setUid(callingUid) 2796 .build()) 2797 .setPollTech(pollTech) 2798 .setListenTech(listenTech) 2799 .build()) 2800 .build()); 2801 } 2802 } catch (RemoteException e) { 2803 Log.e(TAG, "updateDiscoveryTechnology: Remote binder has already died"); 2804 return; 2805 } 2806 } else { 2807 return; 2808 } 2809 2810 applyRouting(true); 2811 } 2812 } 2813 2814 @Override setReaderMode( IBinder binder, IAppCallback callback, int flags, Bundle extras, String packageName)2815 public void setReaderMode( 2816 IBinder binder, IAppCallback callback, int flags, Bundle extras, String packageName) 2817 throws RemoteException { 2818 if (Flags.checkPassedInPackage()) { 2819 mNfcPermissions.checkPackage(Binder.getCallingUid(), packageName); 2820 } 2821 int callingUid = Binder.getCallingUid(); 2822 int callingPid = Binder.getCallingPid(); 2823 boolean privilegedCaller = NfcInjector.isPrivileged(callingUid) 2824 || NfcPermissions.checkAdminPermissions(mContext); 2825 // Allow non-foreground callers with system uid or systemui 2826 privilegedCaller |= packageName.equals(SYSTEM_UI); 2827 Log.d(TAG, "setReaderMode: uid=" + callingUid + ", packageName: " 2828 + packageName + ", flags: " + flags); 2829 if (!privilegedCaller 2830 && !mForegroundUtils.registerUidToBackgroundCallback( 2831 NfcService.this, callingUid)) { 2832 Log.e(TAG, "setReaderMode: Caller is not in foreground and is not system process"); 2833 return; 2834 } 2835 boolean disablePolling = flags != 0 && getReaderModeTechMask(flags) == 0; 2836 // Only allow to disable polling for specific callers 2837 if (disablePolling && !(privilegedCaller && mPollingDisableAllowed)) { 2838 Log.e(TAG, "setReaderMode: called with invalid flag parameter."); 2839 return; 2840 } 2841 if (extras != null 2842 && extras.containsKey(NfcAdapter.EXTRA_READER_TECH_A_POLLING_LOOP_ANNOTATION) 2843 && !isReaderModeAnnotationSupported()) { 2844 Log.e(TAG, "setReaderMode() called with annotation on an unsupported device."); 2845 return; 2846 } 2847 synchronized (NfcService.this) { 2848 if (!isNfcEnabled() && !privilegedCaller) { 2849 Log.e(TAG, "setReaderMode: called while NFC is not enabled."); 2850 return; 2851 } 2852 if (flags != 0) { 2853 try { 2854 if (disablePolling) { 2855 ReaderModeDeathRecipient pollingDisableDeathRecipient = 2856 new ReaderModeDeathRecipient(); 2857 binder.linkToDeath(pollingDisableDeathRecipient, 0); 2858 mPollingDisableDeathRecipients.put( 2859 callingPid, pollingDisableDeathRecipient); 2860 } else { 2861 if (mPollingDisableDeathRecipients.size() != 0) { 2862 Log.e(TAG, 2863 "setReaderMode: active polling is forced to disable now"); 2864 return; 2865 } 2866 binder.linkToDeath(mReaderModeDeathRecipient, 0); 2867 } 2868 if (mPollDelayed) { 2869 mHandler.removeMessages(MSG_DELAY_POLLING); 2870 mPollDelayCount = 0; 2871 mReadErrorCount = 0; 2872 mPollDelayed = false; 2873 mDeviceHost.startStopPolling(true); 2874 if (DBG) Log.d(TAG, "setReaderMode: polling is started"); 2875 } 2876 // listenTech is different from the default value, the stored listenTech will be included. 2877 // When using setReaderMode, change listenTech to default & restore to previous value. 2878 if (isNfcEnabled()) { 2879 clearListenTech(disablePolling); 2880 } 2881 updateReaderModeParams(callback, flags, extras, binder, callingUid); 2882 } catch (RemoteException e) { 2883 Log.e(TAG, "setReaderMode: Remote binder has already died"); 2884 return; 2885 } 2886 } else { 2887 try { 2888 ReaderModeDeathRecipient pollingDisableDeathRecipient = 2889 mPollingDisableDeathRecipients.get(callingPid); 2890 mPollingDisableDeathRecipients.remove(callingPid); 2891 2892 if (mPollingDisableDeathRecipients.size() == 0) { 2893 mReaderModeParams = null; 2894 StopPresenceChecking(); 2895 } 2896 2897 if (pollingDisableDeathRecipient != null) { 2898 binder.unlinkToDeath(pollingDisableDeathRecipient, 0); 2899 } else { 2900 binder.unlinkToDeath(mReaderModeDeathRecipient, 0); 2901 } 2902 } catch (NoSuchElementException e) { 2903 Log.e(TAG, "setReaderMode: Reader mode Binder was never registered"); 2904 } finally { 2905 // listenTech is different from the default value, the stored listenTech will be included. 2906 // When using enableReaderMode, change listenTech to default & restore to the previous value. 2907 if (isNfcEnabled()) { 2908 restoreSavedTech(); 2909 } 2910 } 2911 } 2912 mNfcEventLog.logEvent( 2913 NfcEventProto.EventType.newBuilder() 2914 .setReaderModeChange(NfcEventProto.NfcReaderModeChange.newBuilder() 2915 .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder() 2916 .setPackageName(packageName) 2917 .setUid(callingUid) 2918 .build()) 2919 .setFlags(flags) 2920 .build()) 2921 .build()); 2922 if (isNfcEnabled()) { 2923 applyRouting(false); 2924 } 2925 } 2926 checkAndHandleRemovalDetectionMode(true); 2927 } 2928 2929 @Override getNfcAdapterExtrasInterface(String pkg)2930 public INfcAdapterExtras getNfcAdapterExtrasInterface(String pkg) throws RemoteException { 2931 // nfc-extras implementation is no longer present in AOSP. 2932 return null; 2933 } 2934 2935 @Override getNfcDtaInterface(String pkg)2936 public INfcDta getNfcDtaInterface(String pkg) throws RemoteException { 2937 NfcPermissions.enforceAdminPermissions(mContext); 2938 if (mNfcDtaService == null) { 2939 mNfcDtaService = new NfcDtaService(); 2940 } 2941 return mNfcDtaService; 2942 } 2943 2944 @Override getT4tNdefNfceeInterface()2945 public IT4tNdefNfcee getT4tNdefNfceeInterface() throws RemoteException { 2946 return mT4tNdefNfceeService; 2947 } 2948 2949 @Override addNfcUnlockHandler(INfcUnlockHandler unlockHandler, int[] techList)2950 public void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, int[] techList) { 2951 NfcPermissions.enforceAdminPermissions(mContext); 2952 2953 int lockscreenPollMask = computeLockscreenPollMask(techList); 2954 synchronized (NfcService.this) { 2955 mNfcUnlockManager.addUnlockHandler(unlockHandler, lockscreenPollMask); 2956 } 2957 2958 applyRouting(false); 2959 } 2960 2961 @Override removeNfcUnlockHandler(INfcUnlockHandler token)2962 public void removeNfcUnlockHandler(INfcUnlockHandler token) throws RemoteException { 2963 synchronized (NfcService.this) { 2964 mNfcUnlockManager.removeUnlockHandler(token.asBinder()); 2965 } 2966 2967 applyRouting(false); 2968 } 2969 2970 @Override deviceSupportsNfcSecure()2971 public boolean deviceSupportsNfcSecure() { 2972 return mIsSecureNfcCapable; 2973 } 2974 2975 @Override getNfcAntennaInfo()2976 public NfcAntennaInfo getNfcAntennaInfo() { 2977 int positionX[] = mContext.getResources().getIntArray( 2978 R.array.antenna_x); 2979 int positionY[] = mContext.getResources().getIntArray( 2980 R.array.antenna_y); 2981 int width = mContext.getResources().getInteger(R.integer.device_width); 2982 int height = mContext.getResources().getInteger(R.integer.device_height); 2983 boolean isFoldable = mContext.getResources().getBoolean(R.bool.device_foldable); 2984 2985 // If overlays are not set, try reading properties. 2986 if (positionX.length == 0 || positionY.length == 0) { 2987 positionX = NfcProperties.info_antpos_X().stream() 2988 .mapToInt(Integer::intValue) 2989 .toArray(); 2990 positionY = NfcProperties.info_antpos_Y().stream() 2991 .mapToInt(Integer::intValue) 2992 .toArray(); 2993 width = NfcProperties.info_antpos_device_width().orElse(0); 2994 height = NfcProperties.info_antpos_device_height().orElse(0); 2995 isFoldable = NfcProperties.info_antpos_device_foldable().orElse(false); 2996 } 2997 if (positionX.length != positionY.length) { 2998 return null; 2999 } 3000 List<AvailableNfcAntenna> availableNfcAntennas = new ArrayList<>(); 3001 for (int i = 0; i < positionX.length; i++) { 3002 if (positionX[i] >= width || positionY[i] >= height) { 3003 return null; 3004 } 3005 availableNfcAntennas.add(new AvailableNfcAntenna(positionX[i], positionY[i])); 3006 } 3007 return new NfcAntennaInfo( 3008 width, 3009 height, 3010 isFoldable, 3011 availableNfcAntennas); 3012 } 3013 3014 @Override setWlcEnabled(boolean enable)3015 public boolean setWlcEnabled(boolean enable) { 3016 if (!mIsWlcCapable) { 3017 return false; 3018 } 3019 NfcPermissions.enforceAdminPermissions(mContext); 3020 // enable or disable WLC 3021 if (DBG) Log.d(TAG, "setWlcEnabled: " + enable); 3022 synchronized (NfcService.this) { 3023 // check whether NFC is enabled 3024 if (!isNfcEnabled()) { 3025 return false; 3026 } 3027 mPrefsEditor.putBoolean(PREF_NFC_CHARGING_ON, enable); 3028 mPrefsEditor.apply(); 3029 mIsWlcEnabled = enable; 3030 mBackupManager.dataChanged(); 3031 } 3032 if (android.nfc.Flags.nfcPersistLog()) { 3033 mNfcEventLog.logEvent( 3034 NfcEventProto.EventType.newBuilder() 3035 .setWlcStateChange( 3036 NfcEventProto.NfcWlcStateChange.newBuilder() 3037 .setEnable(enable) 3038 .build()) 3039 .build()); 3040 } 3041 return true; 3042 } 3043 3044 @Override isWlcEnabled()3045 public boolean isWlcEnabled() throws RemoteException { 3046 if (!mIsWlcCapable) { 3047 return false; 3048 } 3049 // check whether WLC is enabled or disabled 3050 synchronized (NfcService.this) { 3051 return mIsWlcEnabled; 3052 } 3053 } 3054 3055 @Override getWlcListenerDeviceInfo()3056 public WlcListenerDeviceInfo getWlcListenerDeviceInfo() { 3057 if (!mIsWlcCapable) { 3058 return null; 3059 } 3060 synchronized (NfcService.this) { 3061 return mWlcListenerDeviceInfo; 3062 } 3063 } 3064 computeLockscreenPollMask(int[] techList)3065 private int computeLockscreenPollMask(int[] techList) { 3066 3067 Map<Integer, Integer> techCodeToMask = new HashMap<Integer, Integer>(); 3068 3069 techCodeToMask.put(TagTechnology.NFC_A, NFC_POLL_A); 3070 techCodeToMask.put(TagTechnology.NFC_B, NFC_POLL_B); 3071 techCodeToMask.put(TagTechnology.NFC_V, NFC_POLL_V); 3072 techCodeToMask.put(TagTechnology.NFC_F, NFC_POLL_F); 3073 techCodeToMask.put(TagTechnology.NFC_BARCODE, NFC_POLL_KOVIO); 3074 3075 int mask = 0; 3076 3077 for (int i = 0; i < techList.length; i++) { 3078 if (techCodeToMask.containsKey(techList[i])) { 3079 mask |= techCodeToMask.get(techList[i]).intValue(); 3080 } 3081 } 3082 3083 return mask; 3084 } 3085 getReaderModeTechMask(int flags)3086 private int getReaderModeTechMask(int flags) { 3087 int techMask = 0; 3088 if ((flags & NfcAdapter.FLAG_READER_NFC_A) != 0) { 3089 techMask |= NFC_POLL_A; 3090 } 3091 if ((flags & NfcAdapter.FLAG_READER_NFC_B) != 0) { 3092 techMask |= NFC_POLL_B; 3093 } 3094 if ((flags & NfcAdapter.FLAG_READER_NFC_F) != 0) { 3095 techMask |= NFC_POLL_F; 3096 } 3097 if ((flags & NfcAdapter.FLAG_READER_NFC_V) != 0) { 3098 techMask |= NFC_POLL_V; 3099 } 3100 if ((flags & NfcAdapter.FLAG_READER_NFC_BARCODE) != 0) { 3101 techMask |= NFC_POLL_KOVIO; 3102 } 3103 3104 return techMask; 3105 } 3106 updateReaderModeParams( IAppCallback callback, int flags, Bundle extras, IBinder binder, int uid)3107 private void updateReaderModeParams( 3108 IAppCallback callback, int flags, Bundle extras, IBinder binder, int uid) { 3109 synchronized (NfcService.this) { 3110 mReaderModeParams = new ReaderModeParams(); 3111 mReaderModeParams.callback = callback; 3112 mReaderModeParams.flags = flags; 3113 mReaderModeParams.presenceCheckDelay = extras != null 3114 ? (extras.getInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 3115 DEFAULT_PRESENCE_CHECK_DELAY)) 3116 : DEFAULT_PRESENCE_CHECK_DELAY; 3117 mReaderModeParams.binder = binder; 3118 mReaderModeParams.uid = uid; 3119 mReaderModeParams.annotation = extras == null ? null 3120 : extras.getByteArray( 3121 NfcAdapter.EXTRA_READER_TECH_A_POLLING_LOOP_ANNOTATION); 3122 } 3123 } 3124 setTagAppPreferenceInternal(int userId, String pkg, boolean allow)3125 private int setTagAppPreferenceInternal(int userId, String pkg, boolean allow) { 3126 if (!isPackageInstalled(pkg, userId)) { 3127 return NfcAdapter.TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND; 3128 } 3129 if (DBG) { 3130 Log.i(TAG, "setTagAppPreferenceInternal: UserId:" + userId + " pkg:" + pkg + ":" 3131 + allow); 3132 } 3133 synchronized (NfcService.this) { 3134 mTagAppPrefList.computeIfAbsent(userId, key -> new HashMap<String, Boolean>()) 3135 .put(pkg, allow); 3136 } 3137 storeTagAppPrefList(); 3138 return NfcAdapter.TAG_INTENT_APP_PREF_RESULT_SUCCESS; 3139 } 3140 3141 @Override setControllerAlwaysOn(int mode)3142 public void setControllerAlwaysOn(int mode) throws RemoteException { 3143 NfcPermissions.enforceSetControllerAlwaysOnPermissions(mContext); 3144 if (!mIsAlwaysOnSupported) { 3145 throw new UnsupportedOperationException("isControllerAlwaysOn not supported"); 3146 } 3147 if (mode != NfcOemExtension.DISABLE) { 3148 /* AsyncTask params */ 3149 Integer[] paramIntegers = {TASK_ENABLE_ALWAYS_ON, mode}; 3150 new EnableDisableTask().execute(paramIntegers); 3151 } else { 3152 new EnableDisableTask().execute(TASK_DISABLE_ALWAYS_ON); 3153 } 3154 } 3155 3156 @Override isControllerAlwaysOn()3157 public boolean isControllerAlwaysOn() throws RemoteException { 3158 NfcPermissions.enforceSetControllerAlwaysOnPermissions(mContext); 3159 return mIsAlwaysOnSupported && mAlwaysOnState == NfcAdapter.STATE_ON; 3160 } 3161 3162 @Override isControllerAlwaysOnSupported()3163 public boolean isControllerAlwaysOnSupported() throws RemoteException { 3164 NfcPermissions.enforceSetControllerAlwaysOnPermissions(mContext); 3165 return mIsAlwaysOnSupported; 3166 } 3167 3168 @Override registerControllerAlwaysOnListener( INfcControllerAlwaysOnListener listener)3169 public void registerControllerAlwaysOnListener( 3170 INfcControllerAlwaysOnListener listener) throws RemoteException { 3171 NfcPermissions.enforceSetControllerAlwaysOnPermissions(mContext); 3172 if (!mIsAlwaysOnSupported) return; 3173 3174 mAlwaysOnListeners.add(listener); 3175 } 3176 3177 @Override unregisterControllerAlwaysOnListener( INfcControllerAlwaysOnListener listener)3178 public void unregisterControllerAlwaysOnListener( 3179 INfcControllerAlwaysOnListener listener) throws RemoteException { 3180 NfcPermissions.enforceSetControllerAlwaysOnPermissions(mContext); 3181 if (!mIsAlwaysOnSupported) return; 3182 3183 mAlwaysOnListeners.remove(listener); 3184 } 3185 3186 @Override isTagIntentAppPreferenceSupported()3187 public boolean isTagIntentAppPreferenceSupported() throws RemoteException { 3188 return mIsTagAppPrefSupported; 3189 } 3190 3191 @Override getTagIntentAppPreferenceForUser(int userId)3192 public Map getTagIntentAppPreferenceForUser(int userId) throws RemoteException { 3193 NfcPermissions.enforceAdminPermissions(mContext); 3194 if (!mIsTagAppPrefSupported) throw new UnsupportedOperationException(); 3195 synchronized (NfcService.this) { 3196 return mTagAppPrefList.getOrDefault(userId, new HashMap<>()); 3197 } 3198 } 3199 3200 @Override setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)3201 public int setTagIntentAppPreferenceForUser(int userId, 3202 String pkg, boolean allow) throws RemoteException { 3203 NfcPermissions.enforceAdminPermissions(mContext); 3204 if (!mIsTagAppPrefSupported) throw new UnsupportedOperationException(); 3205 return setTagAppPreferenceInternal(userId, pkg, allow); 3206 } 3207 3208 @Override isTagIntentAllowed(String pkg, int userId)3209 public boolean isTagIntentAllowed(String pkg, int userId) throws RemoteException { 3210 if (!android.nfc.Flags.nfcCheckTagIntentPreference()) { 3211 return true; 3212 } 3213 if (!mIsTagAppPrefSupported) { 3214 return true; 3215 } 3216 HashMap<String, Boolean> map; 3217 synchronized (NfcService.this) { 3218 map = mTagAppPrefList.getOrDefault(userId, new HashMap<>()); 3219 } 3220 return map.getOrDefault(pkg, true); 3221 } 3222 enableReaderOption(boolean enable, String pkg)3223 public boolean enableReaderOption(boolean enable, String pkg) { 3224 Log.d(TAG, "enableReaderOption: enabled = " + enable + " calling uid = " 3225 + Binder.getCallingUid()); 3226 if (!mReaderOptionCapable) return false; 3227 NfcPermissions.enforceAdminPermissions(mContext); 3228 synchronized (NfcService.this) { 3229 mPrefsEditor.putBoolean(PREF_NFC_READER_OPTION_ON, enable); 3230 mPrefsEditor.apply(); 3231 mIsReaderOptionEnabled = enable; 3232 mBackupManager.dataChanged(); 3233 } 3234 applyRouting(true); 3235 if (mNfcOemExtensionCallback != null) { 3236 try { 3237 mNfcOemExtensionCallback.onReaderOptionChanged(enable); 3238 } catch (RemoteException e) { 3239 Log.e(TAG, 3240 "enableReaderOption: onReaderOptionChanged failed e = " + e.toString()); 3241 } 3242 } 3243 3244 if (android.nfc.Flags.nfcPersistLog()) { 3245 mNfcEventLog.logEvent( 3246 NfcEventProto.EventType.newBuilder() 3247 .setReaderOptionChange( 3248 NfcEventProto.NfcReaderOptionChange.newBuilder() 3249 .setEnable(enable) 3250 .setAppInfo( 3251 NfcEventProto.NfcAppInfo.newBuilder() 3252 .setPackageName(pkg) 3253 .setUid(Binder.getCallingUid()) 3254 .build()) 3255 .build()) 3256 .build()); 3257 } 3258 return true; 3259 } 3260 3261 @Override isReaderOptionSupported()3262 public boolean isReaderOptionSupported() { 3263 return mReaderOptionCapable; 3264 } 3265 3266 @Override isReaderOptionEnabled()3267 public boolean isReaderOptionEnabled() { 3268 return mIsReaderOptionEnabled; 3269 } 3270 3271 @Override registerWlcStateListener( INfcWlcStateListener listener)3272 public void registerWlcStateListener( 3273 INfcWlcStateListener listener) throws RemoteException { 3274 if (!mIsWlcCapable) { 3275 return; 3276 } 3277 NfcPermissions.enforceAdminPermissions(mContext); 3278 3279 mWlcStateListener.add(listener); 3280 } 3281 3282 @Override unregisterWlcStateListener( INfcWlcStateListener listener)3283 public void unregisterWlcStateListener( 3284 INfcWlcStateListener listener) throws RemoteException { 3285 if (!mIsWlcCapable) { 3286 return; 3287 } 3288 NfcPermissions.enforceAdminPermissions(mContext); 3289 3290 mWlcStateListener.remove(listener); 3291 } 3292 3293 @Override notifyPollingLoop(PollingFrame frame)3294 public void notifyPollingLoop(PollingFrame frame) { 3295 try { 3296 byte[] data; 3297 int type = frame.getType(); 3298 int gain = frame.getVendorSpecificGain(); 3299 byte[] frame_data = frame.getData(); 3300 3301 long timestamp = frame.getTimestamp(); 3302 HexFormat format = HexFormat.ofDelimiter(" "); 3303 String timestampBytes = format.formatHex(new byte[] { 3304 (byte) (timestamp >>> 24), 3305 (byte) (timestamp >>> 16), 3306 (byte) (timestamp >>> 8), 3307 (byte) timestamp }); 3308 int frame_data_length = frame_data == null ? 0 : frame_data.length; 3309 String frame_data_str = 3310 frame_data_length == 0 ? "" : " " + format.formatHex(frame_data); 3311 String type_str = "FF"; 3312 switch (type) { 3313 case PollingFrame.POLLING_LOOP_TYPE_ON: 3314 type_str = "00"; 3315 data = new byte[] { 0x01 }; 3316 break; 3317 case PollingFrame.POLLING_LOOP_TYPE_OFF: 3318 type_str = "00"; 3319 data = new byte[] { 0x00 }; 3320 break; 3321 case PollingFrame.POLLING_LOOP_TYPE_A: 3322 type_str = "01"; 3323 break; 3324 case PollingFrame.POLLING_LOOP_TYPE_B: 3325 type_str = "02"; 3326 break; 3327 case PollingFrame.POLLING_LOOP_TYPE_F: 3328 type_str = "03"; 3329 break; 3330 case PollingFrame.POLLING_LOOP_TYPE_UNKNOWN: 3331 type_str = "07"; 3332 break; 3333 } 3334 data = format.parseHex("6f 0C " + String.format("%02x", 9 + frame_data_length) 3335 + " 03 " + type_str 3336 + " 00 " + String.format("%02x", 5 + frame_data_length) + " " 3337 + timestampBytes + " " + String.format("%02x", gain) + frame_data_str); 3338 ((NativeNfcManager) mDeviceHost).injectNtf(data); 3339 } catch (Exception ex) { 3340 Log.e(TAG, "notifyPollingLoop: error when notifying polling loop", ex); 3341 } 3342 } 3343 3344 @Override notifyTestHceData(int technology, byte[] data)3345 public void notifyTestHceData(int technology, byte[] data) { 3346 onHostCardEmulationData(technology, data); 3347 } 3348 3349 @Override notifyHceDeactivated()3350 public void notifyHceDeactivated() { 3351 try { 3352 mCardEmulationManager.onHostCardEmulationDeactivated(1); 3353 } catch (Exception ex) { 3354 Log.e(TAG, "notifyHceDeactivated: e=", ex); 3355 } 3356 } 3357 3358 @Override handleShellCommand(@onNull ParcelFileDescriptor in, @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, @NonNull String[] args)3359 public int handleShellCommand(@NonNull ParcelFileDescriptor in, 3360 @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, 3361 @NonNull String[] args) { 3362 3363 NfcShellCommand shellCommand = new NfcShellCommand(NfcService.this, mContext); 3364 return shellCommand.exec(this, in.getFileDescriptor(), out.getFileDescriptor(), 3365 err.getFileDescriptor(), args); 3366 } 3367 isPowerSavingModeCmd(int gid, int oid, byte[] payload)3368 private static boolean isPowerSavingModeCmd(int gid, int oid, byte[] payload) { 3369 return gid == NCI_GID_PROP && oid == NCI_MSG_PROP_ANDROID && payload.length > 0 3370 && payload[0] == NCI_MSG_PROP_ANDROID_POWER_SAVING; 3371 } 3372 isQueryPowerSavingStatusCmd(int gid, int oid, byte[] payload)3373 private static boolean isQueryPowerSavingStatusCmd(int gid, int oid, byte[] payload) { 3374 return gid == NCI_GID_PROP && oid == NCI_MSG_PROP_ANDROID && payload.length > 0 3375 && payload[0] == NCI_PROP_ANDROID_QUERY_POWER_SAVING_STATUS_CMD; 3376 } 3377 3378 @Override sendVendorNciMessage(int mt, int gid, int oid, byte[] payload)3379 public int sendVendorNciMessage(int mt, int gid, int oid, byte[] payload) 3380 throws RemoteException { 3381 NfcPermissions.enforceAdminPermissions(mContext); 3382 if ((!isNfcEnabled() && !mIsPowerSavingModeEnabled) && !isControllerAlwaysOn()) { 3383 Log.e(TAG, "sendVendorNciMessage: Nfc is not enabled"); 3384 return NCI_STATUS_FAILED; 3385 } 3386 3387 FutureTask<Integer> sendVendorCmdTask = new FutureTask<>( 3388 () -> { synchronized (NfcService.this) { 3389 if (isPowerSavingModeCmd(gid, oid, payload)) { 3390 boolean status = setPowerSavingMode(payload[1] == 0x01); 3391 return status ? NCI_STATUS_OK : NCI_STATUS_FAILED; 3392 } else if (isQueryPowerSavingStatusCmd(gid, oid, payload)) { 3393 NfcVendorNciResponse response = new NfcVendorNciResponse( 3394 (byte) NCI_STATUS_OK, NCI_GID_PROP, NCI_MSG_PROP_ANDROID, 3395 new byte[] { 3396 (byte) NCI_PROP_ANDROID_QUERY_POWER_SAVING_STATUS_CMD, 3397 0x00, 3398 mIsPowerSavingModeEnabled ? (byte) 0x01 : (byte) 0x00}); 3399 if (response.status == NCI_STATUS_OK) { 3400 mHandler.post(() -> mNfcAdapter.sendVendorNciResponse( 3401 response.gid, response.oid, response.payload)); 3402 } 3403 return Integer.valueOf(response.status); 3404 } else { 3405 NfcVendorNciResponse response = 3406 mDeviceHost.sendRawVendorCmd(mt, gid, oid, payload); 3407 if (response.status == NCI_STATUS_OK) { 3408 mHandler.post(() -> mNfcAdapter.sendVendorNciResponse( 3409 response.gid, response.oid, response.payload)); 3410 } 3411 return Integer.valueOf(response.status); 3412 } 3413 }}); 3414 int status = NCI_STATUS_FAILED; 3415 try { 3416 status = runTaskOnSingleThreadExecutor(sendVendorCmdTask, 3417 SEND_VENDOR_CMD_TIMEOUT_MS); 3418 } catch (TimeoutException e) { 3419 Log.e(TAG, "sendVendorNciMessage: Failed , status : TIMEOUT", e); 3420 } catch (InterruptedException e) { 3421 e.printStackTrace(); 3422 } catch (ExecutionException e) { 3423 e.printStackTrace(); 3424 } 3425 return status; 3426 } 3427 3428 @Override registerVendorExtensionCallback(INfcVendorNciCallback callbacks)3429 public void registerVendorExtensionCallback(INfcVendorNciCallback callbacks) 3430 throws RemoteException { 3431 synchronized (NfcService.this) { 3432 if (DBG) Log.i(TAG, "registerVendorExtensionCallback"); 3433 NfcPermissions.enforceAdminPermissions(mContext); 3434 mNfcVendorNciCallBack = callbacks; 3435 mDeviceHost.enableVendorNciNotifications(true); 3436 } 3437 } 3438 3439 @Override unregisterVendorExtensionCallback(INfcVendorNciCallback callbacks)3440 public void unregisterVendorExtensionCallback(INfcVendorNciCallback callbacks) 3441 throws RemoteException { 3442 synchronized (NfcService.this) { 3443 if (DBG) Log.i(TAG, "unregisterVendorExtensionCallback"); 3444 NfcPermissions.enforceAdminPermissions(mContext); 3445 mNfcVendorNciCallBack = null; 3446 mDeviceHost.enableVendorNciNotifications(false); 3447 } 3448 } 3449 3450 @Override registerOemExtensionCallback(INfcOemExtensionCallback callbacks)3451 public void registerOemExtensionCallback(INfcOemExtensionCallback callbacks) 3452 throws RemoteException { 3453 if (DBG) Log.i(TAG, "registerOemExtensionCallback"); 3454 NfcPermissions.enforceAdminPermissions(mContext); 3455 mNfcOemExtensionCallback = callbacks; 3456 updateNfCState(); 3457 if (mCardEmulationManager != null) { 3458 mCardEmulationManager.setOemExtension(mNfcOemExtensionCallback); 3459 } 3460 if (mNfcDispatcher != null) { 3461 mNfcDispatcher.setOemExtension(mNfcOemExtensionCallback); 3462 } 3463 } 3464 3465 @Override unregisterOemExtensionCallback(INfcOemExtensionCallback callbacks)3466 public void unregisterOemExtensionCallback(INfcOemExtensionCallback callbacks) 3467 throws RemoteException { 3468 if (DBG) Log.i(TAG, "unregisterOemExtensionCallback"); 3469 NfcPermissions.enforceAdminPermissions(mContext); 3470 mNfcOemExtensionCallback = null; 3471 if (mCardEmulationManager != null) { 3472 mCardEmulationManager.setOemExtension(mNfcOemExtensionCallback); 3473 } 3474 if (mNfcDispatcher != null) { 3475 mNfcDispatcher.setOemExtension(mNfcOemExtensionCallback); 3476 } 3477 } 3478 @Override fetchActiveNfceeList()3479 public Map<String, Integer> fetchActiveNfceeList() throws RemoteException { 3480 Map<String, Integer> map = new HashMap<String, Integer>(); 3481 if (isNfcEnabled()) { 3482 map = mDeviceHost.dofetchActiveNfceeList(); 3483 } 3484 return map; 3485 } 3486 3487 @Override clearPreference()3488 public void clearPreference() throws RemoteException { 3489 if (DBG) Log.i(TAG, "clearPreference"); 3490 NfcPermissions.enforceAdminPermissions(mContext); 3491 if (android.nfc.Flags.nfcPersistLog()) { 3492 mNfcEventLog.logEvent(NfcEventProto.EventType.newBuilder() 3493 .setClearPreference( 3494 NfcEventProto.NfcClearPreference.newBuilder() 3495 .build()) 3496 .build()); 3497 } 3498 mPrefsEditor.clear(); 3499 if (mIsNfcUserChangeRestricted) { 3500 mPrefsEditor.putBoolean(PREF_NFC_ON, getNfcOnSetting()); 3501 } 3502 mPrefsEditor.putBoolean( 3503 PREF_NFC_READER_OPTION_ON, mDeviceConfigFacade.getDefaultReaderOption()); 3504 mPrefsEditor.commit(); 3505 } 3506 3507 @Override setScreenState()3508 public void setScreenState() throws RemoteException { 3509 if (DBG) Log.i(TAG, "setScreenState"); 3510 NfcPermissions.enforceAdminPermissions(mContext); 3511 applyScreenState(mScreenStateHelper.checkScreenState(mCheckDisplayStateForScreenState)); 3512 } 3513 3514 @Override checkFirmware()3515 public void checkFirmware() throws RemoteException { 3516 if (DBG) Log.i(TAG, "checkFirmware"); 3517 NfcPermissions.enforceAdminPermissions(mContext); 3518 3519 if (isNfcEnabled()) { 3520 if (DBG) Log.i(TAG, "Check firmware by restarting Nfc stack"); 3521 restartStack(); 3522 return; 3523 } 3524 FutureTask<Integer> checkFirmwareTask = 3525 new FutureTask<>(() -> { 3526 if (DBG) Log.i(TAG, "Nfc is disabled, checking Firmware"); 3527 mDeviceHost.checkFirmware(); 3528 return 0; 3529 }); 3530 try { 3531 runTaskOnSingleThreadExecutor( 3532 checkFirmwareTask, CHECK_FIRMWARE_TIMEOUT_MS); 3533 } catch (TimeoutException e) { 3534 Log.e(TAG, "checkFirmware: failed, status : TIMEOUT", e); 3535 } catch (InterruptedException e) { 3536 e.printStackTrace(); 3537 } catch (ExecutionException e) { 3538 e.printStackTrace(); 3539 } 3540 } 3541 3542 @Override triggerInitialization()3543 public void triggerInitialization() throws RemoteException { 3544 if (DBG) Log.i(TAG, "triggerInitialization"); 3545 NfcPermissions.enforceAdminPermissions(mContext); 3546 new EnableDisableTask().execute(TASK_BOOT); 3547 } 3548 3549 @Override getSettingStatus()3550 public boolean getSettingStatus() throws RemoteException { 3551 if (DBG) Log.i(TAG, "getSettingStatus"); 3552 NfcPermissions.enforceAdminPermissions(mContext); 3553 return getNfcOnSetting(); 3554 } 3555 3556 @Override isTagPresent()3557 public boolean isTagPresent() throws RemoteException { 3558 if (DBG) Log.i(TAG, "isTagPresent"); 3559 NfcPermissions.enforceAdminPermissions(mContext); 3560 return NfcService.this.isTagPresent(); 3561 } 3562 3563 @Override getRoutingTableEntryList()3564 public List<Entry> getRoutingTableEntryList() throws RemoteException { 3565 if (DBG) Log.i(TAG, "getRoutingTableEntry"); 3566 NfcPermissions.enforceAdminPermissions(mContext); 3567 return mRoutingTableParser.getRoutingTableEntryList(mDeviceHost); 3568 } 3569 3570 @Override indicateDataMigration(boolean inProgress, String pkg)3571 public void indicateDataMigration(boolean inProgress, String pkg) throws RemoteException { 3572 if (Flags.checkPassedInPackage()) { 3573 mNfcPermissions.checkPackage(Binder.getCallingUid(), pkg); 3574 } 3575 if (DBG) Log.i(TAG, "indicateDataMigration: inProgress: " + inProgress); 3576 NfcPermissions.enforceAdminPermissions(mContext); 3577 mNfcEventLog.logEvent( 3578 NfcEventProto.EventType.newBuilder() 3579 .setDataMigrationInProgress(NfcEventProto.NfcDataMigrationInProgress 3580 .newBuilder() 3581 .setAppInfo(NfcEventProto.NfcAppInfo.newBuilder() 3582 .setPackageName(pkg) 3583 .setUid(Binder.getCallingUid()) 3584 .build()) 3585 .setInProgress(inProgress) 3586 .build()) 3587 .build()); 3588 } 3589 3590 @Override commitRouting()3591 public int commitRouting() throws RemoteException { 3592 if (isNfcDisabledOrDisabling()) { 3593 Log.d(TAG, "Skip commit routing when NFCC is off " 3594 + "or turning off"); 3595 return STATUS_UNKNOWN_ERROR; 3596 } 3597 if (DBG) Log.i(TAG, "commitRouting"); 3598 NfcPermissions.enforceAdminPermissions(mContext); 3599 return mDeviceHost.commitRouting(); 3600 } 3601 3602 @Override getMaxPausePollingTimeoutMs()3603 public long getMaxPausePollingTimeoutMs() { 3604 if (DBG) Log.i(TAG, "getMaxPausePollingTimeoutMs"); 3605 NfcPermissions.enforceAdminPermissions(mContext); 3606 int timeoutOverlay = mContext.getResources() 3607 .getInteger(R.integer.max_pause_polling_time_out_ms); 3608 return timeoutOverlay > 0 ? (long) timeoutOverlay : MAX_POLLING_PAUSE_TIMEOUT; 3609 } 3610 updateNfCState()3611 private void updateNfCState() { 3612 if (mNfcOemExtensionCallback != null) { 3613 try { 3614 if (DBG) Log.i(TAG, "updateNfCState"); 3615 mNfcOemExtensionCallback.onCardEmulationActivated(mCardEmulationActivated); 3616 mNfcOemExtensionCallback.onRfFieldDetected(mRfFieldActivated); 3617 mNfcOemExtensionCallback.onRfDiscoveryStarted(mRfDiscoveryStarted); 3618 mNfcOemExtensionCallback.onEeListenActivated(mEeListenActivated); 3619 } catch (RemoteException e) { 3620 Log.e(TAG, "updateNfCState: Failed to update, e=", e); 3621 } 3622 } 3623 } 3624 sendVendorNciResponse(int gid, int oid, byte[] payload)3625 private synchronized void sendVendorNciResponse(int gid, int oid, byte[] payload) { 3626 if (VDBG) Log.i(TAG, "onVendorNciResponseReceived"); 3627 if (mNfcVendorNciCallBack != null) { 3628 try { 3629 mNfcVendorNciCallBack.onVendorResponseReceived(gid, oid, payload); 3630 } catch (RemoteException e) { 3631 Log.e(TAG, "onVendorNciResponseReceived: failed, e=", e); 3632 } 3633 } 3634 } 3635 sendVendorNciNotification(int gid, int oid, byte[] payload)3636 private synchronized void sendVendorNciNotification(int gid, int oid, byte[] payload) { 3637 if (VDBG) Log.i(TAG, "sendVendorNciNotification"); 3638 if (mNfcVendorNciCallBack != null) { 3639 try { 3640 mNfcVendorNciCallBack.onVendorNotificationReceived(gid, oid, payload); 3641 } catch (RemoteException e) { 3642 Log.e(TAG, "sendVendorNciNotification: failed, e=", e); 3643 } 3644 } 3645 } 3646 } 3647 3648 3649 final class SeServiceDeathRecipient implements IBinder.DeathRecipient { 3650 @Override binderDied()3651 public void binderDied() { 3652 synchronized (NfcService.this) { 3653 Log.i(TAG, "binderDied: SE Service died"); 3654 mSEService = null; 3655 } 3656 } 3657 } 3658 3659 final class ReaderModeDeathRecipient implements IBinder.DeathRecipient { 3660 @Override binderDied()3661 public void binderDied() { 3662 synchronized (NfcService.this) { 3663 if (mReaderModeParams != null) { 3664 mPollingDisableDeathRecipients.values().remove(this); 3665 resetReaderModeParams(); 3666 } 3667 } 3668 } 3669 } 3670 3671 final class DiscoveryTechDeathRecipient implements IBinder.DeathRecipient { 3672 @Override binderDied()3673 public void binderDied() { 3674 if (DBG) Log.d(TAG, "binderDied: setDiscoveryTech death recipient"); 3675 synchronized (NfcService.this) { 3676 if (isNfcEnabled() && mDiscoveryTechParams != null) { 3677 mDeviceHost.resetDiscoveryTech(); 3678 mDiscoveryTechParams = null; 3679 } 3680 } 3681 applyRouting(true); 3682 } 3683 } 3684 3685 final class TagService extends INfcTag.Stub { 3686 @Override connect(int nativeHandle, int technology)3687 public int connect(int nativeHandle, int technology) throws RemoteException { 3688 NfcPermissions.enforceUserPermissions(mContext); 3689 3690 TagEndpoint tag = null; 3691 3692 if (!isNfcEnabled()) { 3693 return ErrorCodes.ERROR_NOT_INITIALIZED; 3694 } 3695 3696 if (!isReaderOptionEnabled()) { 3697 return ErrorCodes.ERROR_NOT_INITIALIZED; 3698 } 3699 3700 if (checkAndHandleRemovalDetectionMode(true)) { 3701 return ErrorCodes.ERROR_NOT_INITIALIZED; 3702 } 3703 3704 /* find the tag in the hmap */ 3705 tag = (TagEndpoint) findObject(nativeHandle); 3706 if (tag == null) { 3707 return ErrorCodes.ERROR_DISCONNECT; 3708 } 3709 3710 if (!tag.isPresent()) { 3711 return ErrorCodes.ERROR_DISCONNECT; 3712 } 3713 3714 // Note that on most tags, all technologies are behind a single 3715 // handle. This means that the connect at the lower levels 3716 // will do nothing, as the tag is already connected to that handle. 3717 if (tag.connect(technology)) { 3718 return ErrorCodes.SUCCESS; 3719 } else { 3720 return ErrorCodes.ERROR_DISCONNECT; 3721 } 3722 } 3723 3724 @Override reconnect(int nativeHandle)3725 public int reconnect(int nativeHandle) throws RemoteException { 3726 NfcPermissions.enforceUserPermissions(mContext); 3727 3728 TagEndpoint tag = null; 3729 3730 // Check if NFC is enabled 3731 if (!isNfcEnabled()) { 3732 return ErrorCodes.ERROR_NOT_INITIALIZED; 3733 } 3734 3735 if (!isReaderOptionEnabled()) { 3736 return ErrorCodes.ERROR_NOT_INITIALIZED; 3737 } 3738 3739 if (checkAndHandleRemovalDetectionMode(true)) { 3740 return ErrorCodes.ERROR_NOT_INITIALIZED; 3741 } 3742 3743 /* find the tag in the hmap */ 3744 tag = (TagEndpoint) findObject(nativeHandle); 3745 if (tag != null) { 3746 if (tag.reconnect()) { 3747 return ErrorCodes.SUCCESS; 3748 } else { 3749 return ErrorCodes.ERROR_DISCONNECT; 3750 } 3751 } 3752 return ErrorCodes.ERROR_DISCONNECT; 3753 } 3754 3755 @Override getTechList(int nativeHandle)3756 public int[] getTechList(int nativeHandle) throws RemoteException { 3757 NfcPermissions.enforceUserPermissions(mContext); 3758 3759 // Check if NFC is enabled 3760 if (!isNfcEnabled()) { 3761 return null; 3762 } 3763 3764 if (!isReaderOptionEnabled()) { 3765 return null; 3766 } 3767 3768 if (checkAndHandleRemovalDetectionMode(true)) { 3769 return null; 3770 } 3771 3772 /* find the tag in the hmap */ 3773 TagEndpoint tag = (TagEndpoint) findObject(nativeHandle); 3774 if (tag != null) { 3775 return tag.getTechList(); 3776 } 3777 return null; 3778 } 3779 3780 @Override isPresent(int nativeHandle)3781 public boolean isPresent(int nativeHandle) throws RemoteException { 3782 TagEndpoint tag = null; 3783 3784 // Check if NFC is enabled 3785 if (!isNfcEnabled()) { 3786 return false; 3787 } 3788 3789 if (!isReaderOptionEnabled()) { 3790 return false; 3791 } 3792 3793 if (checkAndHandleRemovalDetectionMode(true)) { 3794 return false; 3795 } 3796 3797 /* find the tag in the hmap */ 3798 tag = (TagEndpoint) findObject(nativeHandle); 3799 if (tag == null) { 3800 return false; 3801 } 3802 3803 return tag.isPresent(); 3804 } 3805 3806 @Override isNdef(int nativeHandle)3807 public boolean isNdef(int nativeHandle) throws RemoteException { 3808 NfcPermissions.enforceUserPermissions(mContext); 3809 3810 TagEndpoint tag = null; 3811 3812 // Check if NFC is enabled 3813 if (!isNfcEnabled()) { 3814 return false; 3815 } 3816 3817 if (!isReaderOptionEnabled()) { 3818 return false; 3819 } 3820 3821 if (checkAndHandleRemovalDetectionMode(true)) { 3822 return false; 3823 } 3824 3825 /* find the tag in the hmap */ 3826 tag = (TagEndpoint) findObject(nativeHandle); 3827 int[] ndefInfo = new int[2]; 3828 if (tag == null) { 3829 return false; 3830 } 3831 return tag.checkNdef(ndefInfo); 3832 } 3833 3834 @Override transceive(int nativeHandle, byte[] data, boolean raw)3835 public TransceiveResult transceive(int nativeHandle, byte[] data, boolean raw) 3836 throws RemoteException { 3837 NfcPermissions.enforceUserPermissions(mContext); 3838 3839 TagEndpoint tag = null; 3840 byte[] response; 3841 3842 // Check if NFC is enabled 3843 if (!isNfcEnabled()) { 3844 return null; 3845 } 3846 3847 if (!isReaderOptionEnabled()) { 3848 return null; 3849 } 3850 3851 if (checkAndHandleRemovalDetectionMode(true)) { 3852 return null; 3853 } 3854 3855 /* find the tag in the hmap */ 3856 tag = (TagEndpoint) findObject(nativeHandle); 3857 if (tag != null) { 3858 // Check if length is within limits 3859 if (data.length > getMaxTransceiveLength(tag.getConnectedTechnology())) { 3860 return new TransceiveResult(TransceiveResult.RESULT_EXCEEDED_LENGTH, null); 3861 } 3862 int[] targetLost = new int[1]; 3863 response = tag.transceive(data, raw, targetLost); 3864 int result; 3865 if (response != null) { 3866 result = TransceiveResult.RESULT_SUCCESS; 3867 } else if (targetLost[0] == 1) { 3868 result = TransceiveResult.RESULT_TAGLOST; 3869 } else { 3870 result = TransceiveResult.RESULT_FAILURE; 3871 } 3872 return new TransceiveResult(result, response); 3873 } 3874 return null; 3875 } 3876 3877 @Override ndefRead(int nativeHandle)3878 public NdefMessage ndefRead(int nativeHandle) throws RemoteException { 3879 NfcPermissions.enforceUserPermissions(mContext); 3880 3881 TagEndpoint tag; 3882 3883 // Check if NFC is enabled 3884 if (!isNfcEnabled()) { 3885 return null; 3886 } 3887 3888 if (!isReaderOptionEnabled()) { 3889 return null; 3890 } 3891 3892 if (checkAndHandleRemovalDetectionMode(true)) { 3893 return null; 3894 } 3895 3896 /* find the tag in the hmap */ 3897 tag = (TagEndpoint) findObject(nativeHandle); 3898 if (tag != null) { 3899 byte[] buf = tag.readNdef(); 3900 if (buf == null) { 3901 return null; 3902 } 3903 3904 /* Create an NdefMessage */ 3905 try { 3906 return new NdefMessage(buf); 3907 } catch (FormatException e) { 3908 return null; 3909 } 3910 } 3911 return null; 3912 } 3913 3914 @Override ndefWrite(int nativeHandle, NdefMessage msg)3915 public int ndefWrite(int nativeHandle, NdefMessage msg) throws RemoteException { 3916 NfcPermissions.enforceUserPermissions(mContext); 3917 3918 TagEndpoint tag; 3919 3920 // Check if NFC is enabled 3921 if (!isNfcEnabled()) { 3922 return ErrorCodes.ERROR_NOT_INITIALIZED; 3923 } 3924 3925 if (!isReaderOptionEnabled()) { 3926 return ErrorCodes.ERROR_NOT_INITIALIZED; 3927 } 3928 3929 if (checkAndHandleRemovalDetectionMode(true)) { 3930 return ErrorCodes.ERROR_NOT_INITIALIZED; 3931 } 3932 3933 /* find the tag in the hmap */ 3934 tag = (TagEndpoint) findObject(nativeHandle); 3935 if (tag == null) { 3936 return ErrorCodes.ERROR_IO; 3937 } 3938 3939 if (msg == null) return ErrorCodes.ERROR_INVALID_PARAM; 3940 3941 if (tag.writeNdef(msg.toByteArray())) { 3942 return ErrorCodes.SUCCESS; 3943 } else { 3944 return ErrorCodes.ERROR_IO; 3945 } 3946 3947 } 3948 3949 @Override ndefIsWritable(int nativeHandle)3950 public boolean ndefIsWritable(int nativeHandle) throws RemoteException { 3951 if (checkAndHandleRemovalDetectionMode(true)) { 3952 return false; 3953 } 3954 throw new UnsupportedOperationException(); 3955 } 3956 3957 @Override ndefMakeReadOnly(int nativeHandle)3958 public int ndefMakeReadOnly(int nativeHandle) throws RemoteException { 3959 NfcPermissions.enforceUserPermissions(mContext); 3960 3961 TagEndpoint tag; 3962 3963 // Check if NFC is enabled 3964 if (!isNfcEnabled()) { 3965 return ErrorCodes.ERROR_NOT_INITIALIZED; 3966 } 3967 3968 if (!isReaderOptionEnabled()) { 3969 return ErrorCodes.ERROR_NOT_INITIALIZED; 3970 } 3971 3972 if (checkAndHandleRemovalDetectionMode(true)) { 3973 return ErrorCodes.ERROR_NOT_INITIALIZED; 3974 } 3975 3976 /* find the tag in the hmap */ 3977 tag = (TagEndpoint) findObject(nativeHandle); 3978 if (tag == null) { 3979 return ErrorCodes.ERROR_IO; 3980 } 3981 3982 if (tag.makeReadOnly()) { 3983 return ErrorCodes.SUCCESS; 3984 } else { 3985 return ErrorCodes.ERROR_IO; 3986 } 3987 } 3988 3989 @Override formatNdef(int nativeHandle, byte[] key)3990 public int formatNdef(int nativeHandle, byte[] key) throws RemoteException { 3991 NfcPermissions.enforceUserPermissions(mContext); 3992 3993 TagEndpoint tag; 3994 3995 // Check if NFC is enabled 3996 if (!isNfcEnabled()) { 3997 return ErrorCodes.ERROR_NOT_INITIALIZED; 3998 } 3999 4000 if (!isReaderOptionEnabled()) { 4001 return ErrorCodes.ERROR_NOT_INITIALIZED; 4002 } 4003 4004 if (checkAndHandleRemovalDetectionMode(true)) { 4005 return ErrorCodes.ERROR_NOT_INITIALIZED; 4006 } 4007 4008 /* find the tag in the hmap */ 4009 tag = (TagEndpoint) findObject(nativeHandle); 4010 if (tag == null) { 4011 return ErrorCodes.ERROR_IO; 4012 } 4013 4014 if (tag.formatNdef(key)) { 4015 return ErrorCodes.SUCCESS; 4016 } else { 4017 return ErrorCodes.ERROR_IO; 4018 } 4019 } 4020 4021 @Override rediscover(int nativeHandle)4022 public Tag rediscover(int nativeHandle) throws RemoteException { 4023 NfcPermissions.enforceUserPermissions(mContext); 4024 4025 TagEndpoint tag = null; 4026 4027 // Check if NFC is enabled 4028 if (!isNfcEnabled()) { 4029 return null; 4030 } 4031 4032 if (!isReaderOptionEnabled()) { 4033 return null; 4034 } 4035 4036 if (checkAndHandleRemovalDetectionMode(true)) { 4037 return null; 4038 } 4039 4040 /* find the tag in the hmap */ 4041 tag = (TagEndpoint) findObject(nativeHandle); 4042 if (tag != null) { 4043 // For now the prime usecase for rediscover() is to be able 4044 // to access the NDEF technology after formatting without 4045 // having to remove the tag from the field, or similar 4046 // to have access to NdefFormatable in case low-level commands 4047 // were used to remove NDEF. So instead of doing a full stack 4048 // rediscover (which is poorly supported at the moment anyway), 4049 // we simply remove these two technologies and detect them 4050 // again. 4051 tag.removeTechnology(TagTechnology.NDEF); 4052 tag.removeTechnology(TagTechnology.NDEF_FORMATABLE); 4053 tag.findAndReadNdef(); 4054 // Build a new Tag object to return 4055 try { 4056 /* Avoid setting mCookieUpToDate to negative values */ 4057 mCookieUpToDate = mCookieGenerator.nextLong() >>> 1; 4058 Tag newTag = new Tag(tag.getUid(), tag.getTechList(), 4059 tag.getTechExtras(), tag.getHandle(), mCookieUpToDate, this); 4060 return newTag; 4061 } catch (Exception e) { 4062 Log.e(TAG, "Tag creation exception.", e); 4063 return null; 4064 } 4065 } 4066 return null; 4067 } 4068 4069 @Override setTimeout(int tech, int timeout)4070 public int setTimeout(int tech, int timeout) throws RemoteException { 4071 NfcPermissions.enforceUserPermissions(mContext); 4072 boolean success = mDeviceHost.setTimeout(tech, timeout); 4073 if (success) { 4074 return ErrorCodes.SUCCESS; 4075 } else { 4076 return ErrorCodes.ERROR_INVALID_PARAM; 4077 } 4078 } 4079 4080 @Override getTimeout(int tech)4081 public int getTimeout(int tech) throws RemoteException { 4082 NfcPermissions.enforceUserPermissions(mContext); 4083 4084 return mDeviceHost.getTimeout(tech); 4085 } 4086 4087 @Override resetTimeouts()4088 public void resetTimeouts() throws RemoteException { 4089 NfcPermissions.enforceUserPermissions(mContext); 4090 4091 mDeviceHost.resetTimeouts(); 4092 } 4093 4094 @Override canMakeReadOnly(int ndefType)4095 public boolean canMakeReadOnly(int ndefType) throws RemoteException { 4096 return mDeviceHost.canMakeReadOnly(ndefType); 4097 } 4098 4099 @Override getMaxTransceiveLength(int tech)4100 public int getMaxTransceiveLength(int tech) throws RemoteException { 4101 return mDeviceHost.getMaxTransceiveLength(tech); 4102 } 4103 4104 @Override getExtendedLengthApdusSupported()4105 public boolean getExtendedLengthApdusSupported() throws RemoteException { 4106 return mDeviceHost.getExtendedLengthApdusSupported(); 4107 } 4108 4109 @Override isTagUpToDate(long cookie)4110 public boolean isTagUpToDate(long cookie) throws RemoteException { 4111 if (mCookieUpToDate != -1 && mCookieUpToDate == cookie) { 4112 if (DBG) { 4113 Log.d(TAG, "isTagUpToDate: Tag " + Long.toString(cookie) + " is up to date"); 4114 } 4115 return true; 4116 } 4117 4118 if (DBG) { 4119 Log.d(TAG, "isTagUpToDate: Tag " + Long.toString(cookie) + " is out of date"); 4120 } 4121 EventLog.writeEvent(0x534e4554, "199291025", -1, 4122 "The obsolete tag was attempted to be accessed"); 4123 return false; 4124 } 4125 } 4126 4127 final class NfcDtaService extends INfcDta.Stub { enableDta()4128 public void enableDta() throws RemoteException { 4129 NfcPermissions.enforceAdminPermissions(mContext); 4130 if (!sIsDtaMode) { 4131 mDeviceHost.enableDtaMode(); 4132 sIsDtaMode = true; 4133 Log.d(TAG, "enableDta: DTA Mode is Enabled"); 4134 } else { 4135 Log.d(TAG, "enableDta: DTA Mode is already Enabled"); 4136 } 4137 } 4138 disableDta()4139 public void disableDta() throws RemoteException { 4140 NfcPermissions.enforceAdminPermissions(mContext); 4141 if (sIsDtaMode) { 4142 mDeviceHost.disableDtaMode(); 4143 sIsDtaMode = false; 4144 Log.d(TAG, "disableDta: DTA Mode is Disabled"); 4145 } else { 4146 Log.d(TAG, "disableDta: DTA Mode is already Disabled"); 4147 } 4148 } 4149 enableServer(String serviceName, int serviceSap, int miu, int rwSize,int testCaseId)4150 public boolean enableServer(String serviceName, int serviceSap, int miu, 4151 int rwSize,int testCaseId) throws RemoteException { 4152 NfcPermissions.enforceAdminPermissions(mContext); 4153 return false; 4154 } 4155 disableServer()4156 public void disableServer() throws RemoteException { 4157 } 4158 enableClient(String serviceName, int miu, int rwSize, int testCaseId)4159 public boolean enableClient(String serviceName, int miu, int rwSize, 4160 int testCaseId) throws RemoteException { 4161 NfcPermissions.enforceAdminPermissions(mContext); 4162 return false; 4163 } 4164 disableClient()4165 public void disableClient() throws RemoteException { 4166 return; 4167 } 4168 registerMessageService(String msgServiceName)4169 public boolean registerMessageService(String msgServiceName) 4170 throws RemoteException { 4171 NfcPermissions.enforceAdminPermissions(mContext); 4172 if (msgServiceName == null) return false; 4173 4174 DtaServiceConnector.setMessageService(msgServiceName); 4175 return true; 4176 } 4177 4178 }; 4179 4180 class T4tNdefNfceeService extends IT4tNdefNfcee.Stub { 4181 4182 @Override writeData(final int fileId, byte[] data)4183 public int writeData(final int fileId, byte[] data) { 4184 NfcPermissions.enforceAdminPermissions(mContext); 4185 if (mDeviceHost.isNdefOperationOngoing()) { 4186 return T4tNdefNfcee.WRITE_DATA_ERROR_DEVICE_BUSY; 4187 } 4188 int status = T4tNdefNfcee.WRITE_DATA_ERROR_INTERNAL; 4189 try { 4190 ByteBuffer fileIdInBytes = ByteBuffer.allocate(2); 4191 fileIdInBytes.putShort((short)fileId); 4192 status = mDeviceHost.doWriteData(fileIdInBytes.array(), data); 4193 if (status > 0) status = T4tNdefNfcee.WRITE_DATA_SUCCESS; 4194 } catch (Exception e) { 4195 Log.e(TAG, "writeData: e=", e); 4196 } 4197 Log.i(TAG, "writeData : " + status); 4198 return status; 4199 } 4200 4201 @Override readData(final int fileId)4202 public byte[] readData(final int fileId) { 4203 NfcPermissions.enforceAdminPermissions(mContext); 4204 if (mDeviceHost.isNdefOperationOngoing()) { 4205 throw new IllegalStateException("Device is busy"); 4206 } 4207 byte[] readData = {}; 4208 ByteBuffer fileIdInBytes = ByteBuffer.allocate(2); 4209 fileIdInBytes.putShort((short)fileId); 4210 readData = mDeviceHost.doReadData(fileIdInBytes.array()); 4211 if (readData == null) { 4212 throw new IllegalStateException("Ndef Nfcee read failed"); 4213 } 4214 return readData; 4215 } 4216 4217 @Override readCcfile()4218 public T4tNdefNfceeCcFileInfo readCcfile() { 4219 NfcPermissions.enforceAdminPermissions(mContext); 4220 if (mDeviceHost.isNdefOperationOngoing()) { 4221 throw new IllegalStateException("Device is busy"); 4222 } 4223 T4tNdefNfceeCcFileInfo ccFileInfo = null; 4224 byte[] readData = {}; 4225 4226 try { 4227 readData = mDeviceHost.doReadData(T4T_NFCEE_CC_FILE_ID); 4228 } catch (Exception e) { 4229 Log.e(TAG, "readCcfile: Exception e=", e); 4230 return ccFileInfo; 4231 } 4232 if (readData.length >= 15) { 4233 int cclen = 4234 ((Byte.toUnsignedInt(readData[0])) << 8) + 4235 (Byte.toUnsignedInt(readData[1])); 4236 int version = Byte.toUnsignedInt(readData[2]); 4237 if (version == T4T_NFCEE_MAPPING_VERSION_2_0) { 4238 int ndefFileId = 4239 ((Byte.toUnsignedInt(readData[9])) << 8) + 4240 Byte.toUnsignedInt(readData[10]); 4241 int ndefMaxFileSize = 4242 ((Byte.toUnsignedInt(readData[11])) << 8) + 4243 Byte.toUnsignedInt(readData[12]); 4244 boolean isReadAllowed = readData[13] == 0; 4245 boolean isWriteAllowed = readData[14] == 0; 4246 4247 ccFileInfo = new T4tNdefNfceeCcFileInfo( 4248 cclen, version, ndefFileId, ndefMaxFileSize, isReadAllowed, 4249 isWriteAllowed); 4250 } else { 4251 Log.e(TAG, 4252 "readCcfile: Unsupported NDEF mapping version received. " 4253 + "Versions otherthan 2.0 are not supported."); 4254 throw new UnsupportedOperationException( 4255 "Unsupported NDEF mapping version received"); 4256 } 4257 } else { 4258 Log.e(TAG, "readCcfile: Empty data"); 4259 } 4260 return ccFileInfo; 4261 } 4262 4263 @Override clearNdefData()4264 public int clearNdefData() { 4265 NfcPermissions.enforceAdminPermissions(mContext); 4266 if (mDeviceHost.isNdefOperationOngoing()) { 4267 return T4tNdefNfcee.CLEAR_DATA_FAILED_DEVICE_BUSY; 4268 } 4269 boolean isEnabled = (isNfcEnabled() 4270 || (((mIsAlwaysOnSupported && mAlwaysOnState == NfcAdapter.STATE_ON)) 4271 && (mAlwaysOnMode == NfcOemExtension.ENABLE_EE))); 4272 if (!isEnabled) { 4273 mDeviceHost.setPartialInitMode(NfcOemExtension.ENABLE_EE); 4274 mDeviceHost.initialize(); 4275 } 4276 boolean status = mDeviceHost.doClearNdefData(); 4277 if (!isEnabled) { 4278 mDeviceHost.deinitialize(); 4279 } 4280 Log.i(TAG, "clearNdefData: " + status); 4281 return status 4282 ? T4tNdefNfcee.CLEAR_DATA_SUCCESS 4283 : T4tNdefNfcee.CLEAR_DATA_FAILED_INTERNAL; 4284 } 4285 4286 @Override isNdefOperationOngoing()4287 public boolean isNdefOperationOngoing() { 4288 NfcPermissions.enforceAdminPermissions(mContext); 4289 boolean status = mDeviceHost.isNdefOperationOngoing(); 4290 Log.i(TAG, "isNdefOperationOngoing: " + status); 4291 return status; 4292 } 4293 4294 @Override isNdefNfceeEmulationSupported()4295 public boolean isNdefNfceeEmulationSupported() { 4296 NfcPermissions.enforceAdminPermissions(mContext); 4297 boolean status = mDeviceHost.isNdefNfceeEmulationSupported(); 4298 Log.i(TAG, "isT4tNdefNfceeEmulationSupported: " + status); 4299 return status; 4300 } 4301 } 4302 isNfcEnabledOrShuttingDown()4303 boolean isNfcEnabledOrShuttingDown() { 4304 synchronized (this) { 4305 return (mState == NfcAdapter.STATE_ON || mState == NfcAdapter.STATE_TURNING_OFF); 4306 } 4307 } 4308 isNfcDisabledOrDisabling()4309 boolean isNfcDisabledOrDisabling() { 4310 synchronized (this) { 4311 return (mState == NfcAdapter.STATE_OFF || mState == NfcAdapter.STATE_TURNING_OFF); 4312 } 4313 } 4314 isNfcEnabled()4315 boolean isNfcEnabled() { 4316 synchronized (this) { 4317 return mState == NfcAdapter.STATE_ON; 4318 } 4319 } 4320 isReaderOptionEnabled()4321 boolean isReaderOptionEnabled() { 4322 synchronized (this) { 4323 return mIsReaderOptionEnabled || mReaderModeParams != null; 4324 } 4325 } 4326 4327 class WatchDogThread extends Thread { 4328 final Object mCancelWaiter = new Object(); 4329 final int mTimeout; 4330 boolean mCanceled = false; 4331 WatchDogThread(String threadName, int timeout)4332 public WatchDogThread(String threadName, int timeout) { 4333 super(threadName); 4334 mTimeout = timeout; 4335 } 4336 4337 @Override run()4338 public void run() { 4339 try { 4340 synchronized (mCancelWaiter) { 4341 mCancelWaiter.wait(mTimeout); 4342 if (mCanceled) { 4343 return; 4344 } 4345 } 4346 } catch (InterruptedException e) { 4347 // Should not happen; fall-through to abort. 4348 Log.w(TAG, "run: Watchdog thread interrupted"); 4349 interrupt(); 4350 } 4351 if (mRoutingWakeLock.isHeld()) { 4352 Log.e(TAG, "run: Watchdog triggered, release lock before aborting"); 4353 mRoutingWakeLock.release(); 4354 } 4355 Log.e(TAG, "run: Watchdog triggered, aborting"); 4356 NfcStatsLog.write(NfcStatsLog.NFC_STATE_CHANGED, 4357 NfcStatsLog.NFC_STATE_CHANGED__STATE__CRASH_RESTART); 4358 if (android.nfc.Flags.nfcEventListener() && mCardEmulationManager != null) { 4359 mCardEmulationManager.onInternalErrorReported( 4360 CardEmulation.NFC_INTERNAL_ERROR_NFC_CRASH_RESTART); 4361 } 4362 storeNativeCrashLogs(); 4363 mDeviceHost.doAbort(getName()); 4364 } 4365 cancel()4366 public synchronized void cancel() { 4367 synchronized (mCancelWaiter) { 4368 mCanceled = true; 4369 mCancelWaiter.notify(); 4370 } 4371 } 4372 } 4373 hexStringToBytes(String s)4374 static byte[] hexStringToBytes(String s) { 4375 if (s == null || s.length() == 0) return null; 4376 int len = s.length(); 4377 if (len % 2 != 0) { 4378 s = '0' + s; 4379 len++; 4380 } 4381 byte[] data = new byte[len / 2]; 4382 for (int i = 0; i < len; i += 2) { 4383 int high = Character.digit(s.charAt(i), 16); 4384 int low = Character.digit(s.charAt(i + 1), 16); 4385 if (high == -1 || low == -1) { 4386 Log.e(TAG, "Invalid hex character found."); 4387 return null; 4388 } 4389 data[i / 2] = (byte) ((high << 4) + low); 4390 } 4391 return data; 4392 } 4393 addDeviceLockedStateListener()4394 private void addDeviceLockedStateListener() { 4395 if (android.app.Flags.deviceUnlockListener() && Flags.useDeviceLockListener()) { 4396 try { 4397 mKeyguard.addDeviceLockedStateListener( 4398 mContext.getMainExecutor(), mDeviceLockedStateListener); 4399 } catch (Exception e) { 4400 Log.e(TAG, "addDeviceLockedStateListener: e=" + e); 4401 } 4402 } else { 4403 try { 4404 mKeyguard.addKeyguardLockedStateListener(mContext.getMainExecutor(), 4405 mIKeyguardLockedStateListener); 4406 } catch (Exception e) { 4407 Log.e(TAG, 4408 "addDeviceLockedStateListener: Exception in addKeyguardLockedStateListener " 4409 + e); 4410 } 4411 } 4412 } 4413 4414 /** 4415 * Receives KeyGuard lock state updates 4416 */ 4417 private KeyguardLockedStateListener mIKeyguardLockedStateListener = 4418 new KeyguardLockedStateListener() { 4419 @Override 4420 public void onKeyguardLockedStateChanged(boolean isKeyguardLocked) { 4421 if (!mIsWlcCapable || !mNfcCharging.NfcChargingOnGoing) { 4422 applyScreenState(mScreenStateHelper.checkScreenState(mCheckDisplayStateForScreenState)); 4423 } 4424 } 4425 }; 4426 4427 /** 4428 * Receives Device lock state updates 4429 */ 4430 private DeviceLockedStateListener mDeviceLockedStateListener = 4431 new DeviceLockedStateListener() { 4432 @Override 4433 public void onDeviceLockedStateChanged(boolean isDeviceLocked) { 4434 if (!mIsWlcCapable || !mNfcCharging.NfcChargingOnGoing) { 4435 applyScreenState(mScreenStateHelper.checkScreenState( 4436 mCheckDisplayStateForScreenState)); 4437 } 4438 } 4439 }; 4440 addThermalStatusListener()4441 private void addThermalStatusListener() { 4442 try { 4443 if (mPowerManager != null) { 4444 mPowerManager.addThermalStatusListener(mContext.getMainExecutor(), 4445 mOnThermalStatusChangedListener); 4446 } 4447 } catch (Exception e) { 4448 Log.e(TAG, "addThermalStatusListener: e=" + e); 4449 } 4450 } 4451 4452 /** 4453 * Receives Thermal state updates 4454 */ 4455 private OnThermalStatusChangedListener mOnThermalStatusChangedListener = 4456 new OnThermalStatusChangedListener() { 4457 @Override 4458 public void onThermalStatusChanged(int status) { 4459 switch (status) { 4460 case PowerManager.THERMAL_STATUS_MODERATE: 4461 Log.d(TAG, "onThermalStatusChanged: THERMAL_STATUS_MODERATE"); 4462 break; 4463 case PowerManager.THERMAL_STATUS_SEVERE: 4464 Log.d(TAG, "onThermalStatusChanged: THERMAL_STATUS_SEVERE"); 4465 break; 4466 case PowerManager.THERMAL_STATUS_CRITICAL: 4467 Log.d(TAG, "onThermalStatusChanged: THERMAL_STATUS_CRITICAL"); 4468 break; 4469 default: 4470 Log.d(TAG, "onThermalStatusChanged: : " + status); 4471 break; 4472 } 4473 } 4474 }; 4475 4476 4477 /** 4478 * Read mScreenState and apply NFC-C polling and NFC-EE routing 4479 */ applyRouting(boolean force)4480 void applyRouting(boolean force) { 4481 if (DBG) { 4482 Log.d(TAG, "applyRouting"); 4483 } 4484 synchronized (this) { 4485 if (!isNfcEnabledOrShuttingDown()) { 4486 return; 4487 } 4488 if (mNfcOemExtensionCallback != null 4489 && receiveOemCallbackResult(ACTION_ON_APPLY_ROUTING)) { 4490 Log.d(TAG, "applyRouting: skip due to oem callback"); 4491 return; 4492 } 4493 refreshTagDispatcherInProvisionMode(); 4494 if (mPollingPaused) { 4495 Log.d(TAG, "applyRouting: Not updating discovery parameters, polling paused"); 4496 return; 4497 } 4498 // Special case: if we're transitioning to unlocked state while 4499 // still talking to a tag, postpone re-configuration. 4500 if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED && isTagPresent()) { 4501 Log.d(TAG, "applyRouting: Not updating discovery parameters, tag connected"); 4502 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESUME_POLLING), 4503 APPLY_ROUTING_RETRY_TIMEOUT_MS); 4504 return; 4505 } 4506 4507 WatchDogThread watchDog = new WatchDogThread("applyRouting", ROUTING_WATCHDOG_MS); 4508 try { 4509 watchDog.start(); 4510 // Compute new polling parameters 4511 NfcDiscoveryParameters newParams = computeDiscoveryParameters(mScreenState); 4512 if (force || !newParams.equals(mCurrentDiscoveryParameters)) { 4513 if (newParams.shouldEnableDiscovery()) { 4514 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery(); 4515 mDeviceHost.enableDiscovery(newParams, shouldRestart); 4516 } else { 4517 mDeviceHost.disableDiscovery(); 4518 } 4519 mCurrentDiscoveryParameters = newParams; 4520 } else { 4521 Log.d(TAG, "applyRouting: Discovery configuration equal, not updating"); 4522 } 4523 } finally { 4524 watchDog.cancel(); 4525 } 4526 } 4527 } 4528 computeDiscoveryParameters(int screenState)4529 private NfcDiscoveryParameters computeDiscoveryParameters(int screenState) { 4530 // Recompute discovery parameters based on screen state 4531 NfcDiscoveryParameters.Builder paramsBuilder = NfcDiscoveryParameters.newBuilder(); 4532 // Polling 4533 if (screenState >= NFC_POLLING_MODE && isReaderOptionEnabled()) { 4534 // Check if reader-mode is enabled 4535 if (mReaderModeParams != null) { 4536 int techMask = 0; 4537 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_A) != 0) 4538 techMask |= NFC_POLL_A; 4539 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_B) != 0) 4540 techMask |= NFC_POLL_B; 4541 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_F) != 0) 4542 techMask |= NFC_POLL_F; 4543 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_V) != 0) 4544 techMask |= NFC_POLL_V; 4545 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_BARCODE) != 0) 4546 techMask |= NFC_POLL_KOVIO; 4547 4548 paramsBuilder.setTechMask(techMask); 4549 paramsBuilder.setEnableReaderMode(true); 4550 if (mReaderModeParams.flags != 0 && techMask == 0) { 4551 paramsBuilder.setEnableHostRouting(true); 4552 } 4553 } else { 4554 paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT); 4555 } 4556 } else if (screenState == SCREEN_STATE_ON_LOCKED && mInProvisionMode) { 4557 paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT); 4558 } else if (screenState == SCREEN_STATE_ON_LOCKED && 4559 mNfcUnlockManager.isLockscreenPollingEnabled() && isReaderOptionEnabled()) { 4560 int techMask = 0; 4561 if (mNfcUnlockManager.isLockscreenPollingEnabled()) 4562 techMask |= mNfcUnlockManager.getLockscreenPollMask(); 4563 paramsBuilder.setTechMask(techMask); 4564 paramsBuilder.setEnableLowPowerDiscovery(false); 4565 } 4566 if (mReaderModeParams != null && mReaderModeParams.annotation != null) { 4567 paramsBuilder.setTechAPollingLoopAnnotation(mReaderModeParams.annotation); 4568 } 4569 if (mIsHceCapable) { 4570 // Host routing is always enabled, provided we aren't in reader mode 4571 if (mReaderModeParams == null || mReaderModeParams.flags == DISABLE_POLLING_FLAGS) { 4572 paramsBuilder.setEnableHostRouting(true); 4573 } 4574 } 4575 4576 return paramsBuilder.build(); 4577 } 4578 isTagPresent()4579 private boolean isTagPresent() { 4580 for (Object object : mObjectMap.values()) { 4581 if (object instanceof TagEndpoint) { 4582 return ((TagEndpoint) object).isPresent(); 4583 } 4584 } 4585 return false; 4586 } 4587 refreshTagDispatcherInProvisionMode()4588 private void refreshTagDispatcherInProvisionMode() { 4589 if (mInProvisionMode) { 4590 mInProvisionMode = mNfcInjector.isInProvisionMode(); 4591 if (!mInProvisionMode) { 4592 mNfcDispatcher.disableProvisioningMode(); 4593 } 4594 } 4595 } 4596 isPresenceCheckStopped()4597 private boolean isPresenceCheckStopped() { 4598 boolean isStopped = false; 4599 synchronized (this) { 4600 Object[] objectValues = mObjectMap.values().toArray(); 4601 for (Object object : objectValues) { 4602 if (object instanceof TagEndpoint) { 4603 if (((TagEndpoint) object).isPresenceCheckStopped()) { 4604 isStopped = true; 4605 } 4606 } 4607 } 4608 } 4609 return isStopped; 4610 } 4611 4612 /** 4613 * Stops the Presence check thread without calling 4614 * Disconnect API and onTagDisconnect callback 4615 */ prepareForRemovalDetectionMode()4616 private void prepareForRemovalDetectionMode() { 4617 synchronized (this) { 4618 Object[] objectValues = mObjectMap.values().toArray(); 4619 for (Object object : objectValues) { 4620 if (object instanceof TagEndpoint) { 4621 ((TagEndpoint) object).prepareForRemovalDetectionMode(); 4622 } 4623 } 4624 } 4625 } 4626 StopPresenceChecking()4627 private void StopPresenceChecking() { 4628 Object[] objectValues = mObjectMap.values().toArray(); 4629 if (!ArrayUtils.isEmpty(objectValues)) { 4630 // If there are some tags connected, we need to execute the callback to indicate 4631 // the tag is being forcibly disconnected. 4632 executeOemOnTagConnectedCallback(false); 4633 } 4634 for (Object object : objectValues) { 4635 if (object instanceof TagEndpoint) { 4636 TagEndpoint tag = (TagEndpoint)object; 4637 ((TagEndpoint) object).stopPresenceChecking(); 4638 } 4639 } 4640 } 4641 4642 /** 4643 * Disconnect any target if present 4644 */ maybeDisconnectTarget()4645 void maybeDisconnectTarget() { 4646 if (!isNfcEnabledOrShuttingDown()) { 4647 return; 4648 } 4649 clearAppInactivityDetectionContext(); 4650 Object[] objectsToDisconnect; 4651 synchronized (this) { 4652 Object[] objectValues = mObjectMap.values().toArray(); 4653 // Copy the array before we clear mObjectMap, 4654 // just in case the HashMap values are backed by the same array 4655 objectsToDisconnect = Arrays.copyOf(objectValues, objectValues.length); 4656 mObjectMap.clear(); 4657 } 4658 for (Object o : objectsToDisconnect) { 4659 if (DBG) Log.d(TAG, "maybeDisconnectTarget: " + o.getClass().getName()); 4660 if (o instanceof TagEndpoint) { 4661 // Disconnect from tags 4662 TagEndpoint tag = (TagEndpoint) o; 4663 tag.disconnect(); 4664 } 4665 } 4666 } 4667 findObject(int key)4668 Object findObject(int key) { 4669 synchronized (this) { 4670 Object device = mObjectMap.get(key); 4671 if (device == null) { 4672 Log.w(TAG, "maybeDisconnectTarget: Handle not found"); 4673 } 4674 return device; 4675 } 4676 } 4677 findAndRemoveObject(int handle)4678 Object findAndRemoveObject(int handle) { 4679 synchronized (this) { 4680 Object device = mObjectMap.get(handle); 4681 if (device == null) { 4682 Log.w(TAG, "findAndRemoveObject: Handle not found"); 4683 } else { 4684 mObjectMap.remove(handle); 4685 } 4686 return device; 4687 } 4688 } 4689 registerTagObject(TagEndpoint tag)4690 void registerTagObject(TagEndpoint tag) { 4691 synchronized (this) { 4692 mObjectMap.put(tag.getHandle(), tag); 4693 } 4694 } 4695 unregisterObject(int handle)4696 void unregisterObject(int handle) { 4697 synchronized (this) { 4698 mObjectMap.remove(handle); 4699 } 4700 } 4701 getAidRoutingTableSize()4702 public int getAidRoutingTableSize () 4703 { 4704 int aidTableSize = 0x00; 4705 aidTableSize = mDeviceHost.getAidTableSize(); 4706 return aidTableSize; 4707 } 4708 sendMockNdefTag(NdefMessage msg)4709 public void sendMockNdefTag(NdefMessage msg) { 4710 sendMessage(MSG_MOCK_NDEF, msg); 4711 } 4712 routeAids(String aid, int route, int aidInfo, int power)4713 public void routeAids(String aid, int route, int aidInfo, int power) { 4714 Message msg = mHandler.obtainMessage(); 4715 msg.what = MSG_ROUTE_AID; 4716 msg.arg1 = route; 4717 msg.obj = aid; 4718 msg.arg2 = aidInfo; 4719 4720 Bundle aidPowerState = new Bundle(); 4721 aidPowerState.putInt(MSG_ROUTE_AID_PARAM_TAG, power); 4722 msg.setData(aidPowerState); 4723 4724 mHandler.sendMessage(msg); 4725 } 4726 unrouteAids(String aid)4727 public void unrouteAids(String aid) { 4728 sendMessage(MSG_UNROUTE_AID, aid); 4729 } 4730 getNciVersion()4731 public int getNciVersion() { 4732 return mDeviceHost.getNciVersion(); 4733 } 4734 getT3tIdentifierBytes(String systemCode, String nfcId2, String t3tPmm)4735 private byte[] getT3tIdentifierBytes(String systemCode, String nfcId2, String t3tPmm) { 4736 ByteBuffer buffer = ByteBuffer.allocate(2 + 8 + 8); /* systemcode + nfcid2 + t3tpmm */ 4737 buffer.put(hexStringToBytes(systemCode)); 4738 buffer.put(hexStringToBytes(nfcId2)); 4739 buffer.put(hexStringToBytes(t3tPmm)); 4740 byte[] t3tIdBytes = new byte[buffer.position()]; 4741 buffer.position(0); 4742 buffer.get(t3tIdBytes); 4743 4744 return t3tIdBytes; 4745 } 4746 registerT3tIdentifier(String systemCode, String nfcId2, String t3tPmm)4747 public void registerT3tIdentifier(String systemCode, String nfcId2, String t3tPmm) { 4748 Log.d(TAG, "registerT3tIdentifier"); 4749 4750 byte[] t3tIdentifier = getT3tIdentifierBytes(systemCode, nfcId2, t3tPmm); 4751 sendMessage(MSG_REGISTER_T3T_IDENTIFIER, t3tIdentifier); 4752 } 4753 deregisterT3tIdentifier(String systemCode, String nfcId2, String t3tPmm)4754 public void deregisterT3tIdentifier(String systemCode, String nfcId2, String t3tPmm) { 4755 Log.d(TAG, "deregisterT3tIdentifier"); 4756 4757 byte[] t3tIdentifier = getT3tIdentifierBytes(systemCode, nfcId2, t3tPmm); 4758 sendMessage(MSG_DEREGISTER_T3T_IDENTIFIER, t3tIdentifier); 4759 } 4760 clearT3tIdentifiersCache()4761 public void clearT3tIdentifiersCache() { 4762 Log.d(TAG, "clearT3tIdentifiersCache"); 4763 mDeviceHost.clearT3tIdentifiersCache(); 4764 } 4765 getLfT3tMax()4766 public int getLfT3tMax() { 4767 return mDeviceHost.getLfT3tMax(); 4768 } 4769 commitRouting(boolean isOverrideOrRecover)4770 public int commitRouting(boolean isOverrideOrRecover) { 4771 if (!isOverrideOrRecover) { 4772 // Clear the Handler queue, only last commit_msg is relevant 4773 mHandler.removeMessages(MSG_COMMIT_ROUTING); 4774 mHandler.sendEmptyMessage(MSG_COMMIT_ROUTING); 4775 return STATUS_OK; 4776 } 4777 mCommitRoutingCountDownLatch = new CountDownLatch(1); 4778 mHandler.sendEmptyMessage(MSG_COMMIT_ROUTING); 4779 try { 4780 boolean success = mCommitRoutingCountDownLatch 4781 .await(WAIT_FOR_COMMIT_ROUTING_TIMEOUT_MS, TimeUnit.MILLISECONDS); 4782 if (!success) { 4783 Log.e(TAG, "commitRouting: timed out!"); 4784 return STATUS_UNKNOWN_ERROR; 4785 } else { 4786 Log.i(TAG, "commitRouting: status= " + mCommitRoutingStatus); 4787 return mCommitRoutingStatus; 4788 } 4789 } catch (InterruptedException e) { 4790 return STATUS_UNKNOWN_ERROR; 4791 } finally { 4792 mCommitRoutingCountDownLatch = null; 4793 } 4794 } 4795 sendScreenMessageAfterNfcCharging()4796 public boolean sendScreenMessageAfterNfcCharging() { 4797 if (DBG) Log.d(TAG, "sendScreenMessageAfterNfcCharging"); 4798 4799 if (mPendingPowerStateUpdate == true) { 4800 int screenState = mScreenStateHelper.checkScreenState(mCheckDisplayStateForScreenState); 4801 if (DBG) { 4802 Log.d(TAG, "sendScreenMessageAfterNfcCharging: applying postponed screen state " 4803 + screenState); 4804 } 4805 NfcService.getInstance().sendMessage(MSG_APPLY_SCREEN_STATE, screenState); 4806 mPendingPowerStateUpdate = false; 4807 return true; 4808 } 4809 return false; 4810 } 4811 4812 /** 4813 * get default T4TNfcee power state supported 4814 */ getT4tNfceePowerState()4815 private int getT4tNfceePowerState() { 4816 int powerState = mDeviceHost.getT4TNfceePowerState(); 4817 synchronized (NfcService.this) { 4818 if (mIsSecureNfcEnabled) { 4819 /* Secure nfc on,Setting power state screen on unlocked */ 4820 powerState = POWER_STATE_SWITCH_ON; 4821 } 4822 } 4823 if (DBG) Log.d(TAG, "T4TNfceePowerState: " + powerState); 4824 return powerState; 4825 } 4826 4827 /** 4828 * get info on NDEF-NFCEE feature from HAL config file 4829 */ isNdefNfceefeatureEnabled()4830 public boolean isNdefNfceefeatureEnabled() { 4831 return mDeviceHost.isNdefNfceefeatureEnabled(); 4832 } 4833 sendData(byte[] data)4834 public boolean sendData(byte[] data) { 4835 notifyOemLogEvent(new OemLogItems.Builder(OemLogItems.LOG_ACTION_HCE_DATA) 4836 .setApduResponse(data).build()); 4837 return mDeviceHost.sendRawFrame(data); 4838 } 4839 onPreferredPaymentChanged(int reason)4840 public void onPreferredPaymentChanged(int reason) { 4841 sendMessage(MSG_PREFERRED_PAYMENT_CHANGED, reason); 4842 } 4843 onPreferredSimChanged()4844 public void onPreferredSimChanged() { 4845 mHandler.sendEmptyMessage(MSG_PREFERRED_SIM_CHANGED); 4846 } 4847 clearRoutingTable(int clearFlags)4848 public void clearRoutingTable(int clearFlags) { 4849 //Remove any previously sent messages not yet processed 4850 mHandler.removeMessages(MSG_COMMIT_ROUTING); 4851 mHandler.removeMessages(MSG_ROUTE_AID); 4852 mHandler.removeMessages(MSG_CLEAR_ROUTING_TABLE); 4853 mHandler.removeMessages(MSG_UNROUTE_AID); 4854 sendMessage(MSG_CLEAR_ROUTING_TABLE, clearFlags); 4855 } 4856 setIsoDepProtocolRoute(int route)4857 public void setIsoDepProtocolRoute(int route) { 4858 sendMessage(MSG_UPDATE_ISODEP_PROTOCOL_ROUTE, route); 4859 } 4860 4861 /** 4862 * Set NFCC technology routing for ABF listening 4863 */ setTechnologyABFRoute(int route, int felicaRoute)4864 public void setTechnologyABFRoute(int route, int felicaRoute) { 4865 Message msg = mHandler.obtainMessage(); 4866 msg.what = MSG_UPDATE_TECHNOLOGY_ABF_ROUTE; 4867 msg.arg1 = route; 4868 msg.arg2 = felicaRoute; 4869 mHandler.sendMessage(msg); 4870 } 4871 setSystemCodeRoute(int route)4872 public void setSystemCodeRoute(int route) { 4873 sendMessage(MSG_UPDATE_SYSTEM_CODE_ROUTE, route); 4874 } 4875 sendMessage(int what, Object obj)4876 void sendMessage(int what, Object obj) { 4877 Message msg = mHandler.obtainMessage(); 4878 msg.what = what; 4879 msg.obj = obj; 4880 mHandler.sendMessage(msg); 4881 } 4882 4883 /** 4884 * Send require device unlock for NFC intent to system UI. 4885 */ sendRequireUnlockIntent()4886 public void sendRequireUnlockIntent() { 4887 if (!mIsRequestUnlockShowed && mNfcInjector.isDeviceLocked()) { 4888 if (DBG) Log.d(TAG, "sendRequireUnlockIntent"); 4889 mIsRequestUnlockShowed = true; 4890 mRequireUnlockWakeLock.acquire(); 4891 Intent requireUnlockIntent = 4892 new Intent(NfcAdapter.ACTION_REQUIRE_UNLOCK_FOR_NFC); 4893 requireUnlockIntent.setPackage(SYSTEM_UI); 4894 mContext.sendBroadcast(requireUnlockIntent); 4895 mRequireUnlockWakeLock.release(); 4896 } 4897 } 4898 4899 final class NfcServiceHandler extends Handler { NfcServiceHandler(Looper looper)4900 public NfcServiceHandler(Looper looper) { 4901 super(looper); 4902 } 4903 4904 @Override handleMessage(Message msg)4905 public void handleMessage(Message msg) { 4906 switch (msg.what) { 4907 case MSG_ROUTE_AID: { 4908 Log.d(TAG, "handleMessage: MSG_ROUTE_AID"); 4909 int route = msg.arg1; 4910 int aidInfo = msg.arg2; 4911 String aid = (String) msg.obj; 4912 4913 int power = 0x00; 4914 Bundle bundle = msg.getData(); 4915 if (bundle != null) { 4916 power = bundle.getInt(MSG_ROUTE_AID_PARAM_TAG); 4917 } 4918 4919 mDeviceHost.routeAid(hexStringToBytes(aid), route, aidInfo, power); 4920 // Restart polling config 4921 break; 4922 } 4923 case MSG_UNROUTE_AID: { 4924 Log.d(TAG, "handleMessage: MSG_UNROUTE_AID"); 4925 String aid = (String) msg.obj; 4926 mDeviceHost.unrouteAid(hexStringToBytes(aid)); 4927 break; 4928 } 4929 case MSG_REGISTER_T3T_IDENTIFIER: { 4930 Log.d(TAG, "handleMessage: MSG_REGISTER_T3T_IDENTIFIER"); 4931 mDeviceHost.disableDiscovery(); 4932 4933 byte[] t3tIdentifier = (byte[]) msg.obj; 4934 mDeviceHost.registerT3tIdentifier(t3tIdentifier); 4935 4936 NfcDiscoveryParameters params = computeDiscoveryParameters(mScreenState); 4937 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery(); 4938 mDeviceHost.enableDiscovery(params, shouldRestart); 4939 break; 4940 } 4941 case MSG_DEREGISTER_T3T_IDENTIFIER: { 4942 Log.d(TAG, "handleMessage: MSG_DEREGISTER_T3T_IDENTIFIER"); 4943 mDeviceHost.disableDiscovery(); 4944 4945 byte[] t3tIdentifier = (byte[]) msg.obj; 4946 mDeviceHost.deregisterT3tIdentifier(t3tIdentifier); 4947 4948 NfcDiscoveryParameters params = computeDiscoveryParameters(mScreenState); 4949 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery(); 4950 mDeviceHost.enableDiscovery(params, shouldRestart); 4951 break; 4952 } 4953 case MSG_COMMIT_ROUTING: { 4954 Log.d(TAG, "handleMessage: MSG_COMMIT_ROUTING"); 4955 synchronized (NfcService.this) { 4956 if (isNfcDisabledOrDisabling()) { 4957 Log.d(TAG, "handleMessage: Skip commit routing when NFCC is off " 4958 + "or turning off"); 4959 if (mCommitRoutingCountDownLatch != null) { 4960 mCommitRoutingStatus = STATUS_UNKNOWN_ERROR; 4961 mCommitRoutingCountDownLatch.countDown(); 4962 } 4963 return; 4964 } 4965 if (mCurrentDiscoveryParameters.shouldEnableDiscovery()) { 4966 if (mNfcOemExtensionCallback != null) { 4967 if (receiveOemCallbackResult(ACTION_ON_ROUTING_CHANGED)) { 4968 Log.e(TAG, "handleMessage: Oem skip commitRouting"); 4969 if (mCommitRoutingCountDownLatch != null) { 4970 mCommitRoutingStatus = STATUS_UNKNOWN_ERROR; 4971 mCommitRoutingCountDownLatch.countDown(); 4972 } 4973 return; 4974 } 4975 } 4976 mCommitRoutingStatus = mDeviceHost.commitRouting(); 4977 if (mCommitRoutingCountDownLatch != null) { 4978 mCommitRoutingCountDownLatch.countDown(); 4979 } 4980 } else { 4981 Log.d(TAG, 4982 "handleMessage: Not committing routing because " 4983 + "discovery is disabled"); 4984 } 4985 } 4986 break; 4987 } 4988 case MSG_MOCK_NDEF: { 4989 Log.d(TAG, "handleMessage: MSG_MOCK_NDEF"); 4990 NdefMessage ndefMsg = (NdefMessage) msg.obj; 4991 Bundle extras = new Bundle(); 4992 extras.putParcelable(Ndef.EXTRA_NDEF_MSG, ndefMsg); 4993 extras.putInt(Ndef.EXTRA_NDEF_MAXLENGTH, 0); 4994 extras.putInt(Ndef.EXTRA_NDEF_CARDSTATE, Ndef.NDEF_MODE_READ_ONLY); 4995 extras.putInt(Ndef.EXTRA_NDEF_TYPE, Ndef.TYPE_OTHER); 4996 /* Avoid setting mCookieUpToDate to negative values */ 4997 mCookieUpToDate = mCookieGenerator.nextLong() >>> 1; 4998 Tag tag = Tag.createMockTag(new byte[]{0x00}, 4999 new int[]{TagTechnology.NDEF}, 5000 new Bundle[]{extras}, mCookieUpToDate); 5001 Log.d(TAG, "handleMessage: mock NDEF tag, starting corresponding activity"); 5002 Log.d(TAG, tag.toString()); 5003 int dispatchStatus = mNfcDispatcher.dispatchTag(tag); 5004 if (dispatchStatus == NfcDispatcher.DISPATCH_SUCCESS) { 5005 playSound(SOUND_END); 5006 } else if (dispatchStatus == NfcDispatcher.DISPATCH_FAIL) { 5007 playSound(SOUND_ERROR); 5008 } 5009 break; 5010 } 5011 5012 case MSG_NDEF_TAG: 5013 if (!isNfcEnabled()) 5014 break; 5015 if (DBG) Log.d(TAG, "Tag detected, notifying applications"); 5016 5017 clearAppInactivityDetectionContext(); 5018 5019 TagEndpoint tag = (TagEndpoint) msg.obj; 5020 byte[] debounceTagUid; 5021 int debounceTagMs; 5022 ITagRemovedCallback debounceTagRemovedCallback; 5023 synchronized (NfcService.this) { 5024 debounceTagUid = mDebounceTagUid; 5025 debounceTagMs = mDebounceTagDebounceMs; 5026 debounceTagRemovedCallback = mDebounceTagRemovedCallback; 5027 } 5028 ReaderModeParams readerParams = null; 5029 int presenceCheckDelay = DEFAULT_PRESENCE_CHECK_DELAY; 5030 DeviceHost.TagDisconnectedCallback callback = 5031 new DeviceHost.TagDisconnectedCallback() { 5032 @Override 5033 public void onTagDisconnected() { 5034 mCookieUpToDate = -1; 5035 clearAppInactivityDetectionContext(); 5036 executeOemOnTagConnectedCallback(false); 5037 applyRouting(false); 5038 } 5039 }; 5040 synchronized (NfcService.this) { 5041 readerParams = mReaderModeParams; 5042 } 5043 executeOemOnTagConnectedCallback(true); 5044 if (mNfcOemExtensionCallback != null 5045 && receiveOemCallbackResult(ACTION_ON_READ_NDEF)) { 5046 Log.d(TAG, "handleMessage: skip due to oem callback"); 5047 tag.startPresenceChecking(presenceCheckDelay, callback); 5048 break; 5049 } 5050 if (readerParams != null) { 5051 presenceCheckDelay = readerParams.presenceCheckDelay; 5052 if ((readerParams.flags & NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK) != 0) { 5053 if (DBG) { 5054 Log.d(TAG, "handleMessage: Skipping NDEF detection in reader mode"); 5055 } 5056 tag.startPresenceChecking(presenceCheckDelay, callback); 5057 dispatchTagEndpoint(tag, readerParams); 5058 break; 5059 } 5060 5061 if (mIsDebugBuild && mSkipNdefRead) { 5062 if (DBG) { 5063 Log.d(TAG, "handleMessage: Only NDEF detection in reader mode"); 5064 } 5065 tag.findNdef(); 5066 tag.startPresenceChecking(presenceCheckDelay, callback); 5067 dispatchTagEndpoint(tag, readerParams); 5068 break; 5069 } 5070 } 5071 5072 if (tag.getConnectedTechnology() == TagTechnology.NFC_BARCODE) { 5073 // When these tags start containing NDEF, they will require 5074 // the stack to deal with them in a different way, since 5075 // they are activated only really shortly. 5076 // For now, don't consider NDEF on these. 5077 if (DBG) { 5078 Log.d(TAG, "handleMessage: Skipping NDEF detection for NFC Barcode"); 5079 } 5080 tag.startPresenceChecking(presenceCheckDelay, callback); 5081 dispatchTagEndpoint(tag, readerParams); 5082 if (readerParams == null) { 5083 scheduleAppInactivityDetectionTask(); 5084 } 5085 break; 5086 } 5087 NdefMessage ndefMsg = tag.findAndReadNdef(); 5088 5089 if (ndefMsg == null) { 5090 // First try to see if this was a bad tag read 5091 if (!tag.reconnect()) { 5092 tag.disconnect(); 5093 if (DBG) Log.d(TAG, "handleMessage: Read NDEF error"); 5094 executeOemOnTagConnectedCallback(false); 5095 if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) { 5096 if (mReadErrorCount < mReadErrorCountMax) { 5097 mReadErrorCount++; 5098 } else { 5099 pollingDelay(); 5100 } 5101 if (!sToast_debounce && mNotifyReadFailed) { 5102 Toast.makeText(mContext, R.string.tag_read_error, 5103 Toast.LENGTH_SHORT).show(); 5104 sToast_debounce = true; 5105 mHandler.sendEmptyMessageDelayed(MSG_TOAST_DEBOUNCE_EVENT, 5106 sToast_debounce_time_ms); 5107 } 5108 } 5109 break; 5110 } 5111 } 5112 5113 if (debounceTagUid != null) { 5114 // If we're debouncing and the UID or the NDEF message of the tag match, 5115 // don't dispatch but drop it. 5116 if (Arrays.equals(debounceTagUid, tag.getUid()) || 5117 (ndefMsg != null && ndefMsg.equals(mLastReadNdefMessage))) { 5118 mHandler.removeMessages(MSG_TAG_DEBOUNCE); 5119 mHandler.sendEmptyMessageDelayed(MSG_TAG_DEBOUNCE, debounceTagMs); 5120 tag.disconnect(); 5121 return; 5122 } else { 5123 synchronized (NfcService.this) { 5124 mDebounceTagUid = null; 5125 mDebounceTagRemovedCallback = null; 5126 mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE; 5127 } 5128 if (debounceTagRemovedCallback != null) { 5129 try { 5130 debounceTagRemovedCallback.onTagRemoved(); 5131 } catch (RemoteException e) { 5132 // Ignore 5133 } 5134 } 5135 } 5136 } 5137 5138 mLastReadNdefMessage = ndefMsg; 5139 5140 if (mIsWlcEnabled) { 5141 if (DBG) Log.d(TAG, "handleMessage: Wlc enabled, check for WLC_CAP record"); 5142 5143 if (!mNfcCharging.NfcChargingMode 5144 && (mNfcCharging.checkWlcCapMsg(ndefMsg) == true)) { 5145 if (DBG) Log.d(TAG, "handleMessage: checkWlcCapMsg returned true"); 5146 if (mNfcCharging.startNfcCharging(tag)) { 5147 mNfcCharging.NfcChargingMode = true; 5148 if (DBG) { 5149 Log.d(TAG, 5150 "handleMessage: " 5151 + "Nfc charging mode started successfully"); 5152 } 5153 } else { 5154 if (DBG) { 5155 Log.d(TAG, 5156 "handleMessage: Nfc charging mode not detected"); 5157 } 5158 } 5159 } else if (mIsRWCapable) { 5160 tag.startPresenceChecking(presenceCheckDelay, callback); 5161 dispatchTagEndpoint(tag, readerParams); 5162 } else { 5163 tag.startPresenceChecking(presenceCheckDelay, callback); 5164 } 5165 } else if (mIsRWCapable) { 5166 tag.startPresenceChecking(presenceCheckDelay, callback); 5167 dispatchTagEndpoint(tag, readerParams); 5168 } else { 5169 tag.startPresenceChecking(presenceCheckDelay, callback); 5170 } 5171 if (readerParams == null) { 5172 scheduleAppInactivityDetectionTask(); 5173 } 5174 break; 5175 5176 case MSG_RF_FIELD_ACTIVATED: 5177 Log.d(TAG, "handleMessage: MSG_RF_FIELD_ACTIVATED"); 5178 notifyOemLogEvent(new OemLogItems 5179 .Builder(OemLogItems.LOG_ACTION_RF_FIELD_STATE_CHANGED) 5180 .setRfFieldOnTime(Instant.now()).build()); 5181 if (mCardEmulationManager != null) { 5182 mCardEmulationManager.onFieldChangeDetected(true); 5183 } 5184 Intent fieldOnIntent = new Intent(ACTION_RF_FIELD_ON_DETECTED); 5185 sendNfcPermissionProtectedBroadcast(fieldOnIntent); 5186 if (mIsSecureNfcEnabled) { 5187 sendRequireUnlockIntent(); 5188 } 5189 break; 5190 case MSG_RF_FIELD_DEACTIVATED: 5191 Log.d(TAG, "handleMessage: MSG_RF_FIELD_DEACTIVATED"); 5192 notifyOemLogEvent(new OemLogItems 5193 .Builder(OemLogItems.LOG_ACTION_RF_FIELD_STATE_CHANGED) 5194 .setRfFieldOnTime(Instant.now()).build()); 5195 if (mCardEmulationManager != null) { 5196 mCardEmulationManager.onFieldChangeDetected(false); 5197 } 5198 Intent fieldOffIntent = new Intent(ACTION_RF_FIELD_OFF_DETECTED); 5199 sendNfcPermissionProtectedBroadcast(fieldOffIntent); 5200 break; 5201 case MSG_RESUME_POLLING: 5202 Log.d(TAG, "handleMessage: MSG_RESUME_POLLING"); 5203 mNfcAdapter.resumePolling(); 5204 break; 5205 case MSG_TAG_DEBOUNCE: 5206 Log.d(TAG, "handleMessage: MSG_TAG_DEBOUNCE"); 5207 // Didn't see the tag again, tag is gone 5208 ITagRemovedCallback tagRemovedCallback; 5209 synchronized (NfcService.this) { 5210 mDebounceTagUid = null; 5211 tagRemovedCallback = mDebounceTagRemovedCallback; 5212 mDebounceTagRemovedCallback = null; 5213 mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE; 5214 } 5215 if (tagRemovedCallback != null) { 5216 try { 5217 tagRemovedCallback.onTagRemoved(); 5218 } catch (RemoteException e) { 5219 // Ignore 5220 } 5221 } 5222 break; 5223 5224 case MSG_APPLY_SCREEN_STATE: 5225 mScreenState = (Integer)msg.obj; 5226 Log.d(TAG, "handleMessage: MSG_APPLY_SCREEN_STATE" 5227 + ScreenStateHelper.screenStateToString(mScreenState)); 5228 5229 synchronized (NfcService.this) { 5230 // Disable delay polling when screen state changed 5231 mPollDelayed = false; 5232 mHandler.removeMessages(MSG_DELAY_POLLING); 5233 // If NFC is turning off, we shouldn't need any changes here 5234 if (mState == NfcAdapter.STATE_TURNING_OFF) 5235 return; 5236 } 5237 notifyOemLogEvent( 5238 new OemLogItems.Builder(OemLogItems.LOG_ACTION_SCREEN_STATE_CHANGED) 5239 .build()); 5240 5241 mRoutingWakeLock.acquire(); 5242 try { 5243 if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) { 5244 applyRouting(false); 5245 mIsRequestUnlockShowed = false; 5246 } 5247 int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) 5248 ? (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : 5249 mScreenState; 5250 5251 if (mNfcUnlockManager.isLockscreenPollingEnabled()) { 5252 applyRouting(false); 5253 } 5254 5255 mDeviceHost.doSetScreenState(screen_state_mask, mIsWlcEnabled); 5256 } finally { 5257 if (mRoutingWakeLock.isHeld()) { 5258 mRoutingWakeLock.release(); 5259 } 5260 } 5261 break; 5262 5263 case MSG_TRANSACTION_EVENT: 5264 Log.d(TAG, "handleMessage: MSG_TRANSACTION_EVENT"); 5265 if (mCardEmulationManager != null) { 5266 mCardEmulationManager.onOffHostAidSelected(); 5267 } 5268 byte[][] data = (byte[][]) msg.obj; 5269 synchronized (NfcService.this) { 5270 sendOffHostTransactionEvent(data[0], data[1], data[2]); 5271 } 5272 break; 5273 5274 case MSG_SE_SELECTED_EVENT: 5275 Log.d(TAG, "handleMessage: MSG_SE_SELECTED_EVENT"); 5276 int type = (int) msg.obj; 5277 if (mCardEmulationManager != null && type == SE_SELECTED_AID) { 5278 mCardEmulationManager.onOffHostAidSelected(); 5279 } 5280 break; 5281 case MSG_PREFERRED_PAYMENT_CHANGED: 5282 Log.d(TAG, "handleMessage: MSG_PREFERRED_PAYMENT_CHANGED"); 5283 Intent preferredPaymentChangedIntent = 5284 new Intent(NfcAdapter.ACTION_PREFERRED_PAYMENT_CHANGED); 5285 preferredPaymentChangedIntent.putExtra( 5286 NfcAdapter.EXTRA_PREFERRED_PAYMENT_CHANGED_REASON, (int)msg.obj); 5287 sendPreferredPaymentChangedEvent(preferredPaymentChangedIntent); 5288 break; 5289 5290 case MSG_TOAST_DEBOUNCE_EVENT: 5291 Log.d(TAG, "handleMessage: MSG_TOAST_DEBOUNCE_EVENT"); 5292 sToast_debounce = false; 5293 break; 5294 5295 case MSG_DELAY_POLLING: 5296 Log.d(TAG, "handleMessage: MSG_DELAY_POLLING"); 5297 synchronized (NfcService.this) { 5298 if (!mPollDelayed) { 5299 return; 5300 } 5301 mPollDelayed = false; 5302 mDeviceHost.startStopPolling(true); 5303 } 5304 if (DBG) Log.d(TAG, "handleMessage: Polling is started"); 5305 break; 5306 case MSG_CLEAR_ROUTING_TABLE: 5307 if (!isNfcEnabled()) break; 5308 Log.d(TAG, "handleMessage: MSG_CLEAR_ROUTING_TABLE"); 5309 int clearFlags = (Integer)msg.obj; 5310 mDeviceHost.clearRoutingEntry(clearFlags); 5311 break; 5312 case MSG_UPDATE_ISODEP_PROTOCOL_ROUTE: 5313 Log.d(TAG, "handleMessage: MSG_UPDATE_ISODEP_PROTOCOL_ROUTE"); 5314 if (isNfcEnabled()) { 5315 mDeviceHost.setIsoDepProtocolRoute((Integer) msg.obj); 5316 } 5317 break; 5318 case MSG_UPDATE_TECHNOLOGY_ABF_ROUTE: 5319 Log.d(TAG, "handleMessage: MSG_UPDATE_TECHNOLOGY_ABF_ROUTE"); 5320 int msgRoute = msg.arg1; 5321 int felicaRoute = msg.arg2; 5322 if (isNfcEnabled()) { 5323 mDeviceHost.setTechnologyABFRoute(msgRoute, felicaRoute); 5324 } 5325 break; 5326 case MSG_WATCHDOG_PING: 5327 Log.d(TAG, "handleMessage: MSG_WATCHDOG_PING"); 5328 NfcWatchdog watchdog = (NfcWatchdog) msg.obj; 5329 watchdog.notifyHasReturned(); 5330 if (mLastFieldOnTimestamp + TIME_TO_MONITOR_AFTER_FIELD_ON_MS > 5331 mNfcInjector.getWallClockMillis()) { 5332 watchdog.stopMonitoring(); 5333 } 5334 break; 5335 case MSG_UPDATE_SYSTEM_CODE_ROUTE: 5336 Log.d(TAG, "handleMessage: MSG_UPDATE_SYSTEM_CODE_ROUTE"); 5337 mDeviceHost.setSystemCodeRoute((Integer) msg.obj); 5338 break; 5339 5340 case MSG_PREFERRED_SIM_CHANGED: 5341 if (!isNfcEnabled()) break; 5342 Log.d(TAG, "handleMessage: MSG_PREFERRED_SIM_CHANGED"); 5343 new EnableDisableTask().execute(TASK_DISABLE); 5344 new EnableDisableTask().execute(TASK_ENABLE); 5345 break; 5346 case MSG_RESTART_DISCOVERY: 5347 Log.d(TAG, "handleMessage: MSG_RESTART_DISCOVERY"); 5348 mDeviceHost.restartRfDiscovery(); 5349 break; 5350 default: 5351 Log.e(TAG, "handleMessage: Unknown message received"); 5352 break; 5353 } 5354 } 5355 sendOffHostTransactionEvent(byte[] aid, byte[] data, byte[] readerByteArray)5356 private void sendOffHostTransactionEvent(byte[] aid, byte[] data, byte[] readerByteArray) { 5357 String reader = ""; 5358 int uid = -1; 5359 int offhostCategory = NfcStatsLog.NFC_CARDEMULATION_OCCURRED__CATEGORY__OFFHOST; 5360 try { 5361 StringBuilder aidString = new StringBuilder(aid.length); 5362 for (byte b : aid) { 5363 aidString.append(String.format("%02X", b)); 5364 } 5365 5366 String aidCategory = mCardEmulationManager 5367 .getRegisteredAidCategory(aidString.toString()); 5368 if (DBG) { 5369 Log.d(TAG, "sendOffHostTransactionEvent: aid category=" + aidCategory); 5370 } 5371 if (mStatsdUtils != null) { 5372 mStatsdUtils.setCardEmulationEventCategory(aidCategory); 5373 } else { 5374 switch (aidCategory) { 5375 case CardEmulation.CATEGORY_PAYMENT: 5376 offhostCategory = NfcStatsLog 5377 .NFC_CARDEMULATION_OCCURRED__CATEGORY__OFFHOST_PAYMENT; 5378 break; 5379 case CardEmulation.CATEGORY_OTHER: 5380 offhostCategory = NfcStatsLog 5381 .NFC_CARDEMULATION_OCCURRED__CATEGORY__OFFHOST_OTHER; 5382 break; 5383 default: 5384 offhostCategory = NfcStatsLog 5385 .NFC_CARDEMULATION_OCCURRED__CATEGORY__OFFHOST; 5386 }; 5387 } 5388 5389 reader = new String(readerByteArray, "UTF-8"); 5390 5391 if (!isSEServiceAvailable() || mNfcEventInstalledPackages.isEmpty()) { 5392 return; 5393 } 5394 5395 for (int userId : mNfcEventInstalledPackages.keySet()) { 5396 List<String> packagesOfUser = mNfcEventInstalledPackages.get(userId); 5397 String[] installedPackages = new String[packagesOfUser.size()]; 5398 boolean[] nfcAccess = mSEService.isNfcEventAllowed(reader, aid, 5399 packagesOfUser.toArray(installedPackages), userId); 5400 if (nfcAccess == null) { 5401 continue; 5402 } 5403 Intent intent = new Intent(NfcAdapter.ACTION_TRANSACTION_DETECTED); 5404 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 5405 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 5406 intent.putExtra(NfcAdapter.EXTRA_AID, aid); 5407 intent.putExtra(NfcAdapter.EXTRA_DATA, data); 5408 intent.putExtra(NfcAdapter.EXTRA_SECURE_ELEMENT_NAME, reader); 5409 String url = 5410 new String("nfc://secure:0/" + reader + "/" + aidString.toString()); 5411 intent.setData(Uri.parse(url)); 5412 5413 final BroadcastOptions options = BroadcastOptions.makeBasic(); 5414 options.setBackgroundActivityStartsAllowed(true); 5415 5416 Map<String, Integer> hasIntentPackages = mContext 5417 .getPackageManager() 5418 .queryBroadcastReceiversAsUser(intent, 0, UserHandle.of(userId)) 5419 .stream() 5420 .collect(Collectors.toMap( 5421 activity -> activity.activityInfo.applicationInfo.packageName, 5422 activity -> activity.activityInfo.applicationInfo.uid, 5423 (packageName1, packageName2) -> { 5424 if (DBG) { 5425 Log.d(TAG, 5426 "sendOffHostTransactionEvent: " 5427 + "queryBroadcastReceiversAsUser" 5428 + " duplicate: " + packageName1 + ", " 5429 + packageName2); 5430 } 5431 return packageName1; 5432 })); 5433 if (DBG) { 5434 String[] packageNames = hasIntentPackages 5435 .keySet().toArray(new String[hasIntentPackages.size()]); 5436 Log.d(TAG, "sendOffHostTransactionEvent: queryBroadcastReceiversAsUser: " 5437 + Arrays.toString(packageNames)); 5438 } 5439 5440 boolean foundFirstPackage = false; 5441 for (int i = 0; i < nfcAccess.length; i++) { 5442 if (nfcAccess[i]) { 5443 String packageName = packagesOfUser.get(i); 5444 if (DBG) { 5445 Log.d(TAG, "sendOffHostTransactionEvent: to " + packageName); 5446 } 5447 if (!foundFirstPackage && hasIntentPackages.containsKey(packageName)) { 5448 uid = hasIntentPackages.get(packageName); 5449 if (mStatsdUtils != null) { 5450 mStatsdUtils.setCardEmulationEventUid(uid); 5451 } 5452 foundFirstPackage = true; 5453 } 5454 intent.setPackage(packagesOfUser.get(i)); 5455 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId), null, 5456 options.toBundle()); 5457 } 5458 } 5459 } 5460 } catch (RemoteException e) { 5461 Log.e(TAG, "sendOffHostTransactionEvent: Error in isNfcEventAllowed() " + e); 5462 } catch (UnsupportedEncodingException e) { 5463 Log.e(TAG, "sendOffHostTransactionEvent: Incorrect format for Secure Element name" 5464 + e); 5465 } catch (IllegalArgumentException e) { 5466 Log.e(TAG, "sendOffHostTransactionEvent: Error " + e); 5467 } finally { 5468 if (mStatsdUtils != null) { 5469 mStatsdUtils.logCardEmulationOffhostEvent(reader); 5470 } else { 5471 NfcStatsLog.write(NfcStatsLog.NFC_CARDEMULATION_OCCURRED, 5472 offhostCategory, 5473 reader, 5474 uid); 5475 } 5476 } 5477 } 5478 sendNfcPermissionProtectedBroadcast(Intent intent)5479 private void sendNfcPermissionProtectedBroadcast(Intent intent) { 5480 if (mNfcEventInstalledPackages.isEmpty()) { 5481 return; 5482 } 5483 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 5484 for (int userId : mNfcEventInstalledPackages.keySet()) { 5485 for (String packageName : mNfcEventInstalledPackages.get(userId)) { 5486 intent.setPackage(packageName); 5487 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); 5488 } 5489 } 5490 } 5491 5492 /* Returns the list of packages request for nfc preferred payment service changed and 5493 * have access to NFC Events on any SE */ getNfcPreferredPaymentChangedSEAccessAllowedPackages(int userId)5494 private ArrayList<String> getNfcPreferredPaymentChangedSEAccessAllowedPackages(int userId) { 5495 synchronized (NfcService.this) { 5496 if (!isSEServiceAvailable() 5497 || mNfcPreferredPaymentChangedInstalledPackages.get(userId).isEmpty()) { 5498 return null; 5499 } 5500 String[] readers = null; 5501 try { 5502 readers = mSEService.getReaders(); 5503 } catch (RemoteException e) { 5504 Log.e(TAG, 5505 "getNfcPreferredPaymentChangedSEAccessAllowedPackages: " 5506 + "Error in getReaders() " 5507 + e); 5508 return null; 5509 } 5510 5511 if (readers == null || readers.length == 0) { 5512 return null; 5513 } 5514 boolean[] nfcAccessFinal = null; 5515 List<String> packagesOfUser = 5516 mNfcPreferredPaymentChangedInstalledPackages.get(userId); 5517 String[] installedPackages = new String[packagesOfUser.size()]; 5518 5519 for (String reader : readers) { 5520 try { 5521 boolean[] accessList = mSEService.isNfcEventAllowed(reader, null, 5522 packagesOfUser.toArray(installedPackages), userId 5523 ); 5524 if (accessList == null) { 5525 continue; 5526 } 5527 if (nfcAccessFinal == null) { 5528 nfcAccessFinal = accessList; 5529 } 5530 for (int i = 0; i < accessList.length; i++) { 5531 if (accessList[i]) { 5532 nfcAccessFinal[i] = true; 5533 } 5534 } 5535 } catch (RemoteException e) { 5536 Log.e(TAG, "getNfcPreferredPaymentChangedSEAccessAllowedPackages: " 5537 + "Error in isNfcEventAllowed() " + e); 5538 } catch (IllegalArgumentException e) { 5539 Log.e(TAG, 5540 "getNfcPreferredPaymentChangedSEAccessAllowedPackages: Error " + e); 5541 } 5542 } 5543 if (nfcAccessFinal == null) { 5544 return null; 5545 } 5546 ArrayList<String> packages = new ArrayList<String>(); 5547 for (int i = 0; i < nfcAccessFinal.length; i++) { 5548 if (nfcAccessFinal[i]) { 5549 packages.add(packagesOfUser.get(i)); 5550 } 5551 } 5552 return packages; 5553 } 5554 } 5555 isSystemApp(ApplicationInfo applicationInfo)5556 private boolean isSystemApp(ApplicationInfo applicationInfo) { 5557 return ((applicationInfo.flags & APP_INFO_FLAGS_SYSTEM_APP) != 0); 5558 } 5559 sendPreferredPaymentChangedEvent(Intent intent)5560 private void sendPreferredPaymentChangedEvent(Intent intent) { 5561 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 5562 // Resume app switches so the receivers can start activities without delay 5563 mNfcDispatcher.resumeAppSwitches(); 5564 synchronized (this) { 5565 for (int userId : mNfcPreferredPaymentChangedInstalledPackages.keySet()) { 5566 ArrayList<String> SEPackages = 5567 getNfcPreferredPaymentChangedSEAccessAllowedPackages(userId); 5568 UserHandle userHandle = UserHandle.of(userId); 5569 if (SEPackages != null && !SEPackages.isEmpty()) { 5570 for (String packageName : SEPackages) { 5571 intent.setPackage(packageName); 5572 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 5573 mContext.sendBroadcastAsUser(intent, userHandle); 5574 } 5575 } 5576 PackageManager pm; 5577 try { 5578 pm = mContext.createContextAsUser(userHandle, /*flags=*/0) 5579 .getPackageManager(); 5580 } catch (IllegalStateException e) { 5581 Log.d(TAG, 5582 "sendPreferredPaymentChangedEvent: " 5583 + "Fail to get PackageManager for user: " 5584 + userHandle); 5585 continue; 5586 } 5587 for (String pkgName : 5588 mNfcPreferredPaymentChangedInstalledPackages.get(userId)) { 5589 try { 5590 PackageInfo info = pm.getPackageInfo(pkgName, 0); 5591 if (SEPackages != null && SEPackages.contains(pkgName)) { 5592 continue; 5593 } 5594 if (info.applicationInfo != null 5595 && (isSystemApp(info.applicationInfo) 5596 || info.applicationInfo.isPrivilegedApp())) { 5597 intent.setPackage(pkgName); 5598 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 5599 mContext.sendBroadcastAsUser(intent, userHandle); 5600 } 5601 } catch (Exception e) { 5602 Log.e(TAG, 5603 "sendPreferredPaymentChangedEvent: Exception in getPackageInfo " 5604 + e); 5605 } 5606 } 5607 } 5608 } 5609 } 5610 pollingDelay()5611 private void pollingDelay() { 5612 if (mPollDelayTime <= NO_POLL_DELAY) return; 5613 synchronized (NfcService.this) { 5614 if (!mPollDelayed) { 5615 mPollDelayed = true; 5616 mDeviceHost.startStopPolling(false); 5617 int delayTime = mPollDelayTime; 5618 if (mPollDelayCount < mPollDelayCountMax) { 5619 mPollDelayCount++; 5620 } else { 5621 delayTime = mPollDelayTimeLong; 5622 } 5623 if (DBG) Log.d(TAG, "pollingDelay: delay " + delayTime); 5624 mHandler.sendMessageDelayed( 5625 mHandler.obtainMessage(MSG_DELAY_POLLING), delayTime); 5626 } else { 5627 if (DBG) Log.d(TAG, "pollingDelay: Keep waiting"); 5628 } 5629 } 5630 } 5631 dispatchTagEndpoint(TagEndpoint tagEndpoint, ReaderModeParams readerParams)5632 private void dispatchTagEndpoint(TagEndpoint tagEndpoint, ReaderModeParams readerParams) { 5633 if (mNfcOemExtensionCallback != null 5634 && receiveOemCallbackResult(ACTION_ON_TAG_DISPATCH)) { 5635 Log.d(TAG, "dispatchTagEndpoint: skip due to oem callback"); 5636 return; 5637 } 5638 try { 5639 /* Avoid setting mCookieUpToDate to negative values */ 5640 mCookieUpToDate = mCookieGenerator.nextLong() >>> 1; 5641 Tag tag = new Tag(tagEndpoint.getUid(), tagEndpoint.getTechList(), 5642 tagEndpoint.getTechExtras(), tagEndpoint.getHandle(), 5643 mCookieUpToDate, mNfcTagService); 5644 registerTagObject(tagEndpoint); 5645 if (readerParams != null) { 5646 try { 5647 if ((readerParams.flags & NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS) == 0) { 5648 mVibrator.vibrate(mVibrationEffect, 5649 HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES); 5650 playSound(SOUND_END); 5651 } 5652 if (readerParams.callback != null) { 5653 if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) { 5654 mPowerManager.userActivity(SystemClock.uptimeMillis(), 5655 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0); 5656 } 5657 readerParams.callback.onTagDiscovered(tag); 5658 return; 5659 } else { 5660 // Follow normal dispatch below 5661 } 5662 } catch (RemoteException e) { 5663 Log.e(TAG, 5664 "dispatchTagEndpoint: Reader mode remote has died, falling back ", 5665 e); 5666 // Intentional fall-through 5667 } catch (Exception e) { 5668 // Catch any other exception 5669 Log.e(TAG, "dispatchTagEndpoint: App exception, not dispatching ", e); 5670 return; 5671 } 5672 } 5673 refreshTagDispatcherInProvisionMode(); 5674 int dispatchResult = mNfcDispatcher.dispatchTag(tag); 5675 if (dispatchResult == NfcDispatcher.DISPATCH_FAIL 5676 && !isEndPointRemovalDetectionSupported()) { 5677 if (DBG) Log.d(TAG, "dispatchTagEndpoint: Tag dispatch failed"); 5678 executeOemOnTagConnectedCallback(false); 5679 unregisterObject(tagEndpoint.getHandle()); 5680 if (mPollDelayTime > NO_POLL_DELAY) { 5681 pollingDelay(); 5682 tagEndpoint.stopPresenceChecking(); 5683 } else { 5684 Log.d(TAG, "dispatchTagEndpoint: Keep presence checking"); 5685 } 5686 if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED 5687 && mNotifyDispatchFailed && !mInProvisionMode) { 5688 if (!sToast_debounce) { 5689 Toast.makeText(mContext, R.string.tag_dispatch_failed, 5690 Toast.LENGTH_SHORT).show(); 5691 sToast_debounce = true; 5692 mHandler.sendEmptyMessageDelayed(MSG_TOAST_DEBOUNCE_EVENT, 5693 sToast_debounce_time_ms); 5694 } 5695 playSound(SOUND_ERROR); 5696 } 5697 if (!mAntennaBlockedMessageShown && mDispatchFailedCount++ > mDispatchFailedMax) { 5698 new NfcBlockedNotification(mContext).startNotification(); 5699 synchronized (NfcService.this) { 5700 mPrefsEditor.putBoolean(PREF_ANTENNA_BLOCKED_MESSAGE_SHOWN, true); 5701 mPrefsEditor.apply(); 5702 } 5703 mBackupManager.dataChanged(); 5704 mAntennaBlockedMessageShown = true; 5705 mDispatchFailedCount = 0; 5706 if (DBG) { 5707 Log.d(TAG, 5708 "dispatchTagEndpoint: Tag dispatch failed notification"); 5709 } 5710 } 5711 } else if (dispatchResult == NfcDispatcher.DISPATCH_SUCCESS) { 5712 synchronized (NfcService.this) { 5713 mPollDelayCount = 0; 5714 mReadErrorCount = 0; 5715 } 5716 if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) { 5717 mPowerManager.userActivity(SystemClock.uptimeMillis(), 5718 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0); 5719 } 5720 mDispatchFailedCount = 0; 5721 mVibrator.vibrate(mVibrationEffect, HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES); 5722 playSound(SOUND_END); 5723 notifyOemLogEvent(new OemLogItems.Builder(OemLogItems.LOG_ACTION_TAG_DETECTED) 5724 .setTag(tag).build()); 5725 } 5726 } catch (Exception e) { 5727 Log.e(TAG, "dispatchTagEndpoint: Tag creation exception, not dispatching ", e); 5728 return; 5729 } 5730 } 5731 } 5732 executeOemOnTagConnectedCallback(boolean connected)5733 private void executeOemOnTagConnectedCallback(boolean connected) { 5734 if (mNfcOemExtensionCallback != null) { 5735 try { 5736 mNfcOemExtensionCallback.onTagConnected(connected); 5737 } catch (RemoteException e) { 5738 Log.e(TAG, e.toString()); 5739 } 5740 } 5741 } 5742 5743 private NfcServiceHandler mHandler; 5744 5745 class ApplyRoutingTask extends AsyncTask<Integer, Void, Void> { 5746 @Override doInBackground(Integer... params)5747 protected Void doInBackground(Integer... params) { 5748 synchronized (NfcService.this) { 5749 if (params == null || params.length != 1) { 5750 // force apply current routing 5751 applyRouting(true); 5752 return null; 5753 } 5754 mScreenState = params[0].intValue(); 5755 5756 mRoutingWakeLock.acquire(); 5757 try { 5758 applyRouting(false); 5759 } finally { 5760 if (mRoutingWakeLock.isHeld()) { 5761 mRoutingWakeLock.release(); 5762 } 5763 } 5764 return null; 5765 } 5766 } 5767 } 5768 handleScreenStateChanged()5769 private void handleScreenStateChanged() { 5770 // Perform applyRouting() in AsyncTask to serialize blocking calls 5771 if (mIsWlcCapable && mNfcCharging.NfcChargingOnGoing) { 5772 Log.d(TAG, 5773 "handleScreenStateChanged: MSG_APPLY_SCREEN_STATE postponing due " 5774 + "to a charging pier device"); 5775 mPendingPowerStateUpdate = true; 5776 return; 5777 } 5778 int screenState = mScreenStateHelper.checkScreenState(mCheckDisplayStateForScreenState); 5779 if (screenState == SCREEN_STATE_ON_LOCKED || screenState == SCREEN_STATE_ON_UNLOCKED) { 5780 synchronized (NfcService.this) { 5781 mPollDelayCount = 0; 5782 mReadErrorCount = 0; 5783 } 5784 } 5785 applyScreenState(screenState); 5786 } 5787 isEndPointRemovalDetectionSupported()5788 boolean isEndPointRemovalDetectionSupported() { 5789 if (!(mIsRDCapable && mDeviceHost.isRemovalDetectionInPollModeSupported())) { 5790 Log.d(TAG, "isEndPointRemovalDetectionSupported: not supported"); 5791 return false; 5792 } 5793 if (!(mAppInActivityDetectionTime >= MIN_RF_REMOVAL_DETECTION_TIMEOUT && 5794 (mTagRemovalDetectionWaitTime >= MIN_RF_REMOVAL_DETECTION_TIMEOUT && 5795 mTagRemovalDetectionWaitTime <= MAX_RF_REMOVAL_DETECTION_TIMEOUT))) { 5796 Log.d(TAG, "isEndPointRemovalDetectionSupported: Unexpected wait time"); 5797 return false; 5798 } 5799 return true; 5800 } 5801 scheduleAppInactivityDetectionTask()5802 void scheduleAppInactivityDetectionTask() { 5803 if (isEndPointRemovalDetectionSupported()) { 5804 clearAppInactivityDetectionContext(); 5805 mAppInActivityDetectionTimer = new Timer(); 5806 AppInActivityHandlerTask task = new AppInActivityHandlerTask(); 5807 mAppInActivityDetectionTimer.schedule(task,mAppInActivityDetectionTime); 5808 Log.d(TAG, "scheduleAppInactivityDetectionTask: scheduled"); 5809 } 5810 } 5811 checkAndHandleRemovalDetectionMode(boolean isDisconnectNeeded)5812 boolean checkAndHandleRemovalDetectionMode(boolean isDisconnectNeeded) { 5813 if (mAppInActivityDetectionTimer != null) { 5814 if (isPresenceCheckStopped()) { 5815 Log.d(TAG, "checkAndHandleRemovalDetectionMode: Removal detection state"); 5816 if (isDisconnectNeeded) { 5817 Log.d(TAG, "checkAndHandleRemovalDetectionMode: Restarting discovery.."); 5818 maybeDisconnectTarget(); 5819 return true; 5820 } 5821 } else { 5822 Log.d(TAG, "checkAndHandleRemovalDetectionMode: Clearing Removal " 5823 + "Detection Timer Context"); 5824 clearAppInactivityDetectionContext(); 5825 } 5826 } 5827 return false; 5828 } 5829 5830 class AppInActivityHandlerTask extends TimerTask { run()5831 public void run() { 5832 Log.d(TAG, "run: App Inactivity detected, Requesting to Start Removal " 5833 + "Detection Procedure"); 5834 if (isTagPresent()) { 5835 prepareForRemovalDetectionMode(); 5836 mHandler.post(() -> Toast.makeText(mContext, 5837 "No activity over reader mode, RF removal detection procedure started", 5838 Toast.LENGTH_LONG).show()); 5839 /* Request JNI to start remove detection procedure */ 5840 startRemovalDetection(mTagRemovalDetectionWaitTime); 5841 } else { 5842 clearAppInactivityDetectionContext(); 5843 } 5844 } 5845 } 5846 clearAppInactivityDetectionContext()5847 void clearAppInactivityDetectionContext() { 5848 if (mAppInActivityDetectionTimer != null) { 5849 mAppInActivityDetectionTimer.cancel(); 5850 mAppInActivityDetectionTimer = null; 5851 } 5852 } 5853 5854 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 5855 @Override 5856 public void onReceive(Context context, Intent intent) { 5857 String action = intent.getAction(); 5858 if (action.equals(Intent.ACTION_SCREEN_ON) 5859 || action.equals(Intent.ACTION_SCREEN_OFF) 5860 || action.equals(Intent.ACTION_USER_PRESENT)) { 5861 handleScreenStateChanged(); 5862 } else if (action.equals(Intent.ACTION_BOOT_COMPLETED) && mIsHceCapable) { 5863 if (DBG) Log.d(TAG, action + " received"); 5864 mCardEmulationManager.onBootCompleted(); 5865 } else if (action.equals(Intent.ACTION_USER_SWITCHED)) { 5866 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 5867 mUserId = userId; 5868 updatePackageCache(); 5869 if (DBG) Log.d(TAG, action + "mReceiver.onReceive: UserId: " + userId); 5870 if (mIsHceCapable) { 5871 mCardEmulationManager.onUserSwitched(getUserId()); 5872 } 5873 applyScreenState(mScreenStateHelper.checkScreenState(mCheckDisplayStateForScreenState)); 5874 5875 if ((NFC_SNOOP_LOG_MODE.equals(NfcProperties.snoop_log_mode_values.FULL) || 5876 NFC_VENDOR_DEBUG_ENABLED) && 5877 mDeviceConfigFacade.getEnableDeveloperNotification()){ 5878 new NfcDeveloperOptionNotification(mContext.createContextAsUser( 5879 UserHandle.of(ActivityManager.getCurrentUser()), /*flags=*/0)) 5880 .startNotification(); 5881 } 5882 // Reload when another userId activated 5883 synchronized (NfcService.this) { 5884 initTagAppPrefList(); 5885 } 5886 } else if (action.equals(Intent.ACTION_USER_ADDED)) { 5887 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 5888 setPaymentForegroundPreference(userId); 5889 5890 if ((NFC_SNOOP_LOG_MODE.equals(NfcProperties.snoop_log_mode_values.FULL) || 5891 NFC_VENDOR_DEBUG_ENABLED) && 5892 mDeviceConfigFacade.getEnableDeveloperNotification()) { 5893 new NfcDeveloperOptionNotification(mContext.createContextAsUser( 5894 UserHandle.of(ActivityManager.getCurrentUser()), /*flags=*/0)) 5895 .startNotification(); 5896 } 5897 } else if (action.equals(Intent.ACTION_USER_UNLOCKED) 5898 && mFeatureFlags.enableDirectBootAware()) { 5899 // If this is first unlock after upgrading to NFC stack that is direct boot aware, 5900 // migrate over the data from CE directory to DE directory for access before user 5901 // unlock in subsequent bootups. 5902 if (!mPrefs.getBoolean(PREF_MIGRATE_TO_DE_COMPLETE, false)) { 5903 Log.i(TAG, "mReceiver.onReceive: Migrating shared prefs to DE directory " 5904 + "from CE directory"); 5905 Context ceContext = mContext.createCredentialProtectedStorageContext(); 5906 SharedPreferences cePreferences = 5907 ceContext.getSharedPreferences(PREF, Context.MODE_PRIVATE); 5908 SharedPreferences ceTagPreferences = 5909 ceContext.getSharedPreferences(PREF_TAG_APP_LIST, Context.MODE_PRIVATE); 5910 Log.d(TAG, "mReceiver.onReceive: CE Shared Pref values: " 5911 + cePreferences.getAll() + ", " + ceTagPreferences.getAll()); 5912 if (cePreferences.getAll().isEmpty()) { 5913 Log.d(TAG, 5914 "mReceiver.onReceive: No NFC Shared preferences to " 5915 + "migrate from CE data"); 5916 } else { 5917 if (!mContext.moveSharedPreferencesFrom(ceContext, PREF)) { 5918 Log.e(TAG, 5919 "mReceiver.onReceive: Failed to migrate NFC Shared preferences " 5920 + "to DE directory"); 5921 return; 5922 } 5923 } 5924 if (ceTagPreferences.getAll().isEmpty()) { 5925 Log.d(TAG, 5926 "mReceiver.onReceive: No NFC Shared preferences for tag app " 5927 + "to migrate from CE data"); 5928 } else { 5929 if (!mContext.moveSharedPreferencesFrom(ceContext, PREF_TAG_APP_LIST)) { 5930 Log.e(TAG, 5931 "mReceiver.onReceive: Failed to migrate NFC Shared " 5932 + "preferences for tag app list to DE directory"); 5933 return; 5934 } 5935 initTagAppPrefList(); 5936 } 5937 if (mIsHceCapable) { 5938 mCardEmulationManager.migrateSettingsFilesFromCe(ceContext); 5939 } 5940 // If the move is completed, refresh our reference to the shared preferences. 5941 mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE); 5942 mPrefsEditor = mPrefs.edit(); 5943 mPrefsEditor.putBoolean(PREF_MIGRATE_TO_DE_COMPLETE, true); 5944 mPrefsEditor.apply(); 5945 } 5946 } 5947 } 5948 }; 5949 5950 private final BroadcastReceiver mManagedProfileReceiver = new BroadcastReceiver() { 5951 @Override 5952 public void onReceive(Context context, Intent intent) { 5953 String action = intent.getAction(); 5954 UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER); 5955 5956 // User should be filled for below intents, check the existence. 5957 if (user == null) { 5958 Log.d(TAG, intent.getAction() 5959 + "mManagedProfileReceiver.onReceive: broadcast without EXTRA_USER"); 5960 return; 5961 } 5962 5963 if (mCardEmulationManager == null) { 5964 return; 5965 } 5966 if (action.equals(Intent.ACTION_MANAGED_PROFILE_ADDED) || 5967 action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) || 5968 action.equals(Intent.ACTION_MANAGED_PROFILE_REMOVED) || 5969 action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)) { 5970 if (DBG) { 5971 Log.d(TAG, action + "mManagedProfileReceiver.onReceive: UserId: " 5972 + user.getIdentifier()); 5973 } 5974 mCardEmulationManager.onManagedProfileChanged(); 5975 setPaymentForegroundPreference(user.getIdentifier()); 5976 synchronized (NfcService.this) { 5977 initTagAppPrefList(); 5978 } 5979 } 5980 } 5981 }; 5982 5983 private final BroadcastReceiver mOwnerReceiver = new BroadcastReceiver() { 5984 @Override 5985 public void onReceive(Context context, Intent intent) { 5986 String action = intent.getAction(); 5987 if (action.equals(Intent.ACTION_PACKAGE_REMOVED) 5988 || action.equals(Intent.ACTION_PACKAGE_ADDED) 5989 || action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE) 5990 || action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) { 5991 updatePackageCache(); 5992 renewTagAppPrefList(action); 5993 } else if (action.equals(Intent.ACTION_SHUTDOWN)) { 5994 if (DBG) { 5995 Log.d(TAG, "mOwnerReceiver.onReceive: Shutdown received with UserId: " 5996 + getSendingUser().getIdentifier()); 5997 } 5998 if (!getSendingUser().equals(UserHandle.ALL)) { 5999 return; 6000 } 6001 if (DBG) Log.d(TAG, "mOwnerReceiver.onReceive: Device is shutting down"); 6002 if (mIsAlwaysOnSupported && mAlwaysOnState == NfcAdapter.STATE_ON) { 6003 new EnableDisableTask().execute(TASK_DISABLE_ALWAYS_ON); 6004 } 6005 if (isNfcEnabled()) { 6006 mDeviceHost.shutdown(); 6007 } 6008 } 6009 } 6010 }; 6011 applyScreenState(int screenState)6012 private void applyScreenState(int screenState) { 6013 if (mFeatureFlags.reduceStateTransition() 6014 && mIsWatchType && !mCardEmulationManager.isRequiresScreenOnServiceExist()) { 6015 if (screenState == ScreenStateHelper.SCREEN_STATE_OFF_LOCKED) { 6016 screenState = SCREEN_STATE_ON_LOCKED; 6017 } else if (screenState == ScreenStateHelper.SCREEN_STATE_OFF_UNLOCKED) { 6018 screenState = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED; 6019 } 6020 } 6021 if (DBG) { 6022 Log.d(TAG, "applyScreenState: screenState = " 6023 + ScreenStateHelper.screenStateToString(screenState)); 6024 } 6025 if (mScreenState != screenState) { 6026 if (nci_version != NCI_VERSION_2_0) { 6027 new ApplyRoutingTask().execute(Integer.valueOf(screenState)); 6028 } 6029 if (DBG) Log.d(TAG, "applyScreenState: screenState != mScreenState=" + mScreenState); 6030 sendMessage(MSG_APPLY_SCREEN_STATE, screenState); 6031 } 6032 } 6033 setPaymentForegroundPreference(int user)6034 private void setPaymentForegroundPreference(int user) { 6035 Context uc; 6036 try { 6037 uc = mContext.createContextAsUser(UserHandle.of(user), 0); 6038 } catch (IllegalStateException e) { 6039 Log.d(TAG, 6040 "setPaymentForegroundPreference: Fail to get user context for user: " + user); 6041 return; 6042 } 6043 try { 6044 // Check whether the Settings.Secure.NFC_PAYMENT_FOREGROUND exists or not. 6045 Settings.Secure.getInt(uc.getContentResolver(), 6046 Constants.SETTINGS_SECURE_NFC_PAYMENT_FOREGROUND); 6047 } catch (SettingNotFoundException e) { 6048 boolean foregroundPreference = 6049 mContext.getResources().getBoolean(R.bool.payment_foreground_preference); 6050 Settings.Secure.putInt(uc.getContentResolver(), 6051 Constants.SETTINGS_SECURE_NFC_PAYMENT_FOREGROUND, foregroundPreference ? 1 : 0); 6052 Log.d(TAG, "setPaymentForegroundPreference: NFC_PAYMENT_FOREGROUND preference:" 6053 + foregroundPreference); 6054 } 6055 } 6056 6057 /** 6058 * for debugging only - no i18n 6059 */ stateToString(int state)6060 static String stateToString(int state) { 6061 switch (state) { 6062 case NfcAdapter.STATE_OFF: 6063 return "off"; 6064 case NfcAdapter.STATE_TURNING_ON: 6065 return "turning on"; 6066 case NfcAdapter.STATE_ON: 6067 return "on"; 6068 case NfcAdapter.STATE_TURNING_OFF: 6069 return "turning off"; 6070 default: 6071 return "<error>"; 6072 } 6073 } 6074 stateToProtoEnum(int state)6075 static int stateToProtoEnum(int state) { 6076 switch (state) { 6077 case NfcAdapter.STATE_OFF: 6078 return NfcServiceDumpProto.STATE_OFF; 6079 case NfcAdapter.STATE_TURNING_ON: 6080 return NfcServiceDumpProto.STATE_TURNING_ON; 6081 case NfcAdapter.STATE_ON: 6082 return NfcServiceDumpProto.STATE_ON; 6083 case NfcAdapter.STATE_TURNING_OFF: 6084 return NfcServiceDumpProto.STATE_TURNING_OFF; 6085 default: 6086 return NfcServiceDumpProto.STATE_UNKNOWN; 6087 } 6088 } 6089 copyNativeCrashLogsIfAny(PrintWriter pw)6090 private void copyNativeCrashLogsIfAny(PrintWriter pw) { 6091 try { 6092 File file = new File(NATIVE_LOG_FILE_PATH, NATIVE_LOG_FILE_NAME); 6093 if (!file.exists()) { 6094 return; 6095 } 6096 pw.println("---BEGIN: NATIVE CRASH LOG----"); 6097 Scanner sc = new Scanner(file); 6098 while(sc.hasNextLine()) { 6099 String s = sc.nextLine(); 6100 pw.println(s); 6101 } 6102 pw.println("---END: NATIVE CRASH LOG----"); 6103 sc.close(); 6104 } catch (IOException e) { 6105 Log.e(TAG, "Exception in copyNativeCrashLogsIfAny " + e); 6106 } 6107 } 6108 storeNativeCrashLogs()6109 public void storeNativeCrashLogs() { 6110 FileOutputStream fos = null; 6111 try { 6112 File file = new File(NATIVE_LOG_FILE_PATH, NATIVE_LOG_FILE_NAME); 6113 if (file.length() >= NATIVE_CRASH_FILE_SIZE) { 6114 file.createNewFile(); 6115 } 6116 6117 fos = new FileOutputStream(file, true); 6118 mDeviceHost.dump(new PrintWriter(new StringWriter()), fos.getFD()); 6119 fos.flush(); 6120 } catch (IOException e) { 6121 Log.e(TAG, "storeNativeCrashLogs: e=" + e); 6122 } finally { 6123 if (fos != null) { 6124 try { 6125 fos.close(); 6126 } catch (IOException e) { 6127 Log.e(TAG, "storeNativeCrashLogs: file close " + e); 6128 } 6129 } 6130 } 6131 } 6132 dumpTagAppPreference(PrintWriter pw)6133 private void dumpTagAppPreference(PrintWriter pw) { 6134 pw.println("mIsTagAppPrefSupported =" + mIsTagAppPrefSupported); 6135 if (!mIsTagAppPrefSupported) return; 6136 pw.println("TagAppPreference:"); 6137 for (Integer userId : getEnabledUserIds()) { 6138 HashMap<String, Boolean> map; 6139 synchronized (NfcService.this) { 6140 map = mTagAppPrefList.getOrDefault(userId, new HashMap<>()); 6141 } 6142 if (map.size() > 0) pw.println("userId=" + userId); 6143 for (Map.Entry<String, Boolean> entry : map.entrySet()) { 6144 pw.println("pkg: " + entry.getKey() + " : " + entry.getValue()); 6145 } 6146 } 6147 } 6148 dump(FileDescriptor fd, PrintWriter pw, String[] args)6149 void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 6150 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 6151 != PackageManager.PERMISSION_GRANTED) { 6152 pw.println("Permission Denial: can't dump nfc from pid=" 6153 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 6154 + " without permission " + android.Manifest.permission.DUMP); 6155 return; 6156 } 6157 6158 for (String arg : args) { 6159 if ("--proto".equals(arg)) { 6160 FileOutputStream fos = null; 6161 try { 6162 fos = new FileOutputStream(fd); 6163 ProtoOutputStream proto = new ProtoOutputStream(fos); 6164 synchronized (this) { 6165 dumpDebug(proto); 6166 } 6167 proto.flush(); 6168 } catch (Exception e) { 6169 Log.e(TAG, "dump: exception=" + e); 6170 } finally { 6171 if (fos != null) { 6172 try { 6173 fos.close(); 6174 } catch (IOException e) { 6175 Log.e(TAG, "dump: Exception in storeNativeCrashLogs " + e); 6176 } 6177 } 6178 } 6179 return; 6180 } 6181 } 6182 6183 synchronized (this) { 6184 pw.println("mState=" + stateToString(mState)); 6185 pw.println("mAlwaysOnState=" + stateToString(mAlwaysOnState)); 6186 pw.println("mScreenState=" + ScreenStateHelper.screenStateToString(mScreenState)); 6187 pw.println("mIsSecureNfcEnabled=" + mIsSecureNfcEnabled); 6188 pw.println("mIsReaderOptionEnabled=" + mIsReaderOptionEnabled); 6189 pw.println("mIsAlwaysOnSupported=" + mIsAlwaysOnSupported); 6190 if (mIsWlcCapable) { 6191 pw.println("WlcEnabled=" + mIsWlcEnabled); 6192 } 6193 pw.println("SnoopLogMode=" + NFC_SNOOP_LOG_MODE); 6194 pw.println("VendorDebugEnabled=" + NFC_VENDOR_DEBUG_ENABLED); 6195 pw.println("mIsPowerSavingModeEnabled=" + mIsPowerSavingModeEnabled); 6196 pw.println("mIsObserveModeSupported=" + mNfcAdapter.isObserveModeSupported()); 6197 pw.println("mIsObserveModeEnabled=" + mNfcAdapter.isObserveModeEnabled()); 6198 pw.println("listenTech=0x" + Integer.toHexString(getNfcListenTech())); 6199 pw.println("pollTech=0x" + Integer.toHexString(getNfcPollTech())); 6200 pw.println(mCurrentDiscoveryParameters); 6201 if (mIsHceCapable) { 6202 mCardEmulationManager.dump(fd, pw, args); 6203 } 6204 mNfcDispatcher.dump(fd, pw, args); 6205 if (mState == NfcAdapter.STATE_ON) { 6206 mRoutingTableParser.dump(mDeviceHost, pw); 6207 } 6208 dumpTagAppPreference(pw); 6209 mNfcInjector.getNfcEventLog().dump(fd, pw, args); 6210 copyNativeCrashLogsIfAny(pw); 6211 pw.flush(); 6212 mDeviceHost.dump(pw,fd); 6213 } 6214 } 6215 6216 /** 6217 * Dump debugging information as a NfcServiceDumpProto 6218 * 6219 * Note: 6220 * See proto definition in frameworks/base/core/proto/android/nfc/nfc_service.proto 6221 * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and 6222 * {@link ProtoOutputStream#end(long)} after. 6223 * Never reuse a proto field number. When removing a field, mark it as reserved. 6224 */ dumpDebug(ProtoOutputStream proto)6225 private void dumpDebug(ProtoOutputStream proto) { 6226 proto.write(NfcServiceDumpProto.STATE, stateToProtoEnum(mState)); 6227 proto.write(NfcServiceDumpProto.IN_PROVISION_MODE, mInProvisionMode); 6228 proto.write(NfcServiceDumpProto.SCREEN_STATE, 6229 ScreenStateHelper.screenStateToProtoEnum(mScreenState)); 6230 proto.write(NfcServiceDumpProto.SECURE_NFC_ENABLED, mIsSecureNfcEnabled); 6231 proto.write(NfcServiceDumpProto.POLLING_PAUSED, mPollingPaused); 6232 proto.write(NfcServiceDumpProto.HCE_CAPABLE, mIsHceCapable); 6233 proto.write(NfcServiceDumpProto.HCE_F_CAPABLE, mIsHceFCapable); 6234 proto.write(NfcServiceDumpProto.SECURE_NFC_CAPABLE, mIsSecureNfcCapable); 6235 proto.write(NfcServiceDumpProto.VR_MODE_ENABLED, false); 6236 6237 long token = proto.start(NfcServiceDumpProto.DISCOVERY_PARAMS); 6238 mCurrentDiscoveryParameters.dumpDebug(proto); 6239 proto.end(token); 6240 6241 if (mIsHceCapable) { 6242 token = proto.start(NfcServiceDumpProto.CARD_EMULATION_MANAGER); 6243 mCardEmulationManager.dumpDebug(proto); 6244 proto.end(token); 6245 } 6246 6247 token = proto.start(NfcServiceDumpProto.NFC_DISPATCHER); 6248 mNfcDispatcher.dumpDebug(proto); 6249 proto.end(token); 6250 6251 // Dump native crash logs if any 6252 File file = new File(NATIVE_LOG_FILE_PATH, NATIVE_LOG_FILE_NAME); 6253 if (!file.exists()) { 6254 return; 6255 } 6256 try { 6257 String logs = Files.lines(file.toPath()).collect(Collectors.joining("\n")); 6258 proto.write(NfcServiceDumpProto.NATIVE_CRASH_LOGS, logs); 6259 } catch (IOException e) { 6260 Log.e(TAG, "dumpDebug: IOException=" + e); 6261 } 6262 } 6263 runTaskOnSingleThreadExecutor(FutureTask<Integer> task, int timeoutMs)6264 private int runTaskOnSingleThreadExecutor(FutureTask<Integer> task, int timeoutMs) 6265 throws InterruptedException, TimeoutException, ExecutionException { 6266 ExecutorService executor = Executors.newSingleThreadExecutor(); 6267 executor.submit(task); 6268 try { 6269 return task.get(timeoutMs, TimeUnit.MILLISECONDS); 6270 } catch (TimeoutException e) { 6271 executor.shutdownNow(); 6272 throw e; 6273 } 6274 } 6275 6276 @VisibleForTesting getHandler()6277 public Handler getHandler() { 6278 return mHandler; 6279 } 6280 notifyOemLogEvent(OemLogItems item)6281 public void notifyOemLogEvent(OemLogItems item) { 6282 if (mNfcOemExtensionCallback != null) { 6283 try { 6284 mNfcOemExtensionCallback.onLogEventNotified(item); 6285 } catch (RemoteException e) { 6286 Log.e(TAG, "notifyOemLogEvent: failed e = " + e.toString()); 6287 } 6288 6289 } 6290 } 6291 isFirmwareExitFramesSupported()6292 public boolean isFirmwareExitFramesSupported() { 6293 return mDeviceHost.isFirmwareExitFramesSupported(); 6294 } 6295 getNumberOfFirmwareExitFramesSupported()6296 public int getNumberOfFirmwareExitFramesSupported() { 6297 return mDeviceHost.getNumberOfFirmwareExitFramesSupported(); 6298 } 6299 setFirmwareExitFrameTable(List<ExitFrame> exitFrames, int timeoutMs)6300 public boolean setFirmwareExitFrameTable(List<ExitFrame> exitFrames, int timeoutMs) { 6301 // Check if NFC is enabled 6302 if (!isNfcEnabled()) { 6303 Log.w(TAG, "setFirmwareExitFrameTable: NFC is not enabled"); 6304 return false; 6305 } 6306 6307 if (mCardEmulationManager != null 6308 && mCardEmulationManager.isHostCardEmulationActivated()) { 6309 Log.w(TAG,"setFirmwareExitFrameTable: " + 6310 "Cannot set exit rame table in during a transaction."); 6311 return false; 6312 } 6313 6314 byte[] timeoutBytes = new byte[2]; 6315 if (timeoutMs > 0xFFFF) { 6316 Log.w(TAG, 6317 "setFirmwareExitFrameTable: timeout is larger than 16 bits, " 6318 + "timeout will be truncated"); 6319 timeoutBytes = new byte[] {(byte) 0xFF, (byte) 0xFF}; 6320 } else { 6321 // Convert to little endian, two byte array 6322 timeoutBytes[0] = (byte) timeoutMs; 6323 timeoutBytes[1] = (byte) (timeoutMs >> 8); 6324 } 6325 6326 boolean result = mDeviceHost.setFirmwareExitFrameTable(exitFrames.toArray(ExitFrame[]::new), 6327 timeoutBytes); 6328 6329 if (result && mStatsdUtils != null) { 6330 mStatsdUtils.logExitFrameTableChanged(exitFrames.size(), timeoutMs); 6331 } 6332 6333 return result; 6334 } 6335 } 6336 6337