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