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