blob: e47b3414add069c5e70f7317c8e6e9b86f8a61a0 [file] [log] [blame]
nxpandroid64fd68c2015-09-23 16:45:15 +05301 /*
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 *
18 * The original Work has been changed by NXP Semiconductors.
19 *
nxf35421aca166a2018-02-06 16:00:50 +053020 * Copyright (C) 2015-2018 NXP Semiconductors
nxpandroid64fd68c2015-09-23 16:45:15 +053021 *
22 * Licensed under the Apache License, Version 2.0 (the "License");
23 * you may not use this file except in compliance with the License.
24 * You may obtain a copy of the License at
25 *
26 * http://www.apache.org/licenses/LICENSE-2.0
27 *
28 * Unless required by applicable law or agreed to in writing, software
29 * distributed under the License is distributed on an "AS IS" BASIS,
30 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 * See the License for the specific language governing permissions and
32 * limitations under the License.
33 *
34 ******************************************************************************/
35package com.android.nfc;
36
37import android.app.ActivityManager;
38import android.app.Application;
nxpandroid6fd9cdb2017-07-12 18:25:41 +053039import android.app.backup.BackupManager;
nxpandroid64fd68c2015-09-23 16:45:15 +053040import android.app.KeyguardManager;
41import android.app.PendingIntent;
42import android.app.admin.DevicePolicyManager;
43import android.content.BroadcastReceiver;
44import android.content.ComponentName;
45import android.content.ContentResolver;
46import android.content.Context;
47import android.content.Intent;
48import android.content.IntentFilter;
49import android.content.SharedPreferences;
nxpandroid3649b762017-02-24 15:44:54 +053050
Suhas Sureshca6584b2018-04-27 17:17:22 +053051import android.content.pm.ApplicationInfo;
nxpandroid64fd68c2015-09-23 16:45:15 +053052import android.content.pm.IPackageManager;
53import android.content.pm.PackageInfo;
nxpandroid64fd68c2015-09-23 16:45:15 +053054import android.content.pm.PackageManager;
55import android.content.pm.UserInfo;
56import android.content.res.Resources.NotFoundException;
57import android.media.AudioManager;
58import android.media.SoundPool;
59import android.net.Uri;
60import android.nfc.BeamShareData;
61import android.nfc.ErrorCodes;
62import android.nfc.FormatException;
63import android.nfc.IAppCallback;
64import android.nfc.INfcAdapter;
65import android.nfc.INfcAdapterExtras;
66import android.nfc.INfcCardEmulation;
nxpandroid34627bd2016-05-27 15:52:30 +053067import android.nfc.INfcFCardEmulation;
nxpandroid64fd68c2015-09-23 16:45:15 +053068import android.nfc.INfcTag;
69import android.nfc.INfcUnlockHandler;
nxpandroid281eb922016-08-25 20:27:46 +053070import android.nfc.ITagRemovedCallback;
nxpandroid64fd68c2015-09-23 16:45:15 +053071import android.nfc.NdefMessage;
72import android.nfc.NfcAdapter;
73import android.nfc.Tag;
74import android.nfc.TechListParcel;
75import android.nfc.TransceiveResult;
76import android.nfc.tech.Ndef;
77import android.nfc.tech.TagTechnology;
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +053078import android.nfc.INfcDta;
nxpandroid64fd68c2015-09-23 16:45:15 +053079import android.os.AsyncTask;
80import android.os.Binder;
81import android.os.Build;
82import android.os.Bundle;
83import android.os.Handler;
Suhas Sureshe75588d2018-07-11 15:22:24 +053084import android.os.HwBinder;
nxpandroid64fd68c2015-09-23 16:45:15 +053085import android.os.IBinder;
86import android.os.Message;
87import android.os.PowerManager;
88import android.os.Process;
89import android.os.RemoteException;
90import android.os.ServiceManager;
91import android.os.SystemClock;
Nikhil Chhabraa9e399a2018-01-09 11:47:13 +053092import android.os.SystemProperties;
nxpandroid64fd68c2015-09-23 16:45:15 +053093import android.os.UserHandle;
94import android.os.UserManager;
Suhas Suresh6e05ee02018-04-25 12:19:35 +053095import android.os.VibrationEffect;
96import android.os.Vibrator;
nxpandroid64fd68c2015-09-23 16:45:15 +053097import android.provider.Settings;
Suhas Sureshca6584b2018-04-27 17:17:22 +053098import android.se.omapi.ISecureElementService;
Nikhil Chhabrafc8f3f62018-01-08 20:48:49 +053099import android.service.vr.IVrManager;
100import android.service.vr.IVrStateCallbacks;
nxpandroid64fd68c2015-09-23 16:45:15 +0530101import android.util.Log;
102
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530103import com.android.internal.logging.MetricsLogger;
nxpandroid64fd68c2015-09-23 16:45:15 +0530104import com.android.nfc.DeviceHost.DeviceHostListener;
105import com.android.nfc.DeviceHost.LlcpConnectionlessSocket;
106import com.android.nfc.DeviceHost.LlcpServerSocket;
107import com.android.nfc.DeviceHost.LlcpSocket;
108import com.android.nfc.DeviceHost.NfcDepEndpoint;
109import com.android.nfc.DeviceHost.TagEndpoint;
110
111import com.android.nfc.dhimpl.NativeNfcSecureElement;
112import com.android.nfc.dhimpl.NativeNfcAla;
113import java.security.MessageDigest;
114
115import android.widget.Toast;
116
117import com.android.nfc.cardemulation.AidRoutingManager;
118import com.android.nfc.cardemulation.CardEmulationManager;
nxpandroidebf53fb2016-12-22 18:48:59 +0530119import com.android.nfc.cardemulation.RegisteredAidCache;
nxpandroid64fd68c2015-09-23 16:45:15 +0530120import com.android.nfc.dhimpl.NativeNfcManager;
121import com.android.nfc.handover.HandoverDataParser;
122
123import java.io.FileDescriptor;
124import java.io.PrintWriter;
Suhas Suresh061c9b02018-05-15 17:45:06 +0530125import java.io.UnsupportedEncodingException;
nxpandroid34627bd2016-05-27 15:52:30 +0530126import java.nio.ByteBuffer;
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530127import java.util.concurrent.atomic.AtomicInteger;
nxpandroid64fd68c2015-09-23 16:45:15 +0530128import java.io.InputStream;
129import java.io.OutputStream;
130import java.io.FileInputStream;
131import java.io.FileOutputStream;
132import java.io.File;
nxpandroid281eb922016-08-25 20:27:46 +0530133import java.io.FileWriter;
nxpandroid64fd68c2015-09-23 16:45:15 +0530134import java.io.BufferedReader;
135import java.io.FileReader;
136import java.util.Arrays;
137import java.util.ArrayList;
138import java.util.HashMap;
139import java.util.List;
140import java.util.Map;
141import java.util.NoSuchElementException;
Pratap Reddy49abbe32018-03-27 16:51:59 +0530142import java.util.TimerTask;
143import java.util.Timer;
nxpandroid64fd68c2015-09-23 16:45:15 +0530144import java.io.IOException;
145import java.io.FileNotFoundException;
nxpandroid3649b762017-02-24 15:44:54 +0530146
Ganesh Devaf550e962018-07-24 11:59:09 +0530147import java.lang.reflect.Field;
148import java.lang.reflect.Method;
149import java.lang.reflect.InvocationTargetException;
150
nxpandroid64fd68c2015-09-23 16:45:15 +0530151import android.util.Pair;
152import java.util.HashSet;
nxpandroid64fd68c2015-09-23 16:45:15 +0530153import java.util.concurrent.ExecutionException;
154
155import com.nxp.nfc.INxpNfcAdapter;
nxpandroid64fd68c2015-09-23 16:45:15 +0530156import com.nxp.nfc.INfcVzw;
nxpandroid64fd68c2015-09-23 16:45:15 +0530157import com.nxp.nfc.NxpConstants;
158import com.vzw.nfc.RouteEntry;
159import com.gsma.nfc.internal.NxpNfcController;
160import com.nxp.nfc.gsma.internal.INxpNfcController;
nxf26763be2bd682018-11-12 17:02:43 +0530161import com.nxp.nfc.NxpAidServiceInfo;
Shashank vimal83779082018-02-06 18:10:31 +0530162
nxpandroid64fd68c2015-09-23 16:45:15 +0530163public class NfcService implements DeviceHostListener {
164 private static final String ACTION_MASTER_CLEAR_NOTIFICATION = "android.intent.action.MASTER_CLEAR_NOTIFICATION";
165
166 static final boolean DBG = true;
167 static final String TAG = "NfcService";
168
169 public static final String SERVICE_NAME = "nfc";
170
171 /** Regular NFC permission */
172 private static final String NFC_PERM = android.Manifest.permission.NFC;
173 private static final String NFC_PERM_ERROR = "NFC permission required";
174
175 public static final String PREF = "NfcServicePrefs";
nxpandroida9a68ba2016-01-14 21:12:17 +0530176 public static final String NXP_PREF = "NfcServiceNxpPrefs";
nxpandroid64fd68c2015-09-23 16:45:15 +0530177
178 static final String PREF_NFC_ON = "nfc_on";
179 static final boolean NFC_ON_DEFAULT = true;
180 static final String PREF_NDEF_PUSH_ON = "ndef_push_on";
181 static final boolean NDEF_PUSH_ON_DEFAULT = true;
182 static final String PREF_FIRST_BEAM = "first_beam";
183 static final String PREF_FIRST_BOOT = "first_boot";
nxpandroid64fd68c2015-09-23 16:45:15 +0530184 private static final String PREF_SECURE_ELEMENT_ON = "secure_element_on";
185 private boolean SECURE_ELEMENT_ON_DEFAULT = false;
186 private int SECURE_ELEMENT_ID_DEFAULT = 0;
nxpandroidebf53fb2016-12-22 18:48:59 +0530187 private int SECURE_ELEMENT_UICC_SLOT_DEFAULT = 1;
nxpandroid64fd68c2015-09-23 16:45:15 +0530188 private static final String PREF_DEFAULT_ROUTE_ID = "default_route_id";
189 private static final String PREF_MIFARE_DESFIRE_PROTO_ROUTE_ID = "mifare_desfire_proto_route";
190 private static final String PREF_SET_DEFAULT_ROUTE_ID ="set_default_route";
191 private static final String PREF_MIFARE_CLT_ROUTE_ID= "mifare_clt_route";
nxpandroid64fd68c2015-09-23 16:45:15 +0530192
Suhas Suresh91502772018-08-31 20:28:13 +0530193 private static final String[] path = {"/data/nfc/JcopOs_Update1.apdu",
194 "/data/nfc/JcopOs_Update2.apdu",
195 "/data/nfc/JcopOs_Update3.apdu"};
nxpandroid64fd68c2015-09-23 16:45:15 +0530196
197 private static final String[] PREF_JCOP_MODTIME = {"jcop file1 modtime",
198 "jcop file2 modtime",
199 "jcop file3 modtime"};
200 private static final long[] JCOP_MODTIME_DEFAULT = {-1,-1,-1};
201 private static final long[] JCOP_MODTIME_TEMP = {-1,-1,-1};
202
203 private boolean ETSI_STOP_CONFIG = false;
nxpandroid7d44e572016-08-01 19:11:04 +0530204 private int ROUTE_ID_HOST = 0x00;
205 private int ROUTE_ID_SMX = 0x01;
206 private int ROUTE_ID_UICC = 0x02;
207 private int ROUTE_ID_UICC2 = 0x04;
nxpandroid64fd68c2015-09-23 16:45:15 +0530208
209 private int ROUTE_SWITCH_ON = 0x01;
210 private int ROUTE_SWITCH_OFF = 0x02;
211 private int ROUTE_BATT_OFF= 0x04;
212
213 private int TECH_TYPE_A= 0x01;
214 private int TECH_TYPE_B= 0x02;
215 private int TECH_TYPE_F= 0x04;
216
217 //TODO: Refer L_OSP_EXT [PN547C2]
218// private int DEFAULT_ROUTE_ID_DEFAULT = AidRoutingManager.DEFAULT_ROUTE;
219 private int DEFAULT_ROUTE_ID_DEFAULT = 0x00;
220 static final boolean SE_BROADCASTS_WITH_HCE = true;
221
222 private static final String PREF_SECURE_ELEMENT_ID = "secure_element_id";
nxpandroidebf53fb2016-12-22 18:48:59 +0530223 private static final String PREF_CUR_SELECTED_UICC_ID = "current_selected_uicc_id";
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530224 public static final int ROUTE_LOC_MASK=8;
225 public static final int TECH_TYPE_MASK=11;
226
227 static final String TRON_NFC_CE = "nfc_ce";
228 static final String TRON_NFC_P2P = "nfc_p2p";
229 static final String TRON_NFC_TAG = "nfc_tag";
nxpandroid64fd68c2015-09-23 16:45:15 +0530230
231 static final int MSG_NDEF_TAG = 0;
nxpandroid64fd68c2015-09-23 16:45:15 +0530232 static final int MSG_LLCP_LINK_ACTIVATION = 2;
233 static final int MSG_LLCP_LINK_DEACTIVATED = 3;
234 static final int MSG_TARGET_DESELECTED = 4;
235 static final int MSG_MOCK_NDEF = 7;
236 static final int MSG_SE_FIELD_ACTIVATED = 8;
237 static final int MSG_SE_FIELD_DEACTIVATED = 9;
238 static final int MSG_SE_APDU_RECEIVED = 10;
239 static final int MSG_SE_EMV_CARD_REMOVAL = 11;
240 static final int MSG_SE_MIFARE_ACCESS = 12;
241 static final int MSG_SE_LISTEN_ACTIVATED = 13;
242 static final int MSG_SE_LISTEN_DEACTIVATED = 14;
243 static final int MSG_LLCP_LINK_FIRST_PACKET = 15;
244 static final int MSG_ROUTE_AID = 16;
245 static final int MSG_UNROUTE_AID = 17;
246 static final int MSG_COMMIT_ROUTING = 18;
247 static final int MSG_INVOKE_BEAM = 19;
248
249 static final int MSG_SWP_READER_REQUESTED = 20;
nxpandroid64fd68c2015-09-23 16:45:15 +0530250 static final int MSG_SWP_READER_DEACTIVATED = 22;
251 static final int MSG_CLEAR_ROUTING = 23;
252 static final int MSG_SET_SCREEN_STATE = 25;
253
254
255 static final int MSG_RF_FIELD_ACTIVATED = 26;
256 static final int MSG_RF_FIELD_DEACTIVATED = 27;
257 static final int MSG_RESUME_POLLING = 28;
258 static final int MSG_SWP_READER_REQUESTED_FAIL =29 ;
259 static final int MSG_SWP_READER_TAG_PRESENT = 30;
260 static final int MSG_SWP_READER_TAG_REMOVE = 31;
261 static final int MSG_CONNECTIVITY_EVENT = 40;
262 static final int MSG_VZW_ROUTE_AID = 41;
263 static final int MSG_VZW_COMMIT_ROUTING = 42;
264 static final int MSG_ROUTE_NFCID2 = 43;
265 static final int MSG_UNROUTE_NFCID2 = 44;
266 static final int MSG_COMMITINF_FELICA_ROUTING = 45;
267 static final int MSG_COMMITED_FELICA_ROUTING = 46;
268 static final int MSG_EMVCO_MULTI_CARD_DETECTED_EVENT = 47;
269 static final int MSG_ETSI_START_CONFIG = 48;
270 static final int MSG_ETSI_STOP_CONFIG = 49;
271 static final int MSG_ETSI_SWP_TIMEOUT = 50;
nxpandroide66eb092017-07-12 21:36:08 +0530272 static final int MSG_APPLY_SCREEN_STATE = 51;
nxpandroid34627bd2016-05-27 15:52:30 +0530273 static final int MSG_REGISTER_T3T_IDENTIFIER = 54;
274 static final int MSG_DEREGISTER_T3T_IDENTIFIER = 55;
nxpandroid281eb922016-08-25 20:27:46 +0530275 static final int MSG_TAG_DEBOUNCE = 56;
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530276 static final int MSG_UPDATE_STATS = 57;
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530277 static final int MSG_SWP_READER_RESTART = 58;
nxpandroid5d64ce92016-11-18 19:48:53 +0530278 /*Restart Nfc disbale watchdog timer*/
279 static final int MSG_RESTART_WATCHDOG = 60;
nxpandroida5fd6622017-07-31 16:15:18 +0530280 static final int MSG_ROUTE_APDU = 61;
281 static final int MSG_UNROUTE_APDU = 62;
Suhas Sureshca6584b2018-04-27 17:17:22 +0530282 static final int MSG_TRANSACTION_EVENT = 63;
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530283 // Update stats every 4 hours
284 static final long STATS_UPDATE_INTERVAL_MS = 4 * 60 * 60 * 1000;
nxpandroid64fd68c2015-09-23 16:45:15 +0530285 static final long MAX_POLLING_PAUSE_TIMEOUT = 40000;
286 static final int TASK_ENABLE = 1;
287 static final int TASK_DISABLE = 2;
288 static final int TASK_BOOT = 3;
289 static final int TASK_EE_WIPE = 4;
nxpandroid1680a6d2017-01-13 19:13:14 +0530290 static final int TASK_RESTART = 0x1F;
nxpandroid64fd68c2015-09-23 16:45:15 +0530291 static final int MSG_CHANGE_DEFAULT_ROUTE = 52;
292 static final int MSG_SE_DELIVER_INTENT = 53;
293
294 // Copied from com.android.nfc_extras to avoid library dependency
295 // Must keep in sync with com.android.nfc_extras
296 static final int ROUTE_OFF = 1;
297 static final int ROUTE_ON_WHEN_SCREEN_ON = 2;
298
299 // Return values from NfcEe.open() - these are 1:1 mapped
300 // to the thrown EE_EXCEPTION_ exceptions in nfc-extras.
301 static final int EE_ERROR_IO = -1;
302 static final int EE_ERROR_ALREADY_OPEN = -2;
303 static final int EE_ERROR_INIT = -3;
304 static final int EE_ERROR_LISTEN_MODE = -4;
305 static final int EE_ERROR_EXT_FIELD = -5;
306 static final int EE_ERROR_NFC_DISABLED = -6;
307
308 // Polling technology masks
309 static final int NFC_POLL_A = 0x01;
310 static final int NFC_POLL_B = 0x02;
311 static final int NFC_POLL_F = 0x04;
Nikhil Chhabra288edb02018-01-10 19:36:21 +0530312 static final int NFC_POLL_V = 0x08;
nxpandroid64fd68c2015-09-23 16:45:15 +0530313 static final int NFC_POLL_B_PRIME = 0x10;
314 static final int NFC_POLL_KOVIO = 0x20;
315
316 // minimum screen state that enables NFC polling
317 static final int NFC_POLLING_MODE = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED;
318
319 // Time to wait for NFC controller to initialize before watchdog
320 // goes off. This time is chosen large, because firmware download
321 // may be a part of initialization.
322 static final int INIT_WATCHDOG_MS = 90000;
323 static final int INIT_WATCHDOG_LS_MS = 180000;
324 // Time to wait for routing to be applied before watchdog
325 // goes off
326 static final int ROUTING_WATCHDOG_MS = 10000;
327
328 // Amount of time to wait before closing the NFCEE connection
329 // in a disable/shutdown scenario.
330 static final int WAIT_FOR_NFCEE_OPERATIONS_MS = 5000;
331 // Polling interval for waiting on NFCEE operations
332 static final int WAIT_FOR_NFCEE_POLL_MS = 100;
333
334 // Default delay used for presence checks
335 static final int DEFAULT_PRESENCE_CHECK_DELAY = 125;
336
337 //Delay used for presence checks of NFC_F non-Ndef
338 //Make secure communication done or tranceive next request response command
339 //to pause timer before presence check command is sent
340 static final int NFC_F_TRANSCEIVE_PRESENCE_CHECK_DELAY = 500;
341
342 // The amount of time we wait before manually launching
343 // the Beam animation when called through the share menu.
344 static final int INVOKE_BEAM_DELAY_MS = 1000;
Pratap Reddy49abbe32018-03-27 16:51:59 +0530345 // Default delay used for presence checks in ETSI mode
346 static final int ETSI_PRESENCE_CHECK_DELAY = 1000;
nxpandroid64fd68c2015-09-23 16:45:15 +0530347 // for use with playSound()
348 public static final int SOUND_START = 0;
349 public static final int SOUND_END = 1;
350 public static final int SOUND_ERROR = 2;
351
nxpandroide66eb092017-07-12 21:36:08 +0530352 public static final int NCI_VERSION_2_0 = 0x20;
353
354 public static final int NCI_VERSION_1_0 = 0x10;
nxpandroid64fd68c2015-09-23 16:45:15 +0530355 //ETSI Reader Events
Pratap Reddy49abbe32018-03-27 16:51:59 +0530356 public static final int ETSI_READER_START_SUCCESS = 0;
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530357 public static final int ETSI_READER_START_FAIL = 1;
358 public static final int ETSI_READER_ACTIVATED = 2;
359 public static final int ETSI_READER_STOP = 3;
nxpandroid64fd68c2015-09-23 16:45:15 +0530360
361 //ETSI Reader Req States
362 public static final int STATE_SE_RDR_MODE_INVALID = 0x00;
363 public static final int STATE_SE_RDR_MODE_START_CONFIG = 0x01;
364 public static final int STATE_SE_RDR_MODE_START_IN_PROGRESS = 0x02;
365 public static final int STATE_SE_RDR_MODE_STARTED = 0x03;
366 public static final int STATE_SE_RDR_MODE_ACTIVATED = 0x04;
367 public static final int STATE_SE_RDR_MODE_STOP_CONFIG = 0x05;
368 public static final int STATE_SE_RDR_MODE_STOP_IN_PROGRESS = 0x06;
369 public static final int STATE_SE_RDR_MODE_STOPPED = 0x07;
370
nxpandroid281eb922016-08-25 20:27:46 +0530371 //Transit setconfig status
372 public static final int TRANSIT_SETCONFIG_STAT_SUCCESS = 0x00;
373 public static final int TRANSIT_SETCONFIG_STAT_FAILED = 0xFF;
374
nxpandroid64fd68c2015-09-23 16:45:15 +0530375 public static final String ACTION_RF_FIELD_ON_DETECTED =
376 "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED";
377 public static final String ACTION_RF_FIELD_OFF_DETECTED =
378 "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED";
379 public static final String ACTION_AID_SELECTED =
380 "com.android.nfc_extras.action.AID_SELECTED";
nxpandroid64fd68c2015-09-23 16:45:15 +0530381
382 public static final String ACTION_LLCP_UP =
383 "com.android.nfc.action.LLCP_UP";
384
385 public static final String ACTION_LLCP_DOWN =
386 "com.android.nfc.action.LLCP_DOWN";
387
388 public static final String ACTION_APDU_RECEIVED =
389 "com.android.nfc_extras.action.APDU_RECEIVED";
390 public static final String EXTRA_APDU_BYTES =
391 "com.android.nfc_extras.extra.APDU_BYTES";
392
393 public static final String ACTION_EMV_CARD_REMOVAL =
394 "com.android.nfc_extras.action.EMV_CARD_REMOVAL";
395
396 public static final String ACTION_MIFARE_ACCESS_DETECTED =
397 "com.android.nfc_extras.action.MIFARE_ACCESS_DETECTED";
398 public static final String EXTRA_MIFARE_BLOCK =
399 "com.android.nfc_extras.extra.MIFARE_BLOCK";
400
401 public static final String ACTION_SE_LISTEN_ACTIVATED =
402 "com.android.nfc_extras.action.SE_LISTEN_ACTIVATED";
403 public static final String ACTION_SE_LISTEN_DEACTIVATED =
404 "com.android.nfc_extras.action.SE_LISTEN_DEACTIVATED";
405
406 public static final String ACTION_EMVCO_MULTIPLE_CARD_DETECTED =
407 "com.nxp.action.EMVCO_MULTIPLE_CARD_DETECTED";
408
nxpandroid34627bd2016-05-27 15:52:30 +0530409 public static final String ACTION_UICC_STATUS_RECEIVED =
410 "com.nxp.action.UICC_STATUS_RECEIVED";
411
nxpandroid1680a6d2017-01-13 19:13:14 +0530412 public static final String ACTION_FLASH_SUCCESS =
413 "com.android.nfc_extras.action.ACTION_FLASH_SUCCESS";
414
nxpandroid34627bd2016-05-27 15:52:30 +0530415 public static final String EXTRA_UICC_STATUS = "com.nxp.extra.UICC_STATUS";
416
nxpandroid64fd68c2015-09-23 16:45:15 +0530417 private static final String PACKAGE_SMART_CARD_SERVICE = "org.simalliance.openmobileapi.service";
418 /**
419 * SMART MX ID to be able to select it as the default Secure Element
420 */
421 public static final int SMART_MX_ID_TYPE = 1;
422
423 /**
424 * UICC ID to be able to select it as the default Secure Element
425 */
426 public static final int UICC_ID_TYPE = 2;
427
428 /**
nxpandroid7d44e572016-08-01 19:11:04 +0530429 * UICC2 ID to be able to select it as the default Secure Element
430 */
431 public static final int UICC2_ID_TYPE = 4;
432 /**
nxpandroid64fd68c2015-09-23 16:45:15 +0530433 * ID to be able to select all Secure Elements
434 */
nxpandroid0232af22017-07-12 21:40:33 +0530435 private static int ALL_SE_ID_TYPE = 7;
nxpandroid64fd68c2015-09-23 16:45:15 +0530436
437 public static final int PN547C2_ID = 1;
438 public static final int PN65T_ID = 2;
nxpandroidebf53fb2016-12-22 18:48:59 +0530439 public static final int PN548C2_ID = 3;
nxpandroid64fd68c2015-09-23 16:45:15 +0530440 public static final int PN66T_ID = 4;
nxpandroid34627bd2016-05-27 15:52:30 +0530441 public static final int PN551_ID = 5;
442 public static final int PN67T_ID = 6;
nxpandroid281eb922016-08-25 20:27:46 +0530443 public static final int PN553_ID = 7;
444 public static final int PN80T_ID = 8;
nxpandroid64fd68c2015-09-23 16:45:15 +0530445
446 public static final int LS_RETRY_CNT = 3;
nxpandroid5d3fdf82017-07-31 16:11:33 +0530447 public static final int LOADER_SERVICE_VERSION_LOW_LIMIT = 0x21;
448 public static final int LOADER_SERVICE_VERSION_HIGH_LIMIT = 0x24;
449
nxpandroid64fd68c2015-09-23 16:45:15 +0530450 private int mSelectedSeId = 0;
451 private boolean mNfcSecureElementState;
452 private boolean mIsSmartCardServiceSupported = false;
453 // Timeout to re-apply routing if a tag was present and we postponed it
454 private static final int APPLY_ROUTING_RETRY_TIMEOUT_MS = 5000;
455
Nikhil Chhabrad6957c72018-03-09 11:44:48 +0530456 // these states are for making enable and disable nfc atomic
457 private int NXP_NFC_STATE_OFF = 0;
458 private int NXP_NFC_STATE_TURNING_ON = 1;
459 private int NXP_NFC_STATE_ON = 2;
460 private int NXP_NFC_STATE_TURNING_OFF = 3;
461
nxpandroid64fd68c2015-09-23 16:45:15 +0530462 private final UserManager mUserManager;
nxpandroide66eb092017-07-12 21:36:08 +0530463 private static int nci_version = NCI_VERSION_1_0;
nxpandroid64fd68c2015-09-23 16:45:15 +0530464 // NFC Execution Environment
465 // fields below are protected by this
Ganesh Devaf550e962018-07-24 11:59:09 +0530466 public NativeNfcSecureElement mSecureElement;
nxpandroid64fd68c2015-09-23 16:45:15 +0530467 private OpenSecureElement mOpenEe; // null when EE closed
468 private final ReaderModeDeathRecipient mReaderModeDeathRecipient =
469 new ReaderModeDeathRecipient();
470 private final NfcUnlockManager mNfcUnlockManager;
471
472 private int mEeRoutingState; // contactless interface routing
473 private int mLockscreenPollMask;
Suhas Sureshca6584b2018-04-27 17:17:22 +0530474 // cached version of installed packages requesting Android.permission.NFC_TRANSACTION_EVENTS
Suhas Suresh140f7ac2018-05-15 14:59:11 +0530475 List<String> mNfcEventInstalledPackages = new ArrayList<String>();
nxpandroid64fd68c2015-09-23 16:45:15 +0530476 private NativeNfcAla mNfcAla;
477
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530478 private final BackupManager mBackupManager;
479
nxpandroid64fd68c2015-09-23 16:45:15 +0530480 // fields below are used in multiple threads and protected by synchronized(this)
481 final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>();
482 // mSePackages holds packages that accessed the SE, but only for the owner user,
483 // as SE access is not granted for non-owner users.
484 HashSet<String> mSePackages = new HashSet<String>();
485 int mScreenState;
nxf32288d12785b2017-11-17 15:18:31 +0530486 int mChipVer;
nxpandroid5d64ce92016-11-18 19:48:53 +0530487 boolean mIsTaskBoot = false;
nxpandroid64fd68c2015-09-23 16:45:15 +0530488 boolean mInProvisionMode; // whether we're in setup wizard and enabled NFC provisioning
489 boolean mIsNdefPushEnabled;
490 boolean mNfcPollingEnabled; // current Device Host state of NFC-C polling
491 boolean mHostRouteEnabled; // current Device Host state of host-based routing
492 boolean mReaderModeEnabled; // current Device Host state of reader mode
493 boolean mNfceeRouteEnabled; // current Device Host state of NFC-EE routing
494 NfcDiscoveryParameters mCurrentDiscoveryParameters =
495 NfcDiscoveryParameters.getNfcOffParameters();
496 ReaderModeParams mReaderModeParams;
nxpandroid281eb922016-08-25 20:27:46 +0530497 private int mUserId;
498 boolean mPollingPaused;
499
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +0530500 static final int INVALID_NATIVE_HANDLE = -1;
Nikhil Chhabraefd6b092018-04-11 15:28:06 +0530501 static final int SE_ACCESS_DENIED = -2;
nxpandroid623a3632017-04-10 18:27:16 +0530502 byte[] mDebounceTagUid;
nxpandroid281eb922016-08-25 20:27:46 +0530503 int mDebounceTagDebounceMs;
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +0530504 int mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE;
nxpandroid281eb922016-08-25 20:27:46 +0530505 ITagRemovedCallback mDebounceTagRemovedCallback;
nxpandroid64fd68c2015-09-23 16:45:15 +0530506
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530507 // Only accessed on one thread so doesn't need locking
508 NdefMessage mLastReadNdefMessage;
509
510 // Metrics
511 AtomicInteger mNumTagsDetected;
512 AtomicInteger mNumP2pDetected;
513 AtomicInteger mNumHceDetected;
514
nxpandroid64fd68c2015-09-23 16:45:15 +0530515 // mState is protected by this, however it is only modified in onCreate()
516 // and the default AsyncTask thread so it is read unprotected from that
517 // thread
518 int mState; // one of NfcAdapter.STATE_ON, STATE_TURNING_ON, etc
Nikhil Chhabrad6957c72018-03-09 11:44:48 +0530519 int mNxpNfcState = NXP_NFC_STATE_OFF;
520
nxpandroid64fd68c2015-09-23 16:45:15 +0530521 boolean mPowerShutDown = false; // State for power shut down state
522
523 // fields below are final after onCreate()
524 Context mContext;
525 private DeviceHost mDeviceHost;
526 private SharedPreferences mPrefs;
nxpandroida9a68ba2016-01-14 21:12:17 +0530527 private SharedPreferences mNxpPrefs;
nxpandroid64fd68c2015-09-23 16:45:15 +0530528 private SharedPreferences.Editor mPrefsEditor;
nxpandroida9a68ba2016-01-14 21:12:17 +0530529 private SharedPreferences.Editor mNxpPrefsEditor;
nxpandroid64fd68c2015-09-23 16:45:15 +0530530 private PowerManager.WakeLock mRoutingWakeLock;
531 private PowerManager.WakeLock mEeWakeLock;
532
533 int mStartSound;
534 int mEndSound;
535 int mErrorSound;
536 SoundPool mSoundPool; // playback synchronized on this
537 P2pLinkManager mP2pLinkManager;
538 TagService mNfcTagService;
539 NfcAdapterService mNfcAdapter;
540 NfcAdapterExtrasService mExtrasService;
541// CardEmulationService mCardEmulationService;
542 NxpNfcAdapterService mNxpNfcAdapter;
nxpandroid64fd68c2015-09-23 16:45:15 +0530543 boolean mIsDebugBuild;
544 boolean mIsHceCapable;
nxpandroid34627bd2016-05-27 15:52:30 +0530545 boolean mIsHceFCapable;
Pratap Reddy8f473f02018-04-23 15:18:30 +0530546 public boolean mIsRoutingTableDirty;
nxpandroid64fd68c2015-09-23 16:45:15 +0530547 boolean mIsFelicaOnHostConfigured;
548 boolean mIsFelicaOnHostConfiguring;
549
550 public boolean mIsRouteForced;
nxpandroid64fd68c2015-09-23 16:45:15 +0530551 NfcSccAccessControl mNfcSccAccessControl;
552 NfcSeAccessControl mNfcSeAccessControl;
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +0530553 NfcDtaService mNfcDtaService;
nxpandroid64fd68c2015-09-23 16:45:15 +0530554 NfcVzwService mVzwService;
555 private NfcDispatcher mNfcDispatcher;
556 private PowerManager mPowerManager;
557 private KeyguardManager mKeyguard;
558 ToastHandler mToastHandler;
559 private HandoverDataParser mHandoverDataParser;
560 private ContentResolver mContentResolver;
nxpandroidebf53fb2016-12-22 18:48:59 +0530561 private RegisteredAidCache mAidCache;
nxpandroid64fd68c2015-09-23 16:45:15 +0530562 private CardEmulationManager mCardEmulationManager;
Suhas Suresh6e05ee02018-04-25 12:19:35 +0530563 private Vibrator mVibrator;
564 private VibrationEffect mVibrationEffect;
nxpandroid64fd68c2015-09-23 16:45:15 +0530565 private AidRoutingManager mAidRoutingManager;
Suhas Sureshca6584b2018-04-27 17:17:22 +0530566 private ISecureElementService mSEService;
nxpandroid64fd68c2015-09-23 16:45:15 +0530567 private ScreenStateHelper mScreenStateHelper;
568 private ForegroundUtils mForegroundUtils;
569 private boolean mClearNextTapDefault;
570 private NxpNfcController mNxpNfcController;
571
nxpandroid64fd68c2015-09-23 16:45:15 +0530572 private static NfcService sService;
nxpandroid281eb922016-08-25 20:27:46 +0530573 public static boolean sIsDtaMode = false;
574 public static boolean sIsShortRecordLayout = false;
575 public static boolean sAidTableFull = false;
nxpandroid5d64ce92016-11-18 19:48:53 +0530576 private WatchDogThread disableInternalwatchDog;
nxpandroid64fd68c2015-09-23 16:45:15 +0530577
578 //GSMA
579 private final Boolean defaultTransactionEventReceptionMode = Boolean.FALSE;
nxpandroid623a3632017-04-10 18:27:16 +0530580 private static final Boolean multiReceptionMode = Boolean.TRUE;
581 private static final Boolean unicastReceptionMode = Boolean.FALSE;
nxpandroid64fd68c2015-09-23 16:45:15 +0530582 boolean mIsSentUnicastReception = false;
583
Ganesh Devaf550e962018-07-24 11:59:09 +0530584 //WiredSe
585 Class mWiredSeClass;
586 Method mWiredSeInitMethod, mWiredSeDeInitMwthod;
587 Object mWiredSeObj;
Nikhil Chhabraefd6b092018-04-11 15:28:06 +0530588
nxpandroid64fd68c2015-09-23 16:45:15 +0530589 public void enforceNfcSeAdminPerm(String pkg) {
590 if (pkg == null) {
591 throw new SecurityException("caller must pass a package name");
592 }
593 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
594 if (!mNfcSeAccessControl.check(Binder.getCallingUid(), pkg)) {
595 throw new SecurityException(NfcSeAccessControl.NFCSE_ACCESS_PATH +
596 " denies NFCSe access to " + pkg);
597 }
598 if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
599 throw new SecurityException("only the owner is allowed to act as SCC admin");
600 }
601 }
602 public void enforceNfceeAdminPerm(String pkg) {
603 if (pkg == null) {
604 throw new SecurityException("caller must pass a package name");
605 }
606 NfcPermissions.enforceUserPermissions(mContext);
nxpandroid64fd68c2015-09-23 16:45:15 +0530607 if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
608 throw new SecurityException("only the owner is allowed to call SE APIs");
609 }
610 }
611
612
613 /* SCC Access Control */
614 public void enforceNfcSccAdminPerm(String pkg) {
615 if (pkg == null) {
616 throw new SecurityException("caller must pass a package name");
617 }
618 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
619 if (!mNfcSccAccessControl.check(Binder.getCallingUid(), pkg)) {
620 throw new SecurityException(NfcSccAccessControl.NFCSCC_ACCESS_PATH +
621 " denies NFCSCC access to " + pkg);
622 }
623 if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
624 throw new SecurityException("only the owner is allowed to act as SCC admin");
625 }
626 }
627
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530628 boolean mIsLiveCaseEnabled; // whether live cases are enabled
629 int mLiveCaseTechnology; // Technology mask of accepted NFC tags
630
Nikhil Chhabrafc8f3f62018-01-08 20:48:49 +0530631 private IVrManager vrManager;
632 boolean mIsVrModeEnabled;
633
nxpandroid64fd68c2015-09-23 16:45:15 +0530634 public static NfcService getInstance() {
635 return sService;
636 }
637
638 @Override
639 public void onRemoteEndpointDiscovered(TagEndpoint tag) {
640 sendMessage(NfcService.MSG_NDEF_TAG, tag);
641 }
642
643 public int getRemainingAidTableSize() {
644 return mDeviceHost.getRemainingAidTableSize();
645 }
646
nxpandroidebf53fb2016-12-22 18:48:59 +0530647 public boolean getLastCommitRoutingStatus() {
648 return mAidRoutingManager.getLastCommitRoutingStatus();
649 }
650
nxpandroid64fd68c2015-09-23 16:45:15 +0530651 public int getChipVer() {
652 return mDeviceHost.getChipVer();
653 }
nxf382934d174fd2018-06-29 13:02:43 +0530654
nxpandroid64fd68c2015-09-23 16:45:15 +0530655 /**
656 * Notifies Card emulation deselect
657 */
658 @Override
659 public void onCardEmulationDeselected() {
660 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
661 sendMessage(NfcService.MSG_TARGET_DESELECTED, null);
662 }
663 }
664
665 /**
nxpandroid64fd68c2015-09-23 16:45:15 +0530666 * Notifies connectivity
667 */
668 @Override
669 public void onConnectivityEvent(int evtSrc) {
670 Log.d(TAG, "onConnectivityEvent : Source" + evtSrc);
671 sendMessage(NfcService.MSG_CONNECTIVITY_EVENT, evtSrc);
672 }
673
674 @Override
675 public void onEmvcoMultiCardDetectedEvent() {
676 Log.d(TAG, "onEmvcoMultiCardDetectedEvent");
677 sendMessage(NfcService.MSG_EMVCO_MULTI_CARD_DETECTED_EVENT,null);
678 }
679
680 /**
681 * Notifies transaction
682 */
683 @Override
nxpandroid34627bd2016-05-27 15:52:30 +0530684 public void onHostCardEmulationActivated(int technology) {
nxpandroid64fd68c2015-09-23 16:45:15 +0530685 if (mCardEmulationManager != null) {
nxpandroid34627bd2016-05-27 15:52:30 +0530686 mCardEmulationManager.onHostCardEmulationActivated(technology);
nxpandroid64fd68c2015-09-23 16:45:15 +0530687 }
688 }
689
690 @Override
691 public void onAidRoutingTableFull() {
692 Log.d(TAG, "NxpNci: onAidRoutingTableFull: AID Routing Table is FULL!");
nxpandroid281eb922016-08-25 20:27:46 +0530693 /*if((ROUTE_ID_HOST != GetDefaultRouteLoc())&&(sAidTableFull == false))
nxpandroid64fd68c2015-09-23 16:45:15 +0530694 {
695 Log.d(TAG, "NxpNci: onAidRoutingTableFull: Making Default Route to HOST!");
nxpandroid281eb922016-08-25 20:27:46 +0530696 sAidTableFull = true;
nxpandroid64fd68c2015-09-23 16:45:15 +0530697 mHandler.sendEmptyMessage(NfcService.MSG_CHANGE_DEFAULT_ROUTE);
698 }*/
699 if (mIsHceCapable) {
700 mAidRoutingManager.onNfccRoutingTableCleared();
701 mCardEmulationManager.onRoutingTableChanged();
702 }
703 }
704
705 @Override
nxpandroid5d64ce92016-11-18 19:48:53 +0530706 public void onNotifyT3tConfigure() {
707 if (mCardEmulationManager != null) {
708 mCardEmulationManager.onT3tConfigure();
709 }
710 }
711
712 @Override
713 public void onNotifyReRoutingEntry() {
714 if (mCardEmulationManager != null) {
715 mCardEmulationManager.onReRoutingEntry();
716 }
717 }
718
719 @Override
nxpandroid34627bd2016-05-27 15:52:30 +0530720 public void onHostCardEmulationData(int technology, byte[] data) {
nxpandroid64fd68c2015-09-23 16:45:15 +0530721 if (mCardEmulationManager != null) {
nxpandroid34627bd2016-05-27 15:52:30 +0530722 mCardEmulationManager.onHostCardEmulationData(technology, data);
nxpandroid64fd68c2015-09-23 16:45:15 +0530723 }
724 }
725
726 @Override
nxpandroid34627bd2016-05-27 15:52:30 +0530727 public void onHostCardEmulationDeactivated(int technology) {
nxpandroid64fd68c2015-09-23 16:45:15 +0530728 if (mCardEmulationManager != null) {
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530729 // Do metrics here so we don't slow the CE path down
730 mNumHceDetected.incrementAndGet();
nxpandroid34627bd2016-05-27 15:52:30 +0530731 mCardEmulationManager.onHostCardEmulationDeactivated(technology);
nxpandroid64fd68c2015-09-23 16:45:15 +0530732 }
733 }
734
735 /**
736 * Notifies P2P Device detected, to activate LLCP link
737 */
738 @Override
739 public void onLlcpLinkActivated(NfcDepEndpoint device) {
740 sendMessage(NfcService.MSG_LLCP_LINK_ACTIVATION, device);
741 }
742
743 /**
744 * Notifies P2P Device detected, to activate LLCP link
745 */
746 @Override
747 public void onLlcpLinkDeactivated(NfcDepEndpoint device) {
748 sendMessage(NfcService.MSG_LLCP_LINK_DEACTIVATED, device);
749 }
750
751 /**
752 * Notifies P2P Device detected, first packet received over LLCP link
753 */
754 @Override
755 public void onLlcpFirstPacketReceived(NfcDepEndpoint device) {
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530756 mNumP2pDetected.incrementAndGet();
nxpandroid64fd68c2015-09-23 16:45:15 +0530757 sendMessage(NfcService.MSG_LLCP_LINK_FIRST_PACKET, device);
758 }
759
760 @Override
761 public void onRemoteFieldActivated() {
762 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
763 sendMessage(NfcService.MSG_SE_FIELD_ACTIVATED, null);
764 }
765 }
766
767 @Override
768 public void onRemoteFieldDeactivated() {
769 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
770 sendMessage(NfcService.MSG_SE_FIELD_DEACTIVATED, null);
771 }
772 }
773
774 @Override
775 public void onSeListenActivated() {
776 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
777 sendMessage(NfcService.MSG_SE_LISTEN_ACTIVATED, null);
778 }
779 if (mIsHceCapable) {
nxpandroid34627bd2016-05-27 15:52:30 +0530780 mCardEmulationManager.onHostCardEmulationActivated(TagTechnology.NFC_A);
nxpandroid64fd68c2015-09-23 16:45:15 +0530781 }
782 }
783
784 @Override
785 public void onSeListenDeactivated() {
786 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
787 sendMessage(NfcService.MSG_SE_LISTEN_DEACTIVATED, null);
788 }
789 if( mIsHceCapable) {
nxpandroid34627bd2016-05-27 15:52:30 +0530790 mCardEmulationManager.onHostCardEmulationDeactivated(TagTechnology.NFC_A);
nxpandroid64fd68c2015-09-23 16:45:15 +0530791 }
792 }
793
nxpandroid64fd68c2015-09-23 16:45:15 +0530794 @Override
795 public void onSeApduReceived(byte[] apdu) {
796 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
797 sendMessage(NfcService.MSG_SE_APDU_RECEIVED, apdu);
798 }
799 }
800
801 @Override
802 public void onSeEmvCardRemoval() {
803 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
804 sendMessage(NfcService.MSG_SE_EMV_CARD_REMOVAL, null);
805 }
806 }
807
808 @Override
809 public void onSeMifareAccess(byte[] block) {
810 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
811 sendMessage(NfcService.MSG_SE_MIFARE_ACCESS, block);
812 }
813 }
814
815 @Override
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530816 public void onETSIReaderRequestedEvent(boolean istechA, boolean istechB)
nxpandroid64fd68c2015-09-23 16:45:15 +0530817 {
818 int size=0;
819 ArrayList<Integer> techList = new ArrayList<Integer>();
820 if(istechA)
821 techList.add(TagTechnology.NFC_A);
822 if(istechB)
823 techList.add(TagTechnology.NFC_B);
824
825 sendMessage(NfcService.MSG_SWP_READER_REQUESTED , techList);
826 }
827
828 @Override
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530829 public void onETSIReaderRequestedFail(int FailCause)
nxpandroid64fd68c2015-09-23 16:45:15 +0530830 {
831 sendMessage(NfcService.MSG_SWP_READER_REQUESTED_FAIL , FailCause);
832 }
833
834 @Override
nxpandroid64fd68c2015-09-23 16:45:15 +0530835 public void onETSIReaderModeStartConfig(int eeHandle)
836 {
Pratap Reddy49abbe32018-03-27 16:51:59 +0530837 // Check if NFC is enabled
838 if (!isNfcEnabled()) {
839 return;
840 }
nxpandroid64fd68c2015-09-23 16:45:15 +0530841 ArrayList<Integer> configList = new ArrayList<Integer>();
842 configList.add(eeHandle);
843 sendMessage(NfcService.MSG_ETSI_START_CONFIG, configList);
844 }
845
846 @Override
847 public void onETSIReaderModeStopConfig(int disc_ntf_timeout)
848 {
Pratap Reddy49abbe32018-03-27 16:51:59 +0530849 // Check if NFC is enabled
850 if (!isNfcEnabled()) {
851 return;
852 }
853 EtsiStopConfigTask task = new EtsiStopConfigTask();
854 task.execute(disc_ntf_timeout);
855
nxpandroid64fd68c2015-09-23 16:45:15 +0530856 }
857
858 @Override
859 public void onETSIReaderModeSwpTimeout(int disc_ntf_timeout)
860 {
861 sendMessage(NfcService.MSG_ETSI_SWP_TIMEOUT, disc_ntf_timeout);
862 }
863
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530864 @Override
865 public void onETSIReaderModeRestart() {
866 sendMessage(NfcService.MSG_SWP_READER_RESTART, null);
867 }
868
869 @Override
nxpandroid34627bd2016-05-27 15:52:30 +0530870 public void onUiccStatusEvent(int uiccStat)
871 {
872 Log.i(TAG, "Broadcasting UICC Status : " + uiccStat);
873 Intent uiccStatusIntent = new Intent();
874 uiccStatusIntent.setAction(ACTION_UICC_STATUS_RECEIVED);
875 uiccStatusIntent.putExtra(EXTRA_UICC_STATUS, uiccStat);
876 mContext.sendBroadcast(uiccStatusIntent);
877 }
878
nxpandroid5d64ce92016-11-18 19:48:53 +0530879 @Override
880 public void onRestartWatchDog(int enable) {
881 Log.d(TAG, "Restart Watchdog: WatchDog Thread ID is "+ disableInternalwatchDog.getId());
882 sendMessage(NfcService.MSG_RESTART_WATCHDOG, enable);
883 }
nxpandroid1680a6d2017-01-13 19:13:14 +0530884 @Override
885 public void onFwDwnldReqRestartNfc() {
886 Log.d(TAG, "Restart NFC:When Fw dwnld request was stored during SPI onGoing");
887 new EnableDisableTask().execute(TASK_RESTART);
888 }
nxpandroid5d64ce92016-11-18 19:48:53 +0530889
Suhas Sureshca6584b2018-04-27 17:17:22 +0530890 @Override
891 public void onNfcTransactionEvent(byte[] aid, byte[] data, String seName) {
892 byte[][] dataObj = {aid, data, seName.getBytes()};
893 sendMessage(NfcService.MSG_TRANSACTION_EVENT, dataObj);
894 }
895
nxpandroid64fd68c2015-09-23 16:45:15 +0530896 final class ReaderModeParams {
897 public int flags;
898 public IAppCallback callback;
899 public int presenceCheckDelay;
900 }
901
902 public NfcService(Application nfcApplication) {
903 mUserId = ActivityManager.getCurrentUser();
904 mContext = nfcApplication;
905
906 mNfcTagService = new TagService();
907 mNfcAdapter = new NfcAdapterService();
908 mNxpNfcAdapter = new NxpNfcAdapterService();
909 mExtrasService = new NfcAdapterExtrasService();
nxpandroid64fd68c2015-09-23 16:45:15 +0530910 // mCardEmulationService = new CardEmulationService();
911
Ganesh Devaf550e962018-07-24 11:59:09 +0530912 try {
913 mWiredSeClass = Class.forName("com.android.nfc.WiredSeService");
914 mWiredSeObj = mWiredSeClass.newInstance();
915 } catch (ClassNotFoundException | IllegalAccessException e){
916 Log.e(TAG, "WiredSeService Class not found");
917 } catch (InstantiationException e) {
918 Log.e(TAG, "WiredSeService object Instantiation failed");
919 }
920
nxpandroid64fd68c2015-09-23 16:45:15 +0530921 Log.i(TAG, "Starting NFC service");
922
923 sService = this;
924
925 mScreenStateHelper = new ScreenStateHelper(mContext);
926 mContentResolver = mContext.getContentResolver();
927 mDeviceHost = new NativeNfcManager(mContext, this);
928
929 mNfcUnlockManager = NfcUnlockManager.getInstance();
930
931 mHandoverDataParser = new HandoverDataParser();
932 boolean isNfcProvisioningEnabled = false;
933 try {
934 isNfcProvisioningEnabled = mContext.getResources().getBoolean(
935 R.bool.enable_nfc_provisioning);
936 } catch (NotFoundException e) {
937 }
938
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530939 try {
940 mIsLiveCaseEnabled = mContext.getResources().getBoolean(R.bool.enable_live_cases);
941 } catch (NotFoundException e) {
942 mIsLiveCaseEnabled = false;
943 }
944
945 mLiveCaseTechnology = 0;
946 String[] liveCaseTechList;
947 try {
948 liveCaseTechList = mContext.getResources().getStringArray(R.array.live_case_tag_types);
949 for (int i=0; i < liveCaseTechList.length; i++) {
950 if (liveCaseTechList[i].equals("TypeA")) {
951 mLiveCaseTechnology |= NFC_POLL_A;
952 } else if (liveCaseTechList[i].equals("TypeB")) {
953 mLiveCaseTechnology |= NFC_POLL_B;
954 } else if (liveCaseTechList[i].equals("TypeF")) {
955 mLiveCaseTechnology |= NFC_POLL_F;
956 } else if (liveCaseTechList[i].equals("TypeV")) {
Nikhil Chhabra288edb02018-01-10 19:36:21 +0530957 mLiveCaseTechnology |= NFC_POLL_V;
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530958 }
959 }
960 } catch (NotFoundException e) {
961 mLiveCaseTechnology = 0;
962 }
963
nxpandroid64fd68c2015-09-23 16:45:15 +0530964 if (isNfcProvisioningEnabled) {
965 mInProvisionMode = Settings.Secure.getInt(mContentResolver,
966 Settings.Global.DEVICE_PROVISIONED, 0) == 0;
967 } else {
968 mInProvisionMode = false;
969 }
970
nxpandroid1153eb32015-11-06 18:46:58 +0530971 if(mInProvisionMode)
972 {
973 /* if device is in provision mode, set this mode at lower layers */
974 mDeviceHost.doSetProvisionMode(mInProvisionMode);
975 }
976
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530977 mNfcDispatcher = new NfcDispatcher(mContext, mHandoverDataParser, mInProvisionMode,
978 mIsLiveCaseEnabled);
nxpandroid64fd68c2015-09-23 16:45:15 +0530979 mP2pLinkManager = new P2pLinkManager(mContext, mHandoverDataParser,
980 mDeviceHost.getDefaultLlcpMiu(), mDeviceHost.getDefaultLlcpRwSize());
981
982 mSecureElement = new NativeNfcSecureElement(mContext);
983 mEeRoutingState = ROUTE_OFF;
984 mToastHandler = new ToastHandler(mContext);
985
nxpandroid64fd68c2015-09-23 16:45:15 +0530986 mNfcSccAccessControl = new NfcSccAccessControl(mContext);
987 mNfcSeAccessControl = new NfcSeAccessControl(mContext);
988 mNfcAla = new NativeNfcAla();
989
990 mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE);
991 mPrefsEditor = mPrefs.edit();
nxpandroida9a68ba2016-01-14 21:12:17 +0530992 mNxpPrefs = mContext.getSharedPreferences(NXP_PREF, Context.MODE_PRIVATE);
993 mNxpPrefsEditor = mNxpPrefs.edit();
nxpandroid64fd68c2015-09-23 16:45:15 +0530994
995 mState = NfcAdapter.STATE_OFF;
996 mIsNdefPushEnabled = mPrefs.getBoolean(PREF_NDEF_PUSH_ON, NDEF_PUSH_ON_DEFAULT);
Suhas Suresha18dee02018-04-27 15:28:04 +0530997 enforceBeamShareActivityPolicy(mContext, new UserHandle(mUserId));
nxpandroid64fd68c2015-09-23 16:45:15 +0530998
999 mIsDebugBuild = "userdebug".equals(Build.TYPE) || "eng".equals(Build.TYPE);
1000
1001 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
1002
1003 mRoutingWakeLock = mPowerManager.newWakeLock(
1004 PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mRoutingWakeLock");
1005 mEeWakeLock = mPowerManager.newWakeLock(
1006 PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mEeWakeLock");
1007
1008 mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
1009 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Suhas Suresh6e05ee02018-04-25 12:19:35 +05301010 mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
1011 mVibrationEffect = VibrationEffect.createOneShot(200, VibrationEffect.DEFAULT_AMPLITUDE);
nxpandroid64fd68c2015-09-23 16:45:15 +05301012
1013 mScreenState = mScreenStateHelper.checkScreenState();
1014
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301015 mNumTagsDetected = new AtomicInteger();
1016 mNumP2pDetected = new AtomicInteger();
1017 mNumHceDetected = new AtomicInteger();
1018
1019 mBackupManager = new BackupManager(mContext);
1020
nxpandroid64fd68c2015-09-23 16:45:15 +05301021 // Intents for all users
1022 IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
1023 filter.addAction(Intent.ACTION_SCREEN_OFF);
1024 filter.addAction(Intent.ACTION_SCREEN_ON);
1025 filter.addAction(Intent.ACTION_USER_PRESENT);
1026 filter.addAction(Intent.ACTION_USER_SWITCHED);
nxpandroid64fd68c2015-09-23 16:45:15 +05301027 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null);
1028
nxpandroid5d64ce92016-11-18 19:48:53 +05301029 filter = new IntentFilter(Intent.ACTION_SHUTDOWN);
1030 mContext.registerReceiver(mOwnerReceiver, filter);
1031
nxpandroid64fd68c2015-09-23 16:45:15 +05301032 IntentFilter ownerFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1033 ownerFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
Suhas Sureshc9772c82018-04-27 15:41:19 +05301034 ownerFilter.addAction(Intent.ACTION_SHUTDOWN);
nxpandroid64fd68c2015-09-23 16:45:15 +05301035 mContext.registerReceiver(mOwnerReceiver, ownerFilter);
1036
1037 ownerFilter = new IntentFilter();
1038 ownerFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
1039 ownerFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
1040 ownerFilter.addDataScheme("package");
1041 mContext.registerReceiver(mOwnerReceiver, ownerFilter);
1042
1043 IntentFilter x509CertificateFilter = new IntentFilter();
1044 x509CertificateFilter.addAction(NxpConstants.ACTION_CHECK_X509_RESULT);
nxpandroid5d64ce92016-11-18 19:48:53 +05301045 mContext.registerReceiverAsUser(x509CertificateReceiver, UserHandle.ALL,
1046 x509CertificateFilter, NfcPermissions.ADMIN_PERM, null);
nxpandroid64fd68c2015-09-23 16:45:15 +05301047
Shashank vimal83779082018-02-06 18:10:31 +05301048 IntentFilter activateStkFilter = new IntentFilter();
1049 activateStkFilter.addAction(NxpConstants.CAT_ACTIVATE_NOTIFY_ACTION);
1050 mContext.registerReceiver(mActivateSwpInterface, activateStkFilter);
1051
nxpandroid64fd68c2015-09-23 16:45:15 +05301052 IntentFilter enableNfc = new IntentFilter();
1053 enableNfc.addAction(NxpConstants.ACTION_GSMA_ENABLE_NFC);
nxpandroid5d64ce92016-11-18 19:48:53 +05301054 mContext.registerReceiverAsUser(mEnableNfc, UserHandle.ALL, enableNfc, null, null);
nxpandroid64fd68c2015-09-23 16:45:15 +05301055
1056 IntentFilter lsFilter = new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
1057 //mContext.registerReceiver(mAlaReceiver, lsFilter);
nxpandroid64fd68c2015-09-23 16:45:15 +05301058
1059 IntentFilter policyFilter = new IntentFilter(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1060 mContext.registerReceiverAsUser(mPolicyReceiver, UserHandle.ALL, policyFilter, null, null);
1061
1062 updatePackageCache();
1063
1064 PackageManager pm = mContext.getPackageManager();
nxpandroid34627bd2016-05-27 15:52:30 +05301065 mIsHceCapable =
1066 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION) ||
1067 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF);
1068 mIsHceFCapable =
1069 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF);
1070
nxpandroid64fd68c2015-09-23 16:45:15 +05301071 if (mIsHceCapable) {
1072 mAidRoutingManager = new AidRoutingManager();
nxpandroid1680a6d2017-01-13 19:13:14 +05301073 mCardEmulationManager = new CardEmulationManager(mContext, mAidRoutingManager);
1074 mAidCache = mCardEmulationManager.getRegisteredAidCache();
nxpandroid64fd68c2015-09-23 16:45:15 +05301075 //mCardEmulationManager = new CardEmulationManager(mContext);
1076 Log.d("NfcService", "Before mIsHceCapable");
1077 mNxpNfcController = new NxpNfcController(mContext, mCardEmulationManager);
1078 }
1079
1080 mForegroundUtils = ForegroundUtils.getInstance();
nxpandroid281eb922016-08-25 20:27:46 +05301081
1082 // Make sure this is only called when object construction is complete.
1083 ServiceManager.addService(SERVICE_NAME, mNfcAdapter);
1084
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05301085 ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
Suhas Sureshe89490a2018-07-06 23:36:16 +05301086
nxpandroid64fd68c2015-09-23 16:45:15 +05301087 new EnableDisableTask().execute(TASK_BOOT); // do blocking boot tasks
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301088
1089 mHandler.sendEmptyMessageDelayed(MSG_UPDATE_STATS, STATS_UPDATE_INTERVAL_MS);
Nikhil Chhabrafc8f3f62018-01-08 20:48:49 +05301090
1091 IVrManager mVrManager = IVrManager.Stub.asInterface(ServiceManager.getService(
1092 mContext.VR_SERVICE));
1093 if (mVrManager != null) {
1094 try {
1095 mVrManager.registerListener(mVrStateCallbacks);
1096 mIsVrModeEnabled = mVrManager.getVrModeState();
1097 } catch (RemoteException e) {
1098 Log.e(TAG, "Failed to register VR mode state listener: " + e);
1099 }
1100 }
Suhas Sureshca6584b2018-04-27 17:17:22 +05301101 mSEService = ISecureElementService.Stub.asInterface(ServiceManager.getService(
1102 Context.SECURE_ELEMENT_SERVICE));
nxpandroid5c5b2152017-09-14 12:30:17 +05301103 /*SoundPool clean up before NFC state updated*/
1104 initSoundPool();
nxpandroid64fd68c2015-09-23 16:45:15 +05301105 }
1106
Ganesh Deva272ad052018-07-09 15:56:45 +05301107 private boolean isSEServiceAvailable() {
1108 if (mSEService == null) {
1109 mSEService = ISecureElementService.Stub.asInterface(ServiceManager.getService(
1110 Context.SECURE_ELEMENT_SERVICE));
1111 }
1112 return (mSEService != null);
1113 }
1114
nxpandroid64fd68c2015-09-23 16:45:15 +05301115 void initSoundPool() {
1116 synchronized(this) {
1117 if (mSoundPool == null) {
1118 mSoundPool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0);
1119 mStartSound = mSoundPool.load(mContext, R.raw.start, 1);
1120 mEndSound = mSoundPool.load(mContext, R.raw.end, 1);
1121 mErrorSound = mSoundPool.load(mContext, R.raw.error, 1);
1122 }
1123 }
1124 }
1125
1126 void releaseSoundPool() {
1127 synchronized (this) {
1128 if (mSoundPool != null) {
1129 mSoundPool.release();
1130 mSoundPool = null;
1131 }
1132 }
1133 }
1134
nxpandroid64fd68c2015-09-23 16:45:15 +05301135 void updatePackageCache() {
1136 PackageManager pm = mContext.getPackageManager();
Suhas Sureshca6584b2018-04-27 17:17:22 +05301137 List<PackageInfo> packagesNfcEvents = pm.getPackagesHoldingPermissions(
1138 new String[] {android.Manifest.permission.NFC_TRANSACTION_EVENT},
1139 PackageManager.GET_ACTIVITIES);
nxpandroid64fd68c2015-09-23 16:45:15 +05301140 synchronized (this) {
Suhas Suresh140f7ac2018-05-15 14:59:11 +05301141 mNfcEventInstalledPackages.clear();
1142 for (int i = 0; i < packagesNfcEvents.size(); i++) {
nxf382935cedb182019-02-01 11:48:15 +05301143 mNfcEventInstalledPackages.add(packagesNfcEvents.get(i).packageName);
Suhas Suresh140f7ac2018-05-15 14:59:11 +05301144 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301145 }
1146 }
1147
nxpandroid7d44e572016-08-01 19:11:04 +05301148 int doOpenSecureElementConnection(int seId) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301149 mEeWakeLock.acquire();
1150 try {
nxpandroid7d44e572016-08-01 19:11:04 +05301151 return mSecureElement.doOpenSecureElementConnection(seId);
nxpandroid64fd68c2015-09-23 16:45:15 +05301152 } finally {
1153 mEeWakeLock.release();
1154 }
1155 }
1156
1157 byte[] doTransceive(int handle, byte[] cmd) {
1158 mEeWakeLock.acquire();
1159 try {
1160 return doTransceiveNoLock(handle, cmd);
1161 } finally {
1162 mEeWakeLock.release();
1163 }
1164 }
1165
1166 byte[] doTransceiveNoLock(int handle, byte[] cmd) {
1167 return mSecureElement.doTransceive(handle, cmd);
1168 }
1169
1170 void doDisconnect(int handle) {
1171 mEeWakeLock.acquire();
1172 try {
1173 mSecureElement.doDisconnect(handle);
1174 } finally {
1175 mEeWakeLock.release();
1176 }
1177 }
1178
1179 boolean doReset(int handle) {
1180 mEeWakeLock.acquire();
1181 try {
1182 return mSecureElement.doReset(handle);
1183 } finally {
1184 mEeWakeLock.release();
1185 }
1186 }
1187
1188 public static byte[] CreateSHA(String pkg, int alaVer){
nxpandroid281eb922016-08-25 20:27:46 +05301189 String localTAG = "Utils:CreateSHA";
nxpandroid64fd68c2015-09-23 16:45:15 +05301190 StringBuffer sb = new StringBuffer();
1191 try {
1192 MessageDigest md;
1193 if(alaVer == 1)
1194 md = MessageDigest.getInstance("SHA-256");
1195 else
1196 md = MessageDigest.getInstance("SHA-1");
1197
1198 md.update(pkg.getBytes());
1199
nxpandroid281eb922016-08-25 20:27:46 +05301200 byte[] byteData = md.digest();
1201 Log.i(localTAG, "byteData len : " + byteData.length);
nxpandroid64fd68c2015-09-23 16:45:15 +05301202 /*
1203 for (int i = 0; i < byteData.length; i++) {
1204 sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
1205 }
1206 // Log.i(TAG, "sb.toString()" + sb.toString());*/
1207 return byteData;
1208 } catch (Exception e) {
1209 e.printStackTrace();
1210 }
1211 return null;
1212 }
1213
nxpandroid64fd68c2015-09-23 16:45:15 +05301214 /**
1215 * Manages tasks that involve turning on/off the NFC controller.
1216 * <p/>
1217 * <p>All work that might turn the NFC adapter on or off must be done
1218 * through this task, to keep the handling of mState simple.
1219 * In other words, mState is only modified in these tasks (and we
1220 * don't need a lock to read it in these tasks).
1221 * <p/>
1222 * <p>These tasks are all done on the same AsyncTask background
1223 * thread, so they are serialized. Each task may temporarily transition
1224 * mState to STATE_TURNING_OFF or STATE_TURNING_ON, but must exit in
1225 * either STATE_ON or STATE_OFF. This way each task can be guaranteed
1226 * of starting in either STATE_OFF or STATE_ON, without needing to hold
1227 * NfcService.this for the entire task.
1228 * <p/>
1229 * <p>AsyncTask's are also implicitly queued. This is useful for corner
1230 * cases like turning airplane mode on while TASK_ENABLE is in progress.
1231 * The TASK_DISABLE triggered by airplane mode will be correctly executed
1232 * immediately after TASK_ENABLE is complete. This seems like the most sane
1233 * way to deal with these situations.
1234 * <p/>
1235 * <p>{@link #TASK_ENABLE} enables the NFC adapter, without changing
1236 * preferences
1237 * <p>{@link #TASK_DISABLE} disables the NFC adapter, without changing
1238 * preferences
1239 * <p>{@link #TASK_BOOT} does first boot work and may enable NFC
1240 */
1241 class EnableDisableTask extends AsyncTask<Integer, Void, Void> {
1242 @Override
1243 protected Void doInBackground(Integer... params) {
1244 // Sanity check mState
1245 switch (mState) {
1246 case NfcAdapter.STATE_TURNING_OFF:
1247 case NfcAdapter.STATE_TURNING_ON:
1248 Log.e(TAG, "Processing EnableDisable task " + params[0] + " from bad state " +
1249 mState);
1250 return null;
1251 }
1252
1253 /* AsyncTask sets this thread to THREAD_PRIORITY_BACKGROUND,
1254 * override with the default. THREAD_PRIORITY_BACKGROUND causes
1255 * us to service software I2C too slow for firmware download
1256 * with the NXP PN544.
1257 * TODO: move this to the DAL I2C layer in libnfc-nxp, since this
1258 * problem only occurs on I2C platforms using PN544
1259 */
1260 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1261
1262 switch (params[0].intValue()) {
1263 case TASK_ENABLE:
1264 enableInternal();
1265 break;
1266 case TASK_DISABLE:
1267 disableInternal();
1268 break;
1269 case TASK_BOOT:
Suhas Suresh1fe09dc2018-05-07 11:55:06 +05301270 if (mPrefs.getBoolean(PREF_FIRST_BOOT, true)) {
1271 Log.i(TAG, "First Boot");
1272 mPrefsEditor.putBoolean(PREF_FIRST_BOOT, false);
1273 mPrefsEditor.apply();
1274 mDeviceHost.factoryReset();
1275 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301276 Log.d(TAG, "checking on firmware download");
nxpandroid7d44e572016-08-01 19:11:04 +05301277 if (mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT)) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301278 Log.d(TAG, "NFC is on. Doing normal stuff");
nxpandroid5d64ce92016-11-18 19:48:53 +05301279 mIsTaskBoot = true;
nxpandroid64fd68c2015-09-23 16:45:15 +05301280 enableInternal();
nxpandroid5d64ce92016-11-18 19:48:53 +05301281 mIsTaskBoot = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05301282 } else {
1283 Log.d(TAG, "NFC is off. Checking firmware version");
1284 mDeviceHost.checkFirmware();
1285 }
Nikhil Chhabraa9e399a2018-01-09 11:47:13 +05301286 SystemProperties.set("nfc.initialized", "true");
nxpandroid64fd68c2015-09-23 16:45:15 +05301287 break;
nxpandroid1680a6d2017-01-13 19:13:14 +05301288 case TASK_RESTART:
1289 restartInternal();
1290
nxpandroid64fd68c2015-09-23 16:45:15 +05301291 }
1292
1293 // Restore default AsyncTask priority
1294 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1295 return null;
1296 }
1297
1298 @Override
1299 protected void onPostExecute(Void result) {
1300
1301 if(mState == NfcAdapter.STATE_ON){
1302 IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
1303 filter.addAction(Intent.ACTION_SCREEN_OFF);
1304 filter.addAction(Intent.ACTION_SCREEN_ON);
1305 filter.addAction(Intent.ACTION_USER_PRESENT);
1306 filter.addAction(Intent.ACTION_USER_SWITCHED);
nxpandroid64fd68c2015-09-23 16:45:15 +05301307 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null);
1308 }else if (mState == NfcAdapter.STATE_OFF){
1309 mContext.unregisterReceiver(mReceiver);
1310 IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
1311 filter.addAction(Intent.ACTION_USER_SWITCHED);
nxpandroid64fd68c2015-09-23 16:45:15 +05301312 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null);
1313 }
1314
1315
1316 }
1317
1318 /**
1319 * Check the default Secure Element configuration.
1320 */
1321 void checkSecureElementConfuration() {
1322
1323 /* Get SE List */
nxpandroid281eb922016-08-25 20:27:46 +05301324 int[] seList = mDeviceHost.doGetSecureElementList();
nxpandroidebf53fb2016-12-22 18:48:59 +05301325 int uiccSlot = 0;
1326 uiccSlot = mPrefs.getInt(PREF_CUR_SELECTED_UICC_ID, SECURE_ELEMENT_UICC_SLOT_DEFAULT);
1327 int status = mDeviceHost.setPreferredSimSlot(uiccSlot);
nxpandroid64fd68c2015-09-23 16:45:15 +05301328 /* Check Secure Element setting */
nxpandroid281eb922016-08-25 20:27:46 +05301329 int seNum=mDeviceHost.GetDefaultSE();
1330 if(seNum != 0)
nxpandroid64fd68c2015-09-23 16:45:15 +05301331 {
1332 SECURE_ELEMENT_ON_DEFAULT=true;
nxpandroid281eb922016-08-25 20:27:46 +05301333 SECURE_ELEMENT_ID_DEFAULT=seNum;
nxpandroid64fd68c2015-09-23 16:45:15 +05301334 } else {
nxpandroid281eb922016-08-25 20:27:46 +05301335 if (seList != null) {
1336 for (int i = 0; i < seList.length; i++) {
1337 mDeviceHost.doDeselectSecureElement(seList[i]);
nxpandroid64fd68c2015-09-23 16:45:15 +05301338 }
1339 }
1340 }
1341
1342 mNfcSecureElementState =
nxpandroida9a68ba2016-01-14 21:12:17 +05301343 mNxpPrefs.getBoolean(PREF_SECURE_ELEMENT_ON, SECURE_ELEMENT_ON_DEFAULT);
nxpandroid64fd68c2015-09-23 16:45:15 +05301344
1345 if (mNfcSecureElementState) {
1346 int secureElementId =
nxpandroida9a68ba2016-01-14 21:12:17 +05301347 mNxpPrefs.getInt(PREF_SECURE_ELEMENT_ID, SECURE_ELEMENT_ID_DEFAULT);
nxpandroid64fd68c2015-09-23 16:45:15 +05301348
nxpandroid281eb922016-08-25 20:27:46 +05301349 if (seList != null) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301350 if (secureElementId != ALL_SE_ID_TYPE/* SECURE_ELEMENT_ALL */) {
1351 mDeviceHost.doDeselectSecureElement(UICC_ID_TYPE);
nxpandroid7d44e572016-08-01 19:11:04 +05301352 mDeviceHost.doDeselectSecureElement(UICC2_ID_TYPE);
nxpandroid64fd68c2015-09-23 16:45:15 +05301353 mDeviceHost.doDeselectSecureElement(SMART_MX_ID_TYPE);
1354
nxpandroid281eb922016-08-25 20:27:46 +05301355 for (int i = 0; i < seList.length; i++) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301356
nxpandroid281eb922016-08-25 20:27:46 +05301357 if (seList[i] == secureElementId) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301358 if (secureElementId == SMART_MX_ID_TYPE) { // SECURE_ELEMENT_SMX_ID
nxpandroid281eb922016-08-25 20:27:46 +05301359 if (seList.length > 1) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301360 if (DBG) {
1361 Log.d(TAG, "Deselect UICC");
1362 }
1363 }
1364 Log.d(TAG, "Select SMX");
1365 mDeviceHost.doSelectSecureElement(secureElementId);
1366 mSelectedSeId = secureElementId;
1367 break;
1368 } else if (secureElementId == UICC_ID_TYPE/* SECURE_ELEMENT_UICC_ID */) {
nxpandroid281eb922016-08-25 20:27:46 +05301369 if (seList.length > 1) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301370 if (DBG) {
1371 Log.d(TAG, "Deselect SMX");
1372 }
1373 }
1374 Log.d(TAG, "Select UICC");
1375 mDeviceHost.doSelectSecureElement(secureElementId);
1376 mSelectedSeId = secureElementId;
1377 break;
nxpandroid7d44e572016-08-01 19:11:04 +05301378 }else if (secureElementId == UICC2_ID_TYPE/* SECURE_ELEMENT_UICC_ID */) {
nxpandroid281eb922016-08-25 20:27:46 +05301379 if (seList.length > 1) {
nxpandroid7d44e572016-08-01 19:11:04 +05301380 if (DBG) {
1381 Log.d(TAG, "Deselect SMX");
1382 }
1383 }
1384 Log.d(TAG, "Select UICC2");
1385 mDeviceHost.doSelectSecureElement(secureElementId);
1386 mSelectedSeId = secureElementId;
1387 break;
nxpandroid64fd68c2015-09-23 16:45:15 +05301388 } else if (secureElementId == SECURE_ELEMENT_ID_DEFAULT) {
nxpandroid281eb922016-08-25 20:27:46 +05301389 if (seList.length > 1) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301390 if (DBG) {
1391 Log.d(TAG, "UICC deselected by default");
1392 }
1393 }
1394 }
1395 }
1396 }
1397 } else {
1398 if (DBG) {
1399 Log.d(TAG, "Select ALL_SE");
1400 }
1401
nxpandroid281eb922016-08-25 20:27:46 +05301402 if (seList.length > 1) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301403
nxpandroid281eb922016-08-25 20:27:46 +05301404 for (int i = 0; i < seList.length; i++) {
1405 mDeviceHost.doSelectSecureElement(seList[i]);
nxpandroid64fd68c2015-09-23 16:45:15 +05301406 try{
1407 //Delay b/w two SE selection.
1408 Thread.sleep(200);
1409 } catch(Exception e) {
1410 e.printStackTrace();
1411 }
1412 }
1413 mSelectedSeId = secureElementId;
1414 }
1415 }
1416 }
1417 } else {
nxpandroid281eb922016-08-25 20:27:46 +05301418 if (seList != null && seList.length > 0) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301419 if (DBG) {
1420 Log.d(TAG, "UICC/eSE deselected by default");
1421 }
1422 mDeviceHost.doDeselectSecureElement(UICC_ID_TYPE);
nxpandroid7d44e572016-08-01 19:11:04 +05301423 mDeviceHost.doDeselectSecureElement(UICC2_ID_TYPE);
nxpandroid64fd68c2015-09-23 16:45:15 +05301424 mDeviceHost.doDeselectSecureElement(SMART_MX_ID_TYPE);
1425 }
1426 }
1427 }
1428
1429 boolean getJcopOsFileInfo() {
1430 File jcopOsFile;
1431 Log.i(TAG, "getJcopOsFileInfo");
1432
1433 for (int num = 0; num < 3; num++) {
1434 try{
1435 jcopOsFile = new File(path[num]);
1436 }catch(NullPointerException npe) {
1437 Log.e(TAG,"path to jcop os file was null");
1438 return false;
1439 }
1440 long modtime = jcopOsFile.lastModified();
1441 SharedPreferences prefs = mContext.getSharedPreferences(PREF,Context.MODE_PRIVATE);
1442 long prev_modtime = prefs.getLong(PREF_JCOP_MODTIME[num], JCOP_MODTIME_DEFAULT[num]);
1443 Log.d(TAG,"prev_modtime:" + prev_modtime);
1444 Log.d(TAG,"new_modtime:" + modtime);
1445 if(prev_modtime == modtime){
1446 return false;
1447 }
1448 JCOP_MODTIME_TEMP[num] = modtime;
1449 }
1450 return true;
1451 }
1452
1453 /* jcop os Download at boot time */
1454 void jcopOsDownload() {
1455 int status = ErrorCodes.SUCCESS;
1456 boolean jcopStatus;
1457 Log.i(TAG, "Jcop Download starts");
1458
1459 SharedPreferences prefs = mContext.getSharedPreferences(PREF,Context.MODE_PRIVATE);
1460 jcopStatus = getJcopOsFileInfo();
1461
1462 if( jcopStatus == true) {
1463 Log.i(TAG, "Starting getChipName");
1464 int Ver = mDeviceHost.getChipVer();
nxpandroid281eb922016-08-25 20:27:46 +05301465 if(Ver == PN80T_ID || Ver == PN67T_ID || Ver == PN66T_ID || Ver == PN65T_ID) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301466 status = mDeviceHost.JCOSDownload();
1467 }
1468 if(status != ErrorCodes.SUCCESS) {
1469 Log.i(TAG, "Jcop Download failed");
1470 }
1471 else {
1472 Log.i(TAG, "Jcop Download success");
1473 prefs.edit().putLong(PREF_JCOP_MODTIME[0],JCOP_MODTIME_TEMP[0]).apply();
1474 prefs.edit().putLong(PREF_JCOP_MODTIME[1],JCOP_MODTIME_TEMP[1]).apply();
1475 prefs.edit().putLong(PREF_JCOP_MODTIME[2],JCOP_MODTIME_TEMP[2]).apply();
1476 }
1477 }
1478 }
1479 /**
1480 * Enable NFC adapter functions.
1481 * Does not toggle preferences.
1482 */
1483 boolean enableInternal() {
1484 if (mState == NfcAdapter.STATE_ON) {
1485 return true;
1486 }
1487 Log.i(TAG, "Enabling NFC");
1488 updateState(NfcAdapter.STATE_TURNING_ON);
1489 int timeout = mDeviceHost.getNfcInitTimeout();
1490 if (timeout < INIT_WATCHDOG_MS)
1491 {
1492 timeout = INIT_WATCHDOG_MS;
1493 }
1494 Log.i(TAG, "Enabling NFC timeout" +timeout);
1495 WatchDogThread watchDog = new WatchDogThread("enableInternal", timeout);
1496 watchDog.start();
1497 try {
1498 mRoutingWakeLock.acquire();
1499 try {
1500 if (!mDeviceHost.initialize()) {
1501 Log.w(TAG, "Error enabling NFC");
1502 updateState(NfcAdapter.STATE_OFF);
Ganesh Deva2b056252018-10-25 18:13:13 +05301503 watchDog.cancel();
nxpandroid64fd68c2015-09-23 16:45:15 +05301504 return false;
1505 }
1506 } finally {
1507 mRoutingWakeLock.release();
1508 }
1509 } finally {
1510 watchDog.cancel();
1511 }
nxf32288d12785b2017-11-17 15:18:31 +05301512 mChipVer = mDeviceHost.getChipVer();
1513 if(mChipVer < PN553_ID) {
nxf322881754ee02017-10-24 13:33:24 +05301514 ALL_SE_ID_TYPE &= ~UICC2_ID_TYPE;
nxpandroid5d64ce92016-11-18 19:48:53 +05301515 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301516 checkSecureElementConfuration();
1517
1518 mIsRouteForced = true;
1519 if (mIsHceCapable) {
1520 // Generate the initial card emulation routing table
nxpandroid281eb922016-08-25 20:27:46 +05301521 sAidTableFull = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05301522 mCardEmulationManager.onNfcEnabled();
1523 }
1524 mIsRouteForced = false;
nxpandroide66eb092017-07-12 21:36:08 +05301525 nci_version = getNciVersion();
nxpandroid64fd68c2015-09-23 16:45:15 +05301526
1527 synchronized (NfcService.this) {
1528 mObjectMap.clear();
1529 mP2pLinkManager.enableDisable(mIsNdefPushEnabled, true);
nxpandroid64fd68c2015-09-23 16:45:15 +05301530 }
1531
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301532 synchronized (NfcService.this) {
Suhas Sureshe75588d2018-07-11 15:22:24 +05301533 updateState(NfcAdapter.STATE_ON);
1534 try {
Ganesh Devaf550e962018-07-24 11:59:09 +05301535 mWiredSeInitMethod = mWiredSeClass.getDeclaredMethod("wiredSeInitialize");
1536 mWiredSeInitMethod.invoke(mWiredSeObj);
1537 } catch (NoSuchElementException | NoSuchMethodException e) {
1538 Log.i(TAG, "No such Method WiredSeInitialize");
1539 } catch (RuntimeException | IllegalAccessException | InvocationTargetException e) {
1540 Log.e(TAG, "Error in invoking wiredSeInitialize invocation");
1541 } catch (Exception e) {
1542 Log.e(TAG, "caught Exception during wiredSeInitialize");
1543 e.printStackTrace();
Suhas Sureshe75588d2018-07-11 15:22:24 +05301544 }
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301545 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301546 /* Start polling loop */
1547 Log.e(TAG, "applyRouting -3");
1548 mScreenState = mScreenStateHelper.checkScreenState();
nxpandroide66eb092017-07-12 21:36:08 +05301549 int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ?
1550 (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState;
1551
1552 if(mNfcUnlockManager.isLockscreenPollingEnabled())
1553 applyRouting(false);
1554
1555 mDeviceHost.doSetScreenOrPowerState(screen_state_mask);
nxpandroid64fd68c2015-09-23 16:45:15 +05301556 mIsRoutingTableDirty = true;
nxpandroid5d64ce92016-11-18 19:48:53 +05301557 if((mScreenState < NFC_POLLING_MODE) && mIsTaskBoot)
1558 {
1559 /*During device boot if screen state is other ON_UNLOCKED,
1560 *first send discovery command with poll and linsten enabled
1561 *for DC/DC pass through mode activation.
1562 *Then send normal discovery according to screen state*/
1563 applyRouting(true);
1564 mIsTaskBoot = false;
1565 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301566 applyRouting(true);
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301567 synchronized (NfcService.this) {
1568 mNxpNfcState = NXP_NFC_STATE_ON;
1569 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301570 return true;
1571 }
1572
1573 /**
1574 * Disable all NFC adapter functions.
1575 * Does not toggle preferences.
1576 */
1577 boolean disableInternal() {
1578 if (mState == NfcAdapter.STATE_OFF) {
1579 return true;
1580 }
1581 Log.i(TAG, "Disabling NFC");
1582 updateState(NfcAdapter.STATE_TURNING_OFF);
Ganesh Devaf550e962018-07-24 11:59:09 +05301583
1584 try{
1585 mWiredSeDeInitMwthod = mWiredSeClass.getDeclaredMethod("wiredSeDeInitialize");
1586 mWiredSeDeInitMwthod.invoke(mWiredSeObj);
1587 } catch (NoSuchElementException | NoSuchMethodException e) {
1588 Log.i(TAG, "No such Method WiredSeInitialize");
1589 } catch (RuntimeException | IllegalAccessException | InvocationTargetException e) {
1590 Log.e(TAG, "Error in invoking wiredSeInitialize invocation");
1591 } catch (Exception e) {
1592 Log.e(TAG, "caught Exception during wiredSeInitialize");
1593 e.printStackTrace();
1594 }
1595
nxpandroid5c5b2152017-09-14 12:30:17 +05301596 /*SoundPool clean up before NFC state updated
1597 releaseSoundPool();*/
nxpandroid64fd68c2015-09-23 16:45:15 +05301598
1599 /* Sometimes mDeviceHost.deinitialize() hangs, use a watch-dog.
1600 * Implemented with a new thread (instead of a Handler or AsyncTask),
1601 * because the UI Thread and AsyncTask thread-pools can also get hung
1602 * when the NFC controller stops responding */
nxpandroid5d64ce92016-11-18 19:48:53 +05301603 disableInternalwatchDog = new WatchDogThread("disableInternal", ROUTING_WATCHDOG_MS);
1604 disableInternalwatchDog.start();
nxpandroid64fd68c2015-09-23 16:45:15 +05301605
1606 if (mIsHceCapable) {
1607 mCardEmulationManager.onNfcDisabled();
1608 }
1609
1610 mP2pLinkManager.enableDisable(false, false);
1611
1612 /* The NFC-EE may still be opened by another process,
1613 * and a transceive() could still be in progress on
1614 * another Binder thread.
1615 * Give it a while to finish existing operations
1616 * before we close it.
1617 */
1618 Long startTime = SystemClock.elapsedRealtime();
1619 do {
1620 synchronized (NfcService.this) {
1621 if (mOpenEe == null)
1622 break;
1623 }
1624 try {
1625 Thread.sleep(WAIT_FOR_NFCEE_POLL_MS);
1626 } catch (InterruptedException e) {
1627 // Ignore
1628 }
1629 } while (SystemClock.elapsedRealtime() - startTime < WAIT_FOR_NFCEE_OPERATIONS_MS);
1630
1631 synchronized (NfcService.this) {
1632 if (mOpenEe != null) {
1633 try {
1634 _nfcEeClose(-1, mOpenEe.binder);
1635 } catch (IOException e) { }
1636 }
1637 }
1638
1639 // Stop watchdog if tag present
1640 // A convenient way to stop the watchdog properly consists of
1641 // disconnecting the tag. The polling loop shall be stopped before
1642 // to avoid the tag being discovered again.
1643 maybeDisconnectTarget();
1644
1645 mNfcDispatcher.setForegroundDispatch(null, null, null);
1646
1647 boolean result = mDeviceHost.deinitialize();
1648 if (DBG) Log.d(TAG, "mDeviceHost.deinitialize() = " + result);
1649
nxpandroid5d64ce92016-11-18 19:48:53 +05301650 disableInternalwatchDog.cancel();
nxpandroid64fd68c2015-09-23 16:45:15 +05301651
1652 synchronized (NfcService.this) {
1653 mCurrentDiscoveryParameters = NfcDiscoveryParameters.getNfcOffParameters();
1654 updateState(NfcAdapter.STATE_OFF);
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301655 mNxpNfcState = NXP_NFC_STATE_OFF;
nxpandroid64fd68c2015-09-23 16:45:15 +05301656 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301657 return result;
1658 }
1659
nxpandroid1680a6d2017-01-13 19:13:14 +05301660 boolean restartInternal()
1661 {
1662 boolean result;
1663 result = disableInternal();
1664 if (DBG) Log.d(TAG, "disableInternal status = " + result);
1665 while(true)
1666 {
1667 if(mState == NfcAdapter.STATE_OFF)
1668 {
1669 if (DBG) Log.d(TAG, "disableInternal is success = " + result);
1670 break;
1671 }
1672 }
1673 result = enableInternal();
1674 if (DBG) Log.d(TAG, "enableInternal status = " + result);
1675 while(true)
1676 {
1677 if(mState == NfcAdapter.STATE_ON)
1678 {
1679 if (DBG) Log.d(TAG, "enableInternal is success = " + result);
1680 break;
1681 }
1682 }
1683 Intent flashIntent = new Intent();
1684 flashIntent.setAction(ACTION_FLASH_SUCCESS);
1685 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_FLASH_SUCCESS);
1686 mContext.sendBroadcast(flashIntent);
1687 return result;
1688 }
1689
nxpandroid64fd68c2015-09-23 16:45:15 +05301690 void updateState(int newState) {
1691 synchronized (NfcService.this) {
1692 if (newState == mState) {
1693 return;
1694 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301695 mState = newState;
1696 Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
1697 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1698 intent.putExtra(NfcAdapter.EXTRA_ADAPTER_STATE, mState);
1699 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
1700 }
1701 }
1702 }
1703
1704 void saveNfcOnSetting(boolean on) {
1705 synchronized (NfcService.this) {
1706 mPrefsEditor.putBoolean(PREF_NFC_ON, on);
1707 mPrefsEditor.apply();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301708 mBackupManager.dataChanged();
nxpandroid64fd68c2015-09-23 16:45:15 +05301709 }
1710 }
1711
1712 public void playSound(int sound) {
1713 synchronized (this) {
1714 if (mSoundPool == null) {
1715 Log.w(TAG, "Not playing sound when NFC is disabled");
1716 return;
1717 }
Nikhil Chhabrafc8f3f62018-01-08 20:48:49 +05301718
1719 if (mIsVrModeEnabled) {
1720 Log.d(TAG, "Not playing NFC sound when Vr Mode is enabled");
1721 return;
1722 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301723 switch (sound) {
1724 case SOUND_START:
1725 mSoundPool.play(mStartSound, 1.0f, 1.0f, 0, 0, 1.0f);
1726 break;
1727 case SOUND_END:
1728 mSoundPool.play(mEndSound, 1.0f, 1.0f, 0, 0, 1.0f);
1729 break;
1730 case SOUND_ERROR:
1731 mSoundPool.play(mErrorSound, 1.0f, 1.0f, 0, 0, 1.0f);
1732 break;
1733 }
1734 }
1735 }
1736
1737 synchronized int getUserId() {
1738 return mUserId;
1739 }
1740
Suhas Suresha18dee02018-04-27 15:28:04 +05301741 void enforceBeamShareActivityPolicy(Context context, UserHandle uh) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301742 UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
1743 IPackageManager mIpm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
Suhas Suresha18dee02018-04-27 15:28:04 +05301744 boolean isGlobalEnabled = mIsNdefPushEnabled;
1745 if (uh.getIdentifier() != mUserId) {
1746 try {
1747 int userSetting = mIpm.getComponentEnabledSetting(new ComponentName(
1748 BeamShareActivity.class.getPackageName$(),
1749 BeamShareActivity.class.getName()), uh.getIdentifier());
1750 isGlobalEnabled = (userSetting == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) ? false : true;
1751 } catch (RemoteException e) {
1752 Log.w(TAG, "Unable to get Beam status for user " + uh);
1753 }
1754 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301755 boolean isActiveForUser =
1756 (!um.hasUserRestriction(UserManager.DISALLOW_OUTGOING_BEAM, uh)) &&
1757 isGlobalEnabled;
Suhas Sureshe2a2ff02018-04-27 12:21:19 +05301758 if (DBG) {
Suhas Suresha18dee02018-04-27 15:28:04 +05301759 Log.d(TAG, "Enforcing a policy change on user: " + uh.toString() +
nxpandroid64fd68c2015-09-23 16:45:15 +05301760 ", isActiveForUser = " + isActiveForUser);
1761 }
1762 try {
1763 mIpm.setComponentEnabledSetting(new ComponentName(
1764 BeamShareActivity.class.getPackageName$(),
1765 BeamShareActivity.class.getName()),
1766 isActiveForUser ?
1767 PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
1768 PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
1769 PackageManager.DONT_KILL_APP,
Suhas Suresha18dee02018-04-27 15:28:04 +05301770 uh.getIdentifier());
nxpandroid64fd68c2015-09-23 16:45:15 +05301771 } catch (RemoteException e) {
1772 Log.w(TAG, "Unable to change Beam status for user " + uh);
1773 }
1774 }
1775
1776 final class NfcAdapterService extends INfcAdapter.Stub {
1777 @Override
1778 public boolean enable() throws RemoteException {
nxf38293dcc67462018-08-31 15:57:08 +05301779 NfcPermissions.enforceAdminPermissions(mContext);
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301780 if (mNxpNfcState != NXP_NFC_STATE_OFF) {
1781 return true;
1782 } else {
1783 // do nothing
1784 }
1785
1786 synchronized (NfcService.this) {
1787 mNxpNfcState = NXP_NFC_STATE_TURNING_ON;
1788 }
1789
nxpandroid64fd68c2015-09-23 16:45:15 +05301790 int val = mDeviceHost.GetDefaultSE();
1791 Log.i(TAG, "getDefaultSE " + val);
1792
1793 saveNfcOnSetting(true);
1794
nxpandroid64fd68c2015-09-23 16:45:15 +05301795 new EnableDisableTask().execute(TASK_ENABLE);
1796
1797 return true;
1798 }
1799
nxpandroid64fd68c2015-09-23 16:45:15 +05301800 @Override
1801 public boolean disable(boolean saveState) throws RemoteException {
nxf38293dcc67462018-08-31 15:57:08 +05301802 NfcPermissions.enforceAdminPermissions(mContext);
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301803 if (mNxpNfcState != NXP_NFC_STATE_ON) {
1804 return true;
1805 } else {
1806 // do nothing
1807 }
1808
1809 synchronized (NfcService.this) {
1810 mNxpNfcState = NXP_NFC_STATE_TURNING_OFF;
1811 }
1812
nxpandroid64fd68c2015-09-23 16:45:15 +05301813 Log.d(TAG,"Disabling Nfc.");
1814
1815 //Check if this a device shutdown or Nfc only Nfc disable.
1816 if(!mPowerShutDown)
1817 {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301818 int[] seList = mDeviceHost.doGetSecureElementList();
nxpandroid64fd68c2015-09-23 16:45:15 +05301819 Log.i(TAG, "Disabling NFC Disabling ESE/UICC");
nxpandroid64fd68c2015-09-23 16:45:15 +05301820 //Since only Nfc is getting disabled so disable CE from EE.
nxpandroida9a68ba2016-01-14 21:12:17 +05301821 mDeviceHost.doSetScreenOrPowerState(ScreenStateHelper.POWER_STATE_ON);
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301822 if (seList != null) {
1823 for (int i = 0; i < seList.length; i++) {
1824 mDeviceHost.doDeselectSecureElement(seList[i]);
1825 }
1826 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301827 } else {
1828 Log.i(TAG, "Power off : Disabling NFC Disabling ESE/UICC");
1829 mPowerShutDown = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05301830 mCardEmulationManager.onPreferredForegroundServiceChanged(null);
1831 }
1832
1833 if (saveState) {
1834 saveNfcOnSetting(false);
1835 }
1836
1837 new EnableDisableTask().execute(TASK_DISABLE);
1838
1839 return true;
1840 }
1841
1842 @Override
1843 public void pausePolling(int timeoutInMs) {
1844 NfcPermissions.enforceAdminPermissions(mContext);
1845
1846 if (timeoutInMs <= 0 || timeoutInMs > MAX_POLLING_PAUSE_TIMEOUT) {
1847 Log.e(TAG, "Refusing to pause polling for " + timeoutInMs + "ms.");
1848 return;
1849 }
1850
1851 synchronized (NfcService.this) {
1852 mPollingPaused = true;
1853 mDeviceHost.disableDiscovery();
1854 mHandler.sendMessageDelayed(
1855 mHandler.obtainMessage(MSG_RESUME_POLLING), timeoutInMs);
1856 }
1857 }
1858
1859 @Override
1860 public void resumePolling() {
1861 NfcPermissions.enforceAdminPermissions(mContext);
1862
1863 synchronized (NfcService.this) {
1864 if (!mPollingPaused) {
1865 return;
1866 }
1867
1868 mHandler.removeMessages(MSG_RESUME_POLLING);
1869 mPollingPaused = false;
1870 new ApplyRoutingTask().execute();
1871 }
1872 }
1873
1874 @Override
1875 public boolean isNdefPushEnabled() throws RemoteException {
1876 synchronized (NfcService.this) {
1877 return mState == NfcAdapter.STATE_ON && mIsNdefPushEnabled;
1878 }
1879 }
1880
1881 @Override
1882 public boolean enableNdefPush() throws RemoteException {
1883 NfcPermissions.enforceAdminPermissions(mContext);
1884 synchronized (NfcService.this) {
1885 if (mIsNdefPushEnabled) {
1886 return true;
1887 }
1888 Log.i(TAG, "enabling NDEF Push");
1889 mPrefsEditor.putBoolean(PREF_NDEF_PUSH_ON, true);
1890 mPrefsEditor.apply();
1891 mIsNdefPushEnabled = true;
Suhas Suresha18dee02018-04-27 15:28:04 +05301892 enforceBeamShareActivityPolicy(mContext, new UserHandle(mUserId));
nxpandroid64fd68c2015-09-23 16:45:15 +05301893 if (isNfcEnabled()) {
nxpandroid5d64ce92016-11-18 19:48:53 +05301894 mDeviceHost.doEnablep2p(mIsNdefPushEnabled);
nxpandroid64fd68c2015-09-23 16:45:15 +05301895 mP2pLinkManager.enableDisable(true, true);
1896 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301897 mBackupManager.dataChanged();
nxpandroid64fd68c2015-09-23 16:45:15 +05301898 }
1899 return true;
1900 }
1901
1902 @Override
1903 public boolean disableNdefPush() throws RemoteException {
1904 NfcPermissions.enforceAdminPermissions(mContext);
1905 synchronized (NfcService.this) {
1906 if (!mIsNdefPushEnabled) {
1907 return true;
1908 }
1909 Log.i(TAG, "disabling NDEF Push");
1910 mPrefsEditor.putBoolean(PREF_NDEF_PUSH_ON, false);
1911 mPrefsEditor.apply();
1912 mIsNdefPushEnabled = false;
Suhas Suresha18dee02018-04-27 15:28:04 +05301913 enforceBeamShareActivityPolicy(mContext, new UserHandle(mUserId));
nxpandroid64fd68c2015-09-23 16:45:15 +05301914 if (isNfcEnabled()) {
1915 mP2pLinkManager.enableDisable(false, true);
1916 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301917 mBackupManager.dataChanged();
nxpandroid64fd68c2015-09-23 16:45:15 +05301918 }
1919 return true;
1920 }
1921
1922 @Override
1923 public void setForegroundDispatch(PendingIntent intent,
1924 IntentFilter[] filters, TechListParcel techListsParcel) {
1925 NfcPermissions.enforceUserPermissions(mContext);
nxpandroid281eb922016-08-25 20:27:46 +05301926 if (!mForegroundUtils.isInForeground(Binder.getCallingUid())) {
1927 Log.e(TAG, "setForegroundDispatch: Caller not in foreground.");
1928 return;
1929 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301930 // Short-cut the disable path
1931 if (intent == null && filters == null && techListsParcel == null) {
1932 mNfcDispatcher.setForegroundDispatch(null, null, null);
1933 return;
1934 }
1935
1936 // Validate the IntentFilters
1937 if (filters != null) {
1938 if (filters.length == 0) {
1939 filters = null;
1940 } else {
1941 for (IntentFilter filter : filters) {
1942 if (filter == null) {
1943 throw new IllegalArgumentException("null IntentFilter");
1944 }
1945 }
1946 }
1947 }
1948
1949 // Validate the tech lists
1950 String[][] techLists = null;
1951 if (techListsParcel != null) {
1952 techLists = techListsParcel.getTechLists();
1953 }
1954
1955 mNfcDispatcher.setForegroundDispatch(intent, filters, techLists);
1956 }
1957
1958 @Override
1959 public void setAppCallback(IAppCallback callback) {
1960 NfcPermissions.enforceUserPermissions(mContext);
1961
1962 // don't allow Beam for managed profiles, or devices with a device owner or policy owner
1963 UserInfo userInfo = mUserManager.getUserInfo(UserHandle.getCallingUserId());
1964 if(!mUserManager.hasUserRestriction(
1965 UserManager.DISALLOW_OUTGOING_BEAM, userInfo.getUserHandle())) {
1966 mP2pLinkManager.setNdefCallback(callback, Binder.getCallingUid());
1967 } else if (DBG) {
1968 Log.d(TAG, "Disabling default Beam behavior");
1969 }
1970 }
1971
1972 @Override
1973 public INfcAdapterExtras getNfcAdapterExtrasInterface(String pkg) {
nxpandroida51b5bd2017-04-10 18:28:21 +05301974
1975 if (pkg.equals(PACKAGE_SMART_CARD_SERVICE)){
1976 Log.d(TAG, "wildcard for SmartcardService");
1977 return mExtrasService;
1978 }
1979
nxpandroid64fd68c2015-09-23 16:45:15 +05301980 NfcService.this.enforceNfceeAdminPerm(pkg);
1981 return mExtrasService;
1982 }
1983
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05301984 @Override
1985 public INfcDta getNfcDtaInterface(String pkg) throws RemoteException {
1986 NfcPermissions.enforceAdminPermissions(mContext);
1987 if (mNfcDtaService == null) {
1988 mNfcDtaService = new NfcDtaService();
1989 }
1990 return mNfcDtaService;
1991 }
1992
nxpandroid281eb922016-08-25 20:27:46 +05301993 @Override
1994 public boolean ignore(int nativeHandle, int debounceMs, ITagRemovedCallback callback)
1995 throws RemoteException {
1996 NfcPermissions.enforceUserPermissions(mContext);
1997
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +05301998 if (debounceMs == 0 && mDebounceTagNativeHandle != INVALID_NATIVE_HANDLE
1999 && nativeHandle == mDebounceTagNativeHandle) {
2000 // Remove any previous messages and immediately debounce.
2001 mHandler.removeMessages(MSG_TAG_DEBOUNCE);
2002 mHandler.sendEmptyMessage(MSG_TAG_DEBOUNCE);
2003 return true;
2004 }
2005
nxpandroid281eb922016-08-25 20:27:46 +05302006 TagEndpoint tag = (TagEndpoint) findAndRemoveObject(nativeHandle);
2007 if (tag != null) {
2008 // Store UID and params
2009 int uidLength = tag.getUid().length;
2010 synchronized (NfcService.this) {
2011 mDebounceTagDebounceMs = debounceMs;
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +05302012 mDebounceTagNativeHandle = nativeHandle;
nxpandroid281eb922016-08-25 20:27:46 +05302013 mDebounceTagUid = new byte[uidLength];
2014 mDebounceTagRemovedCallback = callback;
2015 System.arraycopy(tag.getUid(), 0, mDebounceTagUid, 0, uidLength);
2016 }
2017
2018 // Disconnect from this tag; this should resume the normal
2019 // polling loop (and enter listen mode for a while), before
2020 // we pick up any tags again.
2021 tag.disconnect();
2022 mHandler.sendEmptyMessageDelayed(MSG_TAG_DEBOUNCE, debounceMs);
2023 return true;
2024 } else {
2025 return false;
2026 }
2027 }
2028
nxpandroid64fd68c2015-09-23 16:45:15 +05302029 @Override
2030 public void verifyNfcPermission() {
2031 NfcPermissions.enforceUserPermissions(mContext);
2032 }
2033
2034 @Override
2035 public void invokeBeam() {
2036 NfcPermissions.enforceUserPermissions(mContext);
2037
2038 if (mForegroundUtils.isInForeground(Binder.getCallingUid())) {
2039 mP2pLinkManager.onManualBeamInvoke(null);
2040 } else {
2041 Log.e(TAG, "Calling activity not in foreground.");
2042 }
2043 }
2044
2045 @Override
2046 public void invokeBeamInternal(BeamShareData shareData) {
2047 NfcPermissions.enforceAdminPermissions(mContext);
2048 Message msg = Message.obtain();
2049 msg.what = MSG_INVOKE_BEAM;
2050 msg.obj = shareData;
2051 // We have to send this message delayed for two reasons:
2052 // 1) This is an IPC call from BeamShareActivity, which is
2053 // running when the user has invoked Beam through the
2054 // share menu. As soon as BeamShareActivity closes, the UI
2055 // will need some time to rebuild the original Activity.
2056 // Waiting here for a while gives a better chance of the UI
2057 // having been rebuilt, which means the screenshot that the
2058 // Beam animation is using will be more accurate.
2059 // 2) Similarly, because the Activity that launched BeamShareActivity
2060 // with an ACTION_SEND intent is now in paused state, the NDEF
2061 // callbacks that it has registered may no longer be valid.
2062 // Allowing the original Activity to resume will make sure we
2063 // it has a chance to re-register the NDEF message / callback,
2064 // so we share the right data.
2065 //
2066 // Note that this is somewhat of a hack because the delay may not actually
2067 // be long enough for 2) on very slow devices, but there's no better
2068 // way to do this right now without additional framework changes.
2069 mHandler.sendMessageDelayed(msg, INVOKE_BEAM_DELAY_MS);
2070 }
2071
2072 @Override
2073 public INfcTag getNfcTagInterface() throws RemoteException {
2074 return mNfcTagService;
2075 }
2076
2077 @Override
2078 public INfcCardEmulation getNfcCardEmulationInterface() {
2079 if (mIsHceCapable) {
2080 return mCardEmulationManager.getNfcCardEmulationInterface();
2081 } else {
2082 return null;
2083 }
2084 }
2085
nxpandroid34627bd2016-05-27 15:52:30 +05302086 @Override
2087 public INfcFCardEmulation getNfcFCardEmulationInterface() {
2088 if (mIsHceFCapable) {
2089 return mCardEmulationManager.getNfcFCardEmulationInterface();
2090 } else {
2091 return null;
2092 }
2093 }
2094
nxpandroid64fd68c2015-09-23 16:45:15 +05302095
2096 @Override
2097 public int getState() throws RemoteException {
2098 synchronized (NfcService.this) {
2099 return mState;
2100 }
2101 }
2102
2103 @Override
2104 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2105 NfcService.this.dump(fd, pw, args);
2106 }
2107
2108 @Override
2109 public void dispatch(Tag tag) throws RemoteException {
2110 NfcPermissions.enforceAdminPermissions(mContext);
2111 mNfcDispatcher.dispatchTag(tag);
2112 }
2113
2114 @Override
2115 public void setP2pModes(int initiatorModes, int targetModes) throws RemoteException {
2116 NfcPermissions.enforceAdminPermissions(mContext);
2117 mDeviceHost.setP2pInitiatorModes(initiatorModes);
2118 mDeviceHost.setP2pTargetModes(targetModes);
2119 applyRouting(true);
2120 }
2121
2122 @Override
2123 public void setReaderMode(IBinder binder, IAppCallback callback, int flags, Bundle extras)
2124 throws RemoteException {
nxpandroid281eb922016-08-25 20:27:46 +05302125 int callingUid = Binder.getCallingUid();
2126 if (callingUid != Process.SYSTEM_UID && !mForegroundUtils.isInForeground(callingUid)) {
2127 Log.e(TAG, "setReaderMode: Caller is not in foreground and is not system process.");
2128 return;
2129 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302130 synchronized (NfcService.this) {
nxpandroid34627bd2016-05-27 15:52:30 +05302131 if (!isNfcEnabled()) {
2132 Log.e(TAG, "setReaderMode() called while NFC is not enabled.");
2133 return;
2134 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302135 if (flags != 0) {
2136 try {
2137 mReaderModeParams = new ReaderModeParams();
2138 mReaderModeParams.callback = callback;
2139 mReaderModeParams.flags = flags;
2140 mReaderModeParams.presenceCheckDelay = extras != null
2141 ? (extras.getInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY,
2142 DEFAULT_PRESENCE_CHECK_DELAY))
2143 : DEFAULT_PRESENCE_CHECK_DELAY;
2144 binder.linkToDeath(mReaderModeDeathRecipient, 0);
2145 } catch (RemoteException e) {
2146 Log.e(TAG, "Remote binder has already died.");
2147 return;
2148 }
2149 } else {
2150 try {
2151 mReaderModeParams = null;
Suhas Suresh5efc5432018-04-27 15:31:02 +05302152 StopPresenceChecking();
nxpandroid64fd68c2015-09-23 16:45:15 +05302153 binder.unlinkToDeath(mReaderModeDeathRecipient, 0);
2154 } catch (NoSuchElementException e) {
2155 Log.e(TAG, "Reader mode Binder was never registered.");
2156 }
2157 }
2158 Log.e(TAG, "applyRouting -4");
2159 applyRouting(false);
2160 }
2161 }
2162
2163
2164 @Override
2165 public void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, int[] techList) {
2166 NfcPermissions.enforceAdminPermissions(mContext);
2167
2168 int lockscreenPollMask = computeLockscreenPollMask(techList);
2169 synchronized (NfcService.this) {
2170 mNfcUnlockManager.addUnlockHandler(unlockHandler, lockscreenPollMask);
2171 }
2172
2173 applyRouting(false);
2174 }
2175
2176 @Override
2177 public void removeNfcUnlockHandler(INfcUnlockHandler token) throws RemoteException {
2178 synchronized (NfcService.this) {
2179 mNfcUnlockManager.removeUnlockHandler(token.asBinder());
2180 }
2181
2182 applyRouting(false);
2183 }
2184 private int computeLockscreenPollMask(int[] techList) {
2185
2186 Map<Integer, Integer> techCodeToMask = new HashMap<Integer, Integer>();
2187
2188 techCodeToMask.put(TagTechnology.NFC_A, NfcService.NFC_POLL_A);
2189 techCodeToMask.put(TagTechnology.NFC_B, NfcService.NFC_POLL_B);
Nikhil Chhabra288edb02018-01-10 19:36:21 +05302190 techCodeToMask.put(TagTechnology.NFC_V, NfcService.NFC_POLL_V);
nxpandroid64fd68c2015-09-23 16:45:15 +05302191 techCodeToMask.put(TagTechnology.NFC_F, NfcService.NFC_POLL_F);
2192 techCodeToMask.put(TagTechnology.NFC_BARCODE, NfcService.NFC_POLL_KOVIO);
2193 techCodeToMask.put(TagTechnology.MIFARE_CLASSIC, NfcService.NFC_POLL_A);
2194 techCodeToMask.put(TagTechnology.MIFARE_ULTRALIGHT, NfcService.NFC_POLL_A);
2195
2196 int mask = 0;
2197
2198 for (int i = 0; i < techList.length; i++) {
2199 if (techCodeToMask.containsKey(techList[i])) {
2200 mask |= techCodeToMask.get(techList[i]).intValue();
2201 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05302202 int screenState = mScreenStateHelper.checkScreenState();
2203 if (screenState != mScreenState) {
2204 new ApplyRoutingTask().execute(Integer.valueOf(screenState));
2205 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302206 }
2207
2208 return mask;
2209 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05302210
2211 /**
2212 * An interface for nxp extensions
2213 */
nxpandroid64fd68c2015-09-23 16:45:15 +05302214 @Override
nxpandroid6fd9cdb2017-07-12 18:25:41 +05302215 public IBinder getNfcAdapterVendorInterface(String vendor) {
2216 if(vendor.equalsIgnoreCase("nxp")) {
2217 return (IBinder) mNxpNfcAdapter;
2218 } else {
2219 return null;
2220 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302221 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05302222
nxpandroid64fd68c2015-09-23 16:45:15 +05302223 }
2224 final class NxpNfcAdapterService extends INxpNfcAdapter.Stub {
nxpandroid64fd68c2015-09-23 16:45:15 +05302225 //GSMA Changes
2226 @Override
2227 public INxpNfcController getNxpNfcControllerInterface() {
2228 return mNxpNfcController.getNxpNfcControllerInterface();
2229 }
2230
2231 @Override
nxpandroid64fd68c2015-09-23 16:45:15 +05302232 public INfcVzw getNfcVzwInterface() {
2233 NfcPermissions.enforceAdminPermissions(mContext);
2234 //begin
2235 if(mVzwService == null){
2236 mVzwService = new NfcVzwService();
2237 }
2238 //end
2239 return mVzwService;
2240 }
2241
2242 @Override
2243 public int setEmvCoPollProfile(boolean enable, int route) throws RemoteException {
2244 return mDeviceHost.setEmvCoPollProfile(enable, route);
2245 }
2246
2247 @Override
nxpandroid64fd68c2015-09-23 16:45:15 +05302248 public int[] getActiveSecureElementList(String pkg) throws RemoteException {
nxpandroid64fd68c2015-09-23 16:45:15 +05302249
2250 int[] list = null;
2251 if (isNfcEnabled()) {
2252 list = mDeviceHost.doGetActiveSecureElementList();
2253 }
2254 for(int i=0; i< list.length; i++) {
2255 Log.d(TAG, "Active element = "+ list[i]);
2256 }
2257 return list;
2258 }
2259
nxpandroid64fd68c2015-09-23 16:45:15 +05302260 @Override
Ganesh Devaee0da3a2018-11-27 20:29:40 +05302261 public void MifareDesfireRouteSet(int routeLoc, boolean fullPower, boolean lowPower, boolean noPower)
2262 throws RemoteException
2263 {
2264 if((mChipVer < PN553_ID) && (routeLoc == UICC2_ID_TYPE)) {
2265 throw new RemoteException("UICC2 is not supported");
2266 }
2267 int protoRouteEntry = 0;
2268 /*UICC2 ID-4(fromApp) mapped to 3 (JNI)*/
2269 protoRouteEntry=((routeLoc & 0x07) == 0x04) ? (0x03 << ROUTE_LOC_MASK) : /*UICC2*/
2270 ((routeLoc & 0x07) == 0x02) ? (0x02 << ROUTE_LOC_MASK) : /*UICC1*/
2271 ((routeLoc & 0x07) == 0x01) ? (0x01 << ROUTE_LOC_MASK) : /*eSE*/
2272 0x00;
2273 protoRouteEntry |= ((fullPower ? (mDeviceHost.getDefaultDesfirePowerState() & 0x1F) | 0x01 : 0) | (lowPower ? 0x01 << 1 :0 ) | (noPower ? 0x01 << 2 :0));
2274
2275 if(routeLoc == 0x00)
2276 {
2277 /*
2278 bit pos 1 = Power Off
2279 bit pos 2 = Battery Off
2280 bit pos 4 = Screen Off
2281 Set these bits to 0 because in case routeLoc = HOST it can not work on POWER_OFF, BATTERY_OFF and SCREEN_OFF*/
2282 protoRouteEntry &= 0xE9;
2283 }
2284
2285 Log.i(TAG,"MifareDesfireRouteSet : " + protoRouteEntry);
2286 mNxpPrefsEditor = mNxpPrefs.edit();
2287 mNxpPrefsEditor.putInt("PREF_MIFARE_DESFIRE_PROTO_ROUTE_ID", protoRouteEntry);
2288 mNxpPrefsEditor.commit();
2289 Log.i(TAG,"MifareDesfireRouteSet function in");
2290 commitRouting();
2291 }
2292
2293 @Override
nxpandroid64fd68c2015-09-23 16:45:15 +05302294 public void DefaultRouteSet(int routeLoc, boolean fullPower, boolean lowPower, boolean noPower)
2295 throws RemoteException
2296 {
anil.hiranniah3cb5a1f2018-02-07 19:29:55 +05302297 if((mChipVer < PN553_ID) && (routeLoc == UICC2_ID_TYPE)) {
2298 throw new RemoteException("UICC2 is not supported");
2299 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302300 if (mIsHceCapable) {
2301 int protoRouteEntry = 0;
anil.hiranniah3cb5a1f2018-02-07 19:29:55 +05302302 protoRouteEntry=((routeLoc & 0x07) == 0x04) ? (0x03 << ROUTE_LOC_MASK) : /*UICC2*/
2303 ((routeLoc & 0x07) == 0x02) ? (0x02 << ROUTE_LOC_MASK) : /*UICC1*/
2304 ((routeLoc & 0x07) == 0x01) ? (0x01 << ROUTE_LOC_MASK) : /*eSE*/
2305 0x00;
nxpandroid8aecbf82016-09-16 20:21:47 +05302306 protoRouteEntry |= ((fullPower ? (mDeviceHost.getDefaultAidPowerState() & 0x1F) | 0x01 : 0) | (lowPower ? 0x01 << 1 :0 ) | (noPower ? 0x01 << 2 :0));
2307
nxpandroid7d44e572016-08-01 19:11:04 +05302308 if(routeLoc == 0x00)
nxpandroid7d44e572016-08-01 19:11:04 +05302309 {
nxpandroid8aecbf82016-09-16 20:21:47 +05302310 /*
2311 bit pos 1 = Power Off
2312 bit pos 2 = Battery Off
2313 bit pos 4 = Screen Off
2314 Set these bits to 0 because in case routeLoc = HOST it can not work on POWER_OFF, BATTERY_OFF and SCREEN_OFF*/
2315 protoRouteEntry &= 0xE9;
nxpandroid7d44e572016-08-01 19:11:04 +05302316 }
2317 Log.i(TAG,"DefaultRouteSet : " + protoRouteEntry);
nxpandroid64fd68c2015-09-23 16:45:15 +05302318 if(GetDefaultRouteLoc() != routeLoc)
2319 {
nxpandroida9a68ba2016-01-14 21:12:17 +05302320 mNxpPrefsEditor = mNxpPrefs.edit();
2321 mNxpPrefsEditor.putInt("PREF_SET_DEFAULT_ROUTE_ID", protoRouteEntry );
2322 mNxpPrefsEditor.commit();
nxpandroid64fd68c2015-09-23 16:45:15 +05302323 mIsRouteForced = true;
2324 if (mIsHceCapable) {
2325 mAidRoutingManager.onNfccRoutingTableCleared();
2326 mCardEmulationManager.onRoutingTableChanged();
2327 }
2328 mIsRouteForced = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05302329 }
2330 }
2331 else{
2332 Log.i(TAG,"DefaultRoute can not be set. mIsHceCapable = flase");
2333 }
2334 }
2335
nxpandroid64fd68c2015-09-23 16:45:15 +05302336 @Override
Ganesh Devaee0da3a2018-11-27 20:29:40 +05302337 public void MifareCLTRouteSet(int routeLoc, boolean fullPower, boolean lowPower, boolean noPower)
2338 throws RemoteException
2339 {
2340 if((mChipVer < PN553_ID) && (routeLoc == UICC2_ID_TYPE)) {
2341 throw new RemoteException("UICC2 is not supported");
2342 }
2343
2344 int techRouteEntry=0;
2345 techRouteEntry=((routeLoc & 0x07) == 0x04) ? (0x03 << ROUTE_LOC_MASK) : /*UICC2*/
2346 ((routeLoc & 0x07) == 0x02) ? (0x02 << ROUTE_LOC_MASK) : /*UICC1*/
2347 ((routeLoc & 0x07) == 0x01) ? (0x01 << ROUTE_LOC_MASK) : /*eSE*/
2348 0x00;
2349 techRouteEntry |= ((fullPower ? (mDeviceHost.getDefaultMifareCLTPowerState() & 0x1F) | 0x01 : 0) | (lowPower ? 0x01 << 1 :0 ) | (noPower ? 0x01 << 2 :0));
2350 techRouteEntry |= (TECH_TYPE_A << TECH_TYPE_MASK);
2351
2352 Log.i(TAG,"MifareCLTRouteSet : " + techRouteEntry);
2353 mNxpPrefsEditor = mNxpPrefs.edit();
2354 mNxpPrefsEditor.putInt("PREF_MIFARE_CLT_ROUTE_ID", techRouteEntry);
2355 mNxpPrefsEditor.commit();
2356 commitRouting();
2357 }
2358
2359 @Override
nxpandroid64fd68c2015-09-23 16:45:15 +05302360 public byte[] getFWVersion()
2361 {
nxpandroid5d64ce92016-11-18 19:48:53 +05302362 byte[] buf = new byte[3];
nxpandroid64fd68c2015-09-23 16:45:15 +05302363 Log.i(TAG, "Starting getFwVersion");
2364 int fwver = mDeviceHost.getFWVersion();
2365 buf[0] = (byte)((fwver&0xFF00)>>8);
2366 buf[1] = (byte)((fwver&0xFF));
nxpandroid5d64ce92016-11-18 19:48:53 +05302367 buf[2] = (byte)((fwver&0xFF0000)>>16);
nxpandroid64fd68c2015-09-23 16:45:15 +05302368 Log.i(TAG, "Firmware version is 0x"+ buf[0]+" 0x"+buf[1]);
2369 return buf;
2370 }
2371
2372 @Override
nxf3829316ee8ee2018-06-29 12:05:36 +05302373 public byte[] readerPassThruMode(byte status, byte modulationTyp)
2374 throws RemoteException {
2375
2376 Log.i(TAG, "Reader pass through mode request: 0x" + status +
2377 " with modulation: 0x" + modulationTyp);
2378 return mDeviceHost.readerPassThruMode(status, modulationTyp);
2379 }
2380
2381 @Override
2382 public byte[] transceiveAppData(byte[] data) throws RemoteException {
2383
2384 Log.i(TAG, "Transceive requested on reader pass through mode");
2385 return mDeviceHost.transceiveAppData(data);
2386 }
2387
2388 @Override
nxf26763be2bd682018-11-12 17:02:43 +05302389 public List<NxpAidServiceInfo> getServicesAidInfo(int userId, String category){
2390 return mCardEmulationManager.getServicesAidInfo(userId, category);
nxpandroid64fd68c2015-09-23 16:45:15 +05302391 }
nxpandroida9a68ba2016-01-14 21:12:17 +05302392
2393 @Override
2394 public int updateServiceState(int userId , Map serviceState) {
2395 return mCardEmulationManager.updateServiceState(userId ,serviceState);
2396 }
2397
nxpandroid64fd68c2015-09-23 16:45:15 +05302398 @Override
nxpandroid34627bd2016-05-27 15:52:30 +05302399 public int getMaxAidRoutingTableSize() throws RemoteException {
nxpandroid5d64ce92016-11-18 19:48:53 +05302400 NfcPermissions.enforceUserPermissions(mContext);
nxpandroid34627bd2016-05-27 15:52:30 +05302401 return getAidRoutingTableSize();
2402 }
2403
nxpandroid281eb922016-08-25 20:27:46 +05302404
nxpandroid34627bd2016-05-27 15:52:30 +05302405 @Override
2406 public int getCommittedAidRoutingTableSize() throws RemoteException {
nxpandroid5d64ce92016-11-18 19:48:53 +05302407 NfcPermissions.enforceUserPermissions(mContext);
nxpandroid34627bd2016-05-27 15:52:30 +05302408 return (getAidRoutingTableSize() - getRemainingAidTableSize());
2409 }
nxpandroid281eb922016-08-25 20:27:46 +05302410
2411 @Override
2412 public int setConfig(String configs , String pkg) {
2413 Log.e(TAG, "Setting configs for Transit" );
2414 /*Check permissions*/
2415 NfcPermissions.enforceAdminPermissions(mContext);
2416 /*Check if any NFC transactions are ongoing*/
2417 if(mDeviceHost.isNfccBusy())
2418 {
2419 Log.e(TAG, "NFCC is busy.." );
2420 return TRANSIT_SETCONFIG_STAT_FAILED;
2421 }
2422 /*check if format of configs is fine*/
2423 /*Save configurations to file*/
2424 try {
Ganesh Deva382b1062018-07-27 23:09:03 +05302425 File newTextFile = new File("/data/nfc/libnfc-nxpTransit.conf");
nxpandroid281eb922016-08-25 20:27:46 +05302426 if(configs == null)
2427 {
2428 if(newTextFile.delete()){
2429 Log.e(TAG, "Removing transit config file. Taking default Value" );
2430 }else{
2431 System.out.println("Error taking defualt value");
2432 }
2433 }
2434 else
2435 {
2436 FileWriter fw = new FileWriter(newTextFile);
2437 fw.write(configs);
2438 fw.close();
2439 Log.e(TAG, "File Written to libnfc-nxpTransit.conf successfully" );
2440 }
Ganesh Deva382b1062018-07-27 23:09:03 +05302441 mDeviceHost.setTransitConfig(configs);
nxpandroid281eb922016-08-25 20:27:46 +05302442 } catch (Exception e) {
2443 e.printStackTrace();
2444 return TRANSIT_SETCONFIG_STAT_FAILED;
2445 }
2446
2447 /*restart NFC service*/
2448 try {
2449 mNfcAdapter.disable(true);
Ganesh Deva382b1062018-07-27 23:09:03 +05302450 WaitForAdapterChange(NfcAdapter.STATE_OFF);
nxpandroid281eb922016-08-25 20:27:46 +05302451 mNfcAdapter.enable();
Ganesh Deva382b1062018-07-27 23:09:03 +05302452 WaitForAdapterChange(NfcAdapter.STATE_ON);
nxpandroid281eb922016-08-25 20:27:46 +05302453 } catch (Exception e) {
2454 Log.e(TAG, "Unable to restart NFC Service");
2455 e.printStackTrace();
2456 return TRANSIT_SETCONFIG_STAT_FAILED;
2457 }
2458 return TRANSIT_SETCONFIG_STAT_SUCCESS;
2459 }
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05302460
Ganesh Deva382b1062018-07-27 23:09:03 +05302461 private void WaitForAdapterChange(int state) {
2462 while (true) {
2463 if(mState == state) {
2464 break;
2465 }
2466 try {
2467 Thread.sleep(100);
2468 } catch (Exception e) {
2469 e.printStackTrace();
2470 }
2471 }
2472 return;
2473 }
2474
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05302475 @Override
2476 public int mPOSSetReaderMode (String pkg, boolean on) {
2477 NfcService.this.enforceNfceeAdminPerm(pkg);
Pratap Reddy49abbe32018-03-27 16:51:59 +05302478 // Check if NFC is enabled
2479 if (!isNfcEnabled()) {
2480 return NxpConstants.MPOS_STATUS_REJECTED;
2481 }
2482
2483 synchronized(NfcService.this) {
2484 int status = mDeviceHost.mposSetReaderMode(on);
2485 if(!on) {
2486 if(nci_version != NCI_VERSION_2_0) {
2487 applyRouting(true);
2488 } else if(mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED
2489 || mNfcUnlockManager.isLockscreenPollingEnabled()) {
2490 applyRouting(false);
2491 }
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05302492 }
Pratap Reddy49abbe32018-03-27 16:51:59 +05302493 return status;
2494 }
2495 }
2496
2497 @Override
2498 public boolean mPOSGetReaderMode (String pkg) {
2499 NfcService.this.enforceNfceeAdminPerm(pkg);
2500 // Check if NFC is enabled
2501 if (!isNfcEnabled()) {
2502 return false;
2503 }
2504
2505 boolean status = false;
2506 synchronized(NfcService.this) {
2507 status = mDeviceHost.mposGetReaderMode();
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05302508 }
2509 return status;
2510 }
2511
2512 @Override
2513 public void stopPoll(String pkg, int mode) {
2514 NfcService.this.enforceNfceeAdminPerm(pkg);
Pratap Reddy49abbe32018-03-27 16:51:59 +05302515 // Check if NFC is enabled
2516 if (!isNfcEnabled()) {
2517 return;
2518 }
2519
2520 synchronized(NfcService.this) {
2521 mDeviceHost.stopPoll(mode);
2522 }
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05302523 }
2524
2525 @Override
2526 public void startPoll(String pkg) {
2527 NfcService.this.enforceNfceeAdminPerm(pkg);
Pratap Reddy49abbe32018-03-27 16:51:59 +05302528 // Check if NFC is enabled
2529 if (!isNfcEnabled()) {
2530 return;
2531 }
2532
2533 synchronized(NfcService.this) {
2534 mDeviceHost.startPoll();
2535 }
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05302536 }
Ganesh Deva876c65b2018-06-01 18:51:30 +05302537
2538 @Override
nxf38293cd495622018-06-29 10:25:10 +05302539 public int nfcSelfTest(String pkg, int type) {
2540 int status = 0xFF;
2541 NfcService.this.enforceNfceeAdminPerm(pkg);
2542
2543 synchronized(NfcService.this) {
2544 status = mDeviceHost.doNfcSelfTest(type);
2545 }
2546 return status;
2547 }
2548
2549 @Override
Ganesh Deva876c65b2018-06-01 18:51:30 +05302550 public int getSelectedUicc() throws RemoteException {
2551 if (!isNfcEnabled()) {
2552 throw new RemoteException("NFC is not enabled");
2553 }
2554 return mDeviceHost.doGetSelectedUicc();
2555 }
2556
2557 @Override
2558 public int selectUicc(int uiccSlot) throws RemoteException {
2559 synchronized(NfcService.this) {
2560 if (!isNfcEnabled()) {
2561 throw new RemoteException("NFC is not enabled");
2562 }
2563 int status = mDeviceHost.doselectUicc(uiccSlot);
2564 Log.i(TAG, "Update routing table");
2565 /*In case of UICC connected and Enabled or Removed ,
2566 *Reconfigure the routing table based on current UICC parameters
2567 **/
2568 if((status == 0x00)||(status == 0x01))
2569 {
2570 mPrefsEditor.putInt(PREF_CUR_SELECTED_UICC_ID, uiccSlot);
2571 mPrefsEditor.apply();
2572 if((mAidRoutingManager != null) && (mCardEmulationManager != null))
2573 {
2574 Log.i(TAG, "Update routing table");
2575 mAidRoutingManager.onNfccRoutingTableCleared();
2576 mIsRoutingTableDirty = true;
2577 mCardEmulationManager.onNfcEnabled();
2578 }
2579 else
2580 {
2581 Log.i(TAG, "Update only Mifare and Desfire route");
2582 mIsRoutingTableDirty = true;
2583 applyRouting(false);
2584 }
2585 }
2586 return status;
2587 }
2588 }
2589
nxpandroid64fd68c2015-09-23 16:45:15 +05302590 }
2591
2592 final class ReaderModeDeathRecipient implements IBinder.DeathRecipient {
2593 @Override
2594 public void binderDied() {
2595 synchronized (NfcService.this) {
2596 if (mReaderModeParams != null) {
2597 mReaderModeParams = null;
2598 Log.e(TAG, "applyRouting -5");
2599 applyRouting(false);
2600 }
2601 }
2602 }
2603 }
2604
2605 final class TagService extends INfcTag.Stub {
2606 @Override
nxpandroid64fd68c2015-09-23 16:45:15 +05302607 public int connect(int nativeHandle, int technology) throws RemoteException {
2608 NfcPermissions.enforceUserPermissions(mContext);
2609
2610 TagEndpoint tag = null;
2611
2612 if (!isNfcEnabled()) {
2613 return ErrorCodes.ERROR_NOT_INITIALIZED;
2614 }
2615
2616 /* find the tag in the hmap */
2617 tag = (TagEndpoint) findObject(nativeHandle);
2618 if (tag == null) {
2619 return ErrorCodes.ERROR_DISCONNECT;
2620 }
2621
2622 if (!tag.isPresent()) {
2623 return ErrorCodes.ERROR_DISCONNECT;
2624 }
2625
2626 // Note that on most tags, all technologies are behind a single
2627 // handle. This means that the connect at the lower levels
2628 // will do nothing, as the tag is already connected to that handle.
2629 if (tag.connect(technology)) {
2630 return ErrorCodes.SUCCESS;
2631 } else {
2632 return ErrorCodes.ERROR_DISCONNECT;
2633 }
2634 }
2635
2636 @Override
2637 public int reconnect(int nativeHandle) throws RemoteException {
2638 NfcPermissions.enforceUserPermissions(mContext);
2639
2640 TagEndpoint tag = null;
2641
2642 // Check if NFC is enabled
2643 if (!isNfcEnabled()) {
2644 return ErrorCodes.ERROR_NOT_INITIALIZED;
2645 }
2646
2647 /* find the tag in the hmap */
2648 tag = (TagEndpoint) findObject(nativeHandle);
2649 if (tag != null) {
2650 if (tag.reconnect()) {
2651 return ErrorCodes.SUCCESS;
2652 } else {
2653 return ErrorCodes.ERROR_DISCONNECT;
2654 }
2655 }
2656 return ErrorCodes.ERROR_DISCONNECT;
2657 }
2658
2659 @Override
2660 public int[] getTechList(int nativeHandle) throws RemoteException {
2661 NfcPermissions.enforceUserPermissions(mContext);
2662
2663 // Check if NFC is enabled
2664 if (!isNfcEnabled()) {
2665 return null;
2666 }
2667
2668 /* find the tag in the hmap */
2669 TagEndpoint tag = (TagEndpoint) findObject(nativeHandle);
2670 if (tag != null) {
2671 return tag.getTechList();
2672 }
2673 return null;
2674 }
2675
2676 @Override
2677 public boolean isPresent(int nativeHandle) throws RemoteException {
2678 TagEndpoint tag = null;
2679
2680 // Check if NFC is enabled
2681 if (!isNfcEnabled()) {
2682 return false;
2683 }
2684
2685 /* find the tag in the hmap */
2686 tag = (TagEndpoint) findObject(nativeHandle);
2687 if (tag == null) {
2688 return false;
2689 }
2690
2691 return tag.isPresent();
2692 }
2693
2694 @Override
2695 public boolean isNdef(int nativeHandle) throws RemoteException {
2696 NfcPermissions.enforceUserPermissions(mContext);
2697
2698 TagEndpoint tag = null;
2699
2700 // Check if NFC is enabled
2701 if (!isNfcEnabled()) {
2702 return false;
2703 }
2704
2705 /* find the tag in the hmap */
2706 tag = (TagEndpoint) findObject(nativeHandle);
2707 int[] ndefInfo = new int[2];
2708 if (tag == null) {
2709 return false;
2710 }
2711 return tag.checkNdef(ndefInfo);
2712 }
2713
2714 @Override
2715 public TransceiveResult transceive(int nativeHandle, byte[] data, boolean raw)
2716 throws RemoteException {
2717 NfcPermissions.enforceUserPermissions(mContext);
2718
2719 TagEndpoint tag = null;
2720 byte[] response;
2721
2722 // Check if NFC is enabled
2723 if (!isNfcEnabled()) {
2724 return null;
2725 }
2726
2727 /* find the tag in the hmap */
2728 tag = (TagEndpoint) findObject(nativeHandle);
2729 if (tag != null) {
2730 // Check if length is within limits
2731 if (data.length > getMaxTransceiveLength(tag.getConnectedTechnology())) {
2732 return new TransceiveResult(TransceiveResult.RESULT_EXCEEDED_LENGTH, null);
2733 }
2734 int[] targetLost = new int[1];
2735 response = tag.transceive(data, raw, targetLost);
2736 int result;
2737 if (response != null) {
2738 result = TransceiveResult.RESULT_SUCCESS;
2739 } else if (targetLost[0] == 1) {
2740 result = TransceiveResult.RESULT_TAGLOST;
2741 } else {
2742 result = TransceiveResult.RESULT_FAILURE;
2743 }
2744 return new TransceiveResult(result, response);
2745 }
2746 return null;
2747 }
2748
2749 @Override
2750 public NdefMessage ndefRead(int nativeHandle) throws RemoteException {
2751 NfcPermissions.enforceUserPermissions(mContext);
2752
2753 TagEndpoint tag;
2754
2755 // Check if NFC is enabled
2756 if (!isNfcEnabled()) {
2757 return null;
2758 }
2759
2760 /* find the tag in the hmap */
2761 tag = (TagEndpoint) findObject(nativeHandle);
2762 if (tag != null) {
2763 byte[] buf = tag.readNdef();
2764 if (buf == null) {
2765 return null;
2766 }
2767
2768 /* Create an NdefMessage */
2769 try {
2770 return new NdefMessage(buf);
2771 } catch (FormatException e) {
2772 return null;
2773 }
2774 }
2775 return null;
2776 }
2777
2778 @Override
2779 public int ndefWrite(int nativeHandle, NdefMessage msg) throws RemoteException {
2780 NfcPermissions.enforceUserPermissions(mContext);
2781
2782 TagEndpoint tag;
2783
2784 // Check if NFC is enabled
2785 if (!isNfcEnabled()) {
2786 return ErrorCodes.ERROR_NOT_INITIALIZED;
2787 }
2788
2789 /* find the tag in the hmap */
2790 tag = (TagEndpoint) findObject(nativeHandle);
2791 if (tag == null) {
2792 return ErrorCodes.ERROR_IO;
2793 }
2794
2795 if (msg == null) return ErrorCodes.ERROR_INVALID_PARAM;
2796
2797 if (tag.writeNdef(msg.toByteArray())) {
2798 return ErrorCodes.SUCCESS;
2799 } else {
2800 return ErrorCodes.ERROR_IO;
2801 }
2802
2803 }
2804
2805 @Override
2806 public boolean ndefIsWritable(int nativeHandle) throws RemoteException {
2807 throw new UnsupportedOperationException();
2808 }
2809
2810 @Override
2811 public int ndefMakeReadOnly(int nativeHandle) throws RemoteException {
2812 NfcPermissions.enforceUserPermissions(mContext);
2813
2814 TagEndpoint tag;
2815
2816 // Check if NFC is enabled
2817 if (!isNfcEnabled()) {
2818 return ErrorCodes.ERROR_NOT_INITIALIZED;
2819 }
2820
2821 /* find the tag in the hmap */
2822 tag = (TagEndpoint) findObject(nativeHandle);
2823 if (tag == null) {
2824 return ErrorCodes.ERROR_IO;
2825 }
2826
2827 if (tag.makeReadOnly()) {
2828 return ErrorCodes.SUCCESS;
2829 } else {
2830 return ErrorCodes.ERROR_IO;
2831 }
2832 }
2833
2834 @Override
2835 public int formatNdef(int nativeHandle, byte[] key) throws RemoteException {
2836 NfcPermissions.enforceUserPermissions(mContext);
2837
2838 TagEndpoint tag;
2839
2840 // Check if NFC is enabled
2841 if (!isNfcEnabled()) {
2842 return ErrorCodes.ERROR_NOT_INITIALIZED;
2843 }
2844
2845 /* find the tag in the hmap */
2846 tag = (TagEndpoint) findObject(nativeHandle);
2847 if (tag == null) {
2848 return ErrorCodes.ERROR_IO;
2849 }
2850
2851 if (tag.formatNdef(key)) {
2852 return ErrorCodes.SUCCESS;
2853 } else {
2854 return ErrorCodes.ERROR_IO;
2855 }
2856 }
2857
2858 @Override
2859 public Tag rediscover(int nativeHandle) throws RemoteException {
2860 NfcPermissions.enforceUserPermissions(mContext);
2861
2862 TagEndpoint tag = null;
2863
2864 // Check if NFC is enabled
2865 if (!isNfcEnabled()) {
2866 return null;
2867 }
2868
2869 /* find the tag in the hmap */
2870 tag = (TagEndpoint) findObject(nativeHandle);
2871 if (tag != null) {
2872 // For now the prime usecase for rediscover() is to be able
2873 // to access the NDEF technology after formatting without
2874 // having to remove the tag from the field, or similar
2875 // to have access to NdefFormatable in case low-level commands
2876 // were used to remove NDEF. So instead of doing a full stack
2877 // rediscover (which is poorly supported at the moment anyway),
2878 // we simply remove these two technologies and detect them
2879 // again.
2880 tag.removeTechnology(TagTechnology.NDEF);
2881 tag.removeTechnology(TagTechnology.NDEF_FORMATABLE);
2882 tag.findAndReadNdef();
2883 // Build a new Tag object to return
2884 Tag newTag = new Tag(tag.getUid(), tag.getTechList(),
2885 tag.getTechExtras(), tag.getHandle(), this);
2886 return newTag;
2887 }
2888 return null;
2889 }
2890
2891 @Override
2892 public int setTimeout(int tech, int timeout) throws RemoteException {
2893 NfcPermissions.enforceUserPermissions(mContext);
2894 boolean success = mDeviceHost.setTimeout(tech, timeout);
2895 if (success) {
2896 return ErrorCodes.SUCCESS;
2897 } else {
2898 return ErrorCodes.ERROR_INVALID_PARAM;
2899 }
2900 }
2901
2902 @Override
2903 public int getTimeout(int tech) throws RemoteException {
2904 NfcPermissions.enforceUserPermissions(mContext);
2905
2906 return mDeviceHost.getTimeout(tech);
2907 }
2908
2909 @Override
2910 public void resetTimeouts() throws RemoteException {
2911 NfcPermissions.enforceUserPermissions(mContext);
2912
2913 mDeviceHost.resetTimeouts();
2914 }
2915
2916 @Override
2917 public boolean canMakeReadOnly(int ndefType) throws RemoteException {
2918 return mDeviceHost.canMakeReadOnly(ndefType);
2919 }
2920
2921 @Override
2922 public int getMaxTransceiveLength(int tech) throws RemoteException {
2923 return mDeviceHost.getMaxTransceiveLength(tech);
2924 }
2925
2926 @Override
2927 public boolean getExtendedLengthApdusSupported() throws RemoteException {
2928 return mDeviceHost.getExtendedLengthApdusSupported();
2929 }
2930 }
2931
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05302932 final class NfcDtaService extends INfcDta.Stub {
2933 public void enableDta() throws RemoteException {
nxpandroid64fd68c2015-09-23 16:45:15 +05302934 NfcPermissions.enforceAdminPermissions(mContext);
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05302935 if(!sIsDtaMode) {
nxpandroid64fd68c2015-09-23 16:45:15 +05302936 mDeviceHost.enableDtaMode();
nxpandroid281eb922016-08-25 20:27:46 +05302937 sIsDtaMode = true;
nxpandroid64fd68c2015-09-23 16:45:15 +05302938 Log.d(TAG, "DTA Mode is Enabled ");
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05302939 }
2940 }
2941
2942 public void disableDta() throws RemoteException {
2943 NfcPermissions.enforceAdminPermissions(mContext);
2944 if(sIsDtaMode) {
nxpandroid64fd68c2015-09-23 16:45:15 +05302945 mDeviceHost.disableDtaMode();
nxpandroid281eb922016-08-25 20:27:46 +05302946 sIsDtaMode = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05302947 }
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05302948 }
2949
2950 public boolean enableServer(String serviceName, int serviceSap, int miu,
2951 int rwSize,int testCaseId) throws RemoteException {
2952 NfcPermissions.enforceAdminPermissions(mContext);
2953
2954 if(serviceName.equals(null))
2955 return false;
2956
2957 mP2pLinkManager.enableExtDtaSnepServer(serviceName, serviceSap, miu, rwSize,testCaseId);
nxpandroid64fd68c2015-09-23 16:45:15 +05302958 return true;
2959 }
2960
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05302961 public void disableServer() throws RemoteException {
2962 NfcPermissions.enforceAdminPermissions(mContext);
2963 mP2pLinkManager.disableExtDtaSnepServer();
2964 }
2965
2966 public boolean enableClient(String serviceName, int miu, int rwSize,
2967 int testCaseId) throws RemoteException {
2968 NfcPermissions.enforceAdminPermissions(mContext);
2969
2970 if(testCaseId == 0)
2971 return false;
2972
2973 if (testCaseId>20){
2974 sIsShortRecordLayout=true;
2975 testCaseId=testCaseId-20;
2976 } else {
2977 sIsShortRecordLayout=false;
2978 }
2979 Log.d("testCaseId", ""+testCaseId);
2980 mP2pLinkManager.enableDtaSnepClient(serviceName, miu, rwSize, testCaseId);
2981 return true;
2982 }
2983
2984 public void disableClient() throws RemoteException {
2985 NfcPermissions.enforceAdminPermissions(mContext);
2986 mP2pLinkManager.disableDtaSnepClient();
2987 }
2988
2989 public boolean registerMessageService(String msgServiceName)
2990 throws RemoteException {
2991 NfcPermissions.enforceAdminPermissions(mContext);
2992 if(msgServiceName.equals(null))
2993 return false;
2994
2995 DtaServiceConnector.setMessageService(msgServiceName);
2996 return true;
2997 }
2998 };
nxpandroid64fd68c2015-09-23 16:45:15 +05302999
3000 final class NfcVzwService extends INfcVzw.Stub {
3001 @Override
3002 public void setScreenOffCondition(boolean enable) throws RemoteException {
3003
3004 Message msg = mHandler.obtainMessage();
3005 msg.what=MSG_SET_SCREEN_STATE;
3006 msg.arg1= (enable)?1:0;
3007 mHandler.sendMessage(msg);
3008
3009 }
3010
3011 @Override
3012 public boolean setVzwAidList(RouteEntry[] entries)
3013 throws RemoteException {
nxpandroid64fd68c2015-09-23 16:45:15 +05303014 Log.i(TAG, "setVzwAidList enter");
3015 Log.i(TAG, "setVzwAidList entries length =" + entries.length);
3016 if (mIsHceCapable) {
3017 mAidRoutingManager.ClearVzwCache();
3018 for (int i = 0; i < entries.length; i++) {
3019 RouteEntry routeEntry = entries[i];
3020 mAidRoutingManager.UpdateVzwCache(routeEntry.getAid(),
3021 routeEntry.getLocation(), routeEntry.getPowerState(),
3022 routeEntry.isAllowed());
3023
3024 Log.i(TAG,
3025 "AID" + routeEntry.getAid() + "Location "
3026 + routeEntry.getLocation() + "powerstate "
3027 + routeEntry.getPowerState());
3028 }
3029 mAidRoutingManager.onNfccRoutingTableCleared();
3030 mCardEmulationManager.onRoutingTableChanged();
3031 return true;
3032 } else {
3033 return false;
3034 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303035 }
3036
3037 };
3038
3039 void _nfcEeClose(int callingPid, IBinder binder) throws IOException {
3040 // Blocks until a pending open() or transceive() times out.
3041 //TODO: This is incorrect behavior - the close should interrupt pending
3042 // operations. However this is not supported by current hardware.
3043
3044 synchronized (NfcService.this) {
3045 if (!isNfcEnabledOrShuttingDown()) {
3046 throw new IOException("NFC adapter is disabled");
3047 }
3048 if (mOpenEe == null) {
3049 throw new IOException("NFC EE closed");
3050 }
3051 if (callingPid != -1 && callingPid != mOpenEe.pid) {
3052 throw new SecurityException("Wrong PID");
3053 }
3054 if (mOpenEe.binder != binder) {
3055 throw new SecurityException("Wrong binder handle");
3056 }
3057
3058 binder.unlinkToDeath(mOpenEe, 0);
3059 mDeviceHost.resetTimeouts();
3060 doDisconnect(mOpenEe.handle);
3061 mOpenEe = null;
nxpandroid64fd68c2015-09-23 16:45:15 +05303062 }
3063 }
3064
3065 boolean _nfcEeReset() throws IOException {
3066 synchronized (NfcService.this) {
3067 if (!isNfcEnabledOrShuttingDown()) {
3068 throw new IOException("NFC adapter is disabled");
3069 }
3070 if (mOpenEe == null) {
3071 throw new IOException("NFC EE closed");
3072 }
3073 return mSecureElement.doReset(mOpenEe.handle);
3074 }
3075 }
3076
nxpandroid64fd68c2015-09-23 16:45:15 +05303077 final class NfcAdapterExtrasService extends INfcAdapterExtras.Stub {
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05303078 ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
nxpandroid64fd68c2015-09-23 16:45:15 +05303079 private Bundle writeNoException() {
3080 Bundle p = new Bundle();
3081 p.putInt("e", 0);
3082 return p;
3083 }
3084
3085 private Bundle writeEeException(int exceptionType, String message) {
3086 Bundle p = new Bundle();
3087 p.putInt("e", exceptionType);
3088 p.putString("m", message);
3089 return p;
3090 }
3091
3092 @Override
3093 public Bundle open(String pkg, IBinder b) throws RemoteException {
3094 NfcService.this.enforceNfceeAdminPerm(pkg);
3095
3096 Bundle result;
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05303097 if (activityManager.isLowRamDevice()) {
3098 result = writeEeException(SE_ACCESS_DENIED, "SE open access denied.");
nxpandroid64fd68c2015-09-23 16:45:15 +05303099 } else {
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05303100 int handle = _open(b);
3101 if (handle < 0) {
3102 result = writeEeException(handle, "NFCEE open exception.");
3103 } else {
3104 result = writeNoException();
3105 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303106 }
3107 return result;
3108 }
3109
3110 /**
3111 * Opens a connection to the secure element.
3112 *
3113 * @return A handle with a value >= 0 in case of success, or a
3114 * negative value in case of failure.
3115 */
3116 private int _open(IBinder b) {
3117 synchronized(NfcService.this) {
3118 if (!isNfcEnabled()) {
3119 return EE_ERROR_NFC_DISABLED;
3120 }
3121 if (mInProvisionMode) {
3122 // Deny access to the NFCEE as long as the device is being setup
3123 return EE_ERROR_IO;
3124 }
nxpandroid7d44e572016-08-01 19:11:04 +05303125 /*Concurrent access for DWP transactions to be allowed even when P2P is already ongoing */
3126 /*
nxpandroid64fd68c2015-09-23 16:45:15 +05303127 if (mP2pLinkManager.isLlcpActive()) {
3128 // Don't allow PN544-based devices to open the SE while the LLCP
3129 // link is still up or in a debounce state. This avoids race
3130 // conditions in the NXP stack around P2P/SMX switching.
3131 return EE_ERROR_EXT_FIELD;
nxpandroid7d44e572016-08-01 19:11:04 +05303132 }*/
nxpandroid64fd68c2015-09-23 16:45:15 +05303133 if (mOpenEe != null) {
3134 Log.i(TAG, "SE is Busy. returning..");
3135 return EE_ERROR_ALREADY_OPEN;
3136 }
3137 boolean restorePolling = false;
3138 if (mNfcPollingEnabled) {
3139 // Disable polling for tags/P2P when connecting to the SMX
3140 // on PN544-based devices. Whenever nfceeClose is called,
3141 // the polling configuration will be restored.
3142 mDeviceHost.disableDiscovery();
3143 mNfcPollingEnabled = false;
3144 restorePolling = true;
3145 }
3146
nxpandroid7d44e572016-08-01 19:11:04 +05303147 int handle = doOpenSecureElementConnection(0xF3);
nxpandroid64fd68c2015-09-23 16:45:15 +05303148 if (handle < 0) {
3149
3150 if (restorePolling) {
3151 mDeviceHost.enableDiscovery(mCurrentDiscoveryParameters, true);
3152 mNfcPollingEnabled = true;
3153 }
3154 return handle;
3155 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303156 mOpenEe = new OpenSecureElement(getCallingPid(), handle, b);
3157 try {
3158 b.linkToDeath(mOpenEe, 0);
3159 } catch (RemoteException e) {
3160 mOpenEe.binderDied();
3161 }
3162
3163 // Add the calling package to the list of packages that have accessed
3164 // the secure element.
3165 for (String packageName : mContext.getPackageManager().getPackagesForUid(getCallingUid())) {
3166 mSePackages.add(packageName);
3167 }
3168
3169 return handle;
3170 }
3171 }
3172
3173 @Override
3174 public Bundle close(String pkg, IBinder binder) throws RemoteException {
3175 NfcService.this.enforceNfceeAdminPerm(pkg);
3176
3177 Bundle result;
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05303178
3179 if (activityManager.isLowRamDevice()) {
3180 result = writeEeException(SE_ACCESS_DENIED, "SE close access denied.");
3181 } else {
3182 try {
3183 _nfcEeClose(getCallingPid(), binder);
3184 result = writeNoException();
3185 } catch (IOException e) {
3186 result = writeEeException(EE_ERROR_IO, e.getMessage());
3187 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303188 }
3189 return result;
3190 }
3191
nxpandroid64fd68c2015-09-23 16:45:15 +05303192 @Override
3193 public Bundle transceive(String pkg, byte[] in) throws RemoteException {
3194 NfcService.this.enforceNfceeAdminPerm(pkg);
3195
3196 Bundle result;
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05303197
3198 if (activityManager.isLowRamDevice()) {
3199 result = writeEeException(SE_ACCESS_DENIED, "SE transceive access denied.");
3200 } else {
3201 byte[] out;
3202 try {
3203 out = _transceive(in);
3204 result = writeNoException();
3205 result.putByteArray("out", out);
3206 } catch (IOException e) {
3207 result = writeEeException(EE_ERROR_IO, e.getMessage());
3208 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303209 }
3210 return result;
3211 }
3212
3213 private byte[] _transceive(byte[] data) throws IOException {
3214 synchronized(NfcService.this) {
3215 if (!isNfcEnabled()) {
3216 throw new IOException("NFC is not enabled");
3217 }
3218 if (mOpenEe == null) {
3219 throw new IOException("NFC EE is not open");
3220 }
3221 if (getCallingPid() != mOpenEe.pid) {
3222 throw new SecurityException("Wrong PID");
3223 }
3224 }
3225
3226 return doTransceive(mOpenEe.handle, data);
3227 }
3228
nxpandroid64fd68c2015-09-23 16:45:15 +05303229 @Override
3230 public int getCardEmulationRoute(String pkg) throws RemoteException {
3231 NfcService.this.enforceNfceeAdminPerm(pkg);
3232 return mEeRoutingState;
3233 }
3234
3235 @Override
3236 public void setCardEmulationRoute(String pkg, int route) throws RemoteException {
3237 NfcService.this.enforceNfceeAdminPerm(pkg);
3238 mEeRoutingState = route;
3239 ApplyRoutingTask applyRoutingTask = new ApplyRoutingTask();
3240 applyRoutingTask.execute();
3241 try {
3242 // Block until route is set
3243 applyRoutingTask.get();
3244 } catch (ExecutionException e) {
3245 Log.e(TAG, "failed to set card emulation mode");
3246 } catch (InterruptedException e) {
3247 Log.e(TAG, "failed to set card emulation mode");
3248 }
3249 }
3250
3251 @Override
3252 public void authenticate(String pkg, byte[] token) throws RemoteException {
3253 NfcService.this.enforceNfceeAdminPerm(pkg);
3254 }
3255
3256 @Override
3257 public String getDriverName(String pkg) throws RemoteException {
3258 NfcService.this.enforceNfceeAdminPerm(pkg);
3259 return mDeviceHost.getName();
3260 }
3261
3262 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303263
3264 /** resources kept while secure element is open */
3265 private class OpenSecureElement implements IBinder.DeathRecipient {
3266 public int pid; // pid that opened SE
3267 // binder handle used for DeathReceipient. Must keep
3268 // a reference to this, otherwise it can get GC'd and
3269 // the binder stub code might create a different BinderProxy
3270 // for the same remote IBinder, causing mismatched
3271 // link()/unlink()
3272 public IBinder binder;
3273 public int handle; // low-level handle
3274 public OpenSecureElement(int pid, int handle, IBinder binder) {
3275 this.pid = pid;
3276 this.handle = handle;
3277 this.binder = binder;
3278 }
3279 @Override
3280 public void binderDied() {
3281 synchronized (NfcService.this) {
3282 Log.i(TAG, "Tracked app " + pid + " died");
3283 pid = -1;
3284 try {
3285 _nfcEeClose(-1, binder);
3286 } catch (IOException e) { /* already closed */ }
3287 }
3288 }
3289 @Override
3290 public String toString() {
3291 return new StringBuilder('@').append(Integer.toHexString(hashCode())).append("[pid=")
3292 .append(pid).append(" handle=").append(handle).append("]").toString();
3293 }
3294 }
3295
3296 boolean isNfcEnabledOrShuttingDown() {
3297 synchronized (this) {
3298 return (mState == NfcAdapter.STATE_ON || mState == NfcAdapter.STATE_TURNING_OFF);
3299 }
3300 }
3301
3302 boolean isNfcEnabled() {
3303 synchronized (this) {
3304 return mState == NfcAdapter.STATE_ON;
3305 }
3306 }
3307
3308 class WatchDogThread extends Thread {
3309 final Object mCancelWaiter = new Object();
3310 final int mTimeout;
3311 boolean mCanceled = false;
3312
3313 public WatchDogThread(String threadName, int timeout) {
3314 super(threadName);
3315 mTimeout = timeout;
3316 }
3317
3318 @Override
3319 public void run() {
3320 try {
3321 synchronized (mCancelWaiter) {
3322 mCancelWaiter.wait(mTimeout);
3323 if (mCanceled) {
3324 return;
3325 }
3326 }
3327 } catch (InterruptedException e) {
3328 // Should not happen; fall-through to abort.
3329 Log.w(TAG, "Watchdog thread interruped.");
3330 interrupt();
3331 }
3332 Log.e(TAG, "Watchdog triggered, aborting.");
nxpandroid6fd9cdb2017-07-12 18:25:41 +05303333 mDeviceHost.doAbort(getName());
nxpandroid64fd68c2015-09-23 16:45:15 +05303334 }
3335
3336 public synchronized void cancel() {
3337 synchronized (mCancelWaiter) {
3338 mCanceled = true;
3339 mCancelWaiter.notify();
3340 }
3341 }
3342 }
3343
3344 /* For Toast from background process*/
3345
3346 public class ToastHandler
3347 {
3348 // General attributes
3349 private Context mContext;
3350 private Handler mHandler;
3351
3352 public ToastHandler(Context _context)
3353 {
3354 this.mContext = _context;
3355 this.mHandler = new Handler();
3356 }
3357
3358 /**
3359 * Runs the <code>Runnable</code> in a separate <code>Thread</code>.
3360 *
3361 * @param _runnable
3362 * The <code>Runnable</code> containing the <code>Toast</code>
3363 */
3364 private void runRunnable(final Runnable _runnable)
3365 {
3366 Thread thread = new Thread()
3367 {
3368 public void run()
3369 {
3370 mHandler.post(_runnable);
3371 }
3372 };
3373
3374 thread.start();
3375 thread.interrupt();
3376 thread = null;
3377 }
3378
3379 public void showToast(final CharSequence _text, final int _duration)
3380 {
3381 final Runnable runnable = new Runnable()
3382 {
3383 @Override
3384 public void run()
3385 {
3386 Toast.makeText(mContext, _text, _duration).show();
3387 }
3388 };
3389
3390 runRunnable(runnable);
3391 }
3392 }
3393
3394 static byte[] hexStringToBytes(String s) {
3395 if (s == null || s.length() == 0) return null;
3396 int len = s.length();
3397 if (len % 2 != 0) {
3398 s = '0' + s;
3399 len++;
3400 }
3401 byte[] data = new byte[len / 2];
3402 for (int i = 0; i < len; i += 2) {
3403 data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
3404 + Character.digit(s.charAt(i + 1), 16));
3405 }
3406 return data;
3407 }
3408
3409 static String toHexString(byte[] buffer, int offset, int length) {
nxpandroid281eb922016-08-25 20:27:46 +05303410 final char[] hexChars = "0123456789abcdef".toCharArray();
nxpandroid64fd68c2015-09-23 16:45:15 +05303411 char[] chars = new char[2 * length];
3412 for (int j = offset; j < offset + length; ++j) {
nxpandroid281eb922016-08-25 20:27:46 +05303413 chars[2 * (j-offset)] = hexChars[(buffer[j] & 0xF0) >>> 4];
3414 chars[2 * (j-offset) + 1] = hexChars[buffer[j] & 0x0F];
nxpandroid64fd68c2015-09-23 16:45:15 +05303415 }
3416 return new String(chars);
3417 }
3418
3419 /**
3420 * Read mScreenState and apply NFC-C polling and NFC-EE routing
3421 */
3422 void applyRouting(boolean force) {
3423 Log.d(TAG, "applyRouting - enter force = " + force + " mScreenState = " + mScreenState);
3424
3425 synchronized (this) {
3426 //Since Reader mode during wired mode is supported
3427 //enableDiscovery or disableDiscovery is allowed
nxpandroid64fd68c2015-09-23 16:45:15 +05303428 if (!isNfcEnabledOrShuttingDown()) {
3429 // PN544 cannot be reconfigured while EE is open
3430 return;
3431 }
3432 WatchDogThread watchDog = new WatchDogThread("applyRouting", ROUTING_WATCHDOG_MS);
3433 if (mInProvisionMode) {
3434 mInProvisionMode = Settings.Secure.getInt(mContentResolver,
3435 Settings.Global.DEVICE_PROVISIONED, 0) == 0;
3436 if (!mInProvisionMode) {
3437 // Notify dispatcher it's fine to dispatch to any package now
3438 // and allow handover transfers.
3439 mNfcDispatcher.disableProvisioningMode();
nxpandroid1153eb32015-11-06 18:46:58 +05303440 /* if provision mode is disabled, then send this info to lower layers as well */
3441 mDeviceHost.doSetProvisionMode(mInProvisionMode);
nxpandroid64fd68c2015-09-23 16:45:15 +05303442 }
3443 }
3444 // Special case: if we're transitioning to unlocked state while
3445 // still talking to a tag, postpone re-configuration.
3446 if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED && isTagPresent()) {
3447 Log.d(TAG, "Not updating discovery parameters, tag connected.");
3448 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESUME_POLLING),
3449 APPLY_ROUTING_RETRY_TIMEOUT_MS);
3450 return;
3451 }
3452
3453 try {
3454 watchDog.start();
3455 // Compute new polling parameters
3456 NfcDiscoveryParameters newParams = computeDiscoveryParameters(mScreenState);
3457 if (force || !newParams.equals(mCurrentDiscoveryParameters)) {
3458 if (newParams.shouldEnableDiscovery()) {
3459 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery();
3460 mDeviceHost.enableDiscovery(newParams, shouldRestart);
3461 } else {
3462 mDeviceHost.disableDiscovery();
3463 }
3464 mCurrentDiscoveryParameters = newParams;
3465 } else {
3466 Log.d(TAG, "Discovery configuration equal, not updating.");
3467 }
3468 } finally {
3469 watchDog.cancel();
3470 }
3471 }
3472 }
3473
3474 private NfcDiscoveryParameters computeDiscoveryParameters(int screenState) {
3475 // Recompute discovery parameters based on screen state
3476 NfcDiscoveryParameters.Builder paramsBuilder = NfcDiscoveryParameters.newBuilder();
nxpandroide66eb092017-07-12 21:36:08 +05303477
nxpandroid64fd68c2015-09-23 16:45:15 +05303478 // Polling
nxpandroid5d64ce92016-11-18 19:48:53 +05303479 if ((screenState >= NFC_POLLING_MODE)||mIsTaskBoot) {
nxpandroid64fd68c2015-09-23 16:45:15 +05303480 // Check if reader-mode is enabled
3481 if (mReaderModeParams != null) {
3482 int techMask = 0;
3483 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_A) != 0)
3484 techMask |= NFC_POLL_A;
3485 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_B) != 0)
3486 techMask |= NFC_POLL_B;
3487 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_F) != 0)
3488 techMask |= NFC_POLL_F;
3489 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_V) != 0)
Nikhil Chhabra288edb02018-01-10 19:36:21 +05303490 techMask |= NFC_POLL_V;
nxpandroid64fd68c2015-09-23 16:45:15 +05303491 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_BARCODE) != 0)
3492 techMask |= NFC_POLL_KOVIO;
3493
3494 paramsBuilder.setTechMask(techMask);
3495 paramsBuilder.setEnableReaderMode(true);
3496 } else {
3497 paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT);
nxpandroid6fd9cdb2017-07-12 18:25:41 +05303498 paramsBuilder.setEnableP2p(true);
nxpandroid64fd68c2015-09-23 16:45:15 +05303499 }
nxpandroide66eb092017-07-12 21:36:08 +05303500 }
3501 if ((screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mInProvisionMode) &&
3502 !mNfcUnlockManager.isLockscreenPollingEnabled()) {
3503 if (mReaderModeParams != null)
nxpandroid64fd68c2015-09-23 16:45:15 +05303504 paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT);
3505 // enable P2P for MFM/EDU/Corp provisioning
3506 paramsBuilder.setEnableP2p(true);
nxpandroide66eb092017-07-12 21:36:08 +05303507 } else if ((screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED) &&
nxpandroid6fd9cdb2017-07-12 18:25:41 +05303508 (mIsLiveCaseEnabled || mNfcUnlockManager.isLockscreenPollingEnabled())) {
3509 int techMask = 0;
3510 // enable polling for Live Case technologies
3511 if (mIsLiveCaseEnabled)
3512 techMask |= mLiveCaseTechnology;
3513 if (mNfcUnlockManager.isLockscreenPollingEnabled())
nxpandroide66eb092017-07-12 21:36:08 +05303514 {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05303515 techMask |= mNfcUnlockManager.getLockscreenPollMask();
nxpandroide66eb092017-07-12 21:36:08 +05303516 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05303517 paramsBuilder.setTechMask(techMask);
nxpandroid64fd68c2015-09-23 16:45:15 +05303518 paramsBuilder.setEnableLowPowerDiscovery(false);
3519 paramsBuilder.setEnableP2p(false);
3520 }
3521
Suhas Sureshca6584b2018-04-27 17:17:22 +05303522 if (mIsHceCapable && mReaderModeParams == null) {
Nikhil Chhabrae1d07ba2018-01-10 11:33:17 +05303523 // Host routing is always enabled at lock screen or later, provided we aren't in reader mode
3524 paramsBuilder.setEnableHostRouting(true);
3525 }
3526
nxpandroid64fd68c2015-09-23 16:45:15 +05303527 //To make routing table update.
3528 if(mIsRoutingTableDirty) {
3529 mIsRoutingTableDirty = false;
nxpandroida9a68ba2016-01-14 21:12:17 +05303530 int protoRoute = mNxpPrefs.getInt("PREF_MIFARE_DESFIRE_PROTO_ROUTE_ID", GetDefaultMifareDesfireRouteEntry());
3531 int defaultRoute=mNxpPrefs.getInt("PREF_SET_DEFAULT_ROUTE_ID", GetDefaultRouteEntry());
3532 int techRoute=mNxpPrefs.getInt("PREF_MIFARE_CLT_ROUTE_ID", GetDefaultMifateCLTRouteEntry());
nxpandroid281eb922016-08-25 20:27:46 +05303533 if (DBG) Log.d(TAG, "Set default Route Entry");
nxpandroid64fd68c2015-09-23 16:45:15 +05303534 setDefaultRoute(defaultRoute, protoRoute, techRoute);
3535 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303536
nxpandroid64fd68c2015-09-23 16:45:15 +05303537 return paramsBuilder.build();
3538 }
3539
3540 private boolean isTagPresent() {
3541 for (Object object : mObjectMap.values()) {
3542 if (object instanceof TagEndpoint) {
3543 return ((TagEndpoint) object).isPresent();
3544 }
3545 }
3546 return false;
3547 }
Suhas Suresh5efc5432018-04-27 15:31:02 +05303548
3549 private void StopPresenceChecking() {
3550 Object[] objectValues = mObjectMap.values().toArray();
3551 for (Object object : objectValues) {
3552 if (object instanceof TagEndpoint) {
3553 TagEndpoint tag = (TagEndpoint)object;
3554 ((TagEndpoint) object).stopPresenceChecking();
3555 }
3556 }
3557 }
3558
nxpandroid64fd68c2015-09-23 16:45:15 +05303559 /**
3560 * Disconnect any target if present
3561 */
3562 void maybeDisconnectTarget() {
3563 if (!isNfcEnabledOrShuttingDown()) {
3564 return;
3565 }
3566 Object[] objectsToDisconnect;
3567 synchronized (this) {
3568 Object[] objectValues = mObjectMap.values().toArray();
3569 // Copy the array before we clear mObjectMap,
3570 // just in case the HashMap values are backed by the same array
3571 objectsToDisconnect = Arrays.copyOf(objectValues, objectValues.length);
3572 mObjectMap.clear();
3573 }
3574 for (Object o : objectsToDisconnect) {
3575 if (DBG) Log.d(TAG, "disconnecting " + o.getClass().getName());
3576 if (o instanceof TagEndpoint) {
3577 // Disconnect from tags
3578 TagEndpoint tag = (TagEndpoint) o;
3579 tag.disconnect();
3580 } else if (o instanceof NfcDepEndpoint) {
3581 // Disconnect from P2P devices
3582 NfcDepEndpoint device = (NfcDepEndpoint) o;
3583 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) {
3584 // Remote peer is target, request disconnection
3585 device.disconnect();
3586 } else {
3587 // Remote peer is initiator, we cannot disconnect
3588 // Just wait for field removal
3589 }
3590 }
3591 }
3592 }
3593
3594 Object findObject(int key) {
3595 synchronized (this) {
3596 Object device = mObjectMap.get(key);
3597 if (device == null) {
3598 Log.w(TAG, "Handle not found");
3599 }
3600 return device;
3601 }
3602 }
3603
nxpandroid281eb922016-08-25 20:27:46 +05303604 Object findAndRemoveObject(int handle) {
3605 synchronized (this) {
3606 Object device = mObjectMap.get(handle);
3607 if (device == null) {
3608 Log.w(TAG, "Handle not found");
3609 } else {
3610 mObjectMap.remove(handle);
3611 }
3612 return device;
3613 }
3614 }
3615
nxpandroid64fd68c2015-09-23 16:45:15 +05303616 void registerTagObject(TagEndpoint tag) {
3617 synchronized (this) {
3618 mObjectMap.put(tag.getHandle(), tag);
3619 }
3620 }
3621
3622 void unregisterObject(int handle) {
3623 synchronized (this) {
3624 mObjectMap.remove(handle);
3625 }
3626 }
3627
3628 /**
3629 * For use by code in this process
3630 */
3631 public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength)
3632 throws LlcpException {
3633 return mDeviceHost.createLlcpSocket(sap, miu, rw, linearBufferLength);
3634 }
3635
3636 /**
3637 * For use by code in this process
3638 */
3639 public LlcpConnectionlessSocket createLlcpConnectionLessSocket(int sap, String sn)
3640 throws LlcpException {
3641 return mDeviceHost.createLlcpConnectionlessSocket(sap, sn);
3642 }
3643
3644 /**
3645 * For use by code in this process
3646 */
3647 public LlcpServerSocket createLlcpServerSocket(int sap, String sn, int miu, int rw,
3648 int linearBufferLength) throws LlcpException {
3649 return mDeviceHost.createLlcpServerSocket(sap, sn, miu, rw, linearBufferLength);
3650 }
3651
3652 public void sendMockNdefTag(NdefMessage msg) {
3653 sendMessage(MSG_MOCK_NDEF, msg);
3654 }
3655
3656 public void notifyRoutingTableFull()
3657 {
nxf2676386ae0fb2018-11-19 17:33:54 +05303658 mToastHandler.showToast("Last installed NFC Service is not enabled due to limited resources. To enable this service, " +
3659 "please disable other servives in Settings Menu", 20);
3660
nxpandroidebf53fb2016-12-22 18:48:59 +05303661 if(!mNxpNfcController.isGsmaCommitOffhostService()) {
3662 ComponentName prevPaymentComponent = mAidCache.getPreviousPreferredPaymentService();
3663
3664 mNxpPrefsEditor = mNxpPrefs.edit();
3665 mNxpPrefsEditor.putInt("PREF_SET_AID_ROUTING_TABLE_FULL",0x01);
3666 mNxpPrefsEditor.commit();
3667 //broadcast Aid Routing Table Full intent to the user
3668 Intent aidTableFull = new Intent();
3669 aidTableFull.putExtra(NxpConstants.EXTRA_GSMA_PREV_PAYMENT_COMPONENT,prevPaymentComponent);
3670 aidTableFull.setAction(NxpConstants.ACTION_ROUTING_TABLE_FULL);
3671 if (DBG) {
3672 Log.d(TAG, "notify aid routing table full to the user");
3673 }
3674 mContext.sendBroadcastAsUser(aidTableFull, UserHandle.CURRENT);
3675 mAidCache.setPreviousPreferredPaymentService(null);
nxpandroid64fd68c2015-09-23 16:45:15 +05303676 }
nxf2676386ae0fb2018-11-19 17:33:54 +05303677
nxpandroid64fd68c2015-09-23 16:45:15 +05303678 }
3679 /**
3680 * set default Aid route entry in case application does not configure this route entry
3681 */
nxpandroidebf53fb2016-12-22 18:48:59 +05303682 public void setDefaultAidRouteLoc( int routeLoc)
nxpandroid64fd68c2015-09-23 16:45:15 +05303683 {
nxpandroida9a68ba2016-01-14 21:12:17 +05303684 mNxpPrefsEditor = mNxpPrefs.edit();
nxpandroidebf53fb2016-12-22 18:48:59 +05303685 Log.d(TAG, "writing to preferences setDefaultAidRouteLoc :" + routeLoc);
3686
3687 int defaultAidRoute = ((mDeviceHost.getDefaultAidPowerState() & 0x1F) | (routeLoc << ROUTE_LOC_MASK));
3688 if(routeLoc == 0x00)
3689 {
3690 /*
3691 bit pos 1 = Power Off
3692 bit pos 2 = Battery Off
3693 bit pos 4 = Screen Off
3694 Set these bits to 0 because in case routeLoc = HOST it can not work on POWER_OFF, BATTERY_OFF and SCREEN_OFF*/
3695 defaultAidRoute &= 0xE9;
3696 }
3697
3698 mNxpPrefsEditor.putInt("PREF_SET_DEFAULT_ROUTE_ID", defaultAidRoute);
nxpandroida9a68ba2016-01-14 21:12:17 +05303699 mNxpPrefsEditor.commit();
3700 int defaultRoute=mNxpPrefs.getInt("PREF_SET_DEFAULT_ROUTE_ID",0xFF);
nxpandroid64fd68c2015-09-23 16:45:15 +05303701 Log.d(TAG, "reading preferences from user :" + defaultRoute);
3702 }
3703
3704 public int getAidRoutingTableSize ()
3705 {
3706 int aidTableSize = 0x00;
3707 aidTableSize = mDeviceHost.getAidTableSize();
3708 return aidTableSize;
3709 }
3710
nxpandroidcbf24822017-07-12 21:37:17 +05303711 public void routeAids(String aid, int route, int powerState, int aidInfo) {
nxpandroid64fd68c2015-09-23 16:45:15 +05303712 Message msg = mHandler.obtainMessage();
3713 msg.what = MSG_ROUTE_AID;
3714 msg.arg1 = route;
3715 msg.arg2 = powerState;
nxpandroidcbf24822017-07-12 21:37:17 +05303716 Bundle aidbundle = new Bundle();
3717 aidbundle.putInt("aidinfo",aidInfo);
3718 msg.setData(aidbundle);
nxpandroid64fd68c2015-09-23 16:45:15 +05303719 msg.obj = aid;
3720 mHandler.sendMessage(msg);
3721 }
3722
3723 public void unrouteAids(String aid) {
3724 sendMessage(MSG_UNROUTE_AID, aid);
3725 }
nxpandroida5fd6622017-07-31 16:15:18 +05303726
3727 public void routeApduPattern(String apdu, String mask ,int route, int powerState) {
3728 Message msg = mHandler.obtainMessage();
3729 msg.what = MSG_ROUTE_APDU;
3730 msg.arg1 = route;
3731 msg.arg2 = powerState;
3732 Bundle apduPatternbundle = new Bundle();
3733 apduPatternbundle.putString("apduData",apdu);
3734 apduPatternbundle.putString("apduMask",mask);
3735 msg.setData(apduPatternbundle);
3736 mHandler.sendMessage(msg);
3737 }
3738
3739 public void unrouteApduPattern(String apdu) {
3740 //sendMessage(MSG_UNROUTE_APDU, apdu);
3741 mDeviceHost.unrouteApduPattern(hexStringToBytes(apdu));
3742 }
3743
nxpandroide66eb092017-07-12 21:36:08 +05303744 public int getNciVersion() {
3745 return mDeviceHost.getNciVersion();
3746 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05303747 private byte[] getT3tIdentifierBytes(String systemCode, String nfcId2, String t3tPmm) {
3748 ByteBuffer buffer = ByteBuffer.allocate(2 + 8 + 8);
nxpandroid34627bd2016-05-27 15:52:30 +05303749 buffer.put(hexStringToBytes(systemCode));
3750 buffer.put(hexStringToBytes(nfcId2));
nxpandroid6fd9cdb2017-07-12 18:25:41 +05303751 buffer.put(hexStringToBytes(t3tPmm));
nxpandroid34627bd2016-05-27 15:52:30 +05303752 byte[] t3tIdBytes = new byte[buffer.position()];
3753 buffer.position(0);
3754 buffer.get(t3tIdBytes);
nxpandroid6fd9cdb2017-07-12 18:25:41 +05303755
nxpandroid34627bd2016-05-27 15:52:30 +05303756 return t3tIdBytes;
3757 }
3758
nxpandroid6fd9cdb2017-07-12 18:25:41 +05303759 public void registerT3tIdentifier(String systemCode, String nfcId2, String t3tPmm) {
3760 Log.d(TAG, "request to register LF_T3T_IDENTIFIER");
3761
3762 byte[] t3tIdentifier = getT3tIdentifierBytes(systemCode, nfcId2, t3tPmm);
nxpandroid34627bd2016-05-27 15:52:30 +05303763 sendMessage(MSG_REGISTER_T3T_IDENTIFIER, t3tIdentifier);
3764 }
3765
nxpandroid6fd9cdb2017-07-12 18:25:41 +05303766 public void deregisterT3tIdentifier(String systemCode, String nfcId2, String t3tPmm) {
3767 Log.d(TAG, "request to deregister LF_T3T_IDENTIFIER");
3768
3769 byte[] t3tIdentifier = getT3tIdentifierBytes(systemCode, nfcId2, t3tPmm);
nxpandroid34627bd2016-05-27 15:52:30 +05303770 sendMessage(MSG_DEREGISTER_T3T_IDENTIFIER, t3tIdentifier);
3771 }
3772
3773 public void clearT3tIdentifiersCache() {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05303774 Log.d(TAG, "clear T3t Identifiers Cache");
nxpandroid34627bd2016-05-27 15:52:30 +05303775 mDeviceHost.clearT3tIdentifiersCache();
3776 }
3777
3778 public int getLfT3tMax() {
3779 return mDeviceHost.getLfT3tMax();
3780 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303781
3782 public void commitRouting() {
3783 mHandler.sendEmptyMessage(MSG_COMMIT_ROUTING);
3784 }
3785 /**
3786 * get default Aid route entry in case application does not configure this route entry
3787 */
3788 public int GetDefaultRouteLoc()
3789 {
nxpandroida9a68ba2016-01-14 21:12:17 +05303790 int defaultRouteLoc = mNxpPrefs.getInt("PREF_SET_DEFAULT_ROUTE_ID", GetDefaultRouteEntry()) >> ROUTE_LOC_MASK;
nxpandroid64fd68c2015-09-23 16:45:15 +05303791 Log.d(TAG, "GetDefaultRouteLoc :" + defaultRouteLoc);
3792 return defaultRouteLoc ;
3793 }
3794
3795 /**
3796 * get default MifareDesfireRoute route entry in case application does not configure this route entry
3797 */
3798 public int GetDefaultMifareDesfireRouteEntry()
3799 {
nxpandroid7d44e572016-08-01 19:11:04 +05303800 int routeLoc = mDeviceHost.getDefaultDesfireRoute();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05303801 int defaultMifareDesfireRoute = ((mDeviceHost.getDefaultDesfirePowerState() & 0x3F) | (routeLoc << ROUTE_LOC_MASK));
nxpandroid7d44e572016-08-01 19:11:04 +05303802 if(routeLoc == 0x00)
3803 {
nxpandroid8aecbf82016-09-16 20:21:47 +05303804 /*
3805 bit pos 1 = Power Off
3806 bit pos 2 = Battery Off
3807 bit pos 4 = Screen Off
3808 Set these bits to 0 because in case routeLoc = HOST it can not work on POWER_OFF, BATTERY_OFF and SCREEN_OFF*/
nxpandroid6fd9cdb2017-07-12 18:25:41 +05303809 defaultMifareDesfireRoute &= 0xF9;
nxpandroid7d44e572016-08-01 19:11:04 +05303810 }
nxpandroid281eb922016-08-25 20:27:46 +05303811 if (DBG) Log.d(TAG, "defaultMifareDesfireRoute : " + defaultMifareDesfireRoute);
nxpandroid7d44e572016-08-01 19:11:04 +05303812 return defaultMifareDesfireRoute;
nxpandroid64fd68c2015-09-23 16:45:15 +05303813 }
3814 /**
3815 * set default Aid route entry in case application does not configure this route entry
3816 */
3817
3818 public int GetDefaultRouteEntry()
3819 {
nxpandroid7d44e572016-08-01 19:11:04 +05303820 int routeLoc = mDeviceHost.getDefaultAidRoute();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05303821 int defaultAidRoute = ((mDeviceHost.getDefaultAidPowerState() & 0x3F) | (routeLoc << ROUTE_LOC_MASK));
nxpandroid7d44e572016-08-01 19:11:04 +05303822 if(routeLoc == 0x00)
3823 {
nxpandroid8aecbf82016-09-16 20:21:47 +05303824 /*
3825 bit pos 1 = Power Off
3826 bit pos 2 = Battery Off
3827 bit pos 4 = Screen Off
3828 Set these bits to 0 because in case routeLoc = HOST it can not work on POWER_OFF, BATTERY_OFF and SCREEN_OFF*/
nxpandroid6fd9cdb2017-07-12 18:25:41 +05303829 defaultAidRoute &= 0xF9;
nxpandroid7d44e572016-08-01 19:11:04 +05303830 }
nxpandroid281eb922016-08-25 20:27:46 +05303831 if (DBG) Log.d(TAG, "defaultAidRoute : " + defaultAidRoute);
nxpandroid64fd68c2015-09-23 16:45:15 +05303832 return defaultAidRoute;
3833 }
3834
3835 /**
3836 * get default MifateCLT route entry in case application does not configure this route entry
3837 */
3838 public int GetDefaultMifateCLTRouteEntry()
3839 {
nxpandroid7d44e572016-08-01 19:11:04 +05303840 int routeLoc = mDeviceHost.getDefaultMifareCLTRoute();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05303841 int defaultMifateCLTRoute = ((mDeviceHost.getDefaultMifareCLTPowerState() & 0x3F) | (routeLoc << ROUTE_LOC_MASK) | (TECH_TYPE_A << TECH_TYPE_MASK));
nxpandroid7d44e572016-08-01 19:11:04 +05303842
nxpandroid281eb922016-08-25 20:27:46 +05303843 if (DBG) Log.d(TAG, "defaultMifateCLTRoute : " + defaultMifateCLTRoute);
nxpandroid7d44e572016-08-01 19:11:04 +05303844 return defaultMifateCLTRoute;
nxpandroid64fd68c2015-09-23 16:45:15 +05303845 }
3846
3847 public boolean setDefaultRoute(int defaultRouteEntry, int defaultProtoRouteEntry, int defaultTechRouteEntry) {
3848 boolean ret = mDeviceHost.setDefaultRoute(defaultRouteEntry, defaultProtoRouteEntry, defaultTechRouteEntry);
3849 return ret;
3850 }
3851
3852 public int getDefaultRoute() {
nxpandroida9a68ba2016-01-14 21:12:17 +05303853 return mNxpPrefs.getInt(PREF_DEFAULT_ROUTE_ID, DEFAULT_ROUTE_ID_DEFAULT);
nxpandroid64fd68c2015-09-23 16:45:15 +05303854 }
3855
3856
3857 public void commitingFelicaRouting() {
3858 mHandler.sendEmptyMessage(MSG_COMMITINF_FELICA_ROUTING);
3859 }
3860
3861 public void commitedFelicaRouting() {
3862 mHandler.sendEmptyMessage(MSG_COMMITED_FELICA_ROUTING);
3863 }
3864
nxpandroida9a68ba2016-01-14 21:12:17 +05303865 public int getAidRoutingTableStatus() {
3866 int aidTableStatus = 0x00;
3867 aidTableStatus = mNxpPrefs.getInt("PREF_SET_AID_ROUTING_TABLE_FULL",0x00);
3868 return aidTableStatus;
3869 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303870
nxpandroid64fd68c2015-09-23 16:45:15 +05303871 public void clearRouting() {
3872 mHandler.sendEmptyMessage(MSG_CLEAR_ROUTING);
3873 }
3874
3875 public boolean isVzwFeatureEnabled(){
3876 return mDeviceHost.isVzwFeatureEnabled();
3877 }
3878
3879 public boolean sendData(byte[] data) {
3880 return mDeviceHost.sendRawFrame(data);
3881 }
3882
3883 public int getDefaultSecureElement() {
3884 int[] seList = mDeviceHost.doGetSecureElementList();
3885 if ( seList == null || seList.length != 1) {
3886 //use default value
3887 return -1;
3888 } else {
3889 return seList[0];
3890 }
3891 }
3892
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05303893 public void updateLastScreenState()
3894 {
3895 Log.d(TAG, "updateLastScreenState");
3896 int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ?
3897 (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState;
3898 mDeviceHost.doSetScreenOrPowerState(screen_state_mask);
3899 }
3900
nxpandroid64fd68c2015-09-23 16:45:15 +05303901 public void etsiStartConfig(int eeHandle) {
3902 Log.d(TAG, "etsiStartConfig Enter");
3903
3904 Log.d(TAG, "etsiStartConfig : etsiInitConfig");
3905 mDeviceHost.etsiInitConfig();
3906
3907 Log.d(TAG, "etsiStartConfig : disableDiscovery");
3908 mDeviceHost.disableDiscovery();
3909
3910 Log.d(TAG, "etsiStartConfig : etsiReaderConfig");
3911 mDeviceHost.etsiReaderConfig(eeHandle);
3912
3913 Log.d(TAG, "etsiStartConfig : notifyEEReaderEvent");
Pratap Reddy49abbe32018-03-27 16:51:59 +05303914 mDeviceHost.notifyEEReaderEvent(ETSI_READER_START_SUCCESS);
nxpandroid64fd68c2015-09-23 16:45:15 +05303915
3916 Log.d(TAG, "etsiStartConfig : setEtsiReaederState");
3917 mDeviceHost.setEtsiReaederState(STATE_SE_RDR_MODE_STARTED);
3918 //broadcast SWP_READER_ACTIVATED evt
nxpandroid5d64ce92016-11-18 19:48:53 +05303919 Intent swpReaderRequestedIntent = new Intent();
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05303920 swpReaderRequestedIntent.setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_START_SUCCESS);
nxpandroid64fd68c2015-09-23 16:45:15 +05303921 if (DBG) {
3922 Log.d(TAG, "SWP READER - Requested");
3923 }
nxpandroid5d64ce92016-11-18 19:48:53 +05303924 mContext.sendBroadcast(swpReaderRequestedIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05303925
3926 Log.d(TAG, "etsiStartConfig : enableDiscovery");
3927 mDeviceHost.enableDiscovery(mCurrentDiscoveryParameters, true);
3928
3929 Log.d(TAG, "etsiStartConfig Exit");
3930 }
3931
3932 public void etsiStopConfig(int discNtfTimeout) {
3933 Log.d(TAG, "etsiStopConfig Enter");
3934 if( mDeviceHost.getEtsiReaederState() == STATE_SE_RDR_MODE_STOP_IN_PROGRESS)
3935 {
3936 Log.d(TAG, "Attempting etsiStopConfig while STATE_SE_RDR_MODE_STOP_IN_PROGRESS. Returning..");
3937 return;
3938 }
3939 ETSI_STOP_CONFIG = true;
nxpandroid64fd68c2015-09-23 16:45:15 +05303940 Log.d(TAG, "etsiStopConfig : etsiInitConfig");
3941 mDeviceHost.etsiInitConfig();
3942
Pratap Reddy49abbe32018-03-27 16:51:59 +05303943 Timer mTimer = new Timer();
3944 TagRemoveTaskTimer tagRemoveTask = new TagRemoveTaskTimer();
3945 mTimer.schedule(tagRemoveTask, ETSI_PRESENCE_CHECK_DELAY, ETSI_PRESENCE_CHECK_DELAY);
3946
nxpandroid64fd68c2015-09-23 16:45:15 +05303947 Log.d(TAG, "etsiStopConfig : disableDiscovery");
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05303948 mDeviceHost.stopPoll(NxpConstants.ULTRA_LOW_POWER);
Pratap Reddy49abbe32018-03-27 16:51:59 +05303949 mTimer.cancel();
nxpandroid64fd68c2015-09-23 16:45:15 +05303950
3951 if(mDeviceHost.getEtsiReaederState() == STATE_SE_RDR_MODE_STOPPED)
3952 {
3953 Log.d(TAG, "etsiStopConfig :etsi reader already Stopped. Returning..");
3954 ETSI_STOP_CONFIG = false;
3955 return;
3956 }
3957 Log.d(TAG, "etsiStopConfig : etsiResetReaderConfig");
3958 mDeviceHost.etsiResetReaderConfig();
3959
Suhas Sureshe8aa9cf2018-08-01 15:16:59 +05303960 Log.d(TAG, "etsiStopConfig : notifyEEReaderEvent");
3961 mDeviceHost.notifyEEReaderEvent(ETSI_READER_STOP);
3962
Ganesh Deva525a2d52018-06-01 21:39:38 +05303963 Log.d(TAG, "etsiStopConfig : enable discovery");
3964 NfcDiscoveryParameters params = computeDiscoveryParameters(mScreenState);
3965 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery();
3966 mDeviceHost.enableDiscovery(params, shouldRestart);
3967
nxpandroid5d64ce92016-11-18 19:48:53 +05303968 Intent swpReaderDeActivatedIntent = new Intent();
nxpandroid64fd68c2015-09-23 16:45:15 +05303969
3970 //broadcast SWP_READER_DEACTIVATED evt
nxpandroid5d64ce92016-11-18 19:48:53 +05303971 swpReaderDeActivatedIntent
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05303972 .setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_STOP_SUCCESS);
nxpandroid64fd68c2015-09-23 16:45:15 +05303973 if (DBG) {
3974 Log.d(TAG, "SWP READER - DeActivated");
3975 }
nxpandroid5d64ce92016-11-18 19:48:53 +05303976 mContext.sendBroadcast(swpReaderDeActivatedIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05303977
3978 Log.d(TAG, "etsiStopConfig : setEtsiReaederState");
3979 mDeviceHost.setEtsiReaederState(STATE_SE_RDR_MODE_STOPPED);
3980
nxpandroid64fd68c2015-09-23 16:45:15 +05303981 ETSI_STOP_CONFIG = false;
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05303982 updateLastScreenState();
nxpandroid64fd68c2015-09-23 16:45:15 +05303983
3984 Log.d(TAG, "etsiStopConfig Exit");
3985 }
3986
3987 void sendMessage(int what, Object obj) {
3988 Message msg = mHandler.obtainMessage();
3989 msg.what = what;
3990 msg.obj = obj;
3991 mHandler.sendMessage(msg);
3992 }
3993
3994 final class NfcServiceHandler extends Handler {
3995 @Override
3996 public void handleMessage(Message msg) {
3997 switch (msg.what) {
3998 case MSG_ROUTE_AID: {
3999 int route = msg.arg1;
4000 int power = msg.arg2;
nxpandroidcbf24822017-07-12 21:37:17 +05304001 int aidInfo = 0x00;
4002 Bundle dataBundle = msg.getData();
4003 if (dataBundle != null)
4004 aidInfo = dataBundle.getInt("aidinfo");
nxpandroid64fd68c2015-09-23 16:45:15 +05304005 String aid = (String) msg.obj;
nxpandroidcbf24822017-07-12 21:37:17 +05304006 String cuttedAid = aid;
4007 if(aid.endsWith("*")||aid.endsWith("#")) {
4008 cuttedAid = aid.substring(0, aid.length() - 1);
nxpandroid64fd68c2015-09-23 16:45:15 +05304009 }
nxpandroidcbf24822017-07-12 21:37:17 +05304010 mDeviceHost.routeAid(hexStringToBytes(cuttedAid), route, power, aidInfo);
nxpandroid64fd68c2015-09-23 16:45:15 +05304011 // Restart polling config
4012 break;
4013 }
nxpandroid34627bd2016-05-27 15:52:30 +05304014 case MSG_REGISTER_T3T_IDENTIFIER: {
4015 Log.d(TAG, "message to register LF_T3T_IDENTIFIER");
4016 mDeviceHost.disableDiscovery();
4017
4018 byte[] t3tIdentifier = (byte[]) msg.obj;
4019 mDeviceHost.registerT3tIdentifier(t3tIdentifier);
4020
4021 NfcDiscoveryParameters params = computeDiscoveryParameters(mScreenState);
4022 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery();
4023 mDeviceHost.enableDiscovery(params, shouldRestart);
4024 break;
4025 }
4026 case MSG_DEREGISTER_T3T_IDENTIFIER: {
4027 Log.d(TAG, "message to deregister LF_T3T_IDENTIFIER");
4028 mDeviceHost.disableDiscovery();
4029
4030 byte[] t3tIdentifier = (byte[]) msg.obj;
4031 mDeviceHost.deregisterT3tIdentifier(t3tIdentifier);
4032
4033 NfcDiscoveryParameters params = computeDiscoveryParameters(mScreenState);
4034 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery();
4035 mDeviceHost.enableDiscovery(params, shouldRestart);
4036 break;
4037 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304038 case MSG_INVOKE_BEAM: {
4039 mP2pLinkManager.onManualBeamInvoke((BeamShareData)msg.obj);
4040 break;
4041 }
nxpandroida5fd6622017-07-31 16:15:18 +05304042
nxpandroid64fd68c2015-09-23 16:45:15 +05304043 case MSG_UNROUTE_AID: {
4044 String aid = (String) msg.obj;
4045 mDeviceHost.unrouteAid(hexStringToBytes(aid));
4046 break;
4047 }
4048
nxpandroid64fd68c2015-09-23 16:45:15 +05304049 case MSG_COMMITINF_FELICA_ROUTING: {
4050 Log.e(TAG, "applyRouting -10");
4051 mIsFelicaOnHostConfiguring = true;
4052 applyRouting(true);
4053 break;
4054 }
4055
4056 case MSG_COMMITED_FELICA_ROUTING: {
4057 Log.e(TAG, "applyRouting -11");
4058 mIsFelicaOnHostConfigured = true;
4059 applyRouting(true);
4060 break;
4061 }
4062
nxpandroid64fd68c2015-09-23 16:45:15 +05304063 case MSG_COMMIT_ROUTING: {
4064 Log.e(TAG, "applyRouting -9");
4065 boolean commit = false;
nxpandroid07d1cc22017-09-14 12:20:58 +05304066 boolean enForced = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05304067 synchronized (NfcService.this) {
4068 if (mCurrentDiscoveryParameters.shouldEnableDiscovery()) {
4069 commit = true;
nxpandroid07d1cc22017-09-14 12:20:58 +05304070 }else if(mAidRoutingManager.isRoutingTableUpdated()){
4071 commit = true;
4072 enForced = true;
4073 Log.d(TAG, "Routing table is updated thus needs to be committed.");
4074 }
4075 else {
nxpandroid64fd68c2015-09-23 16:45:15 +05304076 Log.d(TAG, "Not committing routing because discovery is disabled.");
4077 }
4078 }
4079 if (commit) {
4080 mIsRoutingTableDirty = true;
nxpandroid07d1cc22017-09-14 12:20:58 +05304081 applyRouting(enForced);
nxpandroid64fd68c2015-09-23 16:45:15 +05304082 }
4083
4084
4085 break;
4086 }
4087 case MSG_CLEAR_ROUTING: {
4088 mDeviceHost.clearAidTable();
4089 break;
4090 }
4091
4092 case MSG_CHANGE_DEFAULT_ROUTE:
4093 Log.d(TAG, "Handler: Change default route");
4094 try{
4095 mNxpNfcAdapter.DefaultRouteSet(ROUTE_ID_HOST, true, false, false);
4096 } catch(RemoteException re) {
4097 Log.d(TAG, "NxpNci: onAidRoutingTableFull: Exception to change default route to host!");
4098 }
4099 break;
4100
4101 case MSG_MOCK_NDEF: {
4102 NdefMessage ndefMsg = (NdefMessage) msg.obj;
4103 Bundle extras = new Bundle();
4104 extras.putParcelable(Ndef.EXTRA_NDEF_MSG, ndefMsg);
4105 extras.putInt(Ndef.EXTRA_NDEF_MAXLENGTH, 0);
4106 extras.putInt(Ndef.EXTRA_NDEF_CARDSTATE, Ndef.NDEF_MODE_READ_ONLY);
4107 extras.putInt(Ndef.EXTRA_NDEF_TYPE, Ndef.TYPE_OTHER);
4108 Tag tag = Tag.createMockTag(new byte[]{0x00},
4109 new int[]{TagTechnology.NDEF},
4110 new Bundle[]{extras});
4111 Log.d(TAG, "mock NDEF tag, starting corresponding activity");
4112 Log.d(TAG, tag.toString());
4113 int dispatchStatus = mNfcDispatcher.dispatchTag(tag);
4114 if (dispatchStatus == NfcDispatcher.DISPATCH_SUCCESS) {
4115 playSound(SOUND_END);
4116 } else if (dispatchStatus == NfcDispatcher.DISPATCH_FAIL) {
4117 playSound(SOUND_ERROR);
4118 }
4119 break;
4120 }
4121
4122 case MSG_SE_DELIVER_INTENT: {
4123 Log.d(TAG, "SE DELIVER INTENT");
4124 Intent seIntent = (Intent) msg.obj;
4125
4126 String action = seIntent.getAction();
4127 if (action.equals("com.gsma.services.nfc.action.TRANSACTION_EVENT")) {
4128 byte[] byteAid = seIntent.getByteArrayExtra("com.android.nfc_extras.extra.AID");
4129 byte[] data = seIntent.getByteArrayExtra("com.android.nfc_extras.extra.DATA");
Ganesh Deva2c027052018-08-07 15:18:32 +05304130 String seName = seIntent.getStringExtra("com.android.nfc_extras.extra.SECURE_ELEMENT_NAME");
nxpandroid64fd68c2015-09-23 16:45:15 +05304131 StringBuffer strAid = new StringBuffer();
4132 for (int i = 0; i < byteAid.length; i++) {
4133 String hex = Integer.toHexString(0xFF & byteAid[i]);
4134 if (hex.length() == 1)
4135 strAid.append('0');
4136 strAid.append(hex);
4137 }
4138 Intent gsmaIntent = new Intent();
4139 gsmaIntent.setAction("com.gsma.services.nfc.action.TRANSACTION_EVENT");
4140 if (byteAid != null)
4141 gsmaIntent.putExtra("com.gsma.services.nfc.extra.AID", byteAid);
4142 if (data != null)
4143 gsmaIntent.putExtra("com.gsma.services.nfc.extra.DATA", data);
4144
4145 //"nfc://secure:0/<seName>/<strAid>"
4146 String url = new String ("nfc://secure:0/" + seName + "/" + strAid);
4147 gsmaIntent.setData(Uri.parse(url));
4148 gsmaIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
4149 gsmaIntent.setPackage(seIntent.getPackage());
4150
4151 Boolean receptionMode = mNxpNfcController.mMultiReceptionMap.get(seName);
4152 if (receptionMode == null)
4153 receptionMode = defaultTransactionEventReceptionMode;
4154
4155 if (receptionMode == multiReceptionMode) {
4156 // if multicast reception for GSMA
4157 mContext.sendBroadcast(gsmaIntent);
4158 } else {
4159 // if unicast reception for GSMA
4160 try {
4161 if (mIsSentUnicastReception == false) {
4162 //start gsma
4163 gsmaIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4164 mContext.startActivity(gsmaIntent);
4165 mIsSentUnicastReception = true;
4166 }
4167 } catch (Exception e) {
4168 if (DBG) Log.d(TAG, "Exception: " + e.getMessage());
4169 }
4170 }
4171 } else {
4172 mContext.sendBroadcast(seIntent);
4173 }
4174 break;
4175 }
4176
4177 case MSG_NDEF_TAG:
4178 if (DBG) Log.d(TAG, "Tag detected, notifying applications");
Suhas Suresh31963a02018-04-25 12:14:23 +05304179 mPowerManager.userActivity(SystemClock.uptimeMillis(),
4180 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0);
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304181 mNumTagsDetected.incrementAndGet();
nxpandroid64fd68c2015-09-23 16:45:15 +05304182 TagEndpoint tag = (TagEndpoint) msg.obj;
nxpandroid281eb922016-08-25 20:27:46 +05304183 byte[] debounceTagUid;
4184 int debounceTagMs;
4185 ITagRemovedCallback debounceTagRemovedCallback;
4186 synchronized (NfcService.this) {
4187 debounceTagUid = mDebounceTagUid;
4188 debounceTagMs = mDebounceTagDebounceMs;
4189 debounceTagRemovedCallback = mDebounceTagRemovedCallback;
4190 }
nxpandroid281eb922016-08-25 20:27:46 +05304191
nxpandroid64fd68c2015-09-23 16:45:15 +05304192 ReaderModeParams readerParams = null;
4193 int presenceCheckDelay = DEFAULT_PRESENCE_CHECK_DELAY;
4194 DeviceHost.TagDisconnectedCallback callback =
4195 new DeviceHost.TagDisconnectedCallback() {
4196 @Override
4197 public void onTagDisconnected(long handle) {
nxpandroid03323c82017-09-14 11:13:16 +05304198 if(nci_version != NCI_VERSION_2_0) {
4199 applyRouting(false);
4200 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304201 }
4202 };
4203 synchronized (NfcService.this) {
4204 readerParams = mReaderModeParams;
4205 }
4206 if (readerParams != null) {
4207 presenceCheckDelay = readerParams.presenceCheckDelay;
4208 if ((readerParams.flags & NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK) != 0) {
4209 if (DBG) Log.d(TAG, "Skipping NDEF detection in reader mode");
4210 tag.startPresenceChecking(presenceCheckDelay, callback);
4211 dispatchTagEndpoint(tag, readerParams);
4212 break;
4213 }
4214 }
4215
nxpandroid64fd68c2015-09-23 16:45:15 +05304216 if (tag.getConnectedTechnology() == TagTechnology.NFC_BARCODE) {
4217 // When these tags start containing NDEF, they will require
4218 // the stack to deal with them in a different way, since
4219 // they are activated only really shortly.
4220 // For now, don't consider NDEF on these.
4221 if (DBG) Log.d(TAG, "Skipping NDEF detection for NFC Barcode");
4222 tag.startPresenceChecking(presenceCheckDelay, callback);
4223 dispatchTagEndpoint(tag, readerParams);
4224 break;
4225 }
4226 NdefMessage ndefMsg = tag.findAndReadNdef();
4227
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304228 if (ndefMsg == null) {
4229 // First try to see if this was a bad tag read
4230 if (!tag.reconnect()) {
nxpandroid64fd68c2015-09-23 16:45:15 +05304231 tag.disconnect();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304232 break;
nxpandroid64fd68c2015-09-23 16:45:15 +05304233 }
4234 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304235
4236 if (debounceTagUid != null) {
4237 // If we're debouncing and the UID or the NDEF message of the tag match,
4238 // don't dispatch but drop it.
4239 if (Arrays.equals(debounceTagUid, tag.getUid()) ||
4240 (ndefMsg != null && ndefMsg.equals(mLastReadNdefMessage))) {
4241 mHandler.removeMessages(MSG_TAG_DEBOUNCE);
4242 mHandler.sendEmptyMessageDelayed(MSG_TAG_DEBOUNCE, debounceTagMs);
4243 tag.disconnect();
4244 return;
4245 } else {
4246 synchronized (NfcService.this) {
4247 mDebounceTagUid = null;
4248 mDebounceTagRemovedCallback = null;
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +05304249 mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE;
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304250 }
4251 if (debounceTagRemovedCallback != null) {
4252 try {
4253 debounceTagRemovedCallback.onTagRemoved();
4254 } catch (RemoteException e) {
4255 // Ignore
4256 }
4257 }
4258 }
4259 }
4260
4261 mLastReadNdefMessage = ndefMsg;
4262
4263 tag.startPresenceChecking(presenceCheckDelay, callback);
4264 dispatchTagEndpoint(tag, readerParams);
nxpandroid64fd68c2015-09-23 16:45:15 +05304265 break;
4266
nxpandroid64fd68c2015-09-23 16:45:15 +05304267 case MSG_CONNECTIVITY_EVENT:
4268 if (DBG) {
4269 Log.d(TAG, "SE EVENT CONNECTIVITY");
4270 }
4271 Integer evtSrcInfo = (Integer) msg.obj;
4272 Log.d(TAG, "Event source " + evtSrcInfo);
4273 String evtSrc = "";
4274 if(evtSrcInfo == UICC_ID_TYPE) {
4275 evtSrc = NxpConstants.UICC_ID;
nxpandroid7d44e572016-08-01 19:11:04 +05304276 } else if(evtSrcInfo == UICC2_ID_TYPE) {
4277 evtSrc = NxpConstants.UICC2_ID;
nxpandroid64fd68c2015-09-23 16:45:15 +05304278 } else if(evtSrcInfo == SMART_MX_ID_TYPE) {
4279 evtSrc = NxpConstants.SMART_MX_ID;
4280 }
4281
4282 Intent eventConnectivityIntent = new Intent();
4283 eventConnectivityIntent.setAction(NxpConstants.ACTION_CONNECTIVITY_EVENT_DETECTED);
4284 eventConnectivityIntent.putExtra(NxpConstants.EXTRA_SOURCE, evtSrc);
4285 if (DBG) {
4286 Log.d(TAG, "Broadcasting Intent");
4287 }
4288 mContext.sendBroadcast(eventConnectivityIntent, NfcPermissions.NFC_PERMISSION);
4289 break;
4290
4291 case MSG_EMVCO_MULTI_CARD_DETECTED_EVENT:
4292 if (DBG) {
4293 Log.d(TAG, "EMVCO MULTI CARD DETECTED EVENT");
4294 }
4295
4296 Intent eventEmvcoMultiCardIntent = new Intent();
4297 eventEmvcoMultiCardIntent.setAction(ACTION_EMVCO_MULTIPLE_CARD_DETECTED);
4298 if (DBG) {
4299 Log.d(TAG, "Broadcasting Intent");
4300 }
4301 mContext.sendBroadcast(eventEmvcoMultiCardIntent, NFC_PERM);
4302 break;
4303
4304 case MSG_SE_EMV_CARD_REMOVAL:
4305 if (DBG) Log.d(TAG, "Card Removal message");
4306 /* Send broadcast */
4307 Intent cardRemovalIntent = new Intent();
4308 cardRemovalIntent.setAction(ACTION_EMV_CARD_REMOVAL);
4309 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_EMV_CARD_REMOVAL);
4310 sendSeBroadcast(cardRemovalIntent);
4311 break;
4312
4313 case MSG_SE_APDU_RECEIVED:
4314 if (DBG) Log.d(TAG, "APDU Received message");
4315 byte[] apduBytes = (byte[]) msg.obj;
4316 /* Send broadcast */
4317 Intent apduReceivedIntent = new Intent();
4318 apduReceivedIntent.setAction(ACTION_APDU_RECEIVED);
4319 if (apduBytes != null && apduBytes.length > 0) {
4320 apduReceivedIntent.putExtra(EXTRA_APDU_BYTES, apduBytes);
4321 }
4322 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_APDU_RECEIVED);
4323 sendSeBroadcast(apduReceivedIntent);
4324 break;
4325
4326 case MSG_SE_MIFARE_ACCESS:
4327 if (DBG) Log.d(TAG, "MIFARE access message");
4328 /* Send broadcast */
4329 byte[] mifareCmd = (byte[]) msg.obj;
4330 Intent mifareAccessIntent = new Intent();
4331 mifareAccessIntent.setAction(ACTION_MIFARE_ACCESS_DETECTED);
4332 if (mifareCmd != null && mifareCmd.length > 1) {
4333 int mifareBlock = mifareCmd[1] & 0xff;
4334 if (DBG) Log.d(TAG, "Mifare Block=" + mifareBlock);
4335 mifareAccessIntent.putExtra(EXTRA_MIFARE_BLOCK, mifareBlock);
4336 }
4337 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_MIFARE_ACCESS_DETECTED);
4338 sendSeBroadcast(mifareAccessIntent);
4339 break;
4340
4341 case MSG_LLCP_LINK_ACTIVATION:
Suhas Suresh31963a02018-04-25 12:14:23 +05304342 mPowerManager.userActivity(SystemClock.uptimeMillis(),
4343 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0);
nxpandroid64fd68c2015-09-23 16:45:15 +05304344 if (mIsDebugBuild) {
4345 Intent actIntent = new Intent(ACTION_LLCP_UP);
4346 mContext.sendBroadcast(actIntent);
4347 }
4348 llcpActivated((NfcDepEndpoint) msg.obj);
4349 break;
4350
4351 case MSG_LLCP_LINK_DEACTIVATED:
4352 if (mIsDebugBuild) {
4353 Intent deactIntent = new Intent(ACTION_LLCP_DOWN);
4354 mContext.sendBroadcast(deactIntent);
4355 }
4356 NfcDepEndpoint device = (NfcDepEndpoint) msg.obj;
4357 boolean needsDisconnect = false;
4358
4359 Log.d(TAG, "LLCP Link Deactivated message. Restart polling loop.");
4360 synchronized (NfcService.this) {
4361 /* Check if the device has been already unregistered */
4362 if (mObjectMap.remove(device.getHandle()) != null) {
4363 /* Disconnect if we are initiator */
4364 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) {
4365 if (DBG) Log.d(TAG, "disconnecting from target");
4366 needsDisconnect = true;
4367 } else {
4368 if (DBG) Log.d(TAG, "not disconnecting from initiator");
4369 }
4370 }
4371 }
4372 if (needsDisconnect) {
4373 device.disconnect(); // restarts polling loop
4374 }
4375
4376 mP2pLinkManager.onLlcpDeactivated();
4377 break;
4378 case MSG_LLCP_LINK_FIRST_PACKET:
4379 mP2pLinkManager.onLlcpFirstPacketReceived();
4380 break;
4381 case MSG_TARGET_DESELECTED:
4382 /* Broadcast Intent Target Deselected */
4383 if (DBG) Log.d(TAG, "Target Deselected");
4384 Intent intent = new Intent();
4385 intent.setAction(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
4386 if (DBG) Log.d(TAG, "Broadcasting Intent");
4387 mContext.sendOrderedBroadcast(intent, NfcPermissions.NFC_PERMISSION);
4388 break;
4389
4390 case MSG_SE_FIELD_ACTIVATED: {
4391 if (DBG) Log.d(TAG, "SE FIELD ACTIVATED");
4392 Intent eventFieldOnIntent = new Intent();
4393 eventFieldOnIntent.setAction(ACTION_RF_FIELD_ON_DETECTED);
4394 sendSeBroadcast(eventFieldOnIntent);
4395 break;
4396 }
4397 case MSG_RESUME_POLLING:
4398 mNfcAdapter.resumePolling();
4399 break;
4400
4401 case MSG_SE_FIELD_DEACTIVATED: {
4402 if (DBG) Log.d(TAG, "SE FIELD DEACTIVATED");
4403 Intent eventFieldOffIntent = new Intent();
4404 eventFieldOffIntent.setAction(ACTION_RF_FIELD_OFF_DETECTED);
4405 sendSeBroadcast(eventFieldOffIntent);
4406 break;
4407 }
4408
4409 case MSG_SE_LISTEN_ACTIVATED: {
4410 if (DBG) Log.d(TAG, "SE LISTEN MODE ACTIVATED");
4411 Intent listenModeActivated = new Intent();
4412 listenModeActivated.setAction(ACTION_SE_LISTEN_ACTIVATED);
4413 sendSeBroadcast(listenModeActivated);
4414 break;
4415 }
4416
4417 case MSG_SE_LISTEN_DEACTIVATED: {
4418 if (DBG) Log.d(TAG, "SE LISTEN MODE DEACTIVATED");
4419 Intent listenModeDeactivated = new Intent();
4420 listenModeDeactivated.setAction(ACTION_SE_LISTEN_DEACTIVATED);
4421 sendSeBroadcast(listenModeDeactivated);
4422 break;
4423 }
4424
4425 case MSG_SWP_READER_REQUESTED:
4426
4427 /* Send broadcast ordered */
nxpandroid281eb922016-08-25 20:27:46 +05304428 Intent swpReaderRequestedIntent = new Intent();
nxpandroid64fd68c2015-09-23 16:45:15 +05304429 ArrayList<Integer> techList = (ArrayList<Integer>) msg.obj;
nxpandroid281eb922016-08-25 20:27:46 +05304430 Integer[] techs = techList.toArray(new Integer[techList.size()]);
4431 swpReaderRequestedIntent
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05304432 .setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_START_SUCCESS);
nxpandroid64fd68c2015-09-23 16:45:15 +05304433 if (DBG) {
4434 Log.d(TAG, "SWP READER - Requested");
4435 }
nxpandroid281eb922016-08-25 20:27:46 +05304436 mContext.sendBroadcast(swpReaderRequestedIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05304437 break;
4438
4439 case MSG_SWP_READER_REQUESTED_FAIL:
4440
4441 /* Send broadcast ordered */
nxpandroid281eb922016-08-25 20:27:46 +05304442 Intent swpReaderRequestedFailIntent = new Intent();
nxpandroid64fd68c2015-09-23 16:45:15 +05304443
nxpandroid281eb922016-08-25 20:27:46 +05304444 swpReaderRequestedFailIntent
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05304445 .setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_START_FAIL);
nxpandroid64fd68c2015-09-23 16:45:15 +05304446 if (DBG) {
4447 Log.d(TAG, "SWP READER - Requested Fail");
4448 }
nxpandroid281eb922016-08-25 20:27:46 +05304449 mContext.sendBroadcast(swpReaderRequestedFailIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05304450 break;
4451
nxpandroid64fd68c2015-09-23 16:45:15 +05304452 case MSG_ETSI_START_CONFIG:
4453 {
4454 Log.d(TAG, "NfcServiceHandler - MSG_ETSI_START_CONFIG");
4455 ArrayList<Integer> configList = (ArrayList<Integer>) msg.obj;
4456 int eeHandle;
4457 if(configList.contains(0x402))
4458 {
4459 eeHandle = 0x402;
4460 }
4461 else{
4462 eeHandle = 0x4C0;
4463 }
Pratap Reddy49abbe32018-03-27 16:51:59 +05304464 synchronized (NfcService.this) {
4465 etsiStartConfig(eeHandle);
4466 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304467 }
4468 break;
4469
4470 case MSG_ETSI_STOP_CONFIG:
4471
4472 Log.d(TAG, "NfcServiceHandler - MSG_ETSI_STOP_CONFIG");
4473
4474 etsiStopConfig((int)msg.obj);
4475 break;
4476
4477 case MSG_ETSI_SWP_TIMEOUT:
4478
4479 Log.d(TAG, "NfcServiceHandler - MSG_ETSI_SWP_TIMEOUT");
4480
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05304481 /* Send broadcast ordered */
4482 Intent swpReaderTimeoutIntent = new Intent();
nxpandroid64fd68c2015-09-23 16:45:15 +05304483
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05304484 swpReaderTimeoutIntent
4485 .setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_TIMEOUT);
4486 if (DBG) {
4487 Log.d(TAG, "SWP READER - Timeout");
4488 }
4489 mContext.sendBroadcast(swpReaderTimeoutIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05304490 break;
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05304491
4492 case MSG_SWP_READER_RESTART:
4493
4494 Log.d(TAG, "NfcServiceHandler - MSG_SWP_READER_RESTART");
4495
4496 /* Send broadcast ordered */
4497 Intent swpReaderRestartIntent = new Intent();
4498
4499 swpReaderRestartIntent
4500 .setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_RESTART);
4501 if (DBG) {
4502 Log.d(TAG, "SWP READER - RESTART");
4503 }
4504 mContext.sendBroadcast(swpReaderRestartIntent);
4505 break;
4506
nxpandroide66eb092017-07-12 21:36:08 +05304507 case MSG_APPLY_SCREEN_STATE:
nxpandroid64fd68c2015-09-23 16:45:15 +05304508
4509 mScreenState = (int)msg.obj;
Nikhil Chhabra20be8d92018-01-09 18:32:58 +05304510
4511 // If NFC is turning off, we shouldn't need any changes here
4512 synchronized (NfcService.this) {
4513 if (mState == NfcAdapter.STATE_TURNING_OFF)
4514 return;
4515 }
4516
nxpandroide66eb092017-07-12 21:36:08 +05304517 int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ?
4518 (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState;
Suhas Sureshd8a71d22017-11-06 18:48:14 +05304519 mDeviceHost.doSetScreenOrPowerState(screen_state_mask);
nxpandroide66eb092017-07-12 21:36:08 +05304520
Bhupendra Paware1c7ede2018-02-26 11:51:32 +05304521 if(nci_version != NCI_VERSION_2_0) {
4522 applyRouting(false);
4523 } else if(mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED
Suhas Sureshd8a71d22017-11-06 18:48:14 +05304524 || mNfcUnlockManager.isLockscreenPollingEnabled()) {
nxpandroide66eb092017-07-12 21:36:08 +05304525 applyRouting(false);
Suhas Sureshd8a71d22017-11-06 18:48:14 +05304526 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304527 break;
nxpandroid281eb922016-08-25 20:27:46 +05304528 case MSG_TAG_DEBOUNCE:
4529 // Didn't see the tag again, tag is gone
4530 ITagRemovedCallback tagRemovedCallback;
4531 synchronized (NfcService.this) {
4532 mDebounceTagUid = null;
4533 tagRemovedCallback = mDebounceTagRemovedCallback;
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304534 mDebounceTagRemovedCallback = null;
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +05304535 mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE;
nxpandroid281eb922016-08-25 20:27:46 +05304536 }
4537 if (tagRemovedCallback != null) {
4538 try {
4539 tagRemovedCallback.onTagRemoved();
4540 } catch (RemoteException e) {
4541 // Ignore
4542 }
4543 }
4544 break;
nxpandroid5d64ce92016-11-18 19:48:53 +05304545 case MSG_RESTART_WATCHDOG:
4546 int enable = msg.arg1;
4547 disableInternalwatchDog.cancel();
4548 try{
4549 disableInternalwatchDog.join();
4550 } catch (java.lang.InterruptedException e) {
4551 }
4552 disableInternalwatchDog = new WatchDogThread("disableInternal", ROUTING_WATCHDOG_MS);
4553 Log.d(TAG, "New Watchdog: WatchDog Thread ID is "+ disableInternalwatchDog.getId());
4554 disableInternalwatchDog.start();
4555 break;
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304556 case MSG_UPDATE_STATS:
4557 if (mNumTagsDetected.get() > 0) {
4558 MetricsLogger.count(mContext, TRON_NFC_TAG, mNumTagsDetected.get());
4559 mNumTagsDetected.set(0);
4560 }
4561 if (mNumHceDetected.get() > 0) {
4562 MetricsLogger.count(mContext, TRON_NFC_CE, mNumHceDetected.get());
4563 mNumHceDetected.set(0);
4564 }
4565 if (mNumP2pDetected.get() > 0) {
4566 MetricsLogger.count(mContext, TRON_NFC_P2P, mNumP2pDetected.get());
4567 mNumP2pDetected.set(0);
4568 }
4569 removeMessages(MSG_UPDATE_STATS);
4570 sendEmptyMessageDelayed(MSG_UPDATE_STATS, STATS_UPDATE_INTERVAL_MS);
4571 break;
nxpandroida5fd6622017-07-31 16:15:18 +05304572
4573 case MSG_ROUTE_APDU:{
4574 int route = msg.arg1;
4575 int power = msg.arg2;
4576 String apduData = null;
4577 String apduMask = null;
4578 Bundle dataBundle = msg.getData();
4579 if (dataBundle != null) {
4580 apduData = dataBundle.getString("apduData");
4581 apduMask = dataBundle.getString("apduMask");
4582 }
4583 // Send the APDU
4584 if(apduData != null && dataBundle != null)
4585 mDeviceHost.routeApduPattern(route, power, hexStringToBytes(apduData) ,hexStringToBytes(apduMask));
4586 break;
4587 }
4588 case MSG_UNROUTE_APDU: {
4589 String apdu = (String) msg.obj;
4590 mDeviceHost.unrouteApduPattern(hexStringToBytes(apdu));
4591 break;
4592 }
Suhas Sureshca6584b2018-04-27 17:17:22 +05304593 case MSG_TRANSACTION_EVENT:
4594 if (mCardEmulationManager != null) {
4595 mCardEmulationManager.onOffHostAidSelected();
4596 }
4597 byte[][] data = (byte[][]) msg.obj;
Suhas Suresh061c9b02018-05-15 17:45:06 +05304598 sendOffHostTransactionEvent(data[0], data[1], data[2]);
4599 break;
nxpandroid64fd68c2015-09-23 16:45:15 +05304600 default:
4601 Log.e(TAG, "Unknown message received");
4602 break;
4603 }
4604 }
4605
Suhas Suresh061c9b02018-05-15 17:45:06 +05304606 private void sendOffHostTransactionEvent(byte[] aid, byte[] data, byte[] readerByteArray) {
Suhas Suresh38249952018-05-18 00:03:00 +05304607
Ganesh Deva272ad052018-07-09 15:56:45 +05304608 if (!isSEServiceAvailable() || mNfcEventInstalledPackages.isEmpty()) {
Suhas Sureshca6584b2018-04-27 17:17:22 +05304609 return;
4610 }
Suhas Sureshca6584b2018-04-27 17:17:22 +05304611 try {
Suhas Suresh061c9b02018-05-15 17:45:06 +05304612 String reader = new String(readerByteArray, "UTF-8");
4613 String[] installedPackages = new String[mNfcEventInstalledPackages.size()];
Suhas Sureshca6584b2018-04-27 17:17:22 +05304614 boolean[] nfcAccess = mSEService.isNFCEventAllowed(reader, aid,
4615 mNfcEventInstalledPackages.toArray(installedPackages));
4616 if (nfcAccess == null) {
4617 return;
4618 }
4619 ArrayList<String> packages = new ArrayList<String>();
nxf38293fa39fab2018-07-23 15:50:08 +05304620 Intent intent = new Intent(NfcAdapter.ACTION_TRANSACTION_DETECTED);
Suhas Sureshca6584b2018-04-27 17:17:22 +05304621 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
Suhas Suresh061c9b02018-05-15 17:45:06 +05304622 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
nxf38293fa39fab2018-07-23 15:50:08 +05304623 intent.putExtra(NfcAdapter.EXTRA_AID, aid);
4624 intent.putExtra(NfcAdapter.EXTRA_DATA, data);
Ganesh Deva2c027052018-08-07 15:18:32 +05304625 intent.putExtra(NfcAdapter.EXTRA_SECURE_ELEMENT_NAME, reader);
Suhas Suresh061c9b02018-05-15 17:45:06 +05304626 StringBuilder aidString = new StringBuilder(aid.length);
4627 for (byte b : aid) {
4628 aidString.append(String.format("%02X", b));
4629 }
4630 String url = new String ("nfc://secure:0/" + reader + "/" + aidString.toString());
4631 intent.setData(Uri.parse(url));
Suhas Sureshca6584b2018-04-27 17:17:22 +05304632 for (int i = 0; i < nfcAccess.length; i++) {
4633 if (nfcAccess[i]) {
Suhas Suresh140f7ac2018-05-15 14:59:11 +05304634 intent.setPackage(mNfcEventInstalledPackages.get(i));
Suhas Sureshca6584b2018-04-27 17:17:22 +05304635 mContext.sendBroadcast(intent);
4636 }
4637 }
4638 } catch (RemoteException e) {
4639 Log.e(TAG, "Error in isNFCEventAllowed() " + e);
Suhas Suresh061c9b02018-05-15 17:45:06 +05304640 } catch (UnsupportedEncodingException e) {
4641 Log.e(TAG, "Incorrect format for Secure Element name" + e);
Suhas Sureshca6584b2018-04-27 17:17:22 +05304642 }
4643 }
4644
4645 /* Returns the list of packages that have access to NFC Events on any SE */
4646 private ArrayList<String> getSEAccessAllowedPackages() {
Ganesh Deva272ad052018-07-09 15:56:45 +05304647 if (!isSEServiceAvailable() || mNfcEventInstalledPackages.isEmpty()) {
Suhas Sureshca6584b2018-04-27 17:17:22 +05304648 return null;
4649 }
4650 String[] readers = null;
4651 try {
4652 readers = mSEService.getReaders();
4653 } catch (RemoteException e) {
4654 Log.e(TAG, "Error in getReaders() " + e);
4655 return null;
4656 }
4657
4658 if (readers == null || readers.length == 0) {
4659 return null;
4660 }
4661 boolean[] nfcAccessFinal = null;
4662 String[] installedPackages = new String[mNfcEventInstalledPackages.size()];
4663 for (String reader : readers) {
4664 try {
4665 boolean[] accessList = mSEService.isNFCEventAllowed(reader, null,
4666 mNfcEventInstalledPackages.toArray(installedPackages));
4667 if (accessList == null) {
4668 continue;
4669 }
4670 if (nfcAccessFinal == null) {
4671 nfcAccessFinal = accessList;
4672 }
4673 for (int i = 0; i < accessList.length; i++) {
4674 if (accessList[i]) {
4675 nfcAccessFinal[i] = true;
4676 }
4677 }
4678 } catch (RemoteException e) {
4679 Log.e(TAG, "Error in isNFCEventAllowed() " + e);
4680 }
4681 }
4682 if (nfcAccessFinal == null) {
4683 return null;
4684 }
4685 ArrayList<String> packages = new ArrayList<String>();
4686 for (int i = 0; i < nfcAccessFinal.length; i++) {
4687 if (nfcAccessFinal[i]) {
Suhas Suresh140f7ac2018-05-15 14:59:11 +05304688 packages.add(mNfcEventInstalledPackages.get(i));
Suhas Sureshca6584b2018-04-27 17:17:22 +05304689 }
4690 }
4691 return packages;
4692 }
4693
nxpandroid64fd68c2015-09-23 16:45:15 +05304694 private void sendSeBroadcast(Intent intent) {
4695 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
4696 // Resume app switches so the receivers can start activites without delay
4697 mNfcDispatcher.resumeAppSwitches();
nxpandroida51b5bd2017-04-10 18:28:21 +05304698 Log.d(TAG, "NFCINTENT sendNfcEeAccessProtectedBroadcast");
nxpandroid64fd68c2015-09-23 16:45:15 +05304699 synchronized(this) {
Suhas Sureshca6584b2018-04-27 17:17:22 +05304700 ArrayList<String> SEPackages = getSEAccessAllowedPackages();
4701 if (SEPackages!= null && !SEPackages.isEmpty()) {
4702 for (String packageName : SEPackages) {
nxpandroid64fd68c2015-09-23 16:45:15 +05304703 intent.setPackage(packageName);
nxpandroida51b5bd2017-04-10 18:28:21 +05304704 Log.d(TAG, "NFCINTENT SENT TO PACKAGE" + packageName);
nxpandroid64fd68c2015-09-23 16:45:15 +05304705 mContext.sendBroadcast(intent);
4706 }
Suhas Sureshca6584b2018-04-27 17:17:22 +05304707 }
Suhas Suresh140f7ac2018-05-15 14:59:11 +05304708 PackageManager pm = mContext.getPackageManager();
4709 for (String packageName : mNfcEventInstalledPackages) {
4710 try {
4711 PackageInfo info = pm.getPackageInfo(packageName, 0);
4712 if (SEPackages != null && SEPackages.contains(packageName)) {
4713 continue;
4714 }
4715 if (info.applicationInfo != null &&
4716 ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 ||
4717 (info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0)) {
4718 intent.setPackage(packageName);
4719 mContext.sendBroadcast(intent);
4720 }
4721 } catch (Exception e) {
4722 Log.e(TAG, "Exception in getPackageInfo " + e);
nxpandroid64fd68c2015-09-23 16:45:15 +05304723 }
4724 }
4725 }
4726 }
4727
4728 private void sendMultiEvtBroadcast(Intent intent) {
4729
4730 ArrayList<String> packageList = mNxpNfcController.getEnabledMultiEvtsPackageList();
nxpandroida9a68ba2016-01-14 21:12:17 +05304731 ComponentName unicastComponent = null;
nxpandroid64fd68c2015-09-23 16:45:15 +05304732 if(packageList.size() == 0) {
4733 Log.d(TAG, "No packages to send broadcast.");
nxpandroida9a68ba2016-01-14 21:12:17 +05304734 unicastComponent = mNxpNfcController.getUnicastPackage();
4735 if(unicastComponent != null)
4736 {
4737 intent.setComponent(unicastComponent);
4738 try {
4739 //start gsma
4740 Log.d(TAG, "Starting activity uincast Pkg"+unicastComponent.flattenToString());
4741 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
4742 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4743 if(mContext.getPackageManager().resolveActivity(intent, 0) != null)
4744 {
nxpandroid5d64ce92016-11-18 19:48:53 +05304745 mContext.startActivityAsUser(intent, UserHandle.CURRENT);
nxpandroida9a68ba2016-01-14 21:12:17 +05304746 } else {
4747 Log.d(TAG, "Intent not resolved");
4748 }
4749 } catch (Exception e) {
4750 if (DBG) Log.d(TAG, "Exception: " + e.getMessage());
4751 }
4752 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304753 return;
4754 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304755 for(int i=0; i<packageList.size(); i++) {
4756 Log.d(TAG,"MultiEvt Enabled Application packageName: " + packageList.get(i));
4757 intent.setPackage(packageList.get(i));
nxpandroid5d64ce92016-11-18 19:48:53 +05304758 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT,
4759 NxpConstants.PERMISSIONS_TRANSACTION_EVENT);
nxpandroid64fd68c2015-09-23 16:45:15 +05304760 }
4761 }
4762
4763 private boolean llcpActivated(NfcDepEndpoint device) {
4764 Log.d(TAG, "LLCP Activation message");
4765
4766 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) {
4767 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_TARGET");
4768 if (device.connect()) {
4769 /* Check LLCP compliance */
4770 if (mDeviceHost.doCheckLlcp()) {
4771 /* Activate LLCP Link */
4772 if (mDeviceHost.doActivateLlcp()) {
4773 if (DBG) Log.d(TAG, "Initiator Activate LLCP OK");
4774 synchronized (NfcService.this) {
4775 // Register P2P device
4776 mObjectMap.put(device.getHandle(), device);
4777 }
nxpandroid1153eb32015-11-06 18:46:58 +05304778 mP2pLinkManager.onLlcpActivated(device.getLlcpVersion());
nxpandroid64fd68c2015-09-23 16:45:15 +05304779 return true;
4780 } else {
4781 /* should not happen */
4782 Log.w(TAG, "Initiator LLCP activation failed. Disconnect.");
4783 device.disconnect();
4784 }
4785 } else {
4786 if (DBG) Log.d(TAG, "Remote Target does not support LLCP. Disconnect.");
4787 device.disconnect();
4788 }
4789 } else {
4790 if (DBG) Log.d(TAG, "Cannot connect remote Target. Polling loop restarted.");
4791 /*
4792 * The polling loop should have been restarted in failing
4793 * doConnect
4794 */
4795 }
4796 } else if (device.getMode() == NfcDepEndpoint.MODE_P2P_INITIATOR) {
4797 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_INITIATOR");
4798 /* Check LLCP compliancy */
4799 if (mDeviceHost.doCheckLlcp()) {
4800 /* Activate LLCP Link */
4801 if (mDeviceHost.doActivateLlcp()) {
4802 if (DBG) Log.d(TAG, "Target Activate LLCP OK");
4803 synchronized (NfcService.this) {
4804 // Register P2P device
4805 mObjectMap.put(device.getHandle(), device);
4806 }
nxpandroid1153eb32015-11-06 18:46:58 +05304807 mP2pLinkManager.onLlcpActivated(device.getLlcpVersion());
nxpandroid64fd68c2015-09-23 16:45:15 +05304808 return true;
4809 }
4810 } else {
4811 Log.w(TAG, "checkLlcp failed");
4812 }
4813 }
4814
4815 return false;
4816 }
4817
4818 private void dispatchTagEndpoint(TagEndpoint tagEndpoint, ReaderModeParams readerParams) {
4819 Tag tag = new Tag(tagEndpoint.getUid(), tagEndpoint.getTechList(),
4820 tagEndpoint.getTechExtras(), tagEndpoint.getHandle(), mNfcTagService);
4821 registerTagObject(tagEndpoint);
4822 if (readerParams != null) {
4823 try {
4824 if ((readerParams.flags & NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS) == 0) {
Suhas Suresh6e05ee02018-04-25 12:19:35 +05304825 mVibrator.vibrate(mVibrationEffect);
nxpandroid64fd68c2015-09-23 16:45:15 +05304826 playSound(SOUND_END);
4827 }
4828 if (readerParams.callback != null) {
4829 readerParams.callback.onTagDiscovered(tag);
4830 return;
4831 } else {
4832 // Follow normal dispatch below
4833 }
4834 } catch (RemoteException e) {
4835 Log.e(TAG, "Reader mode remote has died, falling back.", e);
4836 // Intentional fall-through
4837 } catch (Exception e) {
4838 // Catch any other exception
4839 Log.e(TAG, "App exception, not dispatching.", e);
4840 return;
4841 }
4842 }
4843 int dispatchResult = mNfcDispatcher.dispatchTag(tag);
4844 if (dispatchResult == NfcDispatcher.DISPATCH_FAIL) {
4845 unregisterObject(tagEndpoint.getHandle());
4846 playSound(SOUND_ERROR);
4847 } else if (dispatchResult == NfcDispatcher.DISPATCH_SUCCESS) {
Suhas Suresh6e05ee02018-04-25 12:19:35 +05304848 mVibrator.vibrate(mVibrationEffect);
nxpandroid64fd68c2015-09-23 16:45:15 +05304849 playSound(SOUND_END);
4850 }
4851 }
4852 }
4853
4854 private NfcServiceHandler mHandler = new NfcServiceHandler();
4855
4856 class ApplyRoutingTask extends AsyncTask<Integer, Void, Void> {
4857 @Override
4858 protected Void doInBackground(Integer... params) {
4859 synchronized (NfcService.this) {
4860 if (params == null || params.length != 1) {
4861 // force apply current routing
4862 Log.e(TAG, "applyRouting -1");
4863 applyRouting(true);
4864 return null;
4865 }
4866 mScreenState = params[0].intValue();
nxpandroid64fd68c2015-09-23 16:45:15 +05304867 mRoutingWakeLock.acquire();
4868 try {
4869 Log.e(TAG, "applyRouting -2");
4870 applyRouting(false);
4871 } finally {
4872 mRoutingWakeLock.release();
4873 }
4874 return null;
4875 }
4876 }
4877 }
4878
Pratap Reddy49abbe32018-03-27 16:51:59 +05304879 class EtsiStopConfigTask extends AsyncTask<Integer, Void, Void> {
nxpandroid64fd68c2015-09-23 16:45:15 +05304880 @Override
4881 protected Void doInBackground(Integer... params) {
Pratap Reddy49abbe32018-03-27 16:51:59 +05304882 synchronized (NfcService.this) {
4883 etsiStopConfig(params[0].intValue());
nxpandroid64fd68c2015-09-23 16:45:15 +05304884 return null;
Pratap Reddy49abbe32018-03-27 16:51:59 +05304885 }
4886 }
4887 }
4888
4889 class TagRemoveTaskTimer extends TimerTask {
4890 public void run()
4891 {
4892 Intent swpReaderTagRemoveIntent = new Intent();
4893 swpReaderTagRemoveIntent.setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_REMOVE_CARD);
4894 if (DBG) {
4895 Log.d(TAG, "SWP READER - Tag Remove");
4896 }
4897 mContext.sendBroadcast(swpReaderTagRemoveIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05304898 }
4899 }
4900
4901
4902 private final BroadcastReceiver x509CertificateReceiver = new BroadcastReceiver() {
4903 @Override
4904 public void onReceive(Context context, Intent intent) {
4905 boolean result = intent.getBooleanExtra(NxpConstants.EXTRA_RESULT, false);
4906 mNxpNfcController.setResultForCertificates(result);
4907 }
4908 };
4909
4910 private final BroadcastReceiver mEnableNfc = new BroadcastReceiver() {
4911 @Override
4912 public void onReceive(Context context, Intent intent) {
4913 String action = intent.getAction();
4914 Intent nfcDialogIntent = new Intent(mContext, EnableNfcDialogActivity.class);
4915 nfcDialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
4916 mContext.startActivityAsUser(nfcDialogIntent, UserHandle.CURRENT);
4917 }
4918 };
4919
Shashank vimal83779082018-02-06 18:10:31 +05304920 private final BroadcastReceiver mActivateSwpInterface = new BroadcastReceiver() {
4921 @Override
4922 public void onReceive(Context context, Intent intent) {
4923
4924 String action = intent.getAction();
4925
4926 if(NxpConstants.CAT_ACTIVATE_NOTIFY_ACTION.equals(action)){
4927
4928 Log.i(TAG, "Received ACTIVATE intent:" + action);
4929
4930 if(mSelectedSeId != ALL_SE_ID_TYPE){
4931 mDeviceHost.doSelectSecureElement(mSelectedSeId);
4932 Log.i(TAG, "Activated:" + mSelectedSeId);
4933 }
4934 else{
4935 int[] seList = mDeviceHost.doGetSecureElementList();
4936 Log.i(TAG, "Activating all SE:");
4937
4938 for(int i = 0; i < seList.length; i++){
4939 mDeviceHost.doActivateSecureElement(seList[i]);
4940 try{
4941 //Delay between two SE selection
4942 Thread.sleep(200);
4943 }catch(Exception e){
4944 e.printStackTrace();
4945 }
4946 }
4947 }
4948 }
4949 }
4950 };
4951
4952
nxpandroid64fd68c2015-09-23 16:45:15 +05304953 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
4954 @Override
4955 public void onReceive(Context context, Intent intent) {
4956 String action = intent.getAction();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304957 Log.e(TAG, "screen state "+action);
nxpandroid64fd68c2015-09-23 16:45:15 +05304958 if (action.equals(
4959 NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) {
4960 // Perform applyRouting() in AsyncTask to serialize blocking calls
4961 new ApplyRoutingTask().execute();
4962 } else if ((action.equals(Intent.ACTION_SCREEN_ON)
4963 || action.equals(Intent.ACTION_SCREEN_OFF)
4964 || action.equals(Intent.ACTION_USER_PRESENT)) &&
4965 mState == NfcAdapter.STATE_ON) {
4966 // Perform applyRouting() in AsyncTask to serialize blocking calls
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304967 int screenState = mScreenStateHelper.checkScreenState();
nxpandroid64fd68c2015-09-23 16:45:15 +05304968 if (action.equals(Intent.ACTION_SCREEN_OFF)) {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304969 if(mScreenState != ScreenStateHelper.SCREEN_STATE_OFF_LOCKED)
nxpandroid64fd68c2015-09-23 16:45:15 +05304970 {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304971 Log.e(TAG, "screen state OFF required");
4972 screenState = mKeyguard.isKeyguardLocked() ?
4973 ScreenStateHelper.SCREEN_STATE_OFF_LOCKED :
4974 ScreenStateHelper.SCREEN_STATE_OFF_UNLOCKED;
nxpandroid64fd68c2015-09-23 16:45:15 +05304975 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304976 } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
4977 screenState = mKeyguard.isKeyguardLocked() ?
4978 ScreenStateHelper.SCREEN_STATE_ON_LOCKED : ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED;
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304979 Log.e(TAG, "screen state on");
4980 /*
nxpandroid64fd68c2015-09-23 16:45:15 +05304981 if(screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mScreenState == ScreenStateHelper.SCREEN_STATE_OFF) {
nxpandroid64fd68c2015-09-23 16:45:15 +05304982 } else if (screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mScreenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED) {
4983 return;
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304984 }*/
nxpandroid64fd68c2015-09-23 16:45:15 +05304985 } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
4986 if (mScreenState != ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304987 Log.e(TAG, "screen state user present");
nxpandroid64fd68c2015-09-23 16:45:15 +05304988 screenState = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED;
nxpandroid64fd68c2015-09-23 16:45:15 +05304989 } else {
4990 return;
4991 }
4992 }
Bhupendra Paware1c7ede2018-02-26 11:51:32 +05304993 /* This piece of code is duplicate as MSG_APPLY_SCREEN_STATE
4994 is already calling applyRouting api */
4995 /*if(nci_version != NCI_VERSION_2_0) {
nxpandroide66eb092017-07-12 21:36:08 +05304996 new ApplyRoutingTask().execute(Integer.valueOf(screenState));
Bhupendra Paware1c7ede2018-02-26 11:51:32 +05304997 }*/
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05304998
4999 if( mDeviceHost.getEtsiReaederState() == STATE_SE_RDR_MODE_STOPPED ||
5000 mDeviceHost.getEtsiReaederState() == STATE_SE_RDR_MODE_INVALID) {
5001 sendMessage(NfcService.MSG_APPLY_SCREEN_STATE, screenState);
5002 } else {
5003 Log.e(TAG, "mPOS in progress holding screen state "+screenState);
5004 mScreenState = screenState;
5005 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305006 Log.e(TAG, "screen state "+screenState);
5007 Log.e(TAG, "screen state mScreenState "+mScreenState);
nxpandroid64fd68c2015-09-23 16:45:15 +05305008 } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305009 int screenState = mScreenStateHelper.checkScreenState();
nxpandroid64fd68c2015-09-23 16:45:15 +05305010 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
Suhas Sureshe2a2ff02018-04-27 12:21:19 +05305011 int beamSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5012 try {
5013 IPackageManager mIpm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
5014 beamSetting = mIpm.getComponentEnabledSetting(new ComponentName(
5015 BeamShareActivity.class.getPackageName$(),
5016 BeamShareActivity.class.getName()),
5017 userId);
5018 } catch(RemoteException e) {
5019 Log.e(TAG, "Error int getComponentEnabledSetting for BeamShareActivity");
5020 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305021 synchronized (this) {
5022 mUserId = userId;
Suhas Sureshe2a2ff02018-04-27 12:21:19 +05305023 if (beamSetting == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
5024 mIsNdefPushEnabled = false;
5025 } else {
5026 mIsNdefPushEnabled = true;
5027 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305028 }
5029 mP2pLinkManager.onUserSwitched(getUserId());
5030 if (mIsHceCapable) {
5031 mCardEmulationManager.onUserSwitched(getUserId());
5032 }
nxpandroide66eb092017-07-12 21:36:08 +05305033 screenState = mScreenStateHelper.checkScreenState();
nxpandroid64fd68c2015-09-23 16:45:15 +05305034 new ApplyRoutingTask().execute(Integer.valueOf(screenState));
nxpandroid64fd68c2015-09-23 16:45:15 +05305035 }
5036 }
5037 };
5038
5039 private final BroadcastReceiver mOwnerReceiver = new BroadcastReceiver() {
5040 @Override
5041 public void onReceive(Context context, Intent intent) {
5042 String action = intent.getAction();
5043 if (action.equals(Intent.ACTION_PACKAGE_REMOVED) ||
5044 action.equals(Intent.ACTION_PACKAGE_ADDED) ||
5045 action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE) ||
5046 action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) {
5047 updatePackageCache();
5048
nxpandroid5d64ce92016-11-18 19:48:53 +05305049 } else if(action.equals(Intent.ACTION_SHUTDOWN)) {
5050 mPowerShutDown = true;
5051 if (DBG) Log.d(TAG,"Device is shutting down.");
5052 mDeviceHost.doSetScreenOrPowerState(ScreenStateHelper.POWER_STATE_OFF);
Suhas Suresh9139dc22018-05-09 15:48:37 +05305053 if (isNfcEnabled()) {
5054 mDeviceHost.shutdown();
5055 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305056 }
5057 }
5058 };
5059
nxpandroid64fd68c2015-09-23 16:45:15 +05305060 private final BroadcastReceiver mPolicyReceiver = new BroadcastReceiver() {
5061 @Override
5062 public void onReceive(Context context, Intent intent){
5063 String action = intent.getAction();
5064 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
5065 .equals(action)) {
5066 enforceBeamShareActivityPolicy(context,
Suhas Suresha18dee02018-04-27 15:28:04 +05305067 new UserHandle(getSendingUserId()));
nxpandroid64fd68c2015-09-23 16:45:15 +05305068 }
5069 }
5070 };
5071
Nikhil Chhabrafc8f3f62018-01-08 20:48:49 +05305072 private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
5073 @Override
5074 public void onVrStateChanged(boolean enabled) {
5075 synchronized (this) {
5076 mIsVrModeEnabled = enabled;
5077 }
5078 }
5079 };
5080
nxpandroid64fd68c2015-09-23 16:45:15 +05305081 /**
nxpandroid64fd68c2015-09-23 16:45:15 +05305082 * for debugging only - no i18n
5083 */
5084 static String stateToString(int state) {
5085 switch (state) {
5086 case NfcAdapter.STATE_OFF:
5087 return "off";
5088 case NfcAdapter.STATE_TURNING_ON:
5089 return "turning on";
5090 case NfcAdapter.STATE_ON:
5091 return "on";
5092 case NfcAdapter.STATE_TURNING_OFF:
5093 return "turning off";
5094 default:
5095 return "<error>";
5096 }
5097 }
5098
5099 void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
5100 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
5101 != PackageManager.PERMISSION_GRANTED) {
5102 pw.println("Permission Denial: can't dump nfc from from pid="
5103 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5104 + " without permission " + android.Manifest.permission.DUMP);
5105 return;
5106 }
5107
5108 synchronized (this) {
5109 pw.println("mState=" + stateToString(mState));
5110 pw.println("mIsZeroClickRequested=" + mIsNdefPushEnabled);
5111 pw.println("mScreenState=" + ScreenStateHelper.screenStateToString(mScreenState));
5112 pw.println("mNfcPollingEnabled=" + mNfcPollingEnabled);
5113 pw.println("mNfceeRouteEnabled=" + mNfceeRouteEnabled);
5114 pw.println("mOpenEe=" + mOpenEe);
nxpandroid64fd68c2015-09-23 16:45:15 +05305115 pw.println("mLockscreenPollMask=" + mLockscreenPollMask);
5116 pw.println(mCurrentDiscoveryParameters);
5117 mP2pLinkManager.dump(fd, pw, args);
5118 if (mIsHceCapable) {
5119 mCardEmulationManager.dump(fd, pw, args);
5120 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305121 mNfcDispatcher.dump(fd, pw, args);
Nikhil Chhabra9645ab62018-01-09 18:44:05 +05305122 pw.flush();
Nikhil Chhabra1e1ac462018-01-10 12:53:43 +05305123 mDeviceHost.dump(fd);
nxpandroid64fd68c2015-09-23 16:45:15 +05305124
5125 }
5126 }
nxpandroid34627bd2016-05-27 15:52:30 +05305127 /**
5128 * Update the status of all the services which were populated to commit to routing table
5129 */
5130 public void updateStatusOfServices(boolean commitStatus) {
nxpandroidebf53fb2016-12-22 18:48:59 +05305131 if(commitStatus == true)
5132 {
5133 mAidCache.setPreviousPreferredPaymentService(null);
5134 }
nxpandroid34627bd2016-05-27 15:52:30 +05305135 mCardEmulationManager.updateStatusOfServices(commitStatus);
5136 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305137}