1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.nfc; 18 19 import android.app.ActivityManager; 20 import android.app.Application; 21 import android.app.backup.BackupManager; 22 import android.app.KeyguardManager; 23 import android.app.PendingIntent; 24 import android.app.admin.DevicePolicyManager; 25 import android.content.BroadcastReceiver; 26 import android.content.ComponentName; 27 import android.content.ContentResolver; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.content.IntentFilter; 31 import android.content.SharedPreferences; 32 import android.content.pm.ApplicationInfo; 33 import android.content.pm.IPackageManager; 34 import android.content.pm.PackageInfo; 35 import android.content.pm.PackageManager; 36 import android.content.pm.UserInfo; 37 import android.content.res.Resources.NotFoundException; 38 import android.media.AudioManager; 39 import android.media.SoundPool; 40 import android.net.Uri; 41 import android.nfc.BeamShareData; 42 import android.nfc.ErrorCodes; 43 import android.nfc.FormatException; 44 import android.nfc.IAppCallback; 45 import android.nfc.INfcAdapter; 46 import android.nfc.INfcAdapterExtras; 47 import android.nfc.INfcCardEmulation; 48 import android.nfc.INfcDta; 49 import android.nfc.INfcFCardEmulation; 50 import android.nfc.INfcTag; 51 import android.nfc.INfcUnlockHandler; 52 import android.nfc.ITagRemovedCallback; 53 import android.nfc.NdefMessage; 54 import android.nfc.NfcAdapter; 55 import android.nfc.Tag; 56 import android.nfc.TechListParcel; 57 import android.nfc.TransceiveResult; 58 import android.nfc.tech.Ndef; 59 import android.nfc.tech.TagTechnology; 60 import android.os.AsyncTask; 61 import android.os.Binder; 62 import android.os.Build; 63 import android.os.Bundle; 64 import android.os.Handler; 65 import android.os.IBinder; 66 import android.os.Message; 67 import android.os.PowerManager; 68 import android.os.Process; 69 import android.os.RemoteException; 70 import android.os.ServiceManager; 71 import android.os.SystemClock; 72 import android.os.SystemProperties; 73 import android.os.UserHandle; 74 import android.os.UserManager; 75 import android.os.VibrationEffect; 76 import android.os.Vibrator; 77 import android.provider.Settings; 78 import android.se.omapi.ISecureElementService; 79 import android.service.vr.IVrManager; 80 import android.service.vr.IVrStateCallbacks; 81 import android.util.Log; 82 83 import com.android.internal.logging.MetricsLogger; 84 import com.android.nfc.DeviceHost.DeviceHostListener; 85 import com.android.nfc.DeviceHost.LlcpConnectionlessSocket; 86 import com.android.nfc.DeviceHost.LlcpServerSocket; 87 import com.android.nfc.DeviceHost.LlcpSocket; 88 import com.android.nfc.DeviceHost.NfcDepEndpoint; 89 import com.android.nfc.DeviceHost.TagEndpoint; 90 import com.android.nfc.cardemulation.CardEmulationManager; 91 import com.android.nfc.dhimpl.NativeNfcManager; 92 import com.android.nfc.handover.HandoverDataParser; 93 94 import java.io.FileDescriptor; 95 import java.io.PrintWriter; 96 import java.io.UnsupportedEncodingException; 97 import java.nio.ByteBuffer; 98 import java.util.concurrent.atomic.AtomicInteger; 99 import java.util.Arrays; 100 import java.util.ArrayList; 101 import java.util.HashMap; 102 import java.util.List; 103 import java.util.Map; 104 import java.util.NoSuchElementException; 105 106 107 public class NfcService implements DeviceHostListener { 108 static final boolean DBG = false; 109 static final String TAG = "NfcService"; 110 111 public static final String SERVICE_NAME = "nfc"; 112 113 public static final String PREF = "NfcServicePrefs"; 114 115 static final String PREF_NFC_ON = "nfc_on"; 116 static final boolean NFC_ON_DEFAULT = true; 117 static final String PREF_NDEF_PUSH_ON = "ndef_push_on"; 118 static final boolean NDEF_PUSH_ON_DEFAULT = true; 119 static final String PREF_FIRST_BEAM = "first_beam"; 120 static final String PREF_FIRST_BOOT = "first_boot"; 121 122 static final String TRON_NFC_CE = "nfc_ce"; 123 static final String TRON_NFC_P2P = "nfc_p2p"; 124 static final String TRON_NFC_TAG = "nfc_tag"; 125 126 static final int MSG_NDEF_TAG = 0; 127 static final int MSG_LLCP_LINK_ACTIVATION = 1; 128 static final int MSG_LLCP_LINK_DEACTIVATED = 2; 129 static final int MSG_MOCK_NDEF = 3; 130 static final int MSG_LLCP_LINK_FIRST_PACKET = 4; 131 static final int MSG_ROUTE_AID = 5; 132 static final int MSG_UNROUTE_AID = 6; 133 static final int MSG_COMMIT_ROUTING = 7; 134 static final int MSG_INVOKE_BEAM = 8; 135 static final int MSG_RF_FIELD_ACTIVATED = 9; 136 static final int MSG_RF_FIELD_DEACTIVATED = 10; 137 static final int MSG_RESUME_POLLING = 11; 138 static final int MSG_REGISTER_T3T_IDENTIFIER = 12; 139 static final int MSG_DEREGISTER_T3T_IDENTIFIER = 13; 140 static final int MSG_TAG_DEBOUNCE = 14; 141 static final int MSG_UPDATE_STATS = 15; 142 static final int MSG_APPLY_SCREEN_STATE = 16; 143 static final int MSG_TRANSACTION_EVENT = 17; 144 145 // Update stats every 4 hours 146 static final long STATS_UPDATE_INTERVAL_MS = 4 * 60 * 60 * 1000; 147 static final long MAX_POLLING_PAUSE_TIMEOUT = 40000; 148 149 static final int TASK_ENABLE = 1; 150 static final int TASK_DISABLE = 2; 151 static final int TASK_BOOT = 3; 152 153 // Polling technology masks 154 static final int NFC_POLL_A = 0x01; 155 static final int NFC_POLL_B = 0x02; 156 static final int NFC_POLL_F = 0x04; 157 static final int NFC_POLL_V = 0x08; 158 static final int NFC_POLL_B_PRIME = 0x10; 159 static final int NFC_POLL_KOVIO = 0x20; 160 161 // minimum screen state that enables NFC polling 162 static final int NFC_POLLING_MODE = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED; 163 164 // Time to wait for NFC controller to initialize before watchdog 165 // goes off. This time is chosen large, because firmware download 166 // may be a part of initialization. 167 static final int INIT_WATCHDOG_MS = 90000; 168 169 // Time to wait for routing to be applied before watchdog 170 // goes off 171 static final int ROUTING_WATCHDOG_MS = 10000; 172 173 // Default delay used for presence checks 174 static final int DEFAULT_PRESENCE_CHECK_DELAY = 125; 175 176 // The amount of time we wait before manually launching 177 // the Beam animation when called through the share menu. 178 static final int INVOKE_BEAM_DELAY_MS = 1000; 179 180 // RF field events as defined in NFC extras 181 public static final String ACTION_RF_FIELD_ON_DETECTED = 182 "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED"; 183 public static final String ACTION_RF_FIELD_OFF_DETECTED = 184 "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED"; 185 186 public static boolean sIsShortRecordLayout = false; 187 188 // for use with playSound() 189 public static final int SOUND_START = 0; 190 public static final int SOUND_END = 1; 191 public static final int SOUND_ERROR = 2; 192 193 public static final int NCI_VERSION_2_0 = 0x20; 194 195 public static final int NCI_VERSION_1_0 = 0x10; 196 197 public static final String ACTION_LLCP_UP = 198 "com.android.nfc.action.LLCP_UP"; 199 200 public static final String ACTION_LLCP_DOWN = 201 "com.android.nfc.action.LLCP_DOWN"; 202 203 // Timeout to re-apply routing if a tag was present and we postponed it 204 private static final int APPLY_ROUTING_RETRY_TIMEOUT_MS = 5000; 205 206 private final UserManager mUserManager; 207 208 private static int nci_version = NCI_VERSION_1_0; 209 // NFC Execution Environment 210 // fields below are protected by this 211 private final ReaderModeDeathRecipient mReaderModeDeathRecipient = 212 new ReaderModeDeathRecipient(); 213 private final NfcUnlockManager mNfcUnlockManager; 214 215 private final BackupManager mBackupManager; 216 217 // cached version of installed packages requesting Android.permission.NFC_TRANSACTION_EVENTS 218 List<String> mNfcEventInstalledPackages = new ArrayList<String>(); 219 220 // fields below are used in multiple threads and protected by synchronized(this) 221 final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>(); 222 int mScreenState; 223 boolean mInProvisionMode; // whether we're in setup wizard and enabled NFC provisioning 224 boolean mIsNdefPushEnabled; 225 NfcDiscoveryParameters mCurrentDiscoveryParameters = 226 NfcDiscoveryParameters.getNfcOffParameters(); 227 228 ReaderModeParams mReaderModeParams; 229 230 private int mUserId; 231 boolean mPollingPaused; 232 233 static final int INVALID_NATIVE_HANDLE = -1; 234 byte mDebounceTagUid[]; 235 int mDebounceTagDebounceMs; 236 int mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE; 237 ITagRemovedCallback mDebounceTagRemovedCallback; 238 239 // Only accessed on one thread so doesn't need locking 240 NdefMessage mLastReadNdefMessage; 241 242 // Metrics 243 AtomicInteger mNumTagsDetected; 244 AtomicInteger mNumP2pDetected; 245 AtomicInteger mNumHceDetected; 246 247 // mState is protected by this, however it is only modified in onCreate() 248 // and the default AsyncTask thread so it is read unprotected from that 249 // thread 250 int mState; // one of NfcAdapter.STATE_ON, STATE_TURNING_ON, etc 251 // fields below are final after onCreate() 252 Context mContext; 253 private DeviceHost mDeviceHost; 254 private SharedPreferences mPrefs; 255 private SharedPreferences.Editor mPrefsEditor; 256 private PowerManager.WakeLock mRoutingWakeLock; 257 258 int mStartSound; 259 int mEndSound; 260 int mErrorSound; 261 SoundPool mSoundPool; // playback synchronized on this 262 P2pLinkManager mP2pLinkManager; 263 TagService mNfcTagService; 264 NfcAdapterService mNfcAdapter; 265 NfcDtaService mNfcDtaService; 266 boolean mIsDebugBuild; 267 boolean mIsHceCapable; 268 boolean mIsHceFCapable; 269 270 private NfcDispatcher mNfcDispatcher; 271 private PowerManager mPowerManager; 272 private KeyguardManager mKeyguard; 273 private HandoverDataParser mHandoverDataParser; 274 private ContentResolver mContentResolver; 275 private CardEmulationManager mCardEmulationManager; 276 private Vibrator mVibrator; 277 private VibrationEffect mVibrationEffect; 278 private ISecureElementService mSEService; 279 280 private ScreenStateHelper mScreenStateHelper; 281 private ForegroundUtils mForegroundUtils; 282 283 private static NfcService sService; 284 public static boolean sIsDtaMode = false; 285 286 boolean mIsLiveCaseEnabled; // whether live cases are enabled 287 int mLiveCaseTechnology; // Technology mask of accepted NFC tags 288 289 private IVrManager vrManager; 290 boolean mIsVrModeEnabled; 291 292 public static NfcService getInstance() { 293 return sService; 294 } 295 296 @Override 297 public void onRemoteEndpointDiscovered(TagEndpoint tag) { 298 sendMessage(NfcService.MSG_NDEF_TAG, tag); 299 } 300 301 /** 302 * Notifies transaction 303 */ 304 @Override 305 public void onHostCardEmulationActivated(int technology) { 306 if (mCardEmulationManager != null) { 307 mCardEmulationManager.onHostCardEmulationActivated(technology); 308 } 309 } 310 311 @Override 312 public void onHostCardEmulationData(int technology, byte[] data) { 313 if (mCardEmulationManager != null) { 314 mCardEmulationManager.onHostCardEmulationData(technology, data); 315 } 316 } 317 318 @Override 319 public void onHostCardEmulationDeactivated(int technology) { 320 if (mCardEmulationManager != null) { 321 // Do metrics here so we don't slow the CE path down 322 mNumHceDetected.incrementAndGet(); 323 mCardEmulationManager.onHostCardEmulationDeactivated(technology); 324 } 325 } 326 327 /** 328 * Notifies P2P Device detected, to activate LLCP link 329 */ 330 @Override 331 public void onLlcpLinkActivated(NfcDepEndpoint device) { 332 sendMessage(NfcService.MSG_LLCP_LINK_ACTIVATION, device); 333 } 334 335 /** 336 * Notifies P2P Device detected, to activate LLCP link 337 */ 338 @Override 339 public void onLlcpLinkDeactivated(NfcDepEndpoint device) { 340 sendMessage(NfcService.MSG_LLCP_LINK_DEACTIVATED, device); 341 } 342 343 /** 344 * Notifies P2P Device detected, first packet received over LLCP link 345 */ 346 @Override 347 public void onLlcpFirstPacketReceived(NfcDepEndpoint device) { 348 mNumP2pDetected.incrementAndGet(); 349 sendMessage(NfcService.MSG_LLCP_LINK_FIRST_PACKET, device); 350 } 351 352 @Override 353 public void onRemoteFieldActivated() { 354 sendMessage(NfcService.MSG_RF_FIELD_ACTIVATED, null); 355 } 356 357 @Override 358 public void onRemoteFieldDeactivated() { 359 sendMessage(NfcService.MSG_RF_FIELD_DEACTIVATED, null); 360 } 361 362 @Override 363 public void onNfcTransactionEvent(byte[] aid, byte[] data, String seName) { 364 byte[][] dataObj = {aid, data, seName.getBytes()}; 365 sendMessage(NfcService.MSG_TRANSACTION_EVENT, dataObj); 366 } 367 368 final class ReaderModeParams { 369 public int flags; 370 public IAppCallback callback; 371 public int presenceCheckDelay; 372 } 373 374 public NfcService(Application nfcApplication) { 375 mUserId = ActivityManager.getCurrentUser(); 376 mContext = nfcApplication; 377 378 mNfcTagService = new TagService(); 379 mNfcAdapter = new NfcAdapterService(); 380 Log.i(TAG, "Starting NFC service"); 381 382 sService = this; 383 384 mScreenStateHelper = new ScreenStateHelper(mContext); 385 mContentResolver = mContext.getContentResolver(); 386 mDeviceHost = new NativeNfcManager(mContext, this); 387 388 mNfcUnlockManager = NfcUnlockManager.getInstance(); 389 390 mHandoverDataParser = new HandoverDataParser(); 391 boolean isNfcProvisioningEnabled = false; 392 try { 393 isNfcProvisioningEnabled = mContext.getResources().getBoolean( 394 R.bool.enable_nfc_provisioning); 395 } catch (NotFoundException e) { 396 } 397 398 try { 399 mIsLiveCaseEnabled = mContext.getResources().getBoolean(R.bool.enable_live_cases); 400 } catch (NotFoundException e) { 401 mIsLiveCaseEnabled = false; 402 } 403 404 mLiveCaseTechnology = 0; 405 String[] liveCaseTechList; 406 try { 407 liveCaseTechList = mContext.getResources().getStringArray(R.array.live_case_tag_types); 408 for (int i=0; i < liveCaseTechList.length; i++) { 409 if (liveCaseTechList[i].equals("TypeA")) { 410 mLiveCaseTechnology |= NFC_POLL_A; 411 } else if (liveCaseTechList[i].equals("TypeB")) { 412 mLiveCaseTechnology |= NFC_POLL_B; 413 } else if (liveCaseTechList[i].equals("TypeF")) { 414 mLiveCaseTechnology |= NFC_POLL_F; 415 } else if (liveCaseTechList[i].equals("TypeV")) { 416 mLiveCaseTechnology |= NFC_POLL_V; 417 } 418 } 419 } catch (NotFoundException e) { 420 mLiveCaseTechnology = 0; 421 } 422 423 if (isNfcProvisioningEnabled) { 424 mInProvisionMode = Settings.Secure.getInt(mContentResolver, 425 Settings.Global.DEVICE_PROVISIONED, 0) == 0; 426 } else { 427 mInProvisionMode = false; 428 } 429 430 mNfcDispatcher = new NfcDispatcher(mContext, mHandoverDataParser, mInProvisionMode, 431 mIsLiveCaseEnabled); 432 mP2pLinkManager = new P2pLinkManager(mContext, mHandoverDataParser, 433 mDeviceHost.getDefaultLlcpMiu(), mDeviceHost.getDefaultLlcpRwSize()); 434 435 mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE); 436 mPrefsEditor = mPrefs.edit(); 437 438 mState = NfcAdapter.STATE_OFF; 439 mIsNdefPushEnabled = mPrefs.getBoolean(PREF_NDEF_PUSH_ON, NDEF_PUSH_ON_DEFAULT); 440 enforceBeamShareActivityPolicy(mContext, new UserHandle(mUserId)); 441 442 mIsDebugBuild = "userdebug".equals(Build.TYPE) || "eng".equals(Build.TYPE); 443 444 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 445 446 mRoutingWakeLock = mPowerManager.newWakeLock( 447 PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mRoutingWakeLock"); 448 449 mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); 450 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 451 mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); 452 mVibrationEffect = VibrationEffect.createOneShot(200, VibrationEffect.DEFAULT_AMPLITUDE); 453 454 mScreenState = mScreenStateHelper.checkScreenState(); 455 456 mNumTagsDetected = new AtomicInteger(); 457 mNumP2pDetected = new AtomicInteger(); 458 mNumHceDetected = new AtomicInteger(); 459 460 mBackupManager = new BackupManager(mContext); 461 462 // Intents for all users 463 IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); 464 filter.addAction(Intent.ACTION_SCREEN_ON); 465 filter.addAction(Intent.ACTION_USER_PRESENT); 466 filter.addAction(Intent.ACTION_USER_SWITCHED); 467 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null); 468 469 IntentFilter ownerFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); 470 ownerFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 471 ownerFilter.addAction(Intent.ACTION_SHUTDOWN); 472 mContext.registerReceiver(mOwnerReceiver, ownerFilter); 473 474 ownerFilter = new IntentFilter(); 475 ownerFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 476 ownerFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 477 ownerFilter.addDataScheme("package"); 478 mContext.registerReceiver(mOwnerReceiver, ownerFilter); 479 480 IntentFilter policyFilter = new IntentFilter(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); 481 mContext.registerReceiverAsUser(mPolicyReceiver, UserHandle.ALL, policyFilter, null, null); 482 483 updatePackageCache(); 484 485 PackageManager pm = mContext.getPackageManager(); 486 mIsHceCapable = 487 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION) || 488 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF); 489 mIsHceFCapable = 490 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF); 491 if (mIsHceCapable) { 492 mCardEmulationManager = new CardEmulationManager(mContext); 493 } 494 mForegroundUtils = ForegroundUtils.getInstance(); 495 496 // Make sure this is only called when object construction is complete. 497 ServiceManager.addService(SERVICE_NAME, mNfcAdapter); 498 499 new EnableDisableTask().execute(TASK_BOOT); // do blocking boot tasks 500 501 mHandler.sendEmptyMessageDelayed(MSG_UPDATE_STATS, STATS_UPDATE_INTERVAL_MS); 502 503 IVrManager mVrManager = IVrManager.Stub.asInterface(ServiceManager.getService( 504 mContext.VR_SERVICE)); 505 if (mVrManager != null) { 506 try { 507 mVrManager.registerListener(mVrStateCallbacks); 508 mIsVrModeEnabled = mVrManager.getVrModeState(); 509 } catch (RemoteException e) { 510 Log.e(TAG, "Failed to register VR mode state listener: " + e); 511 } 512 } 513 mSEService = ISecureElementService.Stub.asInterface(ServiceManager.getService( 514 Context.SECURE_ELEMENT_SERVICE)); 515 } 516 517 void initSoundPool() { 518 synchronized (this) { 519 if (mSoundPool == null) { 520 mSoundPool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0); 521 mStartSound = mSoundPool.load(mContext, R.raw.start, 1); 522 mEndSound = mSoundPool.load(mContext, R.raw.end, 1); 523 mErrorSound = mSoundPool.load(mContext, R.raw.error, 1); 524 } 525 } 526 } 527 528 void releaseSoundPool() { 529 synchronized (this) { 530 if (mSoundPool != null) { 531 mSoundPool.release(); 532 mSoundPool = null; 533 } 534 } 535 } 536 537 void updatePackageCache() { 538 PackageManager pm = mContext.getPackageManager(); 539 List<PackageInfo> packagesNfcEvents = pm.getPackagesHoldingPermissions( 540 new String[] {android.Manifest.permission.NFC_TRANSACTION_EVENT}, 541 PackageManager.GET_ACTIVITIES); 542 synchronized (this) { 543 mNfcEventInstalledPackages.clear(); 544 for (int i = 0; i < packagesNfcEvents.size(); i++) { 545 mNfcEventInstalledPackages.add(packagesNfcEvents.get(i).packageName); 546 } 547 } 548 } 549 550 /** 551 * Manages tasks that involve turning on/off the NFC controller. 552 * <p/> 553 * <p>All work that might turn the NFC adapter on or off must be done 554 * through this task, to keep the handling of mState simple. 555 * In other words, mState is only modified in these tasks (and we 556 * don't need a lock to read it in these tasks). 557 * <p/> 558 * <p>These tasks are all done on the same AsyncTask background 559 * thread, so they are serialized. Each task may temporarily transition 560 * mState to STATE_TURNING_OFF or STATE_TURNING_ON, but must exit in 561 * either STATE_ON or STATE_OFF. This way each task can be guaranteed 562 * of starting in either STATE_OFF or STATE_ON, without needing to hold 563 * NfcService.this for the entire task. 564 * <p/> 565 * <p>AsyncTask's are also implicitly queued. This is useful for corner 566 * cases like turning airplane mode on while TASK_ENABLE is in progress. 567 * The TASK_DISABLE triggered by airplane mode will be correctly executed 568 * immediately after TASK_ENABLE is complete. This seems like the most sane 569 * way to deal with these situations. 570 * <p/> 571 * <p>{@link #TASK_ENABLE} enables the NFC adapter, without changing 572 * preferences 573 * <p>{@link #TASK_DISABLE} disables the NFC adapter, without changing 574 * preferences 575 * <p>{@link #TASK_BOOT} does first boot work and may enable NFC 576 */ 577 class EnableDisableTask extends AsyncTask<Integer, Void, Void> { 578 @Override 579 protected Void doInBackground(Integer... params) { 580 // Sanity check mState 581 switch (mState) { 582 case NfcAdapter.STATE_TURNING_OFF: 583 case NfcAdapter.STATE_TURNING_ON: 584 Log.e(TAG, "Processing EnableDisable task " + params[0] + " from bad state " + 585 mState); 586 return null; 587 } 588 589 /* AsyncTask sets this thread to THREAD_PRIORITY_BACKGROUND, 590 * override with the default. THREAD_PRIORITY_BACKGROUND causes 591 * us to service software I2C too slow for firmware download 592 * with the NXP PN544. 593 * TODO: move this to the DAL I2C layer in libnfc-nxp, since this 594 * problem only occurs on I2C platforms using PN544 595 */ 596 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 597 598 switch (params[0].intValue()) { 599 case TASK_ENABLE: 600 enableInternal(); 601 break; 602 case TASK_DISABLE: 603 disableInternal(); 604 break; 605 case TASK_BOOT: 606 if (mPrefs.getBoolean(PREF_FIRST_BOOT, true)) { 607 Log.i(TAG, "First Boot"); 608 mPrefsEditor.putBoolean(PREF_FIRST_BOOT, false); 609 mPrefsEditor.apply(); 610 mDeviceHost.factoryReset(); 611 } 612 Log.d(TAG, "checking on firmware download"); 613 if (mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT)) { 614 Log.d(TAG, "NFC is on. Doing normal stuff"); 615 enableInternal(); 616 } else { 617 Log.d(TAG, "NFC is off. Checking firmware version"); 618 mDeviceHost.checkFirmware(); 619 } 620 SystemProperties.set("nfc.initialized", "true"); 621 break; 622 } 623 624 // Restore default AsyncTask priority 625 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 626 return null; 627 } 628 629 /** 630 * Enable NFC adapter functions. 631 * Does not toggle preferences. 632 */ 633 boolean enableInternal() { 634 if (mState == NfcAdapter.STATE_ON) { 635 return true; 636 } 637 Log.i(TAG, "Enabling NFC"); 638 updateState(NfcAdapter.STATE_TURNING_ON); 639 640 WatchDogThread watchDog = new WatchDogThread("enableInternal", INIT_WATCHDOG_MS); 641 watchDog.start(); 642 try { 643 mRoutingWakeLock.acquire(); 644 try { 645 if (!mDeviceHost.initialize()) { 646 Log.w(TAG, "Error enabling NFC"); 647 updateState(NfcAdapter.STATE_OFF); 648 return false; 649 } 650 } finally { 651 mRoutingWakeLock.release(); 652 } 653 } finally { 654 watchDog.cancel(); 655 } 656 657 if (mIsHceCapable) { 658 // Generate the initial card emulation routing table 659 mCardEmulationManager.onNfcEnabled(); 660 } 661 662 nci_version = getNciVersion(); 663 Log.d(TAG, "NCI_Version: " + nci_version); 664 665 synchronized (NfcService.this) { 666 mObjectMap.clear(); 667 mP2pLinkManager.enableDisable(mIsNdefPushEnabled, true); 668 updateState(NfcAdapter.STATE_ON); 669 } 670 671 initSoundPool(); 672 673 mScreenState = mScreenStateHelper.checkScreenState(); 674 int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ? 675 (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState; 676 677 if(mNfcUnlockManager.isLockscreenPollingEnabled()) 678 applyRouting(false); 679 680 mDeviceHost.doSetScreenState(screen_state_mask); 681 682 /* Start polling loop */ 683 684 applyRouting(true); 685 return true; 686 } 687 688 /** 689 * Disable all NFC adapter functions. 690 * Does not toggle preferences. 691 */ 692 boolean disableInternal() { 693 if (mState == NfcAdapter.STATE_OFF) { 694 return true; 695 } 696 Log.i(TAG, "Disabling NFC"); 697 updateState(NfcAdapter.STATE_TURNING_OFF); 698 699 /* Sometimes mDeviceHost.deinitialize() hangs, use a watch-dog. 700 * Implemented with a new thread (instead of a Handler or AsyncTask), 701 * because the UI Thread and AsyncTask thread-pools can also get hung 702 * when the NFC controller stops responding */ 703 WatchDogThread watchDog = new WatchDogThread("disableInternal", ROUTING_WATCHDOG_MS); 704 watchDog.start(); 705 706 if (mIsHceCapable) { 707 mCardEmulationManager.onNfcDisabled(); 708 } 709 710 mP2pLinkManager.enableDisable(false, false); 711 712 // Stop watchdog if tag present 713 // A convenient way to stop the watchdog properly consists of 714 // disconnecting the tag. The polling loop shall be stopped before 715 // to avoid the tag being discovered again. 716 maybeDisconnectTarget(); 717 718 mNfcDispatcher.setForegroundDispatch(null, null, null); 719 720 721 boolean result = mDeviceHost.deinitialize(); 722 if (DBG) Log.d(TAG, "mDeviceHost.deinitialize() = " + result); 723 724 watchDog.cancel(); 725 726 synchronized (NfcService.this) { 727 mCurrentDiscoveryParameters = NfcDiscoveryParameters.getNfcOffParameters(); 728 updateState(NfcAdapter.STATE_OFF); 729 } 730 731 releaseSoundPool(); 732 733 return result; 734 } 735 736 void updateState(int newState) { 737 synchronized (NfcService.this) { 738 if (newState == mState) { 739 return; 740 } 741 mState = newState; 742 Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED); 743 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 744 intent.putExtra(NfcAdapter.EXTRA_ADAPTER_STATE, mState); 745 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT); 746 } 747 } 748 } 749 750 void saveNfcOnSetting(boolean on) { 751 synchronized (NfcService.this) { 752 mPrefsEditor.putBoolean(PREF_NFC_ON, on); 753 mPrefsEditor.apply(); 754 mBackupManager.dataChanged(); 755 } 756 } 757 758 public void playSound(int sound) { 759 synchronized (this) { 760 if (mSoundPool == null) { 761 Log.w(TAG, "Not playing sound when NFC is disabled"); 762 return; 763 } 764 765 if (mIsVrModeEnabled) { 766 Log.d(TAG, "Not playing NFC sound when Vr Mode is enabled"); 767 return; 768 } 769 switch (sound) { 770 case SOUND_START: 771 mSoundPool.play(mStartSound, 1.0f, 1.0f, 0, 0, 1.0f); 772 break; 773 case SOUND_END: 774 mSoundPool.play(mEndSound, 1.0f, 1.0f, 0, 0, 1.0f); 775 break; 776 case SOUND_ERROR: 777 mSoundPool.play(mErrorSound, 1.0f, 1.0f, 0, 0, 1.0f); 778 break; 779 } 780 } 781 } 782 783 synchronized int getUserId() { 784 return mUserId; 785 } 786 787 void enforceBeamShareActivityPolicy(Context context, UserHandle uh) { 788 UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); 789 IPackageManager mIpm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); 790 boolean isGlobalEnabled = mIsNdefPushEnabled; 791 if (uh.getIdentifier() != mUserId) { 792 try { 793 int userSetting = mIpm.getComponentEnabledSetting(new ComponentName( 794 BeamShareActivity.class.getPackageName$(), 795 BeamShareActivity.class.getName()), uh.getIdentifier()); 796 isGlobalEnabled = (userSetting == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) ? false : true; 797 } catch (RemoteException e) { 798 Log.w(TAG, "Unable to get Beam status for user " + uh); 799 } 800 } 801 boolean isActiveForUser = 802 (!um.hasUserRestriction(UserManager.DISALLOW_OUTGOING_BEAM, uh)) && 803 isGlobalEnabled; 804 if (DBG) { 805 Log.d(TAG, "Enforcing a policy change on user: " + uh.toString() + 806 ", isActiveForUser = " + isActiveForUser); 807 } 808 try { 809 mIpm.setComponentEnabledSetting(new ComponentName( 810 BeamShareActivity.class.getPackageName$(), 811 BeamShareActivity.class.getName()), 812 isActiveForUser ? 813 PackageManager.COMPONENT_ENABLED_STATE_ENABLED : 814 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 815 PackageManager.DONT_KILL_APP, 816 uh.getIdentifier()); 817 } catch (RemoteException e) { 818 Log.w(TAG, "Unable to change Beam status for user " + uh); 819 } 820 } 821 822 final class NfcAdapterService extends INfcAdapter.Stub { 823 @Override 824 public boolean enable() throws RemoteException { 825 NfcPermissions.enforceAdminPermissions(mContext); 826 827 saveNfcOnSetting(true); 828 829 new EnableDisableTask().execute(TASK_ENABLE); 830 831 return true; 832 } 833 834 @Override 835 public boolean disable(boolean saveState) throws RemoteException { 836 NfcPermissions.enforceAdminPermissions(mContext); 837 838 if (saveState) { 839 saveNfcOnSetting(false); 840 } 841 842 new EnableDisableTask().execute(TASK_DISABLE); 843 844 return true; 845 } 846 847 @Override 848 public void pausePolling(int timeoutInMs) { 849 NfcPermissions.enforceAdminPermissions(mContext); 850 851 if (timeoutInMs <= 0 || timeoutInMs > MAX_POLLING_PAUSE_TIMEOUT) { 852 Log.e(TAG, "Refusing to pause polling for " + timeoutInMs + "ms."); 853 return; 854 } 855 856 synchronized (NfcService.this) { 857 mPollingPaused = true; 858 mDeviceHost.disableDiscovery(); 859 mHandler.sendMessageDelayed( 860 mHandler.obtainMessage(MSG_RESUME_POLLING), timeoutInMs); 861 } 862 } 863 864 @Override 865 public void resumePolling() { 866 NfcPermissions.enforceAdminPermissions(mContext); 867 868 synchronized (NfcService.this) { 869 if (!mPollingPaused) { 870 return; 871 } 872 873 mHandler.removeMessages(MSG_RESUME_POLLING); 874 mPollingPaused = false; 875 new ApplyRoutingTask().execute(); 876 } 877 } 878 879 @Override 880 public boolean isNdefPushEnabled() throws RemoteException { 881 synchronized (NfcService.this) { 882 return mState == NfcAdapter.STATE_ON && mIsNdefPushEnabled; 883 } 884 } 885 886 @Override 887 public boolean enableNdefPush() throws RemoteException { 888 NfcPermissions.enforceAdminPermissions(mContext); 889 synchronized (NfcService.this) { 890 if (mIsNdefPushEnabled) { 891 return true; 892 } 893 Log.i(TAG, "enabling NDEF Push"); 894 mPrefsEditor.putBoolean(PREF_NDEF_PUSH_ON, true); 895 mPrefsEditor.apply(); 896 mIsNdefPushEnabled = true; 897 enforceBeamShareActivityPolicy(mContext, new UserHandle(mUserId)); 898 if (isNfcEnabled()) { 899 mP2pLinkManager.enableDisable(true, true); 900 } 901 mBackupManager.dataChanged(); 902 } 903 return true; 904 } 905 906 @Override 907 public boolean disableNdefPush() throws RemoteException { 908 NfcPermissions.enforceAdminPermissions(mContext); 909 synchronized (NfcService.this) { 910 if (!mIsNdefPushEnabled) { 911 return true; 912 } 913 Log.i(TAG, "disabling NDEF Push"); 914 mPrefsEditor.putBoolean(PREF_NDEF_PUSH_ON, false); 915 mPrefsEditor.apply(); 916 mIsNdefPushEnabled = false; 917 enforceBeamShareActivityPolicy(mContext, new UserHandle(mUserId)); 918 if (isNfcEnabled()) { 919 mP2pLinkManager.enableDisable(false, true); 920 } 921 mBackupManager.dataChanged(); 922 } 923 return true; 924 } 925 926 @Override 927 public void setForegroundDispatch(PendingIntent intent, 928 IntentFilter[] filters, TechListParcel techListsParcel) { 929 NfcPermissions.enforceUserPermissions(mContext); 930 if (!mForegroundUtils.isInForeground(Binder.getCallingUid())) { 931 Log.e(TAG, "setForegroundDispatch: Caller not in foreground."); 932 return; 933 } 934 // Short-cut the disable path 935 if (intent == null && filters == null && techListsParcel == null) { 936 mNfcDispatcher.setForegroundDispatch(null, null, null); 937 return; 938 } 939 940 // Validate the IntentFilters 941 if (filters != null) { 942 if (filters.length == 0) { 943 filters = null; 944 } else { 945 for (IntentFilter filter : filters) { 946 if (filter == null) { 947 throw new IllegalArgumentException("null IntentFilter"); 948 } 949 } 950 } 951 } 952 953 // Validate the tech lists 954 String[][] techLists = null; 955 if (techListsParcel != null) { 956 techLists = techListsParcel.getTechLists(); 957 } 958 959 mNfcDispatcher.setForegroundDispatch(intent, filters, techLists); 960 } 961 962 963 @Override 964 public void setAppCallback(IAppCallback callback) { 965 NfcPermissions.enforceUserPermissions(mContext); 966 967 // don't allow Beam for managed profiles, or devices with a device owner or policy owner 968 UserInfo userInfo = mUserManager.getUserInfo(UserHandle.getCallingUserId()); 969 if(!mUserManager.hasUserRestriction( 970 UserManager.DISALLOW_OUTGOING_BEAM, userInfo.getUserHandle())) { 971 mP2pLinkManager.setNdefCallback(callback, Binder.getCallingUid()); 972 } else if (DBG) { 973 Log.d(TAG, "Disabling default Beam behavior"); 974 } 975 } 976 977 @Override 978 public boolean ignore(int nativeHandle, int debounceMs, ITagRemovedCallback callback) 979 throws RemoteException { 980 NfcPermissions.enforceUserPermissions(mContext); 981 982 if (debounceMs == 0 && mDebounceTagNativeHandle != INVALID_NATIVE_HANDLE 983 && nativeHandle == mDebounceTagNativeHandle) { 984 // Remove any previous messages and immediately debounce. 985 mHandler.removeMessages(MSG_TAG_DEBOUNCE); 986 mHandler.sendEmptyMessage(MSG_TAG_DEBOUNCE); 987 return true; 988 } 989 990 TagEndpoint tag = (TagEndpoint) findAndRemoveObject(nativeHandle); 991 if (tag != null) { 992 // Store UID and params 993 int uidLength = tag.getUid().length; 994 synchronized (NfcService.this) { 995 mDebounceTagDebounceMs = debounceMs; 996 mDebounceTagNativeHandle = nativeHandle; 997 mDebounceTagUid = new byte[uidLength]; 998 mDebounceTagRemovedCallback = callback; 999 System.arraycopy(tag.getUid(), 0, mDebounceTagUid, 0, uidLength); 1000 } 1001 1002 // Disconnect from this tag; this should resume the normal 1003 // polling loop (and enter listen mode for a while), before 1004 // we pick up any tags again. 1005 tag.disconnect(); 1006 mHandler.sendEmptyMessageDelayed(MSG_TAG_DEBOUNCE, debounceMs); 1007 return true; 1008 } else { 1009 return false; 1010 } 1011 } 1012 1013 @Override 1014 public void verifyNfcPermission() { 1015 NfcPermissions.enforceUserPermissions(mContext); 1016 } 1017 1018 @Override 1019 public void invokeBeam() { 1020 NfcPermissions.enforceUserPermissions(mContext); 1021 1022 if (mForegroundUtils.isInForeground(Binder.getCallingUid())) { 1023 mP2pLinkManager.onManualBeamInvoke(null); 1024 } else { 1025 Log.e(TAG, "Calling activity not in foreground."); 1026 } 1027 } 1028 1029 @Override 1030 public void invokeBeamInternal(BeamShareData shareData) { 1031 NfcPermissions.enforceAdminPermissions(mContext); 1032 Message msg = Message.obtain(); 1033 msg.what = MSG_INVOKE_BEAM; 1034 msg.obj = shareData; 1035 // We have to send this message delayed for two reasons: 1036 // 1) This is an IPC call from BeamShareActivity, which is 1037 // running when the user has invoked Beam through the 1038 // share menu. As soon as BeamShareActivity closes, the UI 1039 // will need some time to rebuild the original Activity. 1040 // Waiting here for a while gives a better chance of the UI 1041 // having been rebuilt, which means the screenshot that the 1042 // Beam animation is using will be more accurate. 1043 // 2) Similarly, because the Activity that launched BeamShareActivity 1044 // with an ACTION_SEND intent is now in paused state, the NDEF 1045 // callbacks that it has registered may no longer be valid. 1046 // Allowing the original Activity to resume will make sure we 1047 // it has a chance to re-register the NDEF message / callback, 1048 // so we share the right data. 1049 // 1050 // Note that this is somewhat of a hack because the delay may not actually 1051 // be long enough for 2) on very slow devices, but there's no better 1052 // way to do this right now without additional framework changes. 1053 mHandler.sendMessageDelayed(msg, INVOKE_BEAM_DELAY_MS); 1054 } 1055 1056 @Override 1057 public INfcTag getNfcTagInterface() throws RemoteException { 1058 return mNfcTagService; 1059 } 1060 1061 @Override 1062 public INfcCardEmulation getNfcCardEmulationInterface() { 1063 if (mIsHceCapable) { 1064 return mCardEmulationManager.getNfcCardEmulationInterface(); 1065 } else { 1066 return null; 1067 } 1068 } 1069 1070 @Override 1071 public INfcFCardEmulation getNfcFCardEmulationInterface() { 1072 if (mIsHceFCapable) { 1073 return mCardEmulationManager.getNfcFCardEmulationInterface(); 1074 } else { 1075 return null; 1076 } 1077 } 1078 1079 @Override 1080 public int getState() throws RemoteException { 1081 synchronized (NfcService.this) { 1082 return mState; 1083 } 1084 } 1085 1086 @Override 1087 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1088 NfcService.this.dump(fd, pw, args); 1089 } 1090 1091 @Override 1092 public void dispatch(Tag tag) throws RemoteException { 1093 NfcPermissions.enforceAdminPermissions(mContext); 1094 mNfcDispatcher.dispatchTag(tag); 1095 } 1096 1097 @Override 1098 public void setP2pModes(int initiatorModes, int targetModes) throws RemoteException { 1099 NfcPermissions.enforceAdminPermissions(mContext); 1100 mDeviceHost.setP2pInitiatorModes(initiatorModes); 1101 mDeviceHost.setP2pTargetModes(targetModes); 1102 applyRouting(true); 1103 } 1104 1105 @Override 1106 public void setReaderMode(IBinder binder, IAppCallback callback, int flags, Bundle extras) 1107 throws RemoteException { 1108 int callingUid = Binder.getCallingUid(); 1109 if (callingUid != Process.SYSTEM_UID && !mForegroundUtils.isInForeground(callingUid)) { 1110 Log.e(TAG, "setReaderMode: Caller is not in foreground and is not system process."); 1111 return; 1112 } 1113 synchronized (NfcService.this) { 1114 if (!isNfcEnabled()) { 1115 Log.e(TAG, "setReaderMode() called while NFC is not enabled."); 1116 return; 1117 } 1118 if (flags != 0) { 1119 try { 1120 mReaderModeParams = new ReaderModeParams(); 1121 mReaderModeParams.callback = callback; 1122 mReaderModeParams.flags = flags; 1123 mReaderModeParams.presenceCheckDelay = extras != null 1124 ? (extras.getInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 1125 DEFAULT_PRESENCE_CHECK_DELAY)) 1126 : DEFAULT_PRESENCE_CHECK_DELAY; 1127 binder.linkToDeath(mReaderModeDeathRecipient, 0); 1128 } catch (RemoteException e) { 1129 Log.e(TAG, "Remote binder has already died."); 1130 return; 1131 } 1132 } else { 1133 try { 1134 mReaderModeParams = null; 1135 StopPresenceChecking(); 1136 binder.unlinkToDeath(mReaderModeDeathRecipient, 0); 1137 } catch (NoSuchElementException e) { 1138 Log.e(TAG, "Reader mode Binder was never registered."); 1139 } 1140 } 1141 applyRouting(false); 1142 } 1143 } 1144 1145 @Override 1146 public INfcAdapterExtras getNfcAdapterExtrasInterface(String pkg) throws RemoteException { 1147 // nfc-extras implementation is no longer present in AOSP. 1148 return null; 1149 } 1150 1151 @Override 1152 public INfcDta getNfcDtaInterface(String pkg) throws RemoteException { 1153 NfcPermissions.enforceAdminPermissions(mContext); 1154 if (mNfcDtaService == null) { 1155 mNfcDtaService = new NfcDtaService(); 1156 } 1157 return mNfcDtaService; 1158 } 1159 1160 @Override 1161 public void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, int[] techList) { 1162 NfcPermissions.enforceAdminPermissions(mContext); 1163 1164 int lockscreenPollMask = computeLockscreenPollMask(techList); 1165 synchronized (NfcService.this) { 1166 mNfcUnlockManager.addUnlockHandler(unlockHandler, lockscreenPollMask); 1167 } 1168 1169 applyRouting(false); 1170 } 1171 1172 @Override 1173 public void removeNfcUnlockHandler(INfcUnlockHandler token) throws RemoteException { 1174 synchronized (NfcService.this) { 1175 mNfcUnlockManager.removeUnlockHandler(token.asBinder()); 1176 } 1177 1178 applyRouting(false); 1179 } 1180 1181 private int computeLockscreenPollMask(int[] techList) { 1182 1183 Map<Integer, Integer> techCodeToMask = new HashMap<Integer, Integer>(); 1184 1185 techCodeToMask.put(TagTechnology.NFC_A, NfcService.NFC_POLL_A); 1186 techCodeToMask.put(TagTechnology.NFC_B, NfcService.NFC_POLL_B); 1187 techCodeToMask.put(TagTechnology.NFC_V, NfcService.NFC_POLL_V); 1188 techCodeToMask.put(TagTechnology.NFC_F, NfcService.NFC_POLL_F); 1189 techCodeToMask.put(TagTechnology.NFC_BARCODE, NfcService.NFC_POLL_KOVIO); 1190 1191 int mask = 0; 1192 1193 for (int i = 0; i < techList.length; i++) { 1194 if (techCodeToMask.containsKey(techList[i])) { 1195 mask |= techCodeToMask.get(techList[i]).intValue(); 1196 } 1197 } 1198 1199 return mask; 1200 } 1201 } 1202 1203 final class ReaderModeDeathRecipient implements IBinder.DeathRecipient { 1204 @Override 1205 public void binderDied() { 1206 synchronized (NfcService.this) { 1207 if (mReaderModeParams != null) { 1208 mReaderModeParams = null; 1209 applyRouting(false); 1210 } 1211 } 1212 } 1213 } 1214 1215 final class TagService extends INfcTag.Stub { 1216 @Override 1217 public int connect(int nativeHandle, int technology) throws RemoteException { 1218 NfcPermissions.enforceUserPermissions(mContext); 1219 1220 TagEndpoint tag = null; 1221 1222 if (!isNfcEnabled()) { 1223 return ErrorCodes.ERROR_NOT_INITIALIZED; 1224 } 1225 1226 /* find the tag in the hmap */ 1227 tag = (TagEndpoint) findObject(nativeHandle); 1228 if (tag == null) { 1229 return ErrorCodes.ERROR_DISCONNECT; 1230 } 1231 1232 if (!tag.isPresent()) { 1233 return ErrorCodes.ERROR_DISCONNECT; 1234 } 1235 1236 // Note that on most tags, all technologies are behind a single 1237 // handle. This means that the connect at the lower levels 1238 // will do nothing, as the tag is already connected to that handle. 1239 if (tag.connect(technology)) { 1240 return ErrorCodes.SUCCESS; 1241 } else { 1242 return ErrorCodes.ERROR_DISCONNECT; 1243 } 1244 } 1245 1246 @Override 1247 public int reconnect(int nativeHandle) throws RemoteException { 1248 NfcPermissions.enforceUserPermissions(mContext); 1249 1250 TagEndpoint tag = null; 1251 1252 // Check if NFC is enabled 1253 if (!isNfcEnabled()) { 1254 return ErrorCodes.ERROR_NOT_INITIALIZED; 1255 } 1256 1257 /* find the tag in the hmap */ 1258 tag = (TagEndpoint) findObject(nativeHandle); 1259 if (tag != null) { 1260 if (tag.reconnect()) { 1261 return ErrorCodes.SUCCESS; 1262 } else { 1263 return ErrorCodes.ERROR_DISCONNECT; 1264 } 1265 } 1266 return ErrorCodes.ERROR_DISCONNECT; 1267 } 1268 1269 @Override 1270 public int[] getTechList(int nativeHandle) throws RemoteException { 1271 NfcPermissions.enforceUserPermissions(mContext); 1272 1273 // Check if NFC is enabled 1274 if (!isNfcEnabled()) { 1275 return null; 1276 } 1277 1278 /* find the tag in the hmap */ 1279 TagEndpoint tag = (TagEndpoint) findObject(nativeHandle); 1280 if (tag != null) { 1281 return tag.getTechList(); 1282 } 1283 return null; 1284 } 1285 1286 @Override 1287 public boolean isPresent(int nativeHandle) throws RemoteException { 1288 TagEndpoint tag = null; 1289 1290 // Check if NFC is enabled 1291 if (!isNfcEnabled()) { 1292 return false; 1293 } 1294 1295 /* find the tag in the hmap */ 1296 tag = (TagEndpoint) findObject(nativeHandle); 1297 if (tag == null) { 1298 return false; 1299 } 1300 1301 return tag.isPresent(); 1302 } 1303 1304 @Override 1305 public boolean isNdef(int nativeHandle) throws RemoteException { 1306 NfcPermissions.enforceUserPermissions(mContext); 1307 1308 TagEndpoint tag = null; 1309 1310 // Check if NFC is enabled 1311 if (!isNfcEnabled()) { 1312 return false; 1313 } 1314 1315 /* find the tag in the hmap */ 1316 tag = (TagEndpoint) findObject(nativeHandle); 1317 int[] ndefInfo = new int[2]; 1318 if (tag == null) { 1319 return false; 1320 } 1321 return tag.checkNdef(ndefInfo); 1322 } 1323 1324 @Override 1325 public TransceiveResult transceive(int nativeHandle, byte[] data, boolean raw) 1326 throws RemoteException { 1327 NfcPermissions.enforceUserPermissions(mContext); 1328 1329 TagEndpoint tag = null; 1330 byte[] response; 1331 1332 // Check if NFC is enabled 1333 if (!isNfcEnabled()) { 1334 return null; 1335 } 1336 1337 /* find the tag in the hmap */ 1338 tag = (TagEndpoint) findObject(nativeHandle); 1339 if (tag != null) { 1340 // Check if length is within limits 1341 if (data.length > getMaxTransceiveLength(tag.getConnectedTechnology())) { 1342 return new TransceiveResult(TransceiveResult.RESULT_EXCEEDED_LENGTH, null); 1343 } 1344 int[] targetLost = new int[1]; 1345 response = tag.transceive(data, raw, targetLost); 1346 int result; 1347 if (response != null) { 1348 result = TransceiveResult.RESULT_SUCCESS; 1349 } else if (targetLost[0] == 1) { 1350 result = TransceiveResult.RESULT_TAGLOST; 1351 } else { 1352 result = TransceiveResult.RESULT_FAILURE; 1353 } 1354 return new TransceiveResult(result, response); 1355 } 1356 return null; 1357 } 1358 1359 @Override 1360 public NdefMessage ndefRead(int nativeHandle) throws RemoteException { 1361 NfcPermissions.enforceUserPermissions(mContext); 1362 1363 TagEndpoint tag; 1364 1365 // Check if NFC is enabled 1366 if (!isNfcEnabled()) { 1367 return null; 1368 } 1369 1370 /* find the tag in the hmap */ 1371 tag = (TagEndpoint) findObject(nativeHandle); 1372 if (tag != null) { 1373 byte[] buf = tag.readNdef(); 1374 if (buf == null) { 1375 return null; 1376 } 1377 1378 /* Create an NdefMessage */ 1379 try { 1380 return new NdefMessage(buf); 1381 } catch (FormatException e) { 1382 return null; 1383 } 1384 } 1385 return null; 1386 } 1387 1388 @Override 1389 public int ndefWrite(int nativeHandle, NdefMessage msg) throws RemoteException { 1390 NfcPermissions.enforceUserPermissions(mContext); 1391 1392 TagEndpoint tag; 1393 1394 // Check if NFC is enabled 1395 if (!isNfcEnabled()) { 1396 return ErrorCodes.ERROR_NOT_INITIALIZED; 1397 } 1398 1399 /* find the tag in the hmap */ 1400 tag = (TagEndpoint) findObject(nativeHandle); 1401 if (tag == null) { 1402 return ErrorCodes.ERROR_IO; 1403 } 1404 1405 if (msg == null) return ErrorCodes.ERROR_INVALID_PARAM; 1406 1407 if (tag.writeNdef(msg.toByteArray())) { 1408 return ErrorCodes.SUCCESS; 1409 } else { 1410 return ErrorCodes.ERROR_IO; 1411 } 1412 1413 } 1414 1415 @Override 1416 public boolean ndefIsWritable(int nativeHandle) throws RemoteException { 1417 throw new UnsupportedOperationException(); 1418 } 1419 1420 @Override 1421 public int ndefMakeReadOnly(int nativeHandle) throws RemoteException { 1422 NfcPermissions.enforceUserPermissions(mContext); 1423 1424 TagEndpoint tag; 1425 1426 // Check if NFC is enabled 1427 if (!isNfcEnabled()) { 1428 return ErrorCodes.ERROR_NOT_INITIALIZED; 1429 } 1430 1431 /* find the tag in the hmap */ 1432 tag = (TagEndpoint) findObject(nativeHandle); 1433 if (tag == null) { 1434 return ErrorCodes.ERROR_IO; 1435 } 1436 1437 if (tag.makeReadOnly()) { 1438 return ErrorCodes.SUCCESS; 1439 } else { 1440 return ErrorCodes.ERROR_IO; 1441 } 1442 } 1443 1444 @Override 1445 public int formatNdef(int nativeHandle, byte[] key) throws RemoteException { 1446 NfcPermissions.enforceUserPermissions(mContext); 1447 1448 TagEndpoint tag; 1449 1450 // Check if NFC is enabled 1451 if (!isNfcEnabled()) { 1452 return ErrorCodes.ERROR_NOT_INITIALIZED; 1453 } 1454 1455 /* find the tag in the hmap */ 1456 tag = (TagEndpoint) findObject(nativeHandle); 1457 if (tag == null) { 1458 return ErrorCodes.ERROR_IO; 1459 } 1460 1461 if (tag.formatNdef(key)) { 1462 return ErrorCodes.SUCCESS; 1463 } else { 1464 return ErrorCodes.ERROR_IO; 1465 } 1466 } 1467 1468 @Override 1469 public Tag rediscover(int nativeHandle) throws RemoteException { 1470 NfcPermissions.enforceUserPermissions(mContext); 1471 1472 TagEndpoint tag = null; 1473 1474 // Check if NFC is enabled 1475 if (!isNfcEnabled()) { 1476 return null; 1477 } 1478 1479 /* find the tag in the hmap */ 1480 tag = (TagEndpoint) findObject(nativeHandle); 1481 if (tag != null) { 1482 // For now the prime usecase for rediscover() is to be able 1483 // to access the NDEF technology after formatting without 1484 // having to remove the tag from the field, or similar 1485 // to have access to NdefFormatable in case low-level commands 1486 // were used to remove NDEF. So instead of doing a full stack 1487 // rediscover (which is poorly supported at the moment anyway), 1488 // we simply remove these two technologies and detect them 1489 // again. 1490 tag.removeTechnology(TagTechnology.NDEF); 1491 tag.removeTechnology(TagTechnology.NDEF_FORMATABLE); 1492 tag.findAndReadNdef(); 1493 // Build a new Tag object to return 1494 Tag newTag = new Tag(tag.getUid(), tag.getTechList(), 1495 tag.getTechExtras(), tag.getHandle(), this); 1496 return newTag; 1497 } 1498 return null; 1499 } 1500 1501 @Override 1502 public int setTimeout(int tech, int timeout) throws RemoteException { 1503 NfcPermissions.enforceUserPermissions(mContext); 1504 boolean success = mDeviceHost.setTimeout(tech, timeout); 1505 if (success) { 1506 return ErrorCodes.SUCCESS; 1507 } else { 1508 return ErrorCodes.ERROR_INVALID_PARAM; 1509 } 1510 } 1511 1512 @Override 1513 public int getTimeout(int tech) throws RemoteException { 1514 NfcPermissions.enforceUserPermissions(mContext); 1515 1516 return mDeviceHost.getTimeout(tech); 1517 } 1518 1519 @Override 1520 public void resetTimeouts() throws RemoteException { 1521 NfcPermissions.enforceUserPermissions(mContext); 1522 1523 mDeviceHost.resetTimeouts(); 1524 } 1525 1526 @Override 1527 public boolean canMakeReadOnly(int ndefType) throws RemoteException { 1528 return mDeviceHost.canMakeReadOnly(ndefType); 1529 } 1530 1531 @Override 1532 public int getMaxTransceiveLength(int tech) throws RemoteException { 1533 return mDeviceHost.getMaxTransceiveLength(tech); 1534 } 1535 1536 @Override 1537 public boolean getExtendedLengthApdusSupported() throws RemoteException { 1538 return mDeviceHost.getExtendedLengthApdusSupported(); 1539 } 1540 } 1541 1542 final class NfcDtaService extends INfcDta.Stub { 1543 public void enableDta() throws RemoteException { 1544 NfcPermissions.enforceAdminPermissions(mContext); 1545 if(!sIsDtaMode) { 1546 mDeviceHost.enableDtaMode(); 1547 sIsDtaMode = true; 1548 Log.d(TAG, "DTA Mode is Enabled "); 1549 } 1550 } 1551 1552 public void disableDta() throws RemoteException { 1553 NfcPermissions.enforceAdminPermissions(mContext); 1554 if(sIsDtaMode) { 1555 mDeviceHost.disableDtaMode(); 1556 sIsDtaMode = false; 1557 } 1558 } 1559 1560 public boolean enableServer(String serviceName, int serviceSap, int miu, 1561 int rwSize,int testCaseId) throws RemoteException { 1562 NfcPermissions.enforceAdminPermissions(mContext); 1563 1564 if(serviceName.equals(null)) 1565 return false; 1566 1567 mP2pLinkManager.enableExtDtaSnepServer(serviceName, serviceSap, miu, rwSize,testCaseId); 1568 return true; 1569 } 1570 1571 public void disableServer() throws RemoteException { 1572 NfcPermissions.enforceAdminPermissions(mContext); 1573 mP2pLinkManager.disableExtDtaSnepServer(); 1574 } 1575 1576 public boolean enableClient(String serviceName, int miu, int rwSize, 1577 int testCaseId) throws RemoteException { 1578 NfcPermissions.enforceAdminPermissions(mContext); 1579 1580 if(testCaseId == 0) 1581 return false; 1582 1583 if (testCaseId>20){ 1584 sIsShortRecordLayout=true; 1585 testCaseId=testCaseId-20; 1586 } else { 1587 sIsShortRecordLayout=false; 1588 } 1589 Log.d("testCaseId", ""+testCaseId); 1590 mP2pLinkManager.enableDtaSnepClient(serviceName, miu, rwSize, testCaseId); 1591 return true; 1592 } 1593 1594 public void disableClient() throws RemoteException { 1595 NfcPermissions.enforceAdminPermissions(mContext); 1596 mP2pLinkManager.disableDtaSnepClient(); 1597 } 1598 1599 public boolean registerMessageService(String msgServiceName) 1600 throws RemoteException { 1601 NfcPermissions.enforceAdminPermissions(mContext); 1602 if(msgServiceName.equals(null)) 1603 return false; 1604 1605 DtaServiceConnector.setMessageService(msgServiceName); 1606 return true; 1607 } 1608 1609 }; 1610 1611 boolean isNfcEnabledOrShuttingDown() { 1612 synchronized (this) { 1613 return (mState == NfcAdapter.STATE_ON || mState == NfcAdapter.STATE_TURNING_OFF); 1614 } 1615 } 1616 1617 boolean isNfcEnabled() { 1618 synchronized (this) { 1619 return mState == NfcAdapter.STATE_ON; 1620 } 1621 } 1622 1623 class WatchDogThread extends Thread { 1624 final Object mCancelWaiter = new Object(); 1625 final int mTimeout; 1626 boolean mCanceled = false; 1627 1628 public WatchDogThread(String threadName, int timeout) { 1629 super(threadName); 1630 mTimeout = timeout; 1631 } 1632 1633 @Override 1634 public void run() { 1635 try { 1636 synchronized (mCancelWaiter) { 1637 mCancelWaiter.wait(mTimeout); 1638 if (mCanceled) { 1639 return; 1640 } 1641 } 1642 } catch (InterruptedException e) { 1643 // Should not happen; fall-through to abort. 1644 Log.w(TAG, "Watchdog thread interruped."); 1645 interrupt(); 1646 } 1647 Log.e(TAG, "Watchdog triggered, aborting."); 1648 mDeviceHost.doAbort(getName()); 1649 } 1650 1651 public synchronized void cancel() { 1652 synchronized (mCancelWaiter) { 1653 mCanceled = true; 1654 mCancelWaiter.notify(); 1655 } 1656 } 1657 } 1658 1659 static byte[] hexStringToBytes(String s) { 1660 if (s == null || s.length() == 0) return null; 1661 int len = s.length(); 1662 if (len % 2 != 0) { 1663 s = '0' + s; 1664 len++; 1665 } 1666 byte[] data = new byte[len / 2]; 1667 for (int i = 0; i < len; i += 2) { 1668 data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 1669 + Character.digit(s.charAt(i + 1), 16)); 1670 } 1671 return data; 1672 } 1673 1674 /** 1675 * Read mScreenState and apply NFC-C polling and NFC-EE routing 1676 */ 1677 void applyRouting(boolean force) { 1678 synchronized (this) { 1679 if (!isNfcEnabledOrShuttingDown()) { 1680 return; 1681 } 1682 WatchDogThread watchDog = new WatchDogThread("applyRouting", ROUTING_WATCHDOG_MS); 1683 if (mInProvisionMode) { 1684 mInProvisionMode = Settings.Secure.getInt(mContentResolver, 1685 Settings.Global.DEVICE_PROVISIONED, 0) == 0; 1686 if (!mInProvisionMode) { 1687 // Notify dispatcher it's fine to dispatch to any package now 1688 // and allow handover transfers. 1689 mNfcDispatcher.disableProvisioningMode(); 1690 } 1691 } 1692 // Special case: if we're transitioning to unlocked state while 1693 // still talking to a tag, postpone re-configuration. 1694 if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED && isTagPresent()) { 1695 Log.d(TAG, "Not updating discovery parameters, tag connected."); 1696 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESUME_POLLING), 1697 APPLY_ROUTING_RETRY_TIMEOUT_MS); 1698 return; 1699 } 1700 1701 try { 1702 watchDog.start(); 1703 // Compute new polling parameters 1704 NfcDiscoveryParameters newParams = computeDiscoveryParameters(mScreenState); 1705 if (force || !newParams.equals(mCurrentDiscoveryParameters)) { 1706 if (newParams.shouldEnableDiscovery()) { 1707 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery(); 1708 mDeviceHost.enableDiscovery(newParams, shouldRestart); 1709 } else { 1710 mDeviceHost.disableDiscovery(); 1711 } 1712 mCurrentDiscoveryParameters = newParams; 1713 } else { 1714 Log.d(TAG, "Discovery configuration equal, not updating."); 1715 } 1716 } finally { 1717 watchDog.cancel(); 1718 } 1719 } 1720 } 1721 1722 private NfcDiscoveryParameters computeDiscoveryParameters(int screenState) { 1723 // Recompute discovery parameters based on screen state 1724 NfcDiscoveryParameters.Builder paramsBuilder = NfcDiscoveryParameters.newBuilder(); 1725 // Polling 1726 if (screenState >= NFC_POLLING_MODE) { 1727 // Check if reader-mode is enabled 1728 if (mReaderModeParams != null) { 1729 int techMask = 0; 1730 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_A) != 0) 1731 techMask |= NFC_POLL_A; 1732 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_B) != 0) 1733 techMask |= NFC_POLL_B; 1734 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_F) != 0) 1735 techMask |= NFC_POLL_F; 1736 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_V) != 0) 1737 techMask |= NFC_POLL_V; 1738 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_BARCODE) != 0) 1739 techMask |= NFC_POLL_KOVIO; 1740 1741 paramsBuilder.setTechMask(techMask); 1742 paramsBuilder.setEnableReaderMode(true); 1743 } else { 1744 paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT); 1745 paramsBuilder.setEnableP2p(true); 1746 } 1747 } else if (screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mInProvisionMode) { 1748 paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT); 1749 // enable P2P for MFM/EDU/Corp provisioning 1750 paramsBuilder.setEnableP2p(true); 1751 } else if (screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && 1752 (mIsLiveCaseEnabled || mNfcUnlockManager.isLockscreenPollingEnabled())) { 1753 int techMask = 0; 1754 // enable polling for Live Case technologies 1755 if (mIsLiveCaseEnabled) 1756 techMask |= mLiveCaseTechnology; 1757 if (mNfcUnlockManager.isLockscreenPollingEnabled()) 1758 techMask |= mNfcUnlockManager.getLockscreenPollMask(); 1759 paramsBuilder.setTechMask(techMask); 1760 paramsBuilder.setEnableLowPowerDiscovery(false); 1761 paramsBuilder.setEnableP2p(false); 1762 } else { 1763 } 1764 1765 if (mIsHceCapable && mReaderModeParams == null) { 1766 // Host routing is always enabled at lock screen or later, provided we aren't in reader mode 1767 paramsBuilder.setEnableHostRouting(true); 1768 } 1769 1770 return paramsBuilder.build(); 1771 } 1772 1773 private boolean isTagPresent() { 1774 for (Object object : mObjectMap.values()) { 1775 if (object instanceof TagEndpoint) { 1776 return ((TagEndpoint) object).isPresent(); 1777 } 1778 } 1779 return false; 1780 } 1781 1782 private void StopPresenceChecking() { 1783 Object[] objectValues = mObjectMap.values().toArray(); 1784 for (Object object : objectValues) { 1785 if (object instanceof TagEndpoint) { 1786 TagEndpoint tag = (TagEndpoint)object; 1787 ((TagEndpoint) object).stopPresenceChecking(); 1788 } 1789 } 1790 } 1791 1792 /** 1793 * Disconnect any target if present 1794 */ 1795 void maybeDisconnectTarget() { 1796 if (!isNfcEnabledOrShuttingDown()) { 1797 return; 1798 } 1799 Object[] objectsToDisconnect; 1800 synchronized (this) { 1801 Object[] objectValues = mObjectMap.values().toArray(); 1802 // Copy the array before we clear mObjectMap, 1803 // just in case the HashMap values are backed by the same array 1804 objectsToDisconnect = Arrays.copyOf(objectValues, objectValues.length); 1805 mObjectMap.clear(); 1806 } 1807 for (Object o : objectsToDisconnect) { 1808 if (DBG) Log.d(TAG, "disconnecting " + o.getClass().getName()); 1809 if (o instanceof TagEndpoint) { 1810 // Disconnect from tags 1811 TagEndpoint tag = (TagEndpoint) o; 1812 tag.disconnect(); 1813 } else if (o instanceof NfcDepEndpoint) { 1814 // Disconnect from P2P devices 1815 NfcDepEndpoint device = (NfcDepEndpoint) o; 1816 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) { 1817 // Remote peer is target, request disconnection 1818 device.disconnect(); 1819 } else { 1820 // Remote peer is initiator, we cannot disconnect 1821 // Just wait for field removal 1822 } 1823 } 1824 } 1825 } 1826 1827 Object findObject(int key) { 1828 synchronized (this) { 1829 Object device = mObjectMap.get(key); 1830 if (device == null) { 1831 Log.w(TAG, "Handle not found"); 1832 } 1833 return device; 1834 } 1835 } 1836 1837 Object findAndRemoveObject(int handle) { 1838 synchronized (this) { 1839 Object device = mObjectMap.get(handle); 1840 if (device == null) { 1841 Log.w(TAG, "Handle not found"); 1842 } else { 1843 mObjectMap.remove(handle); 1844 } 1845 return device; 1846 } 1847 } 1848 1849 void registerTagObject(TagEndpoint tag) { 1850 synchronized (this) { 1851 mObjectMap.put(tag.getHandle(), tag); 1852 } 1853 } 1854 1855 void unregisterObject(int handle) { 1856 synchronized (this) { 1857 mObjectMap.remove(handle); 1858 } 1859 } 1860 1861 /** 1862 * For use by code in this process 1863 */ 1864 public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) 1865 throws LlcpException { 1866 return mDeviceHost.createLlcpSocket(sap, miu, rw, linearBufferLength); 1867 } 1868 1869 /** 1870 * For use by code in this process 1871 */ 1872 public LlcpConnectionlessSocket createLlcpConnectionLessSocket(int sap, String sn) 1873 throws LlcpException { 1874 return mDeviceHost.createLlcpConnectionlessSocket(sap, sn); 1875 } 1876 1877 /** 1878 * For use by code in this process 1879 */ 1880 public LlcpServerSocket createLlcpServerSocket(int sap, String sn, int miu, int rw, 1881 int linearBufferLength) throws LlcpException { 1882 return mDeviceHost.createLlcpServerSocket(sap, sn, miu, rw, linearBufferLength); 1883 } 1884 1885 public void sendMockNdefTag(NdefMessage msg) { 1886 sendMessage(MSG_MOCK_NDEF, msg); 1887 } 1888 1889 public void routeAids(String aid, int route, int aidInfo) { 1890 Message msg = mHandler.obtainMessage(); 1891 msg.what = MSG_ROUTE_AID; 1892 msg.arg1 = route; 1893 msg.obj = aid; 1894 msg.arg2 = aidInfo; 1895 mHandler.sendMessage(msg); 1896 } 1897 1898 public void unrouteAids(String aid) { 1899 sendMessage(MSG_UNROUTE_AID, aid); 1900 } 1901 1902 public int getNciVersion() { 1903 return mDeviceHost.getNciVersion(); 1904 } 1905 1906 private byte[] getT3tIdentifierBytes(String systemCode, String nfcId2, String t3tPmm) { 1907 ByteBuffer buffer = ByteBuffer.allocate(2 + 8 + 8); /* systemcode + nfcid2 + t3tpmm */ 1908 buffer.put(hexStringToBytes(systemCode)); 1909 buffer.put(hexStringToBytes(nfcId2)); 1910 buffer.put(hexStringToBytes(t3tPmm)); 1911 byte[] t3tIdBytes = new byte[buffer.position()]; 1912 buffer.position(0); 1913 buffer.get(t3tIdBytes); 1914 1915 return t3tIdBytes; 1916 } 1917 1918 public void registerT3tIdentifier(String systemCode, String nfcId2, String t3tPmm) { 1919 Log.d(TAG, "request to register LF_T3T_IDENTIFIER"); 1920 1921 byte[] t3tIdentifier = getT3tIdentifierBytes(systemCode, nfcId2, t3tPmm); 1922 sendMessage(MSG_REGISTER_T3T_IDENTIFIER, t3tIdentifier); 1923 } 1924 1925 public void deregisterT3tIdentifier(String systemCode, String nfcId2, String t3tPmm) { 1926 Log.d(TAG, "request to deregister LF_T3T_IDENTIFIER"); 1927 1928 byte[] t3tIdentifier = getT3tIdentifierBytes(systemCode, nfcId2, t3tPmm); 1929 sendMessage(MSG_DEREGISTER_T3T_IDENTIFIER, t3tIdentifier); 1930 } 1931 1932 public void clearT3tIdentifiersCache() { 1933 Log.d(TAG, "clear T3t Identifiers Cache"); 1934 mDeviceHost.clearT3tIdentifiersCache(); 1935 } 1936 1937 public int getLfT3tMax() { 1938 return mDeviceHost.getLfT3tMax(); 1939 } 1940 1941 public void commitRouting() { 1942 mHandler.sendEmptyMessage(MSG_COMMIT_ROUTING); 1943 } 1944 1945 public boolean sendData(byte[] data) { 1946 return mDeviceHost.sendRawFrame(data); 1947 } 1948 1949 void sendMessage(int what, Object obj) { 1950 Message msg = mHandler.obtainMessage(); 1951 msg.what = what; 1952 msg.obj = obj; 1953 mHandler.sendMessage(msg); 1954 } 1955 1956 final class NfcServiceHandler extends Handler { 1957 @Override 1958 public void handleMessage(Message msg) { 1959 switch (msg.what) { 1960 case MSG_ROUTE_AID: { 1961 int route = msg.arg1; 1962 int aidInfo = msg.arg2; 1963 String aid = (String) msg.obj; 1964 mDeviceHost.routeAid(hexStringToBytes(aid), route, aidInfo); 1965 // Restart polling config 1966 break; 1967 } 1968 case MSG_UNROUTE_AID: { 1969 String aid = (String) msg.obj; 1970 mDeviceHost.unrouteAid(hexStringToBytes(aid)); 1971 break; 1972 } 1973 case MSG_REGISTER_T3T_IDENTIFIER: { 1974 Log.d(TAG, "message to register LF_T3T_IDENTIFIER"); 1975 mDeviceHost.disableDiscovery(); 1976 1977 byte[] t3tIdentifier = (byte[]) msg.obj; 1978 mDeviceHost.registerT3tIdentifier(t3tIdentifier); 1979 1980 NfcDiscoveryParameters params = computeDiscoveryParameters(mScreenState); 1981 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery(); 1982 mDeviceHost.enableDiscovery(params, shouldRestart); 1983 break; 1984 } 1985 case MSG_DEREGISTER_T3T_IDENTIFIER: { 1986 Log.d(TAG, "message to deregister LF_T3T_IDENTIFIER"); 1987 mDeviceHost.disableDiscovery(); 1988 1989 byte[] t3tIdentifier = (byte[]) msg.obj; 1990 mDeviceHost.deregisterT3tIdentifier(t3tIdentifier); 1991 1992 NfcDiscoveryParameters params = computeDiscoveryParameters(mScreenState); 1993 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery(); 1994 mDeviceHost.enableDiscovery(params, shouldRestart); 1995 break; 1996 } 1997 case MSG_INVOKE_BEAM: { 1998 mP2pLinkManager.onManualBeamInvoke((BeamShareData)msg.obj); 1999 break; 2000 } 2001 case MSG_COMMIT_ROUTING: { 2002 boolean commit = false; 2003 synchronized (NfcService.this) { 2004 if (mCurrentDiscoveryParameters.shouldEnableDiscovery()) { 2005 commit = true; 2006 } else { 2007 Log.d(TAG, "Not committing routing because discovery is disabled."); 2008 } 2009 } 2010 if (commit) { 2011 mDeviceHost.commitRouting(); 2012 } 2013 break; 2014 } 2015 case MSG_MOCK_NDEF: { 2016 NdefMessage ndefMsg = (NdefMessage) msg.obj; 2017 Bundle extras = new Bundle(); 2018 extras.putParcelable(Ndef.EXTRA_NDEF_MSG, ndefMsg); 2019 extras.putInt(Ndef.EXTRA_NDEF_MAXLENGTH, 0); 2020 extras.putInt(Ndef.EXTRA_NDEF_CARDSTATE, Ndef.NDEF_MODE_READ_ONLY); 2021 extras.putInt(Ndef.EXTRA_NDEF_TYPE, Ndef.TYPE_OTHER); 2022 Tag tag = Tag.createMockTag(new byte[]{0x00}, 2023 new int[]{TagTechnology.NDEF}, 2024 new Bundle[]{extras}); 2025 Log.d(TAG, "mock NDEF tag, starting corresponding activity"); 2026 Log.d(TAG, tag.toString()); 2027 int dispatchStatus = mNfcDispatcher.dispatchTag(tag); 2028 if (dispatchStatus == NfcDispatcher.DISPATCH_SUCCESS) { 2029 playSound(SOUND_END); 2030 } else if (dispatchStatus == NfcDispatcher.DISPATCH_FAIL) { 2031 playSound(SOUND_ERROR); 2032 } 2033 break; 2034 } 2035 2036 case MSG_NDEF_TAG: 2037 if (DBG) Log.d(TAG, "Tag detected, notifying applications"); 2038 mPowerManager.userActivity(SystemClock.uptimeMillis(), 2039 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0); 2040 mNumTagsDetected.incrementAndGet(); 2041 TagEndpoint tag = (TagEndpoint) msg.obj; 2042 byte[] debounceTagUid; 2043 int debounceTagMs; 2044 ITagRemovedCallback debounceTagRemovedCallback; 2045 synchronized (NfcService.this) { 2046 debounceTagUid = mDebounceTagUid; 2047 debounceTagMs = mDebounceTagDebounceMs; 2048 debounceTagRemovedCallback = mDebounceTagRemovedCallback; 2049 } 2050 ReaderModeParams readerParams = null; 2051 int presenceCheckDelay = DEFAULT_PRESENCE_CHECK_DELAY; 2052 DeviceHost.TagDisconnectedCallback callback = 2053 new DeviceHost.TagDisconnectedCallback() { 2054 @Override 2055 public void onTagDisconnected(long handle) { 2056 applyRouting(false); 2057 } 2058 }; 2059 synchronized (NfcService.this) { 2060 readerParams = mReaderModeParams; 2061 } 2062 if (readerParams != null) { 2063 presenceCheckDelay = readerParams.presenceCheckDelay; 2064 if ((readerParams.flags & NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK) != 0) { 2065 if (DBG) Log.d(TAG, "Skipping NDEF detection in reader mode"); 2066 tag.startPresenceChecking(presenceCheckDelay, callback); 2067 dispatchTagEndpoint(tag, readerParams); 2068 break; 2069 } 2070 } 2071 2072 if (tag.getConnectedTechnology() == TagTechnology.NFC_BARCODE) { 2073 // When these tags start containing NDEF, they will require 2074 // the stack to deal with them in a different way, since 2075 // they are activated only really shortly. 2076 // For now, don't consider NDEF on these. 2077 if (DBG) Log.d(TAG, "Skipping NDEF detection for NFC Barcode"); 2078 tag.startPresenceChecking(presenceCheckDelay, callback); 2079 dispatchTagEndpoint(tag, readerParams); 2080 break; 2081 } 2082 NdefMessage ndefMsg = tag.findAndReadNdef(); 2083 2084 if (ndefMsg == null) { 2085 // First try to see if this was a bad tag read 2086 if (!tag.reconnect()) { 2087 tag.disconnect(); 2088 break; 2089 } 2090 } 2091 2092 if (debounceTagUid != null) { 2093 // If we're debouncing and the UID or the NDEF message of the tag match, 2094 // don't dispatch but drop it. 2095 if (Arrays.equals(debounceTagUid, tag.getUid()) || 2096 (ndefMsg != null && ndefMsg.equals(mLastReadNdefMessage))) { 2097 mHandler.removeMessages(MSG_TAG_DEBOUNCE); 2098 mHandler.sendEmptyMessageDelayed(MSG_TAG_DEBOUNCE, debounceTagMs); 2099 tag.disconnect(); 2100 return; 2101 } else { 2102 synchronized (NfcService.this) { 2103 mDebounceTagUid = null; 2104 mDebounceTagRemovedCallback = null; 2105 mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE; 2106 } 2107 if (debounceTagRemovedCallback != null) { 2108 try { 2109 debounceTagRemovedCallback.onTagRemoved(); 2110 } catch (RemoteException e) { 2111 // Ignore 2112 } 2113 } 2114 } 2115 } 2116 2117 mLastReadNdefMessage = ndefMsg; 2118 2119 tag.startPresenceChecking(presenceCheckDelay, callback); 2120 dispatchTagEndpoint(tag, readerParams); 2121 break; 2122 2123 case MSG_LLCP_LINK_ACTIVATION: 2124 mPowerManager.userActivity(SystemClock.uptimeMillis(), 2125 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0); 2126 if (mIsDebugBuild) { 2127 Intent actIntent = new Intent(ACTION_LLCP_UP); 2128 mContext.sendBroadcast(actIntent); 2129 } 2130 llcpActivated((NfcDepEndpoint) msg.obj); 2131 break; 2132 2133 case MSG_LLCP_LINK_DEACTIVATED: 2134 if (mIsDebugBuild) { 2135 Intent deactIntent = new Intent(ACTION_LLCP_DOWN); 2136 mContext.sendBroadcast(deactIntent); 2137 } 2138 NfcDepEndpoint device = (NfcDepEndpoint) msg.obj; 2139 boolean needsDisconnect = false; 2140 2141 Log.d(TAG, "LLCP Link Deactivated message. Restart polling loop."); 2142 synchronized (NfcService.this) { 2143 /* Check if the device has been already unregistered */ 2144 if (mObjectMap.remove(device.getHandle()) != null) { 2145 /* Disconnect if we are initiator */ 2146 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) { 2147 if (DBG) Log.d(TAG, "disconnecting from target"); 2148 needsDisconnect = true; 2149 } else { 2150 if (DBG) Log.d(TAG, "not disconnecting from initiator"); 2151 } 2152 } 2153 } 2154 if (needsDisconnect) { 2155 device.disconnect(); // restarts polling loop 2156 } 2157 2158 mP2pLinkManager.onLlcpDeactivated(); 2159 break; 2160 case MSG_LLCP_LINK_FIRST_PACKET: 2161 mP2pLinkManager.onLlcpFirstPacketReceived(); 2162 break; 2163 case MSG_RF_FIELD_ACTIVATED: 2164 Intent fieldOnIntent = new Intent(ACTION_RF_FIELD_ON_DETECTED); 2165 sendNfcEeAccessProtectedBroadcast(fieldOnIntent); 2166 break; 2167 case MSG_RF_FIELD_DEACTIVATED: 2168 Intent fieldOffIntent = new Intent(ACTION_RF_FIELD_OFF_DETECTED); 2169 sendNfcEeAccessProtectedBroadcast(fieldOffIntent); 2170 break; 2171 case MSG_RESUME_POLLING: 2172 mNfcAdapter.resumePolling(); 2173 break; 2174 case MSG_TAG_DEBOUNCE: 2175 // Didn't see the tag again, tag is gone 2176 ITagRemovedCallback tagRemovedCallback; 2177 synchronized (NfcService.this) { 2178 mDebounceTagUid = null; 2179 tagRemovedCallback = mDebounceTagRemovedCallback; 2180 mDebounceTagRemovedCallback = null; 2181 mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE; 2182 } 2183 if (tagRemovedCallback != null) { 2184 try { 2185 tagRemovedCallback.onTagRemoved(); 2186 } catch (RemoteException e) { 2187 // Ignore 2188 } 2189 } 2190 break; 2191 case MSG_UPDATE_STATS: 2192 if (mNumTagsDetected.get() > 0) { 2193 MetricsLogger.count(mContext, TRON_NFC_TAG, mNumTagsDetected.get()); 2194 mNumTagsDetected.set(0); 2195 } 2196 if (mNumHceDetected.get() > 0) { 2197 MetricsLogger.count(mContext, TRON_NFC_CE, mNumHceDetected.get()); 2198 mNumHceDetected.set(0); 2199 } 2200 if (mNumP2pDetected.get() > 0) { 2201 MetricsLogger.count(mContext, TRON_NFC_P2P, mNumP2pDetected.get()); 2202 mNumP2pDetected.set(0); 2203 } 2204 removeMessages(MSG_UPDATE_STATS); 2205 sendEmptyMessageDelayed(MSG_UPDATE_STATS, STATS_UPDATE_INTERVAL_MS); 2206 break; 2207 2208 case MSG_APPLY_SCREEN_STATE: 2209 mScreenState = (Integer)msg.obj; 2210 2211 // If NFC is turning off, we shouldn't need any changes here 2212 synchronized (NfcService.this) { 2213 if (mState == NfcAdapter.STATE_TURNING_OFF) 2214 return; 2215 } 2216 2217 if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) { 2218 applyRouting(false); 2219 } 2220 int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ? 2221 (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState; 2222 2223 if (mNfcUnlockManager.isLockscreenPollingEnabled()) 2224 applyRouting(false); 2225 2226 mDeviceHost.doSetScreenState(screen_state_mask); 2227 break; 2228 2229 case MSG_TRANSACTION_EVENT: 2230 if (mCardEmulationManager != null) { 2231 mCardEmulationManager.onOffHostAidSelected(); 2232 } 2233 byte[][] data = (byte[][]) msg.obj; 2234 sendOffHostTransactionEvent(data[0], data[1], data[2]); 2235 break; 2236 2237 default: 2238 Log.e(TAG, "Unknown message received"); 2239 break; 2240 } 2241 } 2242 2243 private void sendOffHostTransactionEvent(byte[] aid, byte[] data, byte[] readerByteArray) { 2244 if (mSEService == null || mNfcEventInstalledPackages.isEmpty()) { 2245 return; 2246 } 2247 2248 try { 2249 String reader = new String(readerByteArray, "UTF-8"); 2250 String[] installedPackages = new String[mNfcEventInstalledPackages.size()]; 2251 boolean[] nfcAccess = mSEService.isNFCEventAllowed(reader, aid, 2252 mNfcEventInstalledPackages.toArray(installedPackages)); 2253 if (nfcAccess == null) { 2254 return; 2255 } 2256 ArrayList<String> packages = new ArrayList<String>(); 2257 Intent intent = new Intent(NfcAdapter.ACTION_TRANSACTION_DETECTED); 2258 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 2259 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2260 intent.putExtra(NfcAdapter.EXTRA_AID, aid); 2261 intent.putExtra(NfcAdapter.EXTRA_DATA, data); 2262 intent.putExtra(NfcAdapter.EXTRA_SECURE_ELEMENT_NAME, reader); 2263 StringBuilder aidString = new StringBuilder(aid.length); 2264 for (byte b : aid) { 2265 aidString.append(String.format("%02X", b)); 2266 } 2267 String url = new String ("nfc://secure:0/" + reader + "/" + aidString.toString()); 2268 intent.setData(Uri.parse(url)); 2269 for (int i = 0; i < nfcAccess.length; i++) { 2270 if (nfcAccess[i]) { 2271 intent.setPackage(mNfcEventInstalledPackages.get(i)); 2272 mContext.sendBroadcast(intent); 2273 } 2274 } 2275 } catch (RemoteException e) { 2276 Log.e(TAG, "Error in isNFCEventAllowed() " + e); 2277 } catch (UnsupportedEncodingException e) { 2278 Log.e(TAG, "Incorrect format for Secure Element name" + e); 2279 } 2280 } 2281 2282 /* Returns the list of packages that have access to NFC Events on any SE */ 2283 private ArrayList<String> getSEAccessAllowedPackages() { 2284 if (mSEService == null || mNfcEventInstalledPackages.isEmpty()) { 2285 return null; 2286 } 2287 String[] readers = null; 2288 try { 2289 readers = mSEService.getReaders(); 2290 } catch (RemoteException e) { 2291 Log.e(TAG, "Error in getReaders() " + e); 2292 return null; 2293 } 2294 2295 if (readers == null || readers.length == 0) { 2296 return null; 2297 } 2298 boolean[] nfcAccessFinal = null; 2299 String[] installedPackages = new String[mNfcEventInstalledPackages.size()]; 2300 for (String reader : readers) { 2301 try { 2302 boolean[] accessList = mSEService.isNFCEventAllowed(reader, null, 2303 mNfcEventInstalledPackages.toArray(installedPackages)); 2304 if (accessList == null) { 2305 continue; 2306 } 2307 if (nfcAccessFinal == null) { 2308 nfcAccessFinal = accessList; 2309 } 2310 for (int i = 0; i < accessList.length; i++) { 2311 if (accessList[i]) { 2312 nfcAccessFinal[i] = true; 2313 } 2314 } 2315 } catch (RemoteException e) { 2316 Log.e(TAG, "Error in isNFCEventAllowed() " + e); 2317 } 2318 } 2319 if (nfcAccessFinal == null) { 2320 return null; 2321 } 2322 ArrayList<String> packages = new ArrayList<String>(); 2323 for (int i = 0; i < nfcAccessFinal.length; i++) { 2324 if (nfcAccessFinal[i]) { 2325 packages.add(mNfcEventInstalledPackages.get(i)); 2326 } 2327 } 2328 return packages; 2329 } 2330 2331 private void sendNfcEeAccessProtectedBroadcast(Intent intent) { 2332 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 2333 // Resume app switches so the receivers can start activites without delay 2334 mNfcDispatcher.resumeAppSwitches(); 2335 synchronized (this) { 2336 ArrayList<String> SEPackages = getSEAccessAllowedPackages(); 2337 if (SEPackages!= null && !SEPackages.isEmpty()) { 2338 for (String packageName : SEPackages) { 2339 intent.setPackage(packageName); 2340 mContext.sendBroadcast(intent); 2341 } 2342 } 2343 PackageManager pm = mContext.getPackageManager(); 2344 for (String packageName : mNfcEventInstalledPackages) { 2345 try { 2346 PackageInfo info = pm.getPackageInfo(packageName, 0); 2347 if (SEPackages != null && SEPackages.contains(packageName)) { 2348 continue; 2349 } 2350 if (info.applicationInfo != null && 2351 ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 || 2352 (info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0)) { 2353 intent.setPackage(packageName); 2354 mContext.sendBroadcast(intent); 2355 } 2356 } catch (Exception e) { 2357 Log.e(TAG, "Exception in getPackageInfo " + e); 2358 } 2359 } 2360 } 2361 } 2362 2363 private boolean llcpActivated(NfcDepEndpoint device) { 2364 Log.d(TAG, "LLCP Activation message"); 2365 2366 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) { 2367 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_TARGET"); 2368 if (device.connect()) { 2369 /* Check LLCP compliancy */ 2370 if (mDeviceHost.doCheckLlcp()) { 2371 /* Activate LLCP Link */ 2372 if (mDeviceHost.doActivateLlcp()) { 2373 if (DBG) Log.d(TAG, "Initiator Activate LLCP OK"); 2374 synchronized (NfcService.this) { 2375 // Register P2P device 2376 mObjectMap.put(device.getHandle(), device); 2377 } 2378 mP2pLinkManager.onLlcpActivated(device.getLlcpVersion()); 2379 return true; 2380 } else { 2381 /* should not happen */ 2382 Log.w(TAG, "Initiator LLCP activation failed. Disconnect."); 2383 device.disconnect(); 2384 } 2385 } else { 2386 if (DBG) Log.d(TAG, "Remote Target does not support LLCP. Disconnect."); 2387 device.disconnect(); 2388 } 2389 } else { 2390 if (DBG) Log.d(TAG, "Cannot connect remote Target. Polling loop restarted."); 2391 /* 2392 * The polling loop should have been restarted in failing 2393 * doConnect 2394 */ 2395 } 2396 } else if (device.getMode() == NfcDepEndpoint.MODE_P2P_INITIATOR) { 2397 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_INITIATOR"); 2398 /* Check LLCP compliancy */ 2399 if (mDeviceHost.doCheckLlcp()) { 2400 /* Activate LLCP Link */ 2401 if (mDeviceHost.doActivateLlcp()) { 2402 if (DBG) Log.d(TAG, "Target Activate LLCP OK"); 2403 synchronized (NfcService.this) { 2404 // Register P2P device 2405 mObjectMap.put(device.getHandle(), device); 2406 } 2407 mP2pLinkManager.onLlcpActivated(device.getLlcpVersion()); 2408 return true; 2409 } 2410 } else { 2411 Log.w(TAG, "checkLlcp failed"); 2412 } 2413 } 2414 2415 return false; 2416 } 2417 2418 private void dispatchTagEndpoint(TagEndpoint tagEndpoint, ReaderModeParams readerParams) { 2419 Tag tag = new Tag(tagEndpoint.getUid(), tagEndpoint.getTechList(), 2420 tagEndpoint.getTechExtras(), tagEndpoint.getHandle(), mNfcTagService); 2421 registerTagObject(tagEndpoint); 2422 if (readerParams != null) { 2423 try { 2424 if ((readerParams.flags & NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS) == 0) { 2425 mVibrator.vibrate(mVibrationEffect); 2426 playSound(SOUND_END); 2427 } 2428 if (readerParams.callback != null) { 2429 readerParams.callback.onTagDiscovered(tag); 2430 return; 2431 } else { 2432 // Follow normal dispatch below 2433 } 2434 } catch (RemoteException e) { 2435 Log.e(TAG, "Reader mode remote has died, falling back.", e); 2436 // Intentional fall-through 2437 } catch (Exception e) { 2438 // Catch any other exception 2439 Log.e(TAG, "App exception, not dispatching.", e); 2440 return; 2441 } 2442 } 2443 int dispatchResult = mNfcDispatcher.dispatchTag(tag); 2444 if (dispatchResult == NfcDispatcher.DISPATCH_FAIL) { 2445 unregisterObject(tagEndpoint.getHandle()); 2446 playSound(SOUND_ERROR); 2447 } else if (dispatchResult == NfcDispatcher.DISPATCH_SUCCESS) { 2448 mVibrator.vibrate(mVibrationEffect); 2449 playSound(SOUND_END); 2450 } 2451 } 2452 } 2453 2454 private NfcServiceHandler mHandler = new NfcServiceHandler(); 2455 2456 class ApplyRoutingTask extends AsyncTask<Integer, Void, Void> { 2457 @Override 2458 protected Void doInBackground(Integer... params) { 2459 synchronized (NfcService.this) { 2460 if (params == null || params.length != 1) { 2461 // force apply current routing 2462 applyRouting(true); 2463 return null; 2464 } 2465 mScreenState = params[0].intValue(); 2466 2467 mRoutingWakeLock.acquire(); 2468 try { 2469 applyRouting(false); 2470 } finally { 2471 mRoutingWakeLock.release(); 2472 } 2473 return null; 2474 } 2475 } 2476 } 2477 2478 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 2479 @Override 2480 public void onReceive(Context context, Intent intent) { 2481 String action = intent.getAction(); 2482 if (action.equals(Intent.ACTION_SCREEN_ON) 2483 || action.equals(Intent.ACTION_SCREEN_OFF) 2484 || action.equals(Intent.ACTION_USER_PRESENT)) { 2485 // Perform applyRouting() in AsyncTask to serialize blocking calls 2486 int screenState = mScreenStateHelper.checkScreenState(); 2487 if (action.equals(Intent.ACTION_SCREEN_OFF)) { 2488 if (mScreenState != ScreenStateHelper.SCREEN_STATE_OFF_LOCKED) { 2489 screenState = mKeyguard.isKeyguardLocked() ? 2490 ScreenStateHelper.SCREEN_STATE_OFF_LOCKED : ScreenStateHelper.SCREEN_STATE_OFF_UNLOCKED; 2491 } 2492 } else if (action.equals(Intent.ACTION_SCREEN_ON)) { 2493 screenState = mKeyguard.isKeyguardLocked() 2494 ? ScreenStateHelper.SCREEN_STATE_ON_LOCKED 2495 : ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED; 2496 } else if (action.equals(Intent.ACTION_USER_PRESENT)) { 2497 screenState = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED; 2498 } 2499 if (nci_version != NCI_VERSION_2_0) { 2500 new ApplyRoutingTask().execute(Integer.valueOf(screenState)); 2501 } 2502 sendMessage(NfcService.MSG_APPLY_SCREEN_STATE, screenState); 2503 } else if (action.equals(Intent.ACTION_USER_SWITCHED)) { 2504 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 2505 int beamSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 2506 try { 2507 IPackageManager mIpm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); 2508 beamSetting = mIpm.getComponentEnabledSetting(new ComponentName( 2509 BeamShareActivity.class.getPackageName$(), 2510 BeamShareActivity.class.getName()), 2511 userId); 2512 } catch(RemoteException e) { 2513 Log.e(TAG, "Error int getComponentEnabledSetting for BeamShareActivity"); 2514 } 2515 synchronized (this) { 2516 mUserId = userId; 2517 if (beamSetting == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) { 2518 mIsNdefPushEnabled = false; 2519 } else { 2520 mIsNdefPushEnabled = true; 2521 } 2522 } 2523 mP2pLinkManager.onUserSwitched(getUserId()); 2524 if (mIsHceCapable) { 2525 mCardEmulationManager.onUserSwitched(getUserId()); 2526 } 2527 int screenState = mScreenStateHelper.checkScreenState(); 2528 if (screenState != mScreenState) { 2529 new ApplyRoutingTask().execute(Integer.valueOf(screenState)); 2530 } 2531 } 2532 } 2533 }; 2534 2535 2536 private final BroadcastReceiver mOwnerReceiver = new BroadcastReceiver() { 2537 @Override 2538 public void onReceive(Context context, Intent intent) { 2539 String action = intent.getAction(); 2540 if (action.equals(Intent.ACTION_PACKAGE_REMOVED) || 2541 action.equals(Intent.ACTION_PACKAGE_ADDED) || 2542 action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE) || 2543 action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) { 2544 updatePackageCache(); 2545 } else if (action.equals(Intent.ACTION_SHUTDOWN)) { 2546 if (DBG) Log.d(TAG, "Device is shutting down."); 2547 if (isNfcEnabled()) { 2548 mDeviceHost.shutdown(); 2549 } 2550 } 2551 } 2552 }; 2553 2554 private final BroadcastReceiver mPolicyReceiver = new BroadcastReceiver() { 2555 @Override 2556 public void onReceive(Context context, Intent intent){ 2557 String action = intent.getAction(); 2558 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED 2559 .equals(action)) { 2560 enforceBeamShareActivityPolicy(context, 2561 new UserHandle(getSendingUserId())); 2562 } 2563 } 2564 }; 2565 2566 private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() { 2567 @Override 2568 public void onVrStateChanged(boolean enabled) { 2569 synchronized (this) { 2570 mIsVrModeEnabled = enabled; 2571 } 2572 } 2573 }; 2574 2575 /** 2576 * for debugging only - no i18n 2577 */ 2578 static String stateToString(int state) { 2579 switch (state) { 2580 case NfcAdapter.STATE_OFF: 2581 return "off"; 2582 case NfcAdapter.STATE_TURNING_ON: 2583 return "turning on"; 2584 case NfcAdapter.STATE_ON: 2585 return "on"; 2586 case NfcAdapter.STATE_TURNING_OFF: 2587 return "turning off"; 2588 default: 2589 return "<error>"; 2590 } 2591 } 2592 2593 void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2594 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 2595 != PackageManager.PERMISSION_GRANTED) { 2596 pw.println("Permission Denial: can't dump nfc from from pid=" 2597 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2598 + " without permission " + android.Manifest.permission.DUMP); 2599 return; 2600 } 2601 2602 synchronized (this) { 2603 pw.println("mState=" + stateToString(mState)); 2604 pw.println("mIsZeroClickRequested=" + mIsNdefPushEnabled); 2605 pw.println("mScreenState=" + ScreenStateHelper.screenStateToString(mScreenState)); 2606 pw.println(mCurrentDiscoveryParameters); 2607 mP2pLinkManager.dump(fd, pw, args); 2608 if (mIsHceCapable) { 2609 mCardEmulationManager.dump(fd, pw, args); 2610 } 2611 mNfcDispatcher.dump(fd, pw, args); 2612 pw.flush(); 2613 mDeviceHost.dump(fd); 2614 } 2615 } 2616 } 2617