blob: 10f97ad1aaa2829ff4d2a0d0736a774d31638c0f [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
nxpandroid64fd68c2015-09-23 16:45:15 +053051import android.content.pm.IPackageManager;
52import android.content.pm.PackageInfo;
nxpandroid64fd68c2015-09-23 16:45:15 +053053import android.content.pm.PackageManager;
54import android.content.pm.UserInfo;
55import android.content.res.Resources.NotFoundException;
56import android.media.AudioManager;
57import android.media.SoundPool;
58import android.net.Uri;
59import android.nfc.BeamShareData;
60import android.nfc.ErrorCodes;
61import android.nfc.FormatException;
62import android.nfc.IAppCallback;
63import android.nfc.INfcAdapter;
64import android.nfc.INfcAdapterExtras;
65import android.nfc.INfcCardEmulation;
nxpandroid34627bd2016-05-27 15:52:30 +053066import android.nfc.INfcFCardEmulation;
nxpandroid64fd68c2015-09-23 16:45:15 +053067import android.nfc.INfcTag;
68import android.nfc.INfcUnlockHandler;
nxpandroid281eb922016-08-25 20:27:46 +053069import android.nfc.ITagRemovedCallback;
nxpandroid64fd68c2015-09-23 16:45:15 +053070import android.nfc.NdefMessage;
71import android.nfc.NfcAdapter;
72import android.nfc.Tag;
73import android.nfc.TechListParcel;
74import android.nfc.TransceiveResult;
75import android.nfc.tech.Ndef;
76import android.nfc.tech.TagTechnology;
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +053077import android.nfc.INfcDta;
nxpandroid64fd68c2015-09-23 16:45:15 +053078import android.os.AsyncTask;
79import android.os.Binder;
80import android.os.Build;
81import android.os.Bundle;
82import android.os.Handler;
83import android.os.IBinder;
84import android.os.Message;
85import android.os.PowerManager;
86import android.os.Process;
87import android.os.RemoteException;
88import android.os.ServiceManager;
89import android.os.SystemClock;
Nikhil Chhabraa9e399a2018-01-09 11:47:13 +053090import android.os.SystemProperties;
nxpandroid64fd68c2015-09-23 16:45:15 +053091import android.os.UserHandle;
92import android.os.UserManager;
93import android.provider.Settings;
Nikhil Chhabrafc8f3f62018-01-08 20:48:49 +053094import android.service.vr.IVrManager;
95import android.service.vr.IVrStateCallbacks;
nxpandroid64fd68c2015-09-23 16:45:15 +053096import android.util.Log;
97
nxpandroid6fd9cdb2017-07-12 18:25:41 +053098import com.android.internal.logging.MetricsLogger;
nxpandroid64fd68c2015-09-23 16:45:15 +053099import com.android.nfc.DeviceHost.DeviceHostListener;
100import com.android.nfc.DeviceHost.LlcpConnectionlessSocket;
101import com.android.nfc.DeviceHost.LlcpServerSocket;
102import com.android.nfc.DeviceHost.LlcpSocket;
103import com.android.nfc.DeviceHost.NfcDepEndpoint;
104import com.android.nfc.DeviceHost.TagEndpoint;
105
106import com.android.nfc.dhimpl.NativeNfcSecureElement;
107import com.android.nfc.dhimpl.NativeNfcAla;
108import java.security.MessageDigest;
109
110import android.widget.Toast;
111
112import com.android.nfc.cardemulation.AidRoutingManager;
113import com.android.nfc.cardemulation.CardEmulationManager;
nxpandroidebf53fb2016-12-22 18:48:59 +0530114import com.android.nfc.cardemulation.RegisteredAidCache;
nxpandroid64fd68c2015-09-23 16:45:15 +0530115import com.android.nfc.dhimpl.NativeNfcManager;
116import com.android.nfc.handover.HandoverDataParser;
117
118import java.io.FileDescriptor;
119import java.io.PrintWriter;
nxpandroid34627bd2016-05-27 15:52:30 +0530120import java.nio.ByteBuffer;
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530121import java.util.concurrent.atomic.AtomicInteger;
nxpandroid64fd68c2015-09-23 16:45:15 +0530122import java.io.InputStream;
123import java.io.OutputStream;
124import java.io.FileInputStream;
125import java.io.FileOutputStream;
126import java.io.File;
nxpandroid281eb922016-08-25 20:27:46 +0530127import java.io.FileWriter;
nxpandroid64fd68c2015-09-23 16:45:15 +0530128import java.io.BufferedReader;
129import java.io.FileReader;
130import java.util.Arrays;
131import java.util.ArrayList;
132import java.util.HashMap;
133import java.util.List;
134import java.util.Map;
135import java.util.NoSuchElementException;
136import java.io.IOException;
137import java.io.FileNotFoundException;
nxpandroid3649b762017-02-24 15:44:54 +0530138
nxpandroid64fd68c2015-09-23 16:45:15 +0530139import android.util.Pair;
140import java.util.HashSet;
nxpandroid64fd68c2015-09-23 16:45:15 +0530141import java.util.concurrent.ExecutionException;
142
143import com.nxp.nfc.INxpNfcAdapter;
144import com.nxp.intf.ILoaderService;
145import com.nxp.intf.IJcopService;
146import com.nxp.intf.INxpExtrasService;
147import com.nxp.intf.IeSEClientServicesAdapter;
nxpandroid64fd68c2015-09-23 16:45:15 +0530148import com.nxp.nfc.INfcVzw;
149import com.nxp.nfc.INxpNfcAdapterExtras;
150import com.nxp.nfc.INxpNfcAccessExtras;
nxpandroid64fd68c2015-09-23 16:45:15 +0530151import com.nxp.nfc.NxpConstants;
152import com.vzw.nfc.RouteEntry;
153import com.gsma.nfc.internal.NxpNfcController;
154import com.nxp.nfc.gsma.internal.INxpNfcController;
155
Shashank vimal83779082018-02-06 18:10:31 +0530156
nxpandroid64fd68c2015-09-23 16:45:15 +0530157public class NfcService implements DeviceHostListener {
158 private static final String ACTION_MASTER_CLEAR_NOTIFICATION = "android.intent.action.MASTER_CLEAR_NOTIFICATION";
159
160 static final boolean DBG = true;
161 static final String TAG = "NfcService";
162
163 public static final String SERVICE_NAME = "nfc";
164
165 /** Regular NFC permission */
166 private static final String NFC_PERM = android.Manifest.permission.NFC;
167 private static final String NFC_PERM_ERROR = "NFC permission required";
168
169 public static final String PREF = "NfcServicePrefs";
nxpandroida9a68ba2016-01-14 21:12:17 +0530170 public static final String NXP_PREF = "NfcServiceNxpPrefs";
nxpandroid64fd68c2015-09-23 16:45:15 +0530171
172 static final String PREF_NFC_ON = "nfc_on";
173 static final boolean NFC_ON_DEFAULT = true;
174 static final String PREF_NDEF_PUSH_ON = "ndef_push_on";
175 static final boolean NDEF_PUSH_ON_DEFAULT = true;
176 static final String PREF_FIRST_BEAM = "first_beam";
177 static final String PREF_FIRST_BOOT = "first_boot";
nxpandroid64fd68c2015-09-23 16:45:15 +0530178 private static final String PREF_SECURE_ELEMENT_ON = "secure_element_on";
179 private boolean SECURE_ELEMENT_ON_DEFAULT = false;
180 private int SECURE_ELEMENT_ID_DEFAULT = 0;
nxpandroidebf53fb2016-12-22 18:48:59 +0530181 private int SECURE_ELEMENT_UICC_SLOT_DEFAULT = 1;
nxpandroid64fd68c2015-09-23 16:45:15 +0530182 private static final String PREF_DEFAULT_ROUTE_ID = "default_route_id";
183 private static final String PREF_MIFARE_DESFIRE_PROTO_ROUTE_ID = "mifare_desfire_proto_route";
184 private static final String PREF_SET_DEFAULT_ROUTE_ID ="set_default_route";
185 private static final String PREF_MIFARE_CLT_ROUTE_ID= "mifare_clt_route";
nxpandroidf1f54f52017-07-31 16:08:06 +0530186 private static final String LS_BACKUP_PATH = "/data/vendor/nfc/ls_backup.txt";
187 private static final String LS_UPDATE_BACKUP_PATH = "/data/vendor/nfc/loaderservice_updater.txt";
188 private static final String LS_UPDATE_BACKUP_OUT_PATH = "/data/vendor/nfc/loaderservice_updater_out.txt";
nxpandroid64fd68c2015-09-23 16:45:15 +0530189
nxpandroidf1f54f52017-07-31 16:08:06 +0530190 private static final String[] path = {"/data/vendor/nfc/JcopOs_Update1.apdu",
191 "/data/vendor/nfc/JcopOs_Update2.apdu",
192 "/data/vendor/nfc/JcopOs_Update3.apdu"};
nxpandroid64fd68c2015-09-23 16:45:15 +0530193
194 private static final String[] PREF_JCOP_MODTIME = {"jcop file1 modtime",
195 "jcop file2 modtime",
196 "jcop file3 modtime"};
197 private static final long[] JCOP_MODTIME_DEFAULT = {-1,-1,-1};
198 private static final long[] JCOP_MODTIME_TEMP = {-1,-1,-1};
199
200 private boolean ETSI_STOP_CONFIG = false;
nxpandroid7d44e572016-08-01 19:11:04 +0530201 private int ROUTE_ID_HOST = 0x00;
202 private int ROUTE_ID_SMX = 0x01;
203 private int ROUTE_ID_UICC = 0x02;
204 private int ROUTE_ID_UICC2 = 0x04;
nxpandroid64fd68c2015-09-23 16:45:15 +0530205
206 private int ROUTE_SWITCH_ON = 0x01;
207 private int ROUTE_SWITCH_OFF = 0x02;
208 private int ROUTE_BATT_OFF= 0x04;
209
210 private int TECH_TYPE_A= 0x01;
211 private int TECH_TYPE_B= 0x02;
212 private int TECH_TYPE_F= 0x04;
213
214 //TODO: Refer L_OSP_EXT [PN547C2]
215// private int DEFAULT_ROUTE_ID_DEFAULT = AidRoutingManager.DEFAULT_ROUTE;
216 private int DEFAULT_ROUTE_ID_DEFAULT = 0x00;
217 static final boolean SE_BROADCASTS_WITH_HCE = true;
218
219 private static final String PREF_SECURE_ELEMENT_ID = "secure_element_id";
nxpandroidebf53fb2016-12-22 18:48:59 +0530220 private static final String PREF_CUR_SELECTED_UICC_ID = "current_selected_uicc_id";
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530221 public static final int ROUTE_LOC_MASK=8;
222 public static final int TECH_TYPE_MASK=11;
223
224 static final String TRON_NFC_CE = "nfc_ce";
225 static final String TRON_NFC_P2P = "nfc_p2p";
226 static final String TRON_NFC_TAG = "nfc_tag";
nxpandroid64fd68c2015-09-23 16:45:15 +0530227
228 static final int MSG_NDEF_TAG = 0;
229 static final int MSG_CARD_EMULATION = 1;
230 static final int MSG_LLCP_LINK_ACTIVATION = 2;
231 static final int MSG_LLCP_LINK_DEACTIVATED = 3;
232 static final int MSG_TARGET_DESELECTED = 4;
233 static final int MSG_MOCK_NDEF = 7;
234 static final int MSG_SE_FIELD_ACTIVATED = 8;
235 static final int MSG_SE_FIELD_DEACTIVATED = 9;
236 static final int MSG_SE_APDU_RECEIVED = 10;
237 static final int MSG_SE_EMV_CARD_REMOVAL = 11;
238 static final int MSG_SE_MIFARE_ACCESS = 12;
239 static final int MSG_SE_LISTEN_ACTIVATED = 13;
240 static final int MSG_SE_LISTEN_DEACTIVATED = 14;
241 static final int MSG_LLCP_LINK_FIRST_PACKET = 15;
242 static final int MSG_ROUTE_AID = 16;
243 static final int MSG_UNROUTE_AID = 17;
244 static final int MSG_COMMIT_ROUTING = 18;
245 static final int MSG_INVOKE_BEAM = 19;
246
247 static final int MSG_SWP_READER_REQUESTED = 20;
248 static final int MSG_SWP_READER_ACTIVATED = 21;
249 static final int MSG_SWP_READER_DEACTIVATED = 22;
250 static final int MSG_CLEAR_ROUTING = 23;
251 static final int MSG_SET_SCREEN_STATE = 25;
252
253
254 static final int MSG_RF_FIELD_ACTIVATED = 26;
255 static final int MSG_RF_FIELD_DEACTIVATED = 27;
256 static final int MSG_RESUME_POLLING = 28;
257 static final int MSG_SWP_READER_REQUESTED_FAIL =29 ;
258 static final int MSG_SWP_READER_TAG_PRESENT = 30;
259 static final int MSG_SWP_READER_TAG_REMOVE = 31;
260 static final int MSG_CONNECTIVITY_EVENT = 40;
261 static final int MSG_VZW_ROUTE_AID = 41;
262 static final int MSG_VZW_COMMIT_ROUTING = 42;
263 static final int MSG_ROUTE_NFCID2 = 43;
264 static final int MSG_UNROUTE_NFCID2 = 44;
265 static final int MSG_COMMITINF_FELICA_ROUTING = 45;
266 static final int MSG_COMMITED_FELICA_ROUTING = 46;
267 static final int MSG_EMVCO_MULTI_CARD_DETECTED_EVENT = 47;
268 static final int MSG_ETSI_START_CONFIG = 48;
269 static final int MSG_ETSI_STOP_CONFIG = 49;
270 static final int MSG_ETSI_SWP_TIMEOUT = 50;
nxpandroide66eb092017-07-12 21:36:08 +0530271 static final int MSG_APPLY_SCREEN_STATE = 51;
nxpandroid34627bd2016-05-27 15:52:30 +0530272 static final int MSG_REGISTER_T3T_IDENTIFIER = 54;
273 static final int MSG_DEREGISTER_T3T_IDENTIFIER = 55;
nxpandroid281eb922016-08-25 20:27:46 +0530274 static final int MSG_TAG_DEBOUNCE = 56;
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530275 static final int MSG_UPDATE_STATS = 57;
nxpandroid5d64ce92016-11-18 19:48:53 +0530276 /*Restart Nfc disbale watchdog timer*/
277 static final int MSG_RESTART_WATCHDOG = 60;
nxpandroida5fd6622017-07-31 16:15:18 +0530278 static final int MSG_ROUTE_APDU = 61;
279 static final int MSG_UNROUTE_APDU = 62;
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530280 // Update stats every 4 hours
281 static final long STATS_UPDATE_INTERVAL_MS = 4 * 60 * 60 * 1000;
nxpandroid64fd68c2015-09-23 16:45:15 +0530282 static final long MAX_POLLING_PAUSE_TIMEOUT = 40000;
283 static final int TASK_ENABLE = 1;
284 static final int TASK_DISABLE = 2;
285 static final int TASK_BOOT = 3;
286 static final int TASK_EE_WIPE = 4;
nxpandroid1680a6d2017-01-13 19:13:14 +0530287 static final int TASK_RESTART = 0x1F;
nxpandroid64fd68c2015-09-23 16:45:15 +0530288 static final int MSG_CHANGE_DEFAULT_ROUTE = 52;
289 static final int MSG_SE_DELIVER_INTENT = 53;
290
291 // Copied from com.android.nfc_extras to avoid library dependency
292 // Must keep in sync with com.android.nfc_extras
293 static final int ROUTE_OFF = 1;
294 static final int ROUTE_ON_WHEN_SCREEN_ON = 2;
295
296 // Return values from NfcEe.open() - these are 1:1 mapped
297 // to the thrown EE_EXCEPTION_ exceptions in nfc-extras.
298 static final int EE_ERROR_IO = -1;
299 static final int EE_ERROR_ALREADY_OPEN = -2;
300 static final int EE_ERROR_INIT = -3;
301 static final int EE_ERROR_LISTEN_MODE = -4;
302 static final int EE_ERROR_EXT_FIELD = -5;
303 static final int EE_ERROR_NFC_DISABLED = -6;
304
305 // Polling technology masks
306 static final int NFC_POLL_A = 0x01;
307 static final int NFC_POLL_B = 0x02;
308 static final int NFC_POLL_F = 0x04;
Nikhil Chhabra288edb02018-01-10 19:36:21 +0530309 static final int NFC_POLL_V = 0x08;
nxpandroid64fd68c2015-09-23 16:45:15 +0530310 static final int NFC_POLL_B_PRIME = 0x10;
311 static final int NFC_POLL_KOVIO = 0x20;
312
313 // minimum screen state that enables NFC polling
314 static final int NFC_POLLING_MODE = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED;
315
316 // Time to wait for NFC controller to initialize before watchdog
317 // goes off. This time is chosen large, because firmware download
318 // may be a part of initialization.
319 static final int INIT_WATCHDOG_MS = 90000;
320 static final int INIT_WATCHDOG_LS_MS = 180000;
321 // Time to wait for routing to be applied before watchdog
322 // goes off
323 static final int ROUTING_WATCHDOG_MS = 10000;
324
325 // Amount of time to wait before closing the NFCEE connection
326 // in a disable/shutdown scenario.
327 static final int WAIT_FOR_NFCEE_OPERATIONS_MS = 5000;
328 // Polling interval for waiting on NFCEE operations
329 static final int WAIT_FOR_NFCEE_POLL_MS = 100;
330
331 // Default delay used for presence checks
332 static final int DEFAULT_PRESENCE_CHECK_DELAY = 125;
333
334 //Delay used for presence checks of NFC_F non-Ndef
335 //Make secure communication done or tranceive next request response command
336 //to pause timer before presence check command is sent
337 static final int NFC_F_TRANSCEIVE_PRESENCE_CHECK_DELAY = 500;
338
339 // The amount of time we wait before manually launching
340 // the Beam animation when called through the share menu.
341 static final int INVOKE_BEAM_DELAY_MS = 1000;
342 // for use with playSound()
343 public static final int SOUND_START = 0;
344 public static final int SOUND_END = 1;
345 public static final int SOUND_ERROR = 2;
346
nxpandroide66eb092017-07-12 21:36:08 +0530347 public static final int NCI_VERSION_2_0 = 0x20;
348
349 public static final int NCI_VERSION_1_0 = 0x10;
nxpandroid64fd68c2015-09-23 16:45:15 +0530350 //ETSI Reader Events
351 public static final int ETSI_READER_REQUESTED = 0;
352 public static final int ETSI_READER_START = 1;
353 public static final int ETSI_READER_STOP = 2;
354
355 //ETSI Reader Req States
356 public static final int STATE_SE_RDR_MODE_INVALID = 0x00;
357 public static final int STATE_SE_RDR_MODE_START_CONFIG = 0x01;
358 public static final int STATE_SE_RDR_MODE_START_IN_PROGRESS = 0x02;
359 public static final int STATE_SE_RDR_MODE_STARTED = 0x03;
360 public static final int STATE_SE_RDR_MODE_ACTIVATED = 0x04;
361 public static final int STATE_SE_RDR_MODE_STOP_CONFIG = 0x05;
362 public static final int STATE_SE_RDR_MODE_STOP_IN_PROGRESS = 0x06;
363 public static final int STATE_SE_RDR_MODE_STOPPED = 0x07;
364
nxpandroid281eb922016-08-25 20:27:46 +0530365 //Transit setconfig status
366 public static final int TRANSIT_SETCONFIG_STAT_SUCCESS = 0x00;
367 public static final int TRANSIT_SETCONFIG_STAT_FAILED = 0xFF;
368
nxpandroid64fd68c2015-09-23 16:45:15 +0530369 public static final String ACTION_RF_FIELD_ON_DETECTED =
370 "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED";
371 public static final String ACTION_RF_FIELD_OFF_DETECTED =
372 "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED";
373 public static final String ACTION_AID_SELECTED =
374 "com.android.nfc_extras.action.AID_SELECTED";
375 public static final String EXTRA_AID = "com.android.nfc_extras.extra.AID";
376
377 public static final String ACTION_LLCP_UP =
378 "com.android.nfc.action.LLCP_UP";
379
380 public static final String ACTION_LLCP_DOWN =
381 "com.android.nfc.action.LLCP_DOWN";
382
383 public static final String ACTION_APDU_RECEIVED =
384 "com.android.nfc_extras.action.APDU_RECEIVED";
385 public static final String EXTRA_APDU_BYTES =
386 "com.android.nfc_extras.extra.APDU_BYTES";
387
388 public static final String ACTION_EMV_CARD_REMOVAL =
389 "com.android.nfc_extras.action.EMV_CARD_REMOVAL";
390
391 public static final String ACTION_MIFARE_ACCESS_DETECTED =
392 "com.android.nfc_extras.action.MIFARE_ACCESS_DETECTED";
393 public static final String EXTRA_MIFARE_BLOCK =
394 "com.android.nfc_extras.extra.MIFARE_BLOCK";
395
396 public static final String ACTION_SE_LISTEN_ACTIVATED =
397 "com.android.nfc_extras.action.SE_LISTEN_ACTIVATED";
398 public static final String ACTION_SE_LISTEN_DEACTIVATED =
399 "com.android.nfc_extras.action.SE_LISTEN_DEACTIVATED";
400
401 public static final String ACTION_EMVCO_MULTIPLE_CARD_DETECTED =
402 "com.nxp.action.EMVCO_MULTIPLE_CARD_DETECTED";
403
nxpandroid34627bd2016-05-27 15:52:30 +0530404 public static final String ACTION_UICC_STATUS_RECEIVED =
405 "com.nxp.action.UICC_STATUS_RECEIVED";
406
nxpandroid1680a6d2017-01-13 19:13:14 +0530407 public static final String ACTION_FLASH_SUCCESS =
408 "com.android.nfc_extras.action.ACTION_FLASH_SUCCESS";
409
nxpandroid34627bd2016-05-27 15:52:30 +0530410 public static final String EXTRA_UICC_STATUS = "com.nxp.extra.UICC_STATUS";
411
nxpandroid64fd68c2015-09-23 16:45:15 +0530412 private static final String PACKAGE_SMART_CARD_SERVICE = "org.simalliance.openmobileapi.service";
413 /**
414 * SMART MX ID to be able to select it as the default Secure Element
415 */
416 public static final int SMART_MX_ID_TYPE = 1;
417
418 /**
419 * UICC ID to be able to select it as the default Secure Element
420 */
421 public static final int UICC_ID_TYPE = 2;
422
423 /**
nxpandroid7d44e572016-08-01 19:11:04 +0530424 * UICC2 ID to be able to select it as the default Secure Element
425 */
426 public static final int UICC2_ID_TYPE = 4;
427 /**
nxpandroid64fd68c2015-09-23 16:45:15 +0530428 * ID to be able to select all Secure Elements
429 */
nxpandroid0232af22017-07-12 21:40:33 +0530430 private static int ALL_SE_ID_TYPE = 7;
nxpandroid64fd68c2015-09-23 16:45:15 +0530431
432 public static final int PN547C2_ID = 1;
433 public static final int PN65T_ID = 2;
nxpandroidebf53fb2016-12-22 18:48:59 +0530434 public static final int PN548C2_ID = 3;
nxpandroid64fd68c2015-09-23 16:45:15 +0530435 public static final int PN66T_ID = 4;
nxpandroid34627bd2016-05-27 15:52:30 +0530436 public static final int PN551_ID = 5;
437 public static final int PN67T_ID = 6;
nxpandroid281eb922016-08-25 20:27:46 +0530438 public static final int PN553_ID = 7;
439 public static final int PN80T_ID = 8;
nxpandroid64fd68c2015-09-23 16:45:15 +0530440
441 public static final int LS_RETRY_CNT = 3;
nxpandroid5d3fdf82017-07-31 16:11:33 +0530442 public static final int LOADER_SERVICE_VERSION_LOW_LIMIT = 0x21;
443 public static final int LOADER_SERVICE_VERSION_HIGH_LIMIT = 0x24;
444
nxpandroid64fd68c2015-09-23 16:45:15 +0530445 private int mSelectedSeId = 0;
446 private boolean mNfcSecureElementState;
447 private boolean mIsSmartCardServiceSupported = false;
448 // Timeout to re-apply routing if a tag was present and we postponed it
449 private static final int APPLY_ROUTING_RETRY_TIMEOUT_MS = 5000;
450
Nikhil Chhabrad6957c72018-03-09 11:44:48 +0530451 // these states are for making enable and disable nfc atomic
452 private int NXP_NFC_STATE_OFF = 0;
453 private int NXP_NFC_STATE_TURNING_ON = 1;
454 private int NXP_NFC_STATE_ON = 2;
455 private int NXP_NFC_STATE_TURNING_OFF = 3;
456
nxpandroid64fd68c2015-09-23 16:45:15 +0530457 private final UserManager mUserManager;
nxpandroide66eb092017-07-12 21:36:08 +0530458 private static int nci_version = NCI_VERSION_1_0;
nxpandroid64fd68c2015-09-23 16:45:15 +0530459 // NFC Execution Environment
460 // fields below are protected by this
461 private NativeNfcSecureElement mSecureElement;
462 private OpenSecureElement mOpenEe; // null when EE closed
463 private final ReaderModeDeathRecipient mReaderModeDeathRecipient =
464 new ReaderModeDeathRecipient();
465 private final NfcUnlockManager mNfcUnlockManager;
466
467 private int mEeRoutingState; // contactless interface routing
468 private int mLockscreenPollMask;
469 List<PackageInfo> mInstalledPackages; // cached version of installed packages
470 private NativeNfcAla mNfcAla;
471
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530472 private final BackupManager mBackupManager;
473
nxpandroid64fd68c2015-09-23 16:45:15 +0530474 NfcAccessExtrasService mNfcAccessExtrasService;
475
476 // fields below are used in multiple threads and protected by synchronized(this)
477 final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>();
478 // mSePackages holds packages that accessed the SE, but only for the owner user,
479 // as SE access is not granted for non-owner users.
480 HashSet<String> mSePackages = new HashSet<String>();
481 int mScreenState;
nxf32288d12785b2017-11-17 15:18:31 +0530482 int mChipVer;
nxpandroid5d64ce92016-11-18 19:48:53 +0530483 boolean mIsTaskBoot = false;
nxpandroid64fd68c2015-09-23 16:45:15 +0530484 boolean mInProvisionMode; // whether we're in setup wizard and enabled NFC provisioning
485 boolean mIsNdefPushEnabled;
486 boolean mNfcPollingEnabled; // current Device Host state of NFC-C polling
487 boolean mHostRouteEnabled; // current Device Host state of host-based routing
488 boolean mReaderModeEnabled; // current Device Host state of reader mode
489 boolean mNfceeRouteEnabled; // current Device Host state of NFC-EE routing
490 NfcDiscoveryParameters mCurrentDiscoveryParameters =
491 NfcDiscoveryParameters.getNfcOffParameters();
492 ReaderModeParams mReaderModeParams;
nxpandroid281eb922016-08-25 20:27:46 +0530493 private int mUserId;
494 boolean mPollingPaused;
495
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +0530496 static final int INVALID_NATIVE_HANDLE = -1;
nxpandroid623a3632017-04-10 18:27:16 +0530497 byte[] mDebounceTagUid;
nxpandroid281eb922016-08-25 20:27:46 +0530498 int mDebounceTagDebounceMs;
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +0530499 int mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE;
nxpandroid281eb922016-08-25 20:27:46 +0530500 ITagRemovedCallback mDebounceTagRemovedCallback;
nxpandroid64fd68c2015-09-23 16:45:15 +0530501
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530502 // Only accessed on one thread so doesn't need locking
503 NdefMessage mLastReadNdefMessage;
504
505 // Metrics
506 AtomicInteger mNumTagsDetected;
507 AtomicInteger mNumP2pDetected;
508 AtomicInteger mNumHceDetected;
509
nxpandroid64fd68c2015-09-23 16:45:15 +0530510 // mState is protected by this, however it is only modified in onCreate()
511 // and the default AsyncTask thread so it is read unprotected from that
512 // thread
513 int mState; // one of NfcAdapter.STATE_ON, STATE_TURNING_ON, etc
Nikhil Chhabrad6957c72018-03-09 11:44:48 +0530514 int mNxpNfcState = NXP_NFC_STATE_OFF;
515
nxpandroid64fd68c2015-09-23 16:45:15 +0530516 boolean mPowerShutDown = false; // State for power shut down state
517
518 // fields below are final after onCreate()
519 Context mContext;
520 private DeviceHost mDeviceHost;
521 private SharedPreferences mPrefs;
nxpandroida9a68ba2016-01-14 21:12:17 +0530522 private SharedPreferences mNxpPrefs;
nxpandroid64fd68c2015-09-23 16:45:15 +0530523 private SharedPreferences.Editor mPrefsEditor;
nxpandroida9a68ba2016-01-14 21:12:17 +0530524 private SharedPreferences.Editor mNxpPrefsEditor;
nxpandroid64fd68c2015-09-23 16:45:15 +0530525 private PowerManager.WakeLock mRoutingWakeLock;
526 private PowerManager.WakeLock mEeWakeLock;
527
528 int mStartSound;
529 int mEndSound;
530 int mErrorSound;
531 SoundPool mSoundPool; // playback synchronized on this
532 P2pLinkManager mP2pLinkManager;
533 TagService mNfcTagService;
534 NfcAdapterService mNfcAdapter;
535 NfcAdapterExtrasService mExtrasService;
536// CardEmulationService mCardEmulationService;
537 NxpNfcAdapterService mNxpNfcAdapter;
538 NxpNfcAdapterExtrasService mNxpExtrasService;
539 NxpExtrasService mNxpExtras;
540 EseClientServicesAdapter mEseClientServicesAdapter;
nxpandroid64fd68c2015-09-23 16:45:15 +0530541 boolean mIsDebugBuild;
542 boolean mIsHceCapable;
nxpandroid34627bd2016-05-27 15:52:30 +0530543 boolean mIsHceFCapable;
nxpandroid64fd68c2015-09-23 16:45:15 +0530544 boolean mIsRoutingTableDirty;
545 boolean mIsFelicaOnHostConfigured;
546 boolean mIsFelicaOnHostConfiguring;
547
548 public boolean mIsRouteForced;
549 NfceeAccessControl mNfceeAccessControl;
550 NfcSccAccessControl mNfcSccAccessControl;
551 NfcSeAccessControl mNfcSeAccessControl;
552 NfcAlaService mAlaService;
553 NfcJcopService mJcopService;
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +0530554 NfcDtaService mNfcDtaService;
nxpandroid64fd68c2015-09-23 16:45:15 +0530555 NfcVzwService mVzwService;
556 private NfcDispatcher mNfcDispatcher;
557 private PowerManager mPowerManager;
558 private KeyguardManager mKeyguard;
559 ToastHandler mToastHandler;
560 private HandoverDataParser mHandoverDataParser;
561 private ContentResolver mContentResolver;
nxpandroidebf53fb2016-12-22 18:48:59 +0530562 private RegisteredAidCache mAidCache;
nxpandroid64fd68c2015-09-23 16:45:15 +0530563 private CardEmulationManager mCardEmulationManager;
564 private AidRoutingManager mAidRoutingManager;
nxpandroid64fd68c2015-09-23 16:45:15 +0530565 private ScreenStateHelper mScreenStateHelper;
566 private ForegroundUtils mForegroundUtils;
567 private boolean mClearNextTapDefault;
568 private NxpNfcController mNxpNfcController;
569
nxpandroid64fd68c2015-09-23 16:45:15 +0530570 private static NfcService sService;
nxpandroid281eb922016-08-25 20:27:46 +0530571 public static boolean sIsDtaMode = false;
572 public static boolean sIsShortRecordLayout = false;
573 public static boolean sAidTableFull = false;
nxpandroid5d64ce92016-11-18 19:48:53 +0530574 private WatchDogThread disableInternalwatchDog;
nxpandroid64fd68c2015-09-23 16:45:15 +0530575
576 //GSMA
577 private final Boolean defaultTransactionEventReceptionMode = Boolean.FALSE;
nxpandroid623a3632017-04-10 18:27:16 +0530578 private static final Boolean multiReceptionMode = Boolean.TRUE;
579 private static final Boolean unicastReceptionMode = Boolean.FALSE;
nxpandroid64fd68c2015-09-23 16:45:15 +0530580 boolean mIsSentUnicastReception = false;
581
582 public void enforceNfcSeAdminPerm(String pkg) {
583 if (pkg == null) {
584 throw new SecurityException("caller must pass a package name");
585 }
586 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
587 if (!mNfcSeAccessControl.check(Binder.getCallingUid(), pkg)) {
588 throw new SecurityException(NfcSeAccessControl.NFCSE_ACCESS_PATH +
589 " denies NFCSe access to " + pkg);
590 }
591 if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
592 throw new SecurityException("only the owner is allowed to act as SCC admin");
593 }
594 }
595 public void enforceNfceeAdminPerm(String pkg) {
596 if (pkg == null) {
597 throw new SecurityException("caller must pass a package name");
598 }
599 NfcPermissions.enforceUserPermissions(mContext);
600 if (!mNfceeAccessControl.check(Binder.getCallingUid(), pkg)) {
601 throw new SecurityException(NfceeAccessControl.NFCEE_ACCESS_PATH +
602 " denies NFCEE access to " + pkg);
603 }
604 if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
605 throw new SecurityException("only the owner is allowed to call SE APIs");
606 }
607 }
608
609
610 /* SCC Access Control */
611 public void enforceNfcSccAdminPerm(String pkg) {
612 if (pkg == null) {
613 throw new SecurityException("caller must pass a package name");
614 }
615 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
616 if (!mNfcSccAccessControl.check(Binder.getCallingUid(), pkg)) {
617 throw new SecurityException(NfcSccAccessControl.NFCSCC_ACCESS_PATH +
618 " denies NFCSCC access to " + pkg);
619 }
620 if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
621 throw new SecurityException("only the owner is allowed to act as SCC admin");
622 }
623 }
624
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530625 boolean mIsLiveCaseEnabled; // whether live cases are enabled
626 int mLiveCaseTechnology; // Technology mask of accepted NFC tags
627
Nikhil Chhabrafc8f3f62018-01-08 20:48:49 +0530628 private IVrManager vrManager;
629 boolean mIsVrModeEnabled;
630
nxpandroid64fd68c2015-09-23 16:45:15 +0530631 public static NfcService getInstance() {
632 return sService;
633 }
634
635 @Override
636 public void onRemoteEndpointDiscovered(TagEndpoint tag) {
637 sendMessage(NfcService.MSG_NDEF_TAG, tag);
638 }
639
640 public int getRemainingAidTableSize() {
641 return mDeviceHost.getRemainingAidTableSize();
642 }
643
nxpandroidebf53fb2016-12-22 18:48:59 +0530644 public boolean getLastCommitRoutingStatus() {
645 return mAidRoutingManager.getLastCommitRoutingStatus();
646 }
647
nxpandroid64fd68c2015-09-23 16:45:15 +0530648 public int getChipVer() {
649 return mDeviceHost.getChipVer();
650 }
651 /**
652 * Notifies Card emulation deselect
653 */
654 @Override
655 public void onCardEmulationDeselected() {
656 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
657 sendMessage(NfcService.MSG_TARGET_DESELECTED, null);
658 }
659 }
660
661 /**
662 * Notifies transaction
663 */
664 @Override
665 public void onCardEmulationAidSelected(byte[] aid, byte[] data, int evtSrc) {
666 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
667 Pair<byte[], Integer> dataSrc = new Pair<byte[], Integer>(data, evtSrc);
668 Pair<byte[], Pair> transactionInfo = new Pair<byte[], Pair>(aid, dataSrc);
669 Log.d(TAG, "onCardEmulationAidSelected : Source" + evtSrc);
670
671 sendMessage(NfcService.MSG_CARD_EMULATION, transactionInfo);
672 }
673 }
674
675 /**
676 * Notifies connectivity
677 */
678 @Override
679 public void onConnectivityEvent(int evtSrc) {
680 Log.d(TAG, "onConnectivityEvent : Source" + evtSrc);
681 sendMessage(NfcService.MSG_CONNECTIVITY_EVENT, evtSrc);
682 }
683
684 @Override
685 public void onEmvcoMultiCardDetectedEvent() {
686 Log.d(TAG, "onEmvcoMultiCardDetectedEvent");
687 sendMessage(NfcService.MSG_EMVCO_MULTI_CARD_DETECTED_EVENT,null);
688 }
689
690 /**
691 * Notifies transaction
692 */
693 @Override
nxpandroid34627bd2016-05-27 15:52:30 +0530694 public void onHostCardEmulationActivated(int technology) {
nxpandroid64fd68c2015-09-23 16:45:15 +0530695 if (mCardEmulationManager != null) {
nxpandroid34627bd2016-05-27 15:52:30 +0530696 mCardEmulationManager.onHostCardEmulationActivated(technology);
nxpandroid64fd68c2015-09-23 16:45:15 +0530697 }
698 }
699
700 @Override
701 public void onAidRoutingTableFull() {
702 Log.d(TAG, "NxpNci: onAidRoutingTableFull: AID Routing Table is FULL!");
nxpandroid281eb922016-08-25 20:27:46 +0530703 /*if((ROUTE_ID_HOST != GetDefaultRouteLoc())&&(sAidTableFull == false))
nxpandroid64fd68c2015-09-23 16:45:15 +0530704 {
705 Log.d(TAG, "NxpNci: onAidRoutingTableFull: Making Default Route to HOST!");
nxpandroid281eb922016-08-25 20:27:46 +0530706 sAidTableFull = true;
nxpandroid64fd68c2015-09-23 16:45:15 +0530707 mHandler.sendEmptyMessage(NfcService.MSG_CHANGE_DEFAULT_ROUTE);
708 }*/
709 if (mIsHceCapable) {
710 mAidRoutingManager.onNfccRoutingTableCleared();
711 mCardEmulationManager.onRoutingTableChanged();
712 }
713 }
714
715 @Override
nxpandroid5d64ce92016-11-18 19:48:53 +0530716 public void onNotifyT3tConfigure() {
717 if (mCardEmulationManager != null) {
718 mCardEmulationManager.onT3tConfigure();
719 }
720 }
721
722 @Override
723 public void onNotifyReRoutingEntry() {
724 if (mCardEmulationManager != null) {
725 mCardEmulationManager.onReRoutingEntry();
726 }
727 }
728
729 @Override
nxpandroid34627bd2016-05-27 15:52:30 +0530730 public void onHostCardEmulationData(int technology, byte[] data) {
nxpandroid64fd68c2015-09-23 16:45:15 +0530731 if (mCardEmulationManager != null) {
nxpandroid34627bd2016-05-27 15:52:30 +0530732 mCardEmulationManager.onHostCardEmulationData(technology, data);
nxpandroid64fd68c2015-09-23 16:45:15 +0530733 }
734 }
735
736 @Override
nxpandroid34627bd2016-05-27 15:52:30 +0530737 public void onHostCardEmulationDeactivated(int technology) {
nxpandroid64fd68c2015-09-23 16:45:15 +0530738 if (mCardEmulationManager != null) {
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530739 // Do metrics here so we don't slow the CE path down
740 mNumHceDetected.incrementAndGet();
nxpandroid34627bd2016-05-27 15:52:30 +0530741 mCardEmulationManager.onHostCardEmulationDeactivated(technology);
nxpandroid64fd68c2015-09-23 16:45:15 +0530742 }
743 }
744
745 /**
746 * Notifies P2P Device detected, to activate LLCP link
747 */
748 @Override
749 public void onLlcpLinkActivated(NfcDepEndpoint device) {
750 sendMessage(NfcService.MSG_LLCP_LINK_ACTIVATION, device);
751 }
752
753 /**
754 * Notifies P2P Device detected, to activate LLCP link
755 */
756 @Override
757 public void onLlcpLinkDeactivated(NfcDepEndpoint device) {
758 sendMessage(NfcService.MSG_LLCP_LINK_DEACTIVATED, device);
759 }
760
761 /**
762 * Notifies P2P Device detected, first packet received over LLCP link
763 */
764 @Override
765 public void onLlcpFirstPacketReceived(NfcDepEndpoint device) {
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530766 mNumP2pDetected.incrementAndGet();
nxpandroid64fd68c2015-09-23 16:45:15 +0530767 sendMessage(NfcService.MSG_LLCP_LINK_FIRST_PACKET, device);
768 }
769
770 @Override
771 public void onRemoteFieldActivated() {
772 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
773 sendMessage(NfcService.MSG_SE_FIELD_ACTIVATED, null);
774 }
775 }
776
777 @Override
778 public void onRemoteFieldDeactivated() {
779 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
780 sendMessage(NfcService.MSG_SE_FIELD_DEACTIVATED, null);
781 }
782 }
783
784 @Override
785 public void onSeListenActivated() {
786 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
787 sendMessage(NfcService.MSG_SE_LISTEN_ACTIVATED, null);
788 }
789 if (mIsHceCapable) {
nxpandroid34627bd2016-05-27 15:52:30 +0530790 mCardEmulationManager.onHostCardEmulationActivated(TagTechnology.NFC_A);
nxpandroid64fd68c2015-09-23 16:45:15 +0530791 }
792 }
793
794 @Override
795 public void onSeListenDeactivated() {
796 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
797 sendMessage(NfcService.MSG_SE_LISTEN_DEACTIVATED, null);
798 }
799 if( mIsHceCapable) {
nxpandroid34627bd2016-05-27 15:52:30 +0530800 mCardEmulationManager.onHostCardEmulationDeactivated(TagTechnology.NFC_A);
nxpandroid64fd68c2015-09-23 16:45:15 +0530801 }
802 }
803
nxpandroid64fd68c2015-09-23 16:45:15 +0530804 @Override
805 public void onSeApduReceived(byte[] apdu) {
806 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
807 sendMessage(NfcService.MSG_SE_APDU_RECEIVED, apdu);
808 }
809 }
810
811 @Override
812 public void onSeEmvCardRemoval() {
813 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
814 sendMessage(NfcService.MSG_SE_EMV_CARD_REMOVAL, null);
815 }
816 }
817
818 @Override
819 public void onSeMifareAccess(byte[] block) {
820 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
821 sendMessage(NfcService.MSG_SE_MIFARE_ACCESS, block);
822 }
823 }
824
825 @Override
826 public void onSWPReaderRequestedEvent(boolean istechA, boolean istechB)
827 {
828 int size=0;
829 ArrayList<Integer> techList = new ArrayList<Integer>();
830 if(istechA)
831 techList.add(TagTechnology.NFC_A);
832 if(istechB)
833 techList.add(TagTechnology.NFC_B);
834
835 sendMessage(NfcService.MSG_SWP_READER_REQUESTED , techList);
836 }
837
838 @Override
839 public void onSWPReaderRequestedFail(int FailCause)
840 {
841 sendMessage(NfcService.MSG_SWP_READER_REQUESTED_FAIL , FailCause);
842 }
843
844 @Override
845 public void onSWPReaderActivatedEvent()
846 {
847 sendMessage(NfcService.MSG_SWP_READER_ACTIVATED, null);
848 }
849
850 @Override
851 public void onETSIReaderModeStartConfig(int eeHandle)
852 {
853 ArrayList<Integer> configList = new ArrayList<Integer>();
854 configList.add(eeHandle);
855 sendMessage(NfcService.MSG_ETSI_START_CONFIG, configList);
856 }
857
858 @Override
859 public void onETSIReaderModeStopConfig(int disc_ntf_timeout)
860 {
861 sendMessage(NfcService.MSG_ETSI_STOP_CONFIG, disc_ntf_timeout);
862 }
863
864 @Override
865 public void onETSIReaderModeSwpTimeout(int disc_ntf_timeout)
866 {
867 sendMessage(NfcService.MSG_ETSI_SWP_TIMEOUT, disc_ntf_timeout);
868 }
869
nxpandroid34627bd2016-05-27 15:52:30 +0530870 @Override
871 public void onUiccStatusEvent(int uiccStat)
872 {
873 Log.i(TAG, "Broadcasting UICC Status : " + uiccStat);
874 Intent uiccStatusIntent = new Intent();
875 uiccStatusIntent.setAction(ACTION_UICC_STATUS_RECEIVED);
876 uiccStatusIntent.putExtra(EXTRA_UICC_STATUS, uiccStat);
877 mContext.sendBroadcast(uiccStatusIntent);
878 }
879
nxpandroid5d64ce92016-11-18 19:48:53 +0530880 @Override
881 public void onRestartWatchDog(int enable) {
882 Log.d(TAG, "Restart Watchdog: WatchDog Thread ID is "+ disableInternalwatchDog.getId());
883 sendMessage(NfcService.MSG_RESTART_WATCHDOG, enable);
884 }
nxpandroid1680a6d2017-01-13 19:13:14 +0530885 @Override
886 public void onFwDwnldReqRestartNfc() {
887 Log.d(TAG, "Restart NFC:When Fw dwnld request was stored during SPI onGoing");
888 new EnableDisableTask().execute(TASK_RESTART);
889 }
nxpandroid5d64ce92016-11-18 19:48:53 +0530890
nxpandroid64fd68c2015-09-23 16:45:15 +0530891 final class ReaderModeParams {
892 public int flags;
893 public IAppCallback callback;
894 public int presenceCheckDelay;
895 }
896
897 public NfcService(Application nfcApplication) {
898 mUserId = ActivityManager.getCurrentUser();
899 mContext = nfcApplication;
900
901 mNfcTagService = new TagService();
902 mNfcAdapter = new NfcAdapterService();
903 mNxpNfcAdapter = new NxpNfcAdapterService();
904 mExtrasService = new NfcAdapterExtrasService();
905 mNxpExtrasService = new NxpNfcAdapterExtrasService();
906 // mCardEmulationService = new CardEmulationService();
907
908 Log.i(TAG, "Starting NFC service");
909
910 sService = this;
911
912 mScreenStateHelper = new ScreenStateHelper(mContext);
913 mContentResolver = mContext.getContentResolver();
914 mDeviceHost = new NativeNfcManager(mContext, this);
915
916 mNfcUnlockManager = NfcUnlockManager.getInstance();
917
918 mHandoverDataParser = new HandoverDataParser();
919 boolean isNfcProvisioningEnabled = false;
920 try {
921 isNfcProvisioningEnabled = mContext.getResources().getBoolean(
922 R.bool.enable_nfc_provisioning);
923 } catch (NotFoundException e) {
924 }
925
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530926 try {
927 mIsLiveCaseEnabled = mContext.getResources().getBoolean(R.bool.enable_live_cases);
928 } catch (NotFoundException e) {
929 mIsLiveCaseEnabled = false;
930 }
931
932 mLiveCaseTechnology = 0;
933 String[] liveCaseTechList;
934 try {
935 liveCaseTechList = mContext.getResources().getStringArray(R.array.live_case_tag_types);
936 for (int i=0; i < liveCaseTechList.length; i++) {
937 if (liveCaseTechList[i].equals("TypeA")) {
938 mLiveCaseTechnology |= NFC_POLL_A;
939 } else if (liveCaseTechList[i].equals("TypeB")) {
940 mLiveCaseTechnology |= NFC_POLL_B;
941 } else if (liveCaseTechList[i].equals("TypeF")) {
942 mLiveCaseTechnology |= NFC_POLL_F;
943 } else if (liveCaseTechList[i].equals("TypeV")) {
Nikhil Chhabra288edb02018-01-10 19:36:21 +0530944 mLiveCaseTechnology |= NFC_POLL_V;
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530945 }
946 }
947 } catch (NotFoundException e) {
948 mLiveCaseTechnology = 0;
949 }
950
nxpandroid64fd68c2015-09-23 16:45:15 +0530951 if (isNfcProvisioningEnabled) {
952 mInProvisionMode = Settings.Secure.getInt(mContentResolver,
953 Settings.Global.DEVICE_PROVISIONED, 0) == 0;
954 } else {
955 mInProvisionMode = false;
956 }
957
nxpandroid1153eb32015-11-06 18:46:58 +0530958 if(mInProvisionMode)
959 {
960 /* if device is in provision mode, set this mode at lower layers */
961 mDeviceHost.doSetProvisionMode(mInProvisionMode);
962 }
963
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530964 mNfcDispatcher = new NfcDispatcher(mContext, mHandoverDataParser, mInProvisionMode,
965 mIsLiveCaseEnabled);
nxpandroid64fd68c2015-09-23 16:45:15 +0530966 mP2pLinkManager = new P2pLinkManager(mContext, mHandoverDataParser,
967 mDeviceHost.getDefaultLlcpMiu(), mDeviceHost.getDefaultLlcpRwSize());
968
969 mSecureElement = new NativeNfcSecureElement(mContext);
970 mEeRoutingState = ROUTE_OFF;
971 mToastHandler = new ToastHandler(mContext);
972
973 mNfceeAccessControl = new NfceeAccessControl(mContext);
974 mNfcSccAccessControl = new NfcSccAccessControl(mContext);
975 mNfcSeAccessControl = new NfcSeAccessControl(mContext);
976 mNfcAla = new NativeNfcAla();
977
978 mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE);
979 mPrefsEditor = mPrefs.edit();
nxpandroida9a68ba2016-01-14 21:12:17 +0530980 mNxpPrefs = mContext.getSharedPreferences(NXP_PREF, Context.MODE_PRIVATE);
981 mNxpPrefsEditor = mNxpPrefs.edit();
nxpandroid64fd68c2015-09-23 16:45:15 +0530982
983 mState = NfcAdapter.STATE_OFF;
984 mIsNdefPushEnabled = mPrefs.getBoolean(PREF_NDEF_PUSH_ON, NDEF_PUSH_ON_DEFAULT);
985 setBeamShareActivityState(mIsNdefPushEnabled);
986
987 mIsDebugBuild = "userdebug".equals(Build.TYPE) || "eng".equals(Build.TYPE);
988
989 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
990
991 mRoutingWakeLock = mPowerManager.newWakeLock(
992 PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mRoutingWakeLock");
993 mEeWakeLock = mPowerManager.newWakeLock(
994 PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mEeWakeLock");
995
996 mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
997 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
998
999 mScreenState = mScreenStateHelper.checkScreenState();
1000
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301001 mNumTagsDetected = new AtomicInteger();
1002 mNumP2pDetected = new AtomicInteger();
1003 mNumHceDetected = new AtomicInteger();
1004
1005 mBackupManager = new BackupManager(mContext);
1006
nxpandroid64fd68c2015-09-23 16:45:15 +05301007 // Intents for all users
1008 IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
1009 filter.addAction(Intent.ACTION_SCREEN_OFF);
1010 filter.addAction(Intent.ACTION_SCREEN_ON);
1011 filter.addAction(Intent.ACTION_USER_PRESENT);
1012 filter.addAction(Intent.ACTION_USER_SWITCHED);
nxpandroid64fd68c2015-09-23 16:45:15 +05301013 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null);
1014
nxpandroid5d64ce92016-11-18 19:48:53 +05301015 filter = new IntentFilter(Intent.ACTION_SHUTDOWN);
1016 mContext.registerReceiver(mOwnerReceiver, filter);
1017
nxpandroid64fd68c2015-09-23 16:45:15 +05301018 IntentFilter ownerFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1019 ownerFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
1020 mContext.registerReceiver(mOwnerReceiver, ownerFilter);
1021
1022 ownerFilter = new IntentFilter();
1023 ownerFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
1024 ownerFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
1025 ownerFilter.addDataScheme("package");
1026 mContext.registerReceiver(mOwnerReceiver, ownerFilter);
1027
1028 IntentFilter x509CertificateFilter = new IntentFilter();
1029 x509CertificateFilter.addAction(NxpConstants.ACTION_CHECK_X509_RESULT);
nxpandroid5d64ce92016-11-18 19:48:53 +05301030 mContext.registerReceiverAsUser(x509CertificateReceiver, UserHandle.ALL,
1031 x509CertificateFilter, NfcPermissions.ADMIN_PERM, null);
nxpandroid64fd68c2015-09-23 16:45:15 +05301032
Shashank vimal83779082018-02-06 18:10:31 +05301033 IntentFilter activateStkFilter = new IntentFilter();
1034 activateStkFilter.addAction(NxpConstants.CAT_ACTIVATE_NOTIFY_ACTION);
1035 mContext.registerReceiver(mActivateSwpInterface, activateStkFilter);
1036
nxpandroid64fd68c2015-09-23 16:45:15 +05301037 IntentFilter enableNfc = new IntentFilter();
1038 enableNfc.addAction(NxpConstants.ACTION_GSMA_ENABLE_NFC);
nxpandroid5d64ce92016-11-18 19:48:53 +05301039 mContext.registerReceiverAsUser(mEnableNfc, UserHandle.ALL, enableNfc, null, null);
nxpandroid64fd68c2015-09-23 16:45:15 +05301040
1041 IntentFilter lsFilter = new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
1042 //mContext.registerReceiver(mAlaReceiver, lsFilter);
1043 mContext.registerReceiverAsUser(mAlaReceiver, UserHandle.ALL, lsFilter, null, null);
1044
1045 IntentFilter policyFilter = new IntentFilter(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1046 mContext.registerReceiverAsUser(mPolicyReceiver, UserHandle.ALL, policyFilter, null, null);
1047
1048 updatePackageCache();
1049
1050 PackageManager pm = mContext.getPackageManager();
nxpandroid34627bd2016-05-27 15:52:30 +05301051 mIsHceCapable =
1052 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION) ||
1053 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF);
1054 mIsHceFCapable =
1055 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF);
1056
nxpandroid64fd68c2015-09-23 16:45:15 +05301057 if (mIsHceCapable) {
1058 mAidRoutingManager = new AidRoutingManager();
nxpandroid1680a6d2017-01-13 19:13:14 +05301059 mCardEmulationManager = new CardEmulationManager(mContext, mAidRoutingManager);
1060 mAidCache = mCardEmulationManager.getRegisteredAidCache();
nxpandroid64fd68c2015-09-23 16:45:15 +05301061 //mCardEmulationManager = new CardEmulationManager(mContext);
1062 Log.d("NfcService", "Before mIsHceCapable");
1063 mNxpNfcController = new NxpNfcController(mContext, mCardEmulationManager);
1064 }
1065
1066 mForegroundUtils = ForegroundUtils.getInstance();
nxpandroid281eb922016-08-25 20:27:46 +05301067
1068 // Make sure this is only called when object construction is complete.
1069 ServiceManager.addService(SERVICE_NAME, mNfcAdapter);
1070
nxpandroid64fd68c2015-09-23 16:45:15 +05301071 new EnableDisableTask().execute(TASK_BOOT); // do blocking boot tasks
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301072
1073 mHandler.sendEmptyMessageDelayed(MSG_UPDATE_STATS, STATS_UPDATE_INTERVAL_MS);
Nikhil Chhabrafc8f3f62018-01-08 20:48:49 +05301074
1075 IVrManager mVrManager = IVrManager.Stub.asInterface(ServiceManager.getService(
1076 mContext.VR_SERVICE));
1077 if (mVrManager != null) {
1078 try {
1079 mVrManager.registerListener(mVrStateCallbacks);
1080 mIsVrModeEnabled = mVrManager.getVrModeState();
1081 } catch (RemoteException e) {
1082 Log.e(TAG, "Failed to register VR mode state listener: " + e);
1083 }
1084 }
nxpandroid5c5b2152017-09-14 12:30:17 +05301085 /*SoundPool clean up before NFC state updated*/
1086 initSoundPool();
nxpandroid64fd68c2015-09-23 16:45:15 +05301087 }
1088
1089 void initSoundPool() {
1090 synchronized(this) {
1091 if (mSoundPool == null) {
1092 mSoundPool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0);
1093 mStartSound = mSoundPool.load(mContext, R.raw.start, 1);
1094 mEndSound = mSoundPool.load(mContext, R.raw.end, 1);
1095 mErrorSound = mSoundPool.load(mContext, R.raw.error, 1);
1096 }
1097 }
1098 }
1099
1100 void releaseSoundPool() {
1101 synchronized (this) {
1102 if (mSoundPool != null) {
1103 mSoundPool.release();
1104 mSoundPool = null;
1105 }
1106 }
1107 }
1108
nxpandroid64fd68c2015-09-23 16:45:15 +05301109 void updatePackageCache() {
1110 PackageManager pm = mContext.getPackageManager();
nxpandroid281eb922016-08-25 20:27:46 +05301111 List<PackageInfo> packages = pm.getInstalledPackagesAsUser(0, UserHandle.USER_SYSTEM);
nxpandroid64fd68c2015-09-23 16:45:15 +05301112 synchronized (this) {
1113 mInstalledPackages = packages;
1114 }
1115 }
1116
nxpandroid7d44e572016-08-01 19:11:04 +05301117 int doOpenSecureElementConnection(int seId) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301118 mEeWakeLock.acquire();
1119 try {
nxpandroid7d44e572016-08-01 19:11:04 +05301120 return mSecureElement.doOpenSecureElementConnection(seId);
nxpandroid64fd68c2015-09-23 16:45:15 +05301121 } finally {
1122 mEeWakeLock.release();
1123 }
1124 }
1125
1126 byte[] doTransceive(int handle, byte[] cmd) {
1127 mEeWakeLock.acquire();
1128 try {
1129 return doTransceiveNoLock(handle, cmd);
1130 } finally {
1131 mEeWakeLock.release();
1132 }
1133 }
1134
1135 byte[] doTransceiveNoLock(int handle, byte[] cmd) {
1136 return mSecureElement.doTransceive(handle, cmd);
1137 }
1138
1139 void doDisconnect(int handle) {
1140 mEeWakeLock.acquire();
1141 try {
1142 mSecureElement.doDisconnect(handle);
1143 } finally {
1144 mEeWakeLock.release();
1145 }
1146 }
1147
1148 boolean doReset(int handle) {
1149 mEeWakeLock.acquire();
1150 try {
1151 return mSecureElement.doReset(handle);
1152 } finally {
1153 mEeWakeLock.release();
1154 }
1155 }
1156
1157 public static byte[] CreateSHA(String pkg, int alaVer){
nxpandroid281eb922016-08-25 20:27:46 +05301158 String localTAG = "Utils:CreateSHA";
nxpandroid64fd68c2015-09-23 16:45:15 +05301159 StringBuffer sb = new StringBuffer();
1160 try {
1161 MessageDigest md;
1162 if(alaVer == 1)
1163 md = MessageDigest.getInstance("SHA-256");
1164 else
1165 md = MessageDigest.getInstance("SHA-1");
1166
1167 md.update(pkg.getBytes());
1168
nxpandroid281eb922016-08-25 20:27:46 +05301169 byte[] byteData = md.digest();
1170 Log.i(localTAG, "byteData len : " + byteData.length);
nxpandroid64fd68c2015-09-23 16:45:15 +05301171 /*
1172 for (int i = 0; i < byteData.length; i++) {
1173 sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
1174 }
1175 // Log.i(TAG, "sb.toString()" + sb.toString());*/
1176 return byteData;
1177 } catch (Exception e) {
1178 e.printStackTrace();
1179 }
1180 return null;
1181 }
1182
1183 public static String getCallingAppPkg(Context context) {
nxpandroid281eb922016-08-25 20:27:46 +05301184 String localTAG = "getCallingAppPkg";
nxpandroid64fd68c2015-09-23 16:45:15 +05301185 ActivityManager am = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
1186
1187 // get the info from the currently running task
1188 List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1);
1189
1190 Log.d("topActivity", "CURRENT Activity ::"
1191 + taskInfo.get(0).topActivity.getClassName());
1192 String s = taskInfo.get(0).topActivity.getClassName();
1193
1194 ComponentName componentInfo = taskInfo.get(0).topActivity;
1195 componentInfo.getPackageName();
nxpandroid281eb922016-08-25 20:27:46 +05301196 Log.i(localTAG,"componentInfo.getPackageName()" + componentInfo.getPackageName());
nxpandroid64fd68c2015-09-23 16:45:15 +05301197 return componentInfo.getPackageName();
1198 }
1199
1200 /**
1201 * Manages tasks that involve turning on/off the NFC controller.
1202 * <p/>
1203 * <p>All work that might turn the NFC adapter on or off must be done
1204 * through this task, to keep the handling of mState simple.
1205 * In other words, mState is only modified in these tasks (and we
1206 * don't need a lock to read it in these tasks).
1207 * <p/>
1208 * <p>These tasks are all done on the same AsyncTask background
1209 * thread, so they are serialized. Each task may temporarily transition
1210 * mState to STATE_TURNING_OFF or STATE_TURNING_ON, but must exit in
1211 * either STATE_ON or STATE_OFF. This way each task can be guaranteed
1212 * of starting in either STATE_OFF or STATE_ON, without needing to hold
1213 * NfcService.this for the entire task.
1214 * <p/>
1215 * <p>AsyncTask's are also implicitly queued. This is useful for corner
1216 * cases like turning airplane mode on while TASK_ENABLE is in progress.
1217 * The TASK_DISABLE triggered by airplane mode will be correctly executed
1218 * immediately after TASK_ENABLE is complete. This seems like the most sane
1219 * way to deal with these situations.
1220 * <p/>
1221 * <p>{@link #TASK_ENABLE} enables the NFC adapter, without changing
1222 * preferences
1223 * <p>{@link #TASK_DISABLE} disables the NFC adapter, without changing
1224 * preferences
1225 * <p>{@link #TASK_BOOT} does first boot work and may enable NFC
1226 */
1227 class EnableDisableTask extends AsyncTask<Integer, Void, Void> {
1228 @Override
1229 protected Void doInBackground(Integer... params) {
1230 // Sanity check mState
1231 switch (mState) {
1232 case NfcAdapter.STATE_TURNING_OFF:
1233 case NfcAdapter.STATE_TURNING_ON:
1234 Log.e(TAG, "Processing EnableDisable task " + params[0] + " from bad state " +
1235 mState);
1236 return null;
1237 }
1238
1239 /* AsyncTask sets this thread to THREAD_PRIORITY_BACKGROUND,
1240 * override with the default. THREAD_PRIORITY_BACKGROUND causes
1241 * us to service software I2C too slow for firmware download
1242 * with the NXP PN544.
1243 * TODO: move this to the DAL I2C layer in libnfc-nxp, since this
1244 * problem only occurs on I2C platforms using PN544
1245 */
1246 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1247
1248 switch (params[0].intValue()) {
1249 case TASK_ENABLE:
1250 enableInternal();
1251 break;
1252 case TASK_DISABLE:
1253 disableInternal();
1254 break;
1255 case TASK_BOOT:
1256 Log.d(TAG, "checking on firmware download");
nxpandroid7d44e572016-08-01 19:11:04 +05301257 if (mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT)) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301258 Log.d(TAG, "NFC is on. Doing normal stuff");
nxpandroid5d64ce92016-11-18 19:48:53 +05301259 mIsTaskBoot = true;
nxpandroid64fd68c2015-09-23 16:45:15 +05301260 enableInternal();
nxpandroid5d64ce92016-11-18 19:48:53 +05301261 mIsTaskBoot = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05301262 } else {
1263 Log.d(TAG, "NFC is off. Checking firmware version");
1264 mDeviceHost.checkFirmware();
1265 }
1266 if (mPrefs.getBoolean(PREF_FIRST_BOOT, true)) {
1267 Log.i(TAG, "First Boot");
1268 mPrefsEditor.putBoolean(PREF_FIRST_BOOT, false);
1269 mPrefsEditor.apply();
1270 }
Nikhil Chhabraa9e399a2018-01-09 11:47:13 +05301271 SystemProperties.set("nfc.initialized", "true");
nxpandroid64fd68c2015-09-23 16:45:15 +05301272 break;
nxpandroid1680a6d2017-01-13 19:13:14 +05301273 case TASK_RESTART:
1274 restartInternal();
1275
nxpandroid64fd68c2015-09-23 16:45:15 +05301276 }
1277
1278 // Restore default AsyncTask priority
1279 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1280 return null;
1281 }
1282
1283 @Override
1284 protected void onPostExecute(Void result) {
1285
1286 if(mState == NfcAdapter.STATE_ON){
1287 IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
1288 filter.addAction(Intent.ACTION_SCREEN_OFF);
1289 filter.addAction(Intent.ACTION_SCREEN_ON);
1290 filter.addAction(Intent.ACTION_USER_PRESENT);
1291 filter.addAction(Intent.ACTION_USER_SWITCHED);
nxpandroid64fd68c2015-09-23 16:45:15 +05301292 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null);
1293 }else if (mState == NfcAdapter.STATE_OFF){
1294 mContext.unregisterReceiver(mReceiver);
1295 IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
1296 filter.addAction(Intent.ACTION_USER_SWITCHED);
nxpandroid64fd68c2015-09-23 16:45:15 +05301297 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null);
1298 }
1299
1300
1301 }
1302
1303 /**
1304 * Check the default Secure Element configuration.
1305 */
1306 void checkSecureElementConfuration() {
1307
1308 /* Get SE List */
nxpandroid281eb922016-08-25 20:27:46 +05301309 int[] seList = mDeviceHost.doGetSecureElementList();
nxpandroidebf53fb2016-12-22 18:48:59 +05301310 int uiccSlot = 0;
1311 uiccSlot = mPrefs.getInt(PREF_CUR_SELECTED_UICC_ID, SECURE_ELEMENT_UICC_SLOT_DEFAULT);
1312 int status = mDeviceHost.setPreferredSimSlot(uiccSlot);
nxpandroid64fd68c2015-09-23 16:45:15 +05301313 /* Check Secure Element setting */
nxpandroid281eb922016-08-25 20:27:46 +05301314 int seNum=mDeviceHost.GetDefaultSE();
1315 if(seNum != 0)
nxpandroid64fd68c2015-09-23 16:45:15 +05301316 {
1317 SECURE_ELEMENT_ON_DEFAULT=true;
nxpandroid281eb922016-08-25 20:27:46 +05301318 SECURE_ELEMENT_ID_DEFAULT=seNum;
nxpandroid64fd68c2015-09-23 16:45:15 +05301319 } else {
nxpandroid281eb922016-08-25 20:27:46 +05301320 if (seList != null) {
1321 for (int i = 0; i < seList.length; i++) {
1322 mDeviceHost.doDeselectSecureElement(seList[i]);
nxpandroid64fd68c2015-09-23 16:45:15 +05301323 }
1324 }
1325 }
1326
1327 mNfcSecureElementState =
nxpandroida9a68ba2016-01-14 21:12:17 +05301328 mNxpPrefs.getBoolean(PREF_SECURE_ELEMENT_ON, SECURE_ELEMENT_ON_DEFAULT);
nxpandroid64fd68c2015-09-23 16:45:15 +05301329
1330 if (mNfcSecureElementState) {
1331 int secureElementId =
nxpandroida9a68ba2016-01-14 21:12:17 +05301332 mNxpPrefs.getInt(PREF_SECURE_ELEMENT_ID, SECURE_ELEMENT_ID_DEFAULT);
nxpandroid64fd68c2015-09-23 16:45:15 +05301333
nxpandroid281eb922016-08-25 20:27:46 +05301334 if (seList != null) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301335 if (secureElementId != ALL_SE_ID_TYPE/* SECURE_ELEMENT_ALL */) {
1336 mDeviceHost.doDeselectSecureElement(UICC_ID_TYPE);
nxpandroid7d44e572016-08-01 19:11:04 +05301337 mDeviceHost.doDeselectSecureElement(UICC2_ID_TYPE);
nxpandroid64fd68c2015-09-23 16:45:15 +05301338 mDeviceHost.doDeselectSecureElement(SMART_MX_ID_TYPE);
1339
nxpandroid281eb922016-08-25 20:27:46 +05301340 for (int i = 0; i < seList.length; i++) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301341
nxpandroid281eb922016-08-25 20:27:46 +05301342 if (seList[i] == secureElementId) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301343 if (secureElementId == SMART_MX_ID_TYPE) { // SECURE_ELEMENT_SMX_ID
nxpandroid281eb922016-08-25 20:27:46 +05301344 if (seList.length > 1) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301345 if (DBG) {
1346 Log.d(TAG, "Deselect UICC");
1347 }
1348 }
1349 Log.d(TAG, "Select SMX");
1350 mDeviceHost.doSelectSecureElement(secureElementId);
1351 mSelectedSeId = secureElementId;
1352 break;
1353 } else if (secureElementId == UICC_ID_TYPE/* SECURE_ELEMENT_UICC_ID */) {
nxpandroid281eb922016-08-25 20:27:46 +05301354 if (seList.length > 1) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301355 if (DBG) {
1356 Log.d(TAG, "Deselect SMX");
1357 }
1358 }
1359 Log.d(TAG, "Select UICC");
1360 mDeviceHost.doSelectSecureElement(secureElementId);
1361 mSelectedSeId = secureElementId;
1362 break;
nxpandroid7d44e572016-08-01 19:11:04 +05301363 }else if (secureElementId == UICC2_ID_TYPE/* SECURE_ELEMENT_UICC_ID */) {
nxpandroid281eb922016-08-25 20:27:46 +05301364 if (seList.length > 1) {
nxpandroid7d44e572016-08-01 19:11:04 +05301365 if (DBG) {
1366 Log.d(TAG, "Deselect SMX");
1367 }
1368 }
1369 Log.d(TAG, "Select UICC2");
1370 mDeviceHost.doSelectSecureElement(secureElementId);
1371 mSelectedSeId = secureElementId;
1372 break;
nxpandroid64fd68c2015-09-23 16:45:15 +05301373 } else if (secureElementId == SECURE_ELEMENT_ID_DEFAULT) {
nxpandroid281eb922016-08-25 20:27:46 +05301374 if (seList.length > 1) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301375 if (DBG) {
1376 Log.d(TAG, "UICC deselected by default");
1377 }
1378 }
1379 }
1380 }
1381 }
1382 } else {
1383 if (DBG) {
1384 Log.d(TAG, "Select ALL_SE");
1385 }
1386
nxpandroid281eb922016-08-25 20:27:46 +05301387 if (seList.length > 1) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301388
nxpandroid281eb922016-08-25 20:27:46 +05301389 for (int i = 0; i < seList.length; i++) {
1390 mDeviceHost.doSelectSecureElement(seList[i]);
nxpandroid64fd68c2015-09-23 16:45:15 +05301391 try{
1392 //Delay b/w two SE selection.
1393 Thread.sleep(200);
1394 } catch(Exception e) {
1395 e.printStackTrace();
1396 }
1397 }
1398 mSelectedSeId = secureElementId;
1399 }
1400 }
1401 }
1402 } else {
nxpandroid281eb922016-08-25 20:27:46 +05301403 if (seList != null && seList.length > 0) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301404 if (DBG) {
1405 Log.d(TAG, "UICC/eSE deselected by default");
1406 }
1407 mDeviceHost.doDeselectSecureElement(UICC_ID_TYPE);
nxpandroid7d44e572016-08-01 19:11:04 +05301408 mDeviceHost.doDeselectSecureElement(UICC2_ID_TYPE);
nxpandroid64fd68c2015-09-23 16:45:15 +05301409 mDeviceHost.doDeselectSecureElement(SMART_MX_ID_TYPE);
1410 }
1411 }
1412 }
1413
1414 boolean getJcopOsFileInfo() {
1415 File jcopOsFile;
1416 Log.i(TAG, "getJcopOsFileInfo");
1417
1418 for (int num = 0; num < 3; num++) {
1419 try{
1420 jcopOsFile = new File(path[num]);
1421 }catch(NullPointerException npe) {
1422 Log.e(TAG,"path to jcop os file was null");
1423 return false;
1424 }
1425 long modtime = jcopOsFile.lastModified();
1426 SharedPreferences prefs = mContext.getSharedPreferences(PREF,Context.MODE_PRIVATE);
1427 long prev_modtime = prefs.getLong(PREF_JCOP_MODTIME[num], JCOP_MODTIME_DEFAULT[num]);
1428 Log.d(TAG,"prev_modtime:" + prev_modtime);
1429 Log.d(TAG,"new_modtime:" + modtime);
1430 if(prev_modtime == modtime){
1431 return false;
1432 }
1433 JCOP_MODTIME_TEMP[num] = modtime;
1434 }
1435 return true;
1436 }
1437
1438 /* jcop os Download at boot time */
1439 void jcopOsDownload() {
1440 int status = ErrorCodes.SUCCESS;
1441 boolean jcopStatus;
1442 Log.i(TAG, "Jcop Download starts");
1443
1444 SharedPreferences prefs = mContext.getSharedPreferences(PREF,Context.MODE_PRIVATE);
1445 jcopStatus = getJcopOsFileInfo();
1446
1447 if( jcopStatus == true) {
1448 Log.i(TAG, "Starting getChipName");
1449 int Ver = mDeviceHost.getChipVer();
nxpandroid281eb922016-08-25 20:27:46 +05301450 if(Ver == PN80T_ID || Ver == PN67T_ID || Ver == PN66T_ID || Ver == PN65T_ID) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301451 status = mDeviceHost.JCOSDownload();
1452 }
1453 if(status != ErrorCodes.SUCCESS) {
1454 Log.i(TAG, "Jcop Download failed");
1455 }
1456 else {
1457 Log.i(TAG, "Jcop Download success");
1458 prefs.edit().putLong(PREF_JCOP_MODTIME[0],JCOP_MODTIME_TEMP[0]).apply();
1459 prefs.edit().putLong(PREF_JCOP_MODTIME[1],JCOP_MODTIME_TEMP[1]).apply();
1460 prefs.edit().putLong(PREF_JCOP_MODTIME[2],JCOP_MODTIME_TEMP[2]).apply();
1461 }
1462 }
1463 }
1464 /**
1465 * Enable NFC adapter functions.
1466 * Does not toggle preferences.
1467 */
1468 boolean enableInternal() {
1469 if (mState == NfcAdapter.STATE_ON) {
1470 return true;
1471 }
1472 Log.i(TAG, "Enabling NFC");
1473 updateState(NfcAdapter.STATE_TURNING_ON);
1474 int timeout = mDeviceHost.getNfcInitTimeout();
1475 if (timeout < INIT_WATCHDOG_MS)
1476 {
1477 timeout = INIT_WATCHDOG_MS;
1478 }
1479 Log.i(TAG, "Enabling NFC timeout" +timeout);
1480 WatchDogThread watchDog = new WatchDogThread("enableInternal", timeout);
1481 watchDog.start();
1482 try {
1483 mRoutingWakeLock.acquire();
1484 try {
1485 if (!mDeviceHost.initialize()) {
1486 Log.w(TAG, "Error enabling NFC");
1487 updateState(NfcAdapter.STATE_OFF);
1488 return false;
1489 }
1490 } finally {
1491 mRoutingWakeLock.release();
1492 }
1493 } finally {
1494 watchDog.cancel();
1495 }
nxf32288d12785b2017-11-17 15:18:31 +05301496 mChipVer = mDeviceHost.getChipVer();
1497 if(mChipVer < PN553_ID) {
nxf322881754ee02017-10-24 13:33:24 +05301498 ALL_SE_ID_TYPE &= ~UICC2_ID_TYPE;
nxpandroid5d64ce92016-11-18 19:48:53 +05301499 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301500 checkSecureElementConfuration();
1501
1502 mIsRouteForced = true;
1503 if (mIsHceCapable) {
1504 // Generate the initial card emulation routing table
nxpandroid281eb922016-08-25 20:27:46 +05301505 sAidTableFull = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05301506 mCardEmulationManager.onNfcEnabled();
1507 }
1508 mIsRouteForced = false;
nxpandroide66eb092017-07-12 21:36:08 +05301509 nci_version = getNciVersion();
nxpandroid64fd68c2015-09-23 16:45:15 +05301510
1511 synchronized (NfcService.this) {
1512 mObjectMap.clear();
1513 mP2pLinkManager.enableDisable(mIsNdefPushEnabled, true);
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301514 if(mChipVer == PN80T_ID || mChipVer == PN67T_ID || mChipVer == PN66T_ID || mChipVer == PN65T_ID) {
1515 /*Added for Loader service recover during NFC Off/On*/
1516 NfcAlaService nas = new NfcAlaService();
1517 nas.LSReexecute();
1518 IntentFilter lsFilter = new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
1519 mContext.registerReceiverAsUser(mAlaReceiver, UserHandle.ALL, lsFilter, null, null);
1520 } else {
1521 // do nothing
1522 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301523 }
1524
1525 synchronized (NfcService.this) {
1526 if(mDeviceHost.doCheckJcopDlAtBoot()) {
1527 /* start jcop download */
1528 Log.i(TAG, "Calling Jcop Download");
1529 jcopOsDownload();
1530 }
1531 }
1532
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301533 synchronized (NfcService.this) {
1534 updateState(NfcAdapter.STATE_ON);
1535 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301536 /* Start polling loop */
1537 Log.e(TAG, "applyRouting -3");
1538 mScreenState = mScreenStateHelper.checkScreenState();
nxpandroide66eb092017-07-12 21:36:08 +05301539 int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ?
1540 (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState;
1541
1542 if(mNfcUnlockManager.isLockscreenPollingEnabled())
1543 applyRouting(false);
1544
1545 mDeviceHost.doSetScreenOrPowerState(screen_state_mask);
nxpandroid64fd68c2015-09-23 16:45:15 +05301546 mIsRoutingTableDirty = true;
nxpandroid5d64ce92016-11-18 19:48:53 +05301547 if((mScreenState < NFC_POLLING_MODE) && mIsTaskBoot)
1548 {
1549 /*During device boot if screen state is other ON_UNLOCKED,
1550 *first send discovery command with poll and linsten enabled
1551 *for DC/DC pass through mode activation.
1552 *Then send normal discovery according to screen state*/
1553 applyRouting(true);
1554 mIsTaskBoot = false;
1555 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301556 applyRouting(true);
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301557 synchronized (NfcService.this) {
1558 mNxpNfcState = NXP_NFC_STATE_ON;
1559 }
1560
nxpandroid64fd68c2015-09-23 16:45:15 +05301561 return true;
1562 }
1563
1564 /**
1565 * Disable all NFC adapter functions.
1566 * Does not toggle preferences.
1567 */
1568 boolean disableInternal() {
1569 if (mState == NfcAdapter.STATE_OFF) {
1570 return true;
1571 }
1572 Log.i(TAG, "Disabling NFC");
1573 updateState(NfcAdapter.STATE_TURNING_OFF);
nxpandroid5c5b2152017-09-14 12:30:17 +05301574 /*SoundPool clean up before NFC state updated
1575 releaseSoundPool();*/
nxpandroid64fd68c2015-09-23 16:45:15 +05301576
1577 /* Sometimes mDeviceHost.deinitialize() hangs, use a watch-dog.
1578 * Implemented with a new thread (instead of a Handler or AsyncTask),
1579 * because the UI Thread and AsyncTask thread-pools can also get hung
1580 * when the NFC controller stops responding */
nxpandroid5d64ce92016-11-18 19:48:53 +05301581 disableInternalwatchDog = new WatchDogThread("disableInternal", ROUTING_WATCHDOG_MS);
1582 disableInternalwatchDog.start();
nxpandroid64fd68c2015-09-23 16:45:15 +05301583
1584 if (mIsHceCapable) {
1585 mCardEmulationManager.onNfcDisabled();
1586 }
1587
1588 mP2pLinkManager.enableDisable(false, false);
1589
1590 /* The NFC-EE may still be opened by another process,
1591 * and a transceive() could still be in progress on
1592 * another Binder thread.
1593 * Give it a while to finish existing operations
1594 * before we close it.
1595 */
1596 Long startTime = SystemClock.elapsedRealtime();
1597 do {
1598 synchronized (NfcService.this) {
1599 if (mOpenEe == null)
1600 break;
1601 }
1602 try {
1603 Thread.sleep(WAIT_FOR_NFCEE_POLL_MS);
1604 } catch (InterruptedException e) {
1605 // Ignore
1606 }
1607 } while (SystemClock.elapsedRealtime() - startTime < WAIT_FOR_NFCEE_OPERATIONS_MS);
1608
1609 synchronized (NfcService.this) {
1610 if (mOpenEe != null) {
1611 try {
1612 _nfcEeClose(-1, mOpenEe.binder);
1613 } catch (IOException e) { }
1614 }
1615 }
1616
1617 // Stop watchdog if tag present
1618 // A convenient way to stop the watchdog properly consists of
1619 // disconnecting the tag. The polling loop shall be stopped before
1620 // to avoid the tag being discovered again.
1621 maybeDisconnectTarget();
1622
1623 mNfcDispatcher.setForegroundDispatch(null, null, null);
1624
1625 boolean result = mDeviceHost.deinitialize();
1626 if (DBG) Log.d(TAG, "mDeviceHost.deinitialize() = " + result);
1627
nxpandroid5d64ce92016-11-18 19:48:53 +05301628 disableInternalwatchDog.cancel();
nxpandroid64fd68c2015-09-23 16:45:15 +05301629
1630 synchronized (NfcService.this) {
1631 mCurrentDiscoveryParameters = NfcDiscoveryParameters.getNfcOffParameters();
1632 updateState(NfcAdapter.STATE_OFF);
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301633 mNxpNfcState = NXP_NFC_STATE_OFF;
nxpandroid64fd68c2015-09-23 16:45:15 +05301634 }
1635
nxpandroid64fd68c2015-09-23 16:45:15 +05301636
1637 return result;
1638 }
1639
nxpandroid1680a6d2017-01-13 19:13:14 +05301640 boolean restartInternal()
1641 {
1642 boolean result;
1643 result = disableInternal();
1644 if (DBG) Log.d(TAG, "disableInternal status = " + result);
1645 while(true)
1646 {
1647 if(mState == NfcAdapter.STATE_OFF)
1648 {
1649 if (DBG) Log.d(TAG, "disableInternal is success = " + result);
1650 break;
1651 }
1652 }
1653 result = enableInternal();
1654 if (DBG) Log.d(TAG, "enableInternal status = " + result);
1655 while(true)
1656 {
1657 if(mState == NfcAdapter.STATE_ON)
1658 {
1659 if (DBG) Log.d(TAG, "enableInternal is success = " + result);
1660 break;
1661 }
1662 }
1663 Intent flashIntent = new Intent();
1664 flashIntent.setAction(ACTION_FLASH_SUCCESS);
1665 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_FLASH_SUCCESS);
1666 mContext.sendBroadcast(flashIntent);
1667 return result;
1668 }
1669
nxpandroid64fd68c2015-09-23 16:45:15 +05301670 void updateState(int newState) {
1671 synchronized (NfcService.this) {
1672 if (newState == mState) {
1673 return;
1674 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301675 mState = newState;
1676 Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
1677 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1678 intent.putExtra(NfcAdapter.EXTRA_ADAPTER_STATE, mState);
1679 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
1680 }
1681 }
1682 }
1683
1684 void saveNfcOnSetting(boolean on) {
1685 synchronized (NfcService.this) {
1686 mPrefsEditor.putBoolean(PREF_NFC_ON, on);
1687 mPrefsEditor.apply();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301688 mBackupManager.dataChanged();
nxpandroid64fd68c2015-09-23 16:45:15 +05301689 }
1690 }
1691
1692 public void playSound(int sound) {
1693 synchronized (this) {
1694 if (mSoundPool == null) {
1695 Log.w(TAG, "Not playing sound when NFC is disabled");
1696 return;
1697 }
Nikhil Chhabrafc8f3f62018-01-08 20:48:49 +05301698
1699 if (mIsVrModeEnabled) {
1700 Log.d(TAG, "Not playing NFC sound when Vr Mode is enabled");
1701 return;
1702 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301703 switch (sound) {
1704 case SOUND_START:
1705 mSoundPool.play(mStartSound, 1.0f, 1.0f, 0, 0, 1.0f);
1706 break;
1707 case SOUND_END:
1708 mSoundPool.play(mEndSound, 1.0f, 1.0f, 0, 0, 1.0f);
1709 break;
1710 case SOUND_ERROR:
1711 mSoundPool.play(mErrorSound, 1.0f, 1.0f, 0, 0, 1.0f);
1712 break;
1713 }
1714 }
1715 }
1716
1717 synchronized int getUserId() {
1718 return mUserId;
1719 }
1720
1721 void setBeamShareActivityState(boolean enabled) {
1722 UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
1723 // Propagate the state change to all user profiles related to the current
1724 // user. Note that the list returned by getUserProfiles contains the
1725 // current user.
1726 List <UserHandle> luh = um.getUserProfiles();
1727 for (UserHandle uh : luh){
1728 enforceBeamShareActivityPolicy(mContext, uh, enabled);
1729 }
1730 }
1731
1732 void enforceBeamShareActivityPolicy(Context context, UserHandle uh,
1733 boolean isGlobalEnabled){
1734 UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
1735 IPackageManager mIpm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
1736 boolean isActiveForUser =
1737 (!um.hasUserRestriction(UserManager.DISALLOW_OUTGOING_BEAM, uh)) &&
1738 isGlobalEnabled;
1739 if (DBG){
1740 Log.d(TAG, "Enforcing a policy change on user: " + uh +
1741 ", isActiveForUser = " + isActiveForUser);
1742 }
1743 try {
1744 mIpm.setComponentEnabledSetting(new ComponentName(
1745 BeamShareActivity.class.getPackageName$(),
1746 BeamShareActivity.class.getName()),
1747 isActiveForUser ?
1748 PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
1749 PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
1750 PackageManager.DONT_KILL_APP,
1751 uh.getIdentifier());
1752 } catch (RemoteException e) {
1753 Log.w(TAG, "Unable to change Beam status for user " + uh);
1754 }
1755 }
1756
1757 final class NfcAdapterService extends INfcAdapter.Stub {
1758 @Override
1759 public boolean enable() throws RemoteException {
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301760
1761 if (mNxpNfcState != NXP_NFC_STATE_OFF) {
1762 return true;
1763 } else {
1764 // do nothing
1765 }
1766
1767 synchronized (NfcService.this) {
1768 mNxpNfcState = NXP_NFC_STATE_TURNING_ON;
1769 }
1770
nxpandroid64fd68c2015-09-23 16:45:15 +05301771 NfcPermissions.enforceAdminPermissions(mContext);
1772 int val = mDeviceHost.GetDefaultSE();
1773 Log.i(TAG, "getDefaultSE " + val);
1774
1775 saveNfcOnSetting(true);
1776
nxpandroid64fd68c2015-09-23 16:45:15 +05301777 new EnableDisableTask().execute(TASK_ENABLE);
1778
1779 return true;
1780 }
1781
nxpandroid64fd68c2015-09-23 16:45:15 +05301782 @Override
1783 public boolean disable(boolean saveState) throws RemoteException {
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301784
1785 if (mNxpNfcState != NXP_NFC_STATE_ON) {
1786 return true;
1787 } else {
1788 // do nothing
1789 }
1790
1791 synchronized (NfcService.this) {
1792 mNxpNfcState = NXP_NFC_STATE_TURNING_OFF;
1793 }
1794
nxpandroid64fd68c2015-09-23 16:45:15 +05301795 NfcPermissions.enforceAdminPermissions(mContext);
1796 Log.d(TAG,"Disabling Nfc.");
1797
1798 //Check if this a device shutdown or Nfc only Nfc disable.
1799 if(!mPowerShutDown)
1800 {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301801 int[] seList = mDeviceHost.doGetSecureElementList();
nxpandroid64fd68c2015-09-23 16:45:15 +05301802 Log.i(TAG, "Disabling NFC Disabling ESE/UICC");
nxpandroid64fd68c2015-09-23 16:45:15 +05301803 //Since only Nfc is getting disabled so disable CE from EE.
nxpandroida9a68ba2016-01-14 21:12:17 +05301804 mDeviceHost.doSetScreenOrPowerState(ScreenStateHelper.POWER_STATE_ON);
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301805 if (seList != null) {
1806 for (int i = 0; i < seList.length; i++) {
1807 mDeviceHost.doDeselectSecureElement(seList[i]);
1808 }
1809 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301810 } else {
1811 Log.i(TAG, "Power off : Disabling NFC Disabling ESE/UICC");
1812 mPowerShutDown = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05301813 mCardEmulationManager.onPreferredForegroundServiceChanged(null);
1814 }
1815
1816 if (saveState) {
1817 saveNfcOnSetting(false);
1818 }
1819
1820 new EnableDisableTask().execute(TASK_DISABLE);
1821
1822 return true;
1823 }
1824
1825 @Override
1826 public void pausePolling(int timeoutInMs) {
1827 NfcPermissions.enforceAdminPermissions(mContext);
1828
1829 if (timeoutInMs <= 0 || timeoutInMs > MAX_POLLING_PAUSE_TIMEOUT) {
1830 Log.e(TAG, "Refusing to pause polling for " + timeoutInMs + "ms.");
1831 return;
1832 }
1833
1834 synchronized (NfcService.this) {
1835 mPollingPaused = true;
1836 mDeviceHost.disableDiscovery();
1837 mHandler.sendMessageDelayed(
1838 mHandler.obtainMessage(MSG_RESUME_POLLING), timeoutInMs);
1839 }
1840 }
1841
1842 @Override
1843 public void resumePolling() {
1844 NfcPermissions.enforceAdminPermissions(mContext);
1845
1846 synchronized (NfcService.this) {
1847 if (!mPollingPaused) {
1848 return;
1849 }
1850
1851 mHandler.removeMessages(MSG_RESUME_POLLING);
1852 mPollingPaused = false;
1853 new ApplyRoutingTask().execute();
1854 }
1855 }
1856
1857 @Override
1858 public boolean isNdefPushEnabled() throws RemoteException {
1859 synchronized (NfcService.this) {
1860 return mState == NfcAdapter.STATE_ON && mIsNdefPushEnabled;
1861 }
1862 }
1863
1864 @Override
1865 public boolean enableNdefPush() throws RemoteException {
1866 NfcPermissions.enforceAdminPermissions(mContext);
1867 synchronized (NfcService.this) {
1868 if (mIsNdefPushEnabled) {
1869 return true;
1870 }
1871 Log.i(TAG, "enabling NDEF Push");
1872 mPrefsEditor.putBoolean(PREF_NDEF_PUSH_ON, true);
1873 mPrefsEditor.apply();
1874 mIsNdefPushEnabled = true;
1875 setBeamShareActivityState(true);
1876 if (isNfcEnabled()) {
nxpandroid5d64ce92016-11-18 19:48:53 +05301877 mDeviceHost.doEnablep2p(mIsNdefPushEnabled);
nxpandroid64fd68c2015-09-23 16:45:15 +05301878 mP2pLinkManager.enableDisable(true, true);
1879 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301880 mBackupManager.dataChanged();
nxpandroid64fd68c2015-09-23 16:45:15 +05301881 }
1882 return true;
1883 }
1884
1885 @Override
1886 public boolean disableNdefPush() throws RemoteException {
1887 NfcPermissions.enforceAdminPermissions(mContext);
1888 synchronized (NfcService.this) {
1889 if (!mIsNdefPushEnabled) {
1890 return true;
1891 }
1892 Log.i(TAG, "disabling NDEF Push");
1893 mPrefsEditor.putBoolean(PREF_NDEF_PUSH_ON, false);
1894 mPrefsEditor.apply();
1895 mIsNdefPushEnabled = false;
1896 setBeamShareActivityState(false);
1897 if (isNfcEnabled()) {
1898 mP2pLinkManager.enableDisable(false, true);
1899 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301900 mBackupManager.dataChanged();
nxpandroid64fd68c2015-09-23 16:45:15 +05301901 }
1902 return true;
1903 }
1904
1905 @Override
1906 public void setForegroundDispatch(PendingIntent intent,
1907 IntentFilter[] filters, TechListParcel techListsParcel) {
1908 NfcPermissions.enforceUserPermissions(mContext);
nxpandroid281eb922016-08-25 20:27:46 +05301909 if (!mForegroundUtils.isInForeground(Binder.getCallingUid())) {
1910 Log.e(TAG, "setForegroundDispatch: Caller not in foreground.");
1911 return;
1912 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301913 // Short-cut the disable path
1914 if (intent == null && filters == null && techListsParcel == null) {
1915 mNfcDispatcher.setForegroundDispatch(null, null, null);
1916 return;
1917 }
1918
1919 // Validate the IntentFilters
1920 if (filters != null) {
1921 if (filters.length == 0) {
1922 filters = null;
1923 } else {
1924 for (IntentFilter filter : filters) {
1925 if (filter == null) {
1926 throw new IllegalArgumentException("null IntentFilter");
1927 }
1928 }
1929 }
1930 }
1931
1932 // Validate the tech lists
1933 String[][] techLists = null;
1934 if (techListsParcel != null) {
1935 techLists = techListsParcel.getTechLists();
1936 }
1937
1938 mNfcDispatcher.setForegroundDispatch(intent, filters, techLists);
1939 }
1940
1941 @Override
1942 public void setAppCallback(IAppCallback callback) {
1943 NfcPermissions.enforceUserPermissions(mContext);
1944
1945 // don't allow Beam for managed profiles, or devices with a device owner or policy owner
1946 UserInfo userInfo = mUserManager.getUserInfo(UserHandle.getCallingUserId());
1947 if(!mUserManager.hasUserRestriction(
1948 UserManager.DISALLOW_OUTGOING_BEAM, userInfo.getUserHandle())) {
1949 mP2pLinkManager.setNdefCallback(callback, Binder.getCallingUid());
1950 } else if (DBG) {
1951 Log.d(TAG, "Disabling default Beam behavior");
1952 }
1953 }
1954
1955 @Override
1956 public INfcAdapterExtras getNfcAdapterExtrasInterface(String pkg) {
nxpandroida51b5bd2017-04-10 18:28:21 +05301957
1958 if (pkg.equals(PACKAGE_SMART_CARD_SERVICE)){
1959 Log.d(TAG, "wildcard for SmartcardService");
1960 return mExtrasService;
1961 }
1962
nxpandroid64fd68c2015-09-23 16:45:15 +05301963 NfcService.this.enforceNfceeAdminPerm(pkg);
1964 return mExtrasService;
1965 }
1966
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05301967 @Override
1968 public INfcDta getNfcDtaInterface(String pkg) throws RemoteException {
1969 NfcPermissions.enforceAdminPermissions(mContext);
1970 if (mNfcDtaService == null) {
1971 mNfcDtaService = new NfcDtaService();
1972 }
1973 return mNfcDtaService;
1974 }
1975
nxpandroid281eb922016-08-25 20:27:46 +05301976 @Override
1977 public boolean ignore(int nativeHandle, int debounceMs, ITagRemovedCallback callback)
1978 throws RemoteException {
1979 NfcPermissions.enforceUserPermissions(mContext);
1980
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +05301981 if (debounceMs == 0 && mDebounceTagNativeHandle != INVALID_NATIVE_HANDLE
1982 && nativeHandle == mDebounceTagNativeHandle) {
1983 // Remove any previous messages and immediately debounce.
1984 mHandler.removeMessages(MSG_TAG_DEBOUNCE);
1985 mHandler.sendEmptyMessage(MSG_TAG_DEBOUNCE);
1986 return true;
1987 }
1988
nxpandroid281eb922016-08-25 20:27:46 +05301989 TagEndpoint tag = (TagEndpoint) findAndRemoveObject(nativeHandle);
1990 if (tag != null) {
1991 // Store UID and params
1992 int uidLength = tag.getUid().length;
1993 synchronized (NfcService.this) {
1994 mDebounceTagDebounceMs = debounceMs;
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +05301995 mDebounceTagNativeHandle = nativeHandle;
nxpandroid281eb922016-08-25 20:27:46 +05301996 mDebounceTagUid = new byte[uidLength];
1997 mDebounceTagRemovedCallback = callback;
1998 System.arraycopy(tag.getUid(), 0, mDebounceTagUid, 0, uidLength);
1999 }
2000
2001 // Disconnect from this tag; this should resume the normal
2002 // polling loop (and enter listen mode for a while), before
2003 // we pick up any tags again.
2004 tag.disconnect();
2005 mHandler.sendEmptyMessageDelayed(MSG_TAG_DEBOUNCE, debounceMs);
2006 return true;
2007 } else {
2008 return false;
2009 }
2010 }
2011
nxpandroid64fd68c2015-09-23 16:45:15 +05302012 @Override
2013 public void verifyNfcPermission() {
2014 NfcPermissions.enforceUserPermissions(mContext);
2015 }
2016
2017 @Override
2018 public void invokeBeam() {
2019 NfcPermissions.enforceUserPermissions(mContext);
2020
2021 if (mForegroundUtils.isInForeground(Binder.getCallingUid())) {
2022 mP2pLinkManager.onManualBeamInvoke(null);
2023 } else {
2024 Log.e(TAG, "Calling activity not in foreground.");
2025 }
2026 }
2027
2028 @Override
2029 public void invokeBeamInternal(BeamShareData shareData) {
2030 NfcPermissions.enforceAdminPermissions(mContext);
2031 Message msg = Message.obtain();
2032 msg.what = MSG_INVOKE_BEAM;
2033 msg.obj = shareData;
2034 // We have to send this message delayed for two reasons:
2035 // 1) This is an IPC call from BeamShareActivity, which is
2036 // running when the user has invoked Beam through the
2037 // share menu. As soon as BeamShareActivity closes, the UI
2038 // will need some time to rebuild the original Activity.
2039 // Waiting here for a while gives a better chance of the UI
2040 // having been rebuilt, which means the screenshot that the
2041 // Beam animation is using will be more accurate.
2042 // 2) Similarly, because the Activity that launched BeamShareActivity
2043 // with an ACTION_SEND intent is now in paused state, the NDEF
2044 // callbacks that it has registered may no longer be valid.
2045 // Allowing the original Activity to resume will make sure we
2046 // it has a chance to re-register the NDEF message / callback,
2047 // so we share the right data.
2048 //
2049 // Note that this is somewhat of a hack because the delay may not actually
2050 // be long enough for 2) on very slow devices, but there's no better
2051 // way to do this right now without additional framework changes.
2052 mHandler.sendMessageDelayed(msg, INVOKE_BEAM_DELAY_MS);
2053 }
2054
2055 @Override
2056 public INfcTag getNfcTagInterface() throws RemoteException {
2057 return mNfcTagService;
2058 }
2059
2060 @Override
2061 public INfcCardEmulation getNfcCardEmulationInterface() {
2062 if (mIsHceCapable) {
2063 return mCardEmulationManager.getNfcCardEmulationInterface();
2064 } else {
2065 return null;
2066 }
2067 }
2068
nxpandroid34627bd2016-05-27 15:52:30 +05302069 @Override
2070 public INfcFCardEmulation getNfcFCardEmulationInterface() {
2071 if (mIsHceFCapable) {
2072 return mCardEmulationManager.getNfcFCardEmulationInterface();
2073 } else {
2074 return null;
2075 }
2076 }
2077
nxpandroid64fd68c2015-09-23 16:45:15 +05302078
2079 @Override
2080 public int getState() throws RemoteException {
2081 synchronized (NfcService.this) {
2082 return mState;
2083 }
2084 }
2085
2086 @Override
2087 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2088 NfcService.this.dump(fd, pw, args);
2089 }
2090
2091 @Override
2092 public void dispatch(Tag tag) throws RemoteException {
2093 NfcPermissions.enforceAdminPermissions(mContext);
2094 mNfcDispatcher.dispatchTag(tag);
2095 }
2096
2097 @Override
2098 public void setP2pModes(int initiatorModes, int targetModes) throws RemoteException {
2099 NfcPermissions.enforceAdminPermissions(mContext);
2100 mDeviceHost.setP2pInitiatorModes(initiatorModes);
2101 mDeviceHost.setP2pTargetModes(targetModes);
2102 applyRouting(true);
2103 }
2104
2105 @Override
2106 public void setReaderMode(IBinder binder, IAppCallback callback, int flags, Bundle extras)
2107 throws RemoteException {
nxpandroid281eb922016-08-25 20:27:46 +05302108 int callingUid = Binder.getCallingUid();
2109 if (callingUid != Process.SYSTEM_UID && !mForegroundUtils.isInForeground(callingUid)) {
2110 Log.e(TAG, "setReaderMode: Caller is not in foreground and is not system process.");
2111 return;
2112 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302113 synchronized (NfcService.this) {
nxpandroid34627bd2016-05-27 15:52:30 +05302114 if (!isNfcEnabled()) {
2115 Log.e(TAG, "setReaderMode() called while NFC is not enabled.");
2116 return;
2117 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302118 if (flags != 0) {
2119 try {
2120 mReaderModeParams = new ReaderModeParams();
2121 mReaderModeParams.callback = callback;
2122 mReaderModeParams.flags = flags;
2123 mReaderModeParams.presenceCheckDelay = extras != null
2124 ? (extras.getInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY,
2125 DEFAULT_PRESENCE_CHECK_DELAY))
2126 : DEFAULT_PRESENCE_CHECK_DELAY;
2127 binder.linkToDeath(mReaderModeDeathRecipient, 0);
2128 } catch (RemoteException e) {
2129 Log.e(TAG, "Remote binder has already died.");
2130 return;
2131 }
2132 } else {
2133 try {
2134 mReaderModeParams = null;
2135 binder.unlinkToDeath(mReaderModeDeathRecipient, 0);
2136 } catch (NoSuchElementException e) {
2137 Log.e(TAG, "Reader mode Binder was never registered.");
2138 }
2139 }
2140 Log.e(TAG, "applyRouting -4");
2141 applyRouting(false);
2142 }
2143 }
2144
2145
2146 @Override
2147 public void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, int[] techList) {
2148 NfcPermissions.enforceAdminPermissions(mContext);
2149
2150 int lockscreenPollMask = computeLockscreenPollMask(techList);
2151 synchronized (NfcService.this) {
2152 mNfcUnlockManager.addUnlockHandler(unlockHandler, lockscreenPollMask);
2153 }
2154
2155 applyRouting(false);
2156 }
2157
2158 @Override
2159 public void removeNfcUnlockHandler(INfcUnlockHandler token) throws RemoteException {
2160 synchronized (NfcService.this) {
2161 mNfcUnlockManager.removeUnlockHandler(token.asBinder());
2162 }
2163
2164 applyRouting(false);
2165 }
2166 private int computeLockscreenPollMask(int[] techList) {
2167
2168 Map<Integer, Integer> techCodeToMask = new HashMap<Integer, Integer>();
2169
2170 techCodeToMask.put(TagTechnology.NFC_A, NfcService.NFC_POLL_A);
2171 techCodeToMask.put(TagTechnology.NFC_B, NfcService.NFC_POLL_B);
Nikhil Chhabra288edb02018-01-10 19:36:21 +05302172 techCodeToMask.put(TagTechnology.NFC_V, NfcService.NFC_POLL_V);
nxpandroid64fd68c2015-09-23 16:45:15 +05302173 techCodeToMask.put(TagTechnology.NFC_F, NfcService.NFC_POLL_F);
2174 techCodeToMask.put(TagTechnology.NFC_BARCODE, NfcService.NFC_POLL_KOVIO);
2175 techCodeToMask.put(TagTechnology.MIFARE_CLASSIC, NfcService.NFC_POLL_A);
2176 techCodeToMask.put(TagTechnology.MIFARE_ULTRALIGHT, NfcService.NFC_POLL_A);
2177
2178 int mask = 0;
2179
2180 for (int i = 0; i < techList.length; i++) {
2181 if (techCodeToMask.containsKey(techList[i])) {
2182 mask |= techCodeToMask.get(techList[i]).intValue();
2183 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05302184 int screenState = mScreenStateHelper.checkScreenState();
2185 if (screenState != mScreenState) {
2186 new ApplyRoutingTask().execute(Integer.valueOf(screenState));
2187 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302188 }
2189
2190 return mask;
2191 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05302192
2193 /**
2194 * An interface for nxp extensions
2195 */
nxpandroid64fd68c2015-09-23 16:45:15 +05302196 @Override
nxpandroid6fd9cdb2017-07-12 18:25:41 +05302197 public IBinder getNfcAdapterVendorInterface(String vendor) {
2198 if(vendor.equalsIgnoreCase("nxp")) {
2199 return (IBinder) mNxpNfcAdapter;
2200 } else {
2201 return null;
2202 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302203 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05302204
nxpandroid64fd68c2015-09-23 16:45:15 +05302205 }
2206 final class NxpNfcAdapterService extends INxpNfcAdapter.Stub {
2207 @Override
2208 public INxpNfcAdapterExtras getNxpNfcAdapterExtrasInterface() throws RemoteException {
2209 return mNxpExtrasService;
2210 }
2211 @Override
2212 public IeSEClientServicesAdapter getNfcEseClientServicesAdapterInterface() {
2213 if(mEseClientServicesAdapter == null){
2214 mEseClientServicesAdapter = new EseClientServicesAdapter();
2215 }
2216 return mEseClientServicesAdapter;
2217 }
2218
2219 //GSMA Changes
2220 @Override
2221 public INxpNfcController getNxpNfcControllerInterface() {
2222 return mNxpNfcController.getNxpNfcControllerInterface();
2223 }
2224
2225 @Override
nxpandroid64fd68c2015-09-23 16:45:15 +05302226 public INfcVzw getNfcVzwInterface() {
2227 NfcPermissions.enforceAdminPermissions(mContext);
2228 //begin
2229 if(mVzwService == null){
2230 mVzwService = new NfcVzwService();
2231 }
2232 //end
2233 return mVzwService;
2234 }
2235
2236 @Override
2237 public int setEmvCoPollProfile(boolean enable, int route) throws RemoteException {
2238 return mDeviceHost.setEmvCoPollProfile(enable, route);
2239 }
2240
2241 @Override
2242 public int[] getSecureElementList(String pkg) throws RemoteException {
2243 NfcService.this.enforceNfcSeAdminPerm(pkg);
2244
2245 int[] list = null;
2246 if (isNfcEnabled()) {
2247 list = mDeviceHost.doGetSecureElementList();
2248 }
2249 return list;
2250 }
2251
2252 @Override
2253 public int[] getActiveSecureElementList(String pkg) throws RemoteException {
nxpandroid64fd68c2015-09-23 16:45:15 +05302254
2255 int[] list = null;
2256 if (isNfcEnabled()) {
2257 list = mDeviceHost.doGetActiveSecureElementList();
2258 }
2259 for(int i=0; i< list.length; i++) {
2260 Log.d(TAG, "Active element = "+ list[i]);
2261 }
2262 return list;
2263 }
2264
2265 public INxpNfcAccessExtras getNxpNfcAccessExtrasInterface(String pkg) {
2266 NfcService.this.enforceNfcSccAdminPerm(pkg);
2267 Log.d(TAG, "getNxpNfcAccessExtrasInterface1");
2268 if(mNfcAccessExtrasService == null){
2269 mNfcAccessExtrasService = new NfcAccessExtrasService();
2270 }
2271 return mNfcAccessExtrasService;
2272 }
2273
2274 @Override
2275 public int getSelectedSecureElement(String pkg) throws RemoteException {
2276 NfcService.this.enforceNfcSeAdminPerm(pkg);
2277 return mSelectedSeId;
2278 }
2279 @Override
2280 public int deselectSecureElement(String pkg) throws RemoteException {
2281 NfcService.this.enforceNfcSeAdminPerm(pkg);
nxf32288d12785b2017-11-17 15:18:31 +05302282 if(mChipVer < PN553_ID) {
2283 mSelectedSeId &= ~UICC2_ID_TYPE;
2284 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302285 // Check if NFC is enabled
2286 if (!isNfcEnabled()) {
2287 return ErrorCodes.ERROR_NOT_INITIALIZED;
2288 }
2289
2290 if (mSelectedSeId == 0) {
2291 return ErrorCodes.ERROR_NO_SE_CONNECTED;
2292 }
2293
2294 if (mSelectedSeId != ALL_SE_ID_TYPE/* SECURE_ELEMENT_ALL */) {
2295 mDeviceHost.doDeselectSecureElement(mSelectedSeId);
2296 } else {
2297
2298 /* Get SE List */
nxpandroid281eb922016-08-25 20:27:46 +05302299 int[] seList = mDeviceHost.doGetSecureElementList();
nxpandroid64fd68c2015-09-23 16:45:15 +05302300
nxpandroid281eb922016-08-25 20:27:46 +05302301 for (int i = 0; i < seList.length; i++) {
2302 mDeviceHost.doDeselectSecureElement(seList[i]);
nxpandroid64fd68c2015-09-23 16:45:15 +05302303 }
2304
2305 // mDeviceHost.doSetMultiSEState(false);
2306 }
2307 mNfcSecureElementState = false;
2308 mSelectedSeId = 0;
2309
2310 /* store preference */
nxpandroida9a68ba2016-01-14 21:12:17 +05302311 mNxpPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, false);
2312 mNxpPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, 0);
2313 mNxpPrefsEditor.apply();
nxpandroid64fd68c2015-09-23 16:45:15 +05302314
2315 return ErrorCodes.SUCCESS;
2316 }
2317
2318
2319
2320
2321
2322 @Override
2323 public void storeSePreference(int seId) {
nxf32288d12785b2017-11-17 15:18:31 +05302324 if(mChipVer < PN553_ID) {
2325 seId &= ~UICC2_ID_TYPE;
2326 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302327 NfcPermissions.enforceAdminPermissions(mContext);
2328 /* store */
2329 Log.d(TAG, "SE Preference stored");
nxpandroida9a68ba2016-01-14 21:12:17 +05302330 mNxpPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, true);
2331 mNxpPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, seId);
2332 mNxpPrefsEditor.apply();
nxpandroid64fd68c2015-09-23 16:45:15 +05302333 }
2334
2335 @Override
2336 public int selectSecureElement(String pkg,int seId) throws RemoteException {
2337 NfcService.this.enforceNfcSeAdminPerm(pkg);
2338
nxf32288d12785b2017-11-17 15:18:31 +05302339 if(mChipVer < PN553_ID) {
2340 seId &= ~UICC2_ID_TYPE;
2341 }
2342
nxpandroid64fd68c2015-09-23 16:45:15 +05302343 // Check if NFC is enabled
2344 if (!isNfcEnabled()) {
2345 return ErrorCodes.ERROR_NOT_INITIALIZED;
2346 }
2347
2348 if (mSelectedSeId == seId) {
2349 return ErrorCodes.ERROR_SE_ALREADY_SELECTED;
2350 }
2351
2352 if (mSelectedSeId != 0) {
2353 return ErrorCodes.ERROR_SE_CONNECTED;
2354 }
2355 /* Get SE List */
nxpandroid281eb922016-08-25 20:27:46 +05302356 int[] seList = mDeviceHost.doGetSecureElementList();
nxpandroid64fd68c2015-09-23 16:45:15 +05302357
2358 mSelectedSeId = seId;
2359 if (seId != ALL_SE_ID_TYPE/* SECURE_ELEMENT_ALL */) {
2360 mDeviceHost.doSelectSecureElement(mSelectedSeId);
2361 } else {
nxpandroid281eb922016-08-25 20:27:46 +05302362 if (seList.length > 1) {
2363 for (int i = 0; i < seList.length; i++) {
2364 mDeviceHost.doSelectSecureElement(seList[i]);
nxpandroid64fd68c2015-09-23 16:45:15 +05302365 try{
2366 //Delay b/w two SE selection.
2367 Thread.sleep(200);
2368 } catch(Exception e) {
2369 e.printStackTrace();
2370 }
2371 }
2372 }
2373 }
2374 /* store */
nxpandroida9a68ba2016-01-14 21:12:17 +05302375 mNxpPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, true);
2376 mNxpPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, mSelectedSeId);
2377 mNxpPrefsEditor.apply();
nxpandroid64fd68c2015-09-23 16:45:15 +05302378
2379 mNfcSecureElementState = true;
2380
2381 return ErrorCodes.SUCCESS;
2382 }
2383
2384 public void MifareDesfireRouteSet(int routeLoc, boolean fullPower, boolean lowPower, boolean noPower)
2385 throws RemoteException
2386 {
anil.hiranniah3cb5a1f2018-02-07 19:29:55 +05302387 if((mChipVer < PN553_ID) && (routeLoc == UICC2_ID_TYPE)) {
2388 throw new RemoteException("UICC2 is not supported");
2389 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302390 int protoRouteEntry = 0;
anil.hiranniah3cb5a1f2018-02-07 19:29:55 +05302391 /*UICC2 ID-4(fromApp) mapped to 3 (JNI)*/
2392 protoRouteEntry=((routeLoc & 0x07) == 0x04) ? (0x03 << ROUTE_LOC_MASK) : /*UICC2*/
2393 ((routeLoc & 0x07) == 0x02) ? (0x02 << ROUTE_LOC_MASK) : /*UICC1*/
2394 ((routeLoc & 0x07) == 0x01) ? (0x01 << ROUTE_LOC_MASK) : /*eSE*/
2395 0x00;
nxpandroid8aecbf82016-09-16 20:21:47 +05302396 protoRouteEntry |= ((fullPower ? (mDeviceHost.getDefaultDesfirePowerState() & 0x1F) | 0x01 : 0) | (lowPower ? 0x01 << 1 :0 ) | (noPower ? 0x01 << 2 :0));
2397
nxpandroid7d44e572016-08-01 19:11:04 +05302398 if(routeLoc == 0x00)
nxpandroid7d44e572016-08-01 19:11:04 +05302399 {
nxpandroid8aecbf82016-09-16 20:21:47 +05302400 /*
2401 bit pos 1 = Power Off
2402 bit pos 2 = Battery Off
2403 bit pos 4 = Screen Off
2404 Set these bits to 0 because in case routeLoc = HOST it can not work on POWER_OFF, BATTERY_OFF and SCREEN_OFF*/
2405 protoRouteEntry &= 0xE9;
nxpandroid7d44e572016-08-01 19:11:04 +05302406 }
nxpandroid8aecbf82016-09-16 20:21:47 +05302407
nxpandroid7d44e572016-08-01 19:11:04 +05302408 Log.i(TAG,"MifareDesfireRouteSet : " + protoRouteEntry);
nxpandroida9a68ba2016-01-14 21:12:17 +05302409 mNxpPrefsEditor = mNxpPrefs.edit();
2410 mNxpPrefsEditor.putInt("PREF_MIFARE_DESFIRE_PROTO_ROUTE_ID", protoRouteEntry);
2411 mNxpPrefsEditor.commit();
nxpandroid64fd68c2015-09-23 16:45:15 +05302412 Log.i(TAG,"MifareDesfireRouteSet function in");
2413 commitRouting();
2414 }
2415
2416 public void DefaultRouteSet(int routeLoc, boolean fullPower, boolean lowPower, boolean noPower)
2417 throws RemoteException
2418 {
anil.hiranniah3cb5a1f2018-02-07 19:29:55 +05302419 if((mChipVer < PN553_ID) && (routeLoc == UICC2_ID_TYPE)) {
2420 throw new RemoteException("UICC2 is not supported");
2421 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302422 if (mIsHceCapable) {
2423 int protoRouteEntry = 0;
anil.hiranniah3cb5a1f2018-02-07 19:29:55 +05302424 protoRouteEntry=((routeLoc & 0x07) == 0x04) ? (0x03 << ROUTE_LOC_MASK) : /*UICC2*/
2425 ((routeLoc & 0x07) == 0x02) ? (0x02 << ROUTE_LOC_MASK) : /*UICC1*/
2426 ((routeLoc & 0x07) == 0x01) ? (0x01 << ROUTE_LOC_MASK) : /*eSE*/
2427 0x00;
nxpandroid8aecbf82016-09-16 20:21:47 +05302428 protoRouteEntry |= ((fullPower ? (mDeviceHost.getDefaultAidPowerState() & 0x1F) | 0x01 : 0) | (lowPower ? 0x01 << 1 :0 ) | (noPower ? 0x01 << 2 :0));
2429
nxpandroid7d44e572016-08-01 19:11:04 +05302430 if(routeLoc == 0x00)
nxpandroid7d44e572016-08-01 19:11:04 +05302431 {
nxpandroid8aecbf82016-09-16 20:21:47 +05302432 /*
2433 bit pos 1 = Power Off
2434 bit pos 2 = Battery Off
2435 bit pos 4 = Screen Off
2436 Set these bits to 0 because in case routeLoc = HOST it can not work on POWER_OFF, BATTERY_OFF and SCREEN_OFF*/
2437 protoRouteEntry &= 0xE9;
nxpandroid7d44e572016-08-01 19:11:04 +05302438 }
2439 Log.i(TAG,"DefaultRouteSet : " + protoRouteEntry);
nxpandroid64fd68c2015-09-23 16:45:15 +05302440 if(GetDefaultRouteLoc() != routeLoc)
2441 {
nxpandroida9a68ba2016-01-14 21:12:17 +05302442 mNxpPrefsEditor = mNxpPrefs.edit();
2443 mNxpPrefsEditor.putInt("PREF_SET_DEFAULT_ROUTE_ID", protoRouteEntry );
2444 mNxpPrefsEditor.commit();
nxpandroid64fd68c2015-09-23 16:45:15 +05302445 mIsRouteForced = true;
2446 if (mIsHceCapable) {
2447 mAidRoutingManager.onNfccRoutingTableCleared();
2448 mCardEmulationManager.onRoutingTableChanged();
2449 }
2450 mIsRouteForced = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05302451 }
2452 }
2453 else{
2454 Log.i(TAG,"DefaultRoute can not be set. mIsHceCapable = flase");
2455 }
2456 }
2457
2458 public void MifareCLTRouteSet(int routeLoc, boolean fullPower, boolean lowPower, boolean noPower)
2459 throws RemoteException
2460 {
anil.hiranniah3cb5a1f2018-02-07 19:29:55 +05302461 if((mChipVer < PN553_ID) && (routeLoc == UICC2_ID_TYPE)) {
2462 throw new RemoteException("UICC2 is not supported");
2463 }
2464
nxpandroid64fd68c2015-09-23 16:45:15 +05302465 int techRouteEntry=0;
anil.hiranniah3cb5a1f2018-02-07 19:29:55 +05302466 techRouteEntry=((routeLoc & 0x07) == 0x04) ? (0x03 << ROUTE_LOC_MASK) : /*UICC2*/
2467 ((routeLoc & 0x07) == 0x02) ? (0x02 << ROUTE_LOC_MASK) : /*UICC1*/
2468 ((routeLoc & 0x07) == 0x01) ? (0x01 << ROUTE_LOC_MASK) : /*eSE*/
2469 0x00;
nxpandroid7d44e572016-08-01 19:11:04 +05302470 techRouteEntry |= ((fullPower ? (mDeviceHost.getDefaultMifareCLTPowerState() & 0x1F) | 0x01 : 0) | (lowPower ? 0x01 << 1 :0 ) | (noPower ? 0x01 << 2 :0));
2471 techRouteEntry |= (TECH_TYPE_A << TECH_TYPE_MASK);
2472
2473 Log.i(TAG,"MifareCLTRouteSet : " + techRouteEntry);
nxpandroida9a68ba2016-01-14 21:12:17 +05302474 mNxpPrefsEditor = mNxpPrefs.edit();
2475 mNxpPrefsEditor.putInt("PREF_MIFARE_CLT_ROUTE_ID", techRouteEntry);
2476 mNxpPrefsEditor.commit();
nxpandroid64fd68c2015-09-23 16:45:15 +05302477 commitRouting();
2478 }
2479 @Override
2480 public byte[] getFWVersion()
2481 {
nxpandroid5d64ce92016-11-18 19:48:53 +05302482 byte[] buf = new byte[3];
nxpandroid64fd68c2015-09-23 16:45:15 +05302483 Log.i(TAG, "Starting getFwVersion");
2484 int fwver = mDeviceHost.getFWVersion();
2485 buf[0] = (byte)((fwver&0xFF00)>>8);
2486 buf[1] = (byte)((fwver&0xFF));
nxpandroid5d64ce92016-11-18 19:48:53 +05302487 buf[2] = (byte)((fwver&0xFF0000)>>16);
nxpandroid64fd68c2015-09-23 16:45:15 +05302488 Log.i(TAG, "Firmware version is 0x"+ buf[0]+" 0x"+buf[1]);
2489 return buf;
2490 }
2491
2492 @Override
2493 public Map<String,Integer> getServicesAidCacheSize(int userId, String category){
2494 return mCardEmulationManager.getServicesAidCacheSize(userId, category);
2495 }
nxpandroida9a68ba2016-01-14 21:12:17 +05302496
2497 @Override
2498 public int updateServiceState(int userId , Map serviceState) {
2499 return mCardEmulationManager.updateServiceState(userId ,serviceState);
2500 }
2501
nxpandroid64fd68c2015-09-23 16:45:15 +05302502 @Override
2503 public int getSeInterface(int type) throws RemoteException {
2504 return mDeviceHost.doGetSeInterface(type);
2505 }
2506
nxpandroid34627bd2016-05-27 15:52:30 +05302507 @Override
2508 public int getMaxAidRoutingTableSize() throws RemoteException {
nxpandroid5d64ce92016-11-18 19:48:53 +05302509 NfcPermissions.enforceUserPermissions(mContext);
nxpandroid34627bd2016-05-27 15:52:30 +05302510 return getAidRoutingTableSize();
2511 }
2512
nxpandroid281eb922016-08-25 20:27:46 +05302513
nxpandroid34627bd2016-05-27 15:52:30 +05302514 @Override
2515 public int getCommittedAidRoutingTableSize() throws RemoteException {
nxpandroid5d64ce92016-11-18 19:48:53 +05302516 NfcPermissions.enforceUserPermissions(mContext);
nxpandroid34627bd2016-05-27 15:52:30 +05302517 return (getAidRoutingTableSize() - getRemainingAidTableSize());
2518 }
nxpandroid281eb922016-08-25 20:27:46 +05302519
2520 @Override
2521 public int setConfig(String configs , String pkg) {
2522 Log.e(TAG, "Setting configs for Transit" );
2523 /*Check permissions*/
2524 NfcPermissions.enforceAdminPermissions(mContext);
2525 /*Check if any NFC transactions are ongoing*/
2526 if(mDeviceHost.isNfccBusy())
2527 {
2528 Log.e(TAG, "NFCC is busy.." );
2529 return TRANSIT_SETCONFIG_STAT_FAILED;
2530 }
2531 /*check if format of configs is fine*/
2532 /*Save configurations to file*/
2533 try {
nxpandroidf1f54f52017-07-31 16:08:06 +05302534 File newTextFile = new File("/data/vendor/nfc/libnfc-nxpTransit.conf");
nxpandroid281eb922016-08-25 20:27:46 +05302535 if(configs == null)
2536 {
2537 if(newTextFile.delete()){
2538 Log.e(TAG, "Removing transit config file. Taking default Value" );
2539 }else{
2540 System.out.println("Error taking defualt value");
2541 }
2542 }
2543 else
2544 {
2545 FileWriter fw = new FileWriter(newTextFile);
2546 fw.write(configs);
2547 fw.close();
2548 Log.e(TAG, "File Written to libnfc-nxpTransit.conf successfully" );
2549 }
2550 } catch (Exception e) {
2551 e.printStackTrace();
2552 return TRANSIT_SETCONFIG_STAT_FAILED;
2553 }
2554
2555 /*restart NFC service*/
2556 try {
2557 mNfcAdapter.disable(true);
2558 mNfcAdapter.enable();
2559 } catch (Exception e) {
2560 Log.e(TAG, "Unable to restart NFC Service");
2561 e.printStackTrace();
2562 return TRANSIT_SETCONFIG_STAT_FAILED;
2563 }
2564 return TRANSIT_SETCONFIG_STAT_SUCCESS;
2565 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302566 }
2567
2568 final class ReaderModeDeathRecipient implements IBinder.DeathRecipient {
2569 @Override
2570 public void binderDied() {
2571 synchronized (NfcService.this) {
2572 if (mReaderModeParams != null) {
2573 mReaderModeParams = null;
2574 Log.e(TAG, "applyRouting -5");
2575 applyRouting(false);
2576 }
2577 }
2578 }
2579 }
2580
2581 final class TagService extends INfcTag.Stub {
2582 @Override
nxpandroid64fd68c2015-09-23 16:45:15 +05302583 public int connect(int nativeHandle, int technology) throws RemoteException {
2584 NfcPermissions.enforceUserPermissions(mContext);
2585
2586 TagEndpoint tag = null;
2587
2588 if (!isNfcEnabled()) {
2589 return ErrorCodes.ERROR_NOT_INITIALIZED;
2590 }
2591
2592 /* find the tag in the hmap */
2593 tag = (TagEndpoint) findObject(nativeHandle);
2594 if (tag == null) {
2595 return ErrorCodes.ERROR_DISCONNECT;
2596 }
2597
2598 if (!tag.isPresent()) {
2599 return ErrorCodes.ERROR_DISCONNECT;
2600 }
2601
2602 // Note that on most tags, all technologies are behind a single
2603 // handle. This means that the connect at the lower levels
2604 // will do nothing, as the tag is already connected to that handle.
2605 if (tag.connect(technology)) {
2606 return ErrorCodes.SUCCESS;
2607 } else {
2608 return ErrorCodes.ERROR_DISCONNECT;
2609 }
2610 }
2611
2612 @Override
2613 public int reconnect(int nativeHandle) throws RemoteException {
2614 NfcPermissions.enforceUserPermissions(mContext);
2615
2616 TagEndpoint tag = null;
2617
2618 // Check if NFC is enabled
2619 if (!isNfcEnabled()) {
2620 return ErrorCodes.ERROR_NOT_INITIALIZED;
2621 }
2622
2623 /* find the tag in the hmap */
2624 tag = (TagEndpoint) findObject(nativeHandle);
2625 if (tag != null) {
2626 if (tag.reconnect()) {
2627 return ErrorCodes.SUCCESS;
2628 } else {
2629 return ErrorCodes.ERROR_DISCONNECT;
2630 }
2631 }
2632 return ErrorCodes.ERROR_DISCONNECT;
2633 }
2634
2635 @Override
2636 public int[] getTechList(int nativeHandle) throws RemoteException {
2637 NfcPermissions.enforceUserPermissions(mContext);
2638
2639 // Check if NFC is enabled
2640 if (!isNfcEnabled()) {
2641 return null;
2642 }
2643
2644 /* find the tag in the hmap */
2645 TagEndpoint tag = (TagEndpoint) findObject(nativeHandle);
2646 if (tag != null) {
2647 return tag.getTechList();
2648 }
2649 return null;
2650 }
2651
2652 @Override
2653 public boolean isPresent(int nativeHandle) throws RemoteException {
2654 TagEndpoint tag = null;
2655
2656 // Check if NFC is enabled
2657 if (!isNfcEnabled()) {
2658 return false;
2659 }
2660
2661 /* find the tag in the hmap */
2662 tag = (TagEndpoint) findObject(nativeHandle);
2663 if (tag == null) {
2664 return false;
2665 }
2666
2667 return tag.isPresent();
2668 }
2669
2670 @Override
2671 public boolean isNdef(int nativeHandle) throws RemoteException {
2672 NfcPermissions.enforceUserPermissions(mContext);
2673
2674 TagEndpoint tag = null;
2675
2676 // Check if NFC is enabled
2677 if (!isNfcEnabled()) {
2678 return false;
2679 }
2680
2681 /* find the tag in the hmap */
2682 tag = (TagEndpoint) findObject(nativeHandle);
2683 int[] ndefInfo = new int[2];
2684 if (tag == null) {
2685 return false;
2686 }
2687 return tag.checkNdef(ndefInfo);
2688 }
2689
2690 @Override
2691 public TransceiveResult transceive(int nativeHandle, byte[] data, boolean raw)
2692 throws RemoteException {
2693 NfcPermissions.enforceUserPermissions(mContext);
2694
2695 TagEndpoint tag = null;
2696 byte[] response;
2697
2698 // Check if NFC is enabled
2699 if (!isNfcEnabled()) {
2700 return null;
2701 }
2702
2703 /* find the tag in the hmap */
2704 tag = (TagEndpoint) findObject(nativeHandle);
2705 if (tag != null) {
2706 // Check if length is within limits
2707 if (data.length > getMaxTransceiveLength(tag.getConnectedTechnology())) {
2708 return new TransceiveResult(TransceiveResult.RESULT_EXCEEDED_LENGTH, null);
2709 }
2710 int[] targetLost = new int[1];
2711 response = tag.transceive(data, raw, targetLost);
2712 int result;
2713 if (response != null) {
2714 result = TransceiveResult.RESULT_SUCCESS;
2715 } else if (targetLost[0] == 1) {
2716 result = TransceiveResult.RESULT_TAGLOST;
2717 } else {
2718 result = TransceiveResult.RESULT_FAILURE;
2719 }
2720 return new TransceiveResult(result, response);
2721 }
2722 return null;
2723 }
2724
2725 @Override
2726 public NdefMessage ndefRead(int nativeHandle) throws RemoteException {
2727 NfcPermissions.enforceUserPermissions(mContext);
2728
2729 TagEndpoint tag;
2730
2731 // Check if NFC is enabled
2732 if (!isNfcEnabled()) {
2733 return null;
2734 }
2735
2736 /* find the tag in the hmap */
2737 tag = (TagEndpoint) findObject(nativeHandle);
2738 if (tag != null) {
2739 byte[] buf = tag.readNdef();
2740 if (buf == null) {
2741 return null;
2742 }
2743
2744 /* Create an NdefMessage */
2745 try {
2746 return new NdefMessage(buf);
2747 } catch (FormatException e) {
2748 return null;
2749 }
2750 }
2751 return null;
2752 }
2753
2754 @Override
2755 public int ndefWrite(int nativeHandle, NdefMessage msg) throws RemoteException {
2756 NfcPermissions.enforceUserPermissions(mContext);
2757
2758 TagEndpoint tag;
2759
2760 // Check if NFC is enabled
2761 if (!isNfcEnabled()) {
2762 return ErrorCodes.ERROR_NOT_INITIALIZED;
2763 }
2764
2765 /* find the tag in the hmap */
2766 tag = (TagEndpoint) findObject(nativeHandle);
2767 if (tag == null) {
2768 return ErrorCodes.ERROR_IO;
2769 }
2770
2771 if (msg == null) return ErrorCodes.ERROR_INVALID_PARAM;
2772
2773 if (tag.writeNdef(msg.toByteArray())) {
2774 return ErrorCodes.SUCCESS;
2775 } else {
2776 return ErrorCodes.ERROR_IO;
2777 }
2778
2779 }
2780
2781 @Override
2782 public boolean ndefIsWritable(int nativeHandle) throws RemoteException {
2783 throw new UnsupportedOperationException();
2784 }
2785
2786 @Override
2787 public int ndefMakeReadOnly(int nativeHandle) throws RemoteException {
2788 NfcPermissions.enforceUserPermissions(mContext);
2789
2790 TagEndpoint tag;
2791
2792 // Check if NFC is enabled
2793 if (!isNfcEnabled()) {
2794 return ErrorCodes.ERROR_NOT_INITIALIZED;
2795 }
2796
2797 /* find the tag in the hmap */
2798 tag = (TagEndpoint) findObject(nativeHandle);
2799 if (tag == null) {
2800 return ErrorCodes.ERROR_IO;
2801 }
2802
2803 if (tag.makeReadOnly()) {
2804 return ErrorCodes.SUCCESS;
2805 } else {
2806 return ErrorCodes.ERROR_IO;
2807 }
2808 }
2809
2810 @Override
2811 public int formatNdef(int nativeHandle, byte[] key) 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.formatNdef(key)) {
2828 return ErrorCodes.SUCCESS;
2829 } else {
2830 return ErrorCodes.ERROR_IO;
2831 }
2832 }
2833
2834 @Override
2835 public Tag rediscover(int nativeHandle) throws RemoteException {
2836 NfcPermissions.enforceUserPermissions(mContext);
2837
2838 TagEndpoint tag = null;
2839
2840 // Check if NFC is enabled
2841 if (!isNfcEnabled()) {
2842 return null;
2843 }
2844
2845 /* find the tag in the hmap */
2846 tag = (TagEndpoint) findObject(nativeHandle);
2847 if (tag != null) {
2848 // For now the prime usecase for rediscover() is to be able
2849 // to access the NDEF technology after formatting without
2850 // having to remove the tag from the field, or similar
2851 // to have access to NdefFormatable in case low-level commands
2852 // were used to remove NDEF. So instead of doing a full stack
2853 // rediscover (which is poorly supported at the moment anyway),
2854 // we simply remove these two technologies and detect them
2855 // again.
2856 tag.removeTechnology(TagTechnology.NDEF);
2857 tag.removeTechnology(TagTechnology.NDEF_FORMATABLE);
2858 tag.findAndReadNdef();
2859 // Build a new Tag object to return
2860 Tag newTag = new Tag(tag.getUid(), tag.getTechList(),
2861 tag.getTechExtras(), tag.getHandle(), this);
2862 return newTag;
2863 }
2864 return null;
2865 }
2866
2867 @Override
2868 public int setTimeout(int tech, int timeout) throws RemoteException {
2869 NfcPermissions.enforceUserPermissions(mContext);
2870 boolean success = mDeviceHost.setTimeout(tech, timeout);
2871 if (success) {
2872 return ErrorCodes.SUCCESS;
2873 } else {
2874 return ErrorCodes.ERROR_INVALID_PARAM;
2875 }
2876 }
2877
2878 @Override
2879 public int getTimeout(int tech) throws RemoteException {
2880 NfcPermissions.enforceUserPermissions(mContext);
2881
2882 return mDeviceHost.getTimeout(tech);
2883 }
2884
2885 @Override
2886 public void resetTimeouts() throws RemoteException {
2887 NfcPermissions.enforceUserPermissions(mContext);
2888
2889 mDeviceHost.resetTimeouts();
2890 }
2891
2892 @Override
2893 public boolean canMakeReadOnly(int ndefType) throws RemoteException {
2894 return mDeviceHost.canMakeReadOnly(ndefType);
2895 }
2896
2897 @Override
2898 public int getMaxTransceiveLength(int tech) throws RemoteException {
2899 return mDeviceHost.getMaxTransceiveLength(tech);
2900 }
2901
2902 @Override
2903 public boolean getExtendedLengthApdusSupported() throws RemoteException {
2904 return mDeviceHost.getExtendedLengthApdusSupported();
2905 }
2906 }
2907
2908 final class NfcJcopService extends IJcopService.Stub{
2909
2910 public int jcopOsDownload(String pkg) throws RemoteException
2911 {
2912 NfcService.this.enforceNfceeAdminPerm(pkg);
2913 int status = ErrorCodes.SUCCESS;
2914 boolean mode;
2915 mode = mDeviceHost.doCheckJcopDlAtBoot();
2916 if(mode == false) {
2917 Log.i(TAG, "Starting getChipName");
2918 int Ver = mDeviceHost.getChipVer();
nxpandroid281eb922016-08-25 20:27:46 +05302919 if(Ver == PN80T_ID || Ver == PN67T_ID || Ver == PN66T_ID || Ver == PN65T_ID) {
nxpandroid64fd68c2015-09-23 16:45:15 +05302920 status = mDeviceHost.JCOSDownload();
nxpandroid7d44e572016-08-01 19:11:04 +05302921 }
2922 else {
2923 status = ErrorCodes.ERROR_NOT_SUPPORTED;
nxpandroid64fd68c2015-09-23 16:45:15 +05302924 }
2925 }
2926 else {
2927 status = ErrorCodes.ERROR_NOT_SUPPORTED;
2928 }
2929 return status;
2930 }
2931 }
2932 final class EseClientServicesAdapter extends IeSEClientServicesAdapter.Stub{
2933 @Override
2934 public IJcopService getJcopService() {
2935 if(mJcopService == null){
2936 mJcopService = new NfcJcopService();
2937 }
2938 return mJcopService;
2939 }
2940 @Override
2941 public ILoaderService getLoaderService() {
2942 if(mAlaService == null){
2943 mAlaService = new NfcAlaService();
2944 }
2945 return mAlaService;
2946 }
2947 @Override
2948 public INxpExtrasService getNxpExtrasService() {
2949 if(mNxpExtras == null){
2950 mNxpExtras = new NxpExtrasService();
2951 }
2952 return mNxpExtras;
2953 }
2954 };
2955
2956 final class NfcAlaService extends ILoaderService.Stub{
2957 private boolean isRecovery = false;
2958 private String appName = null;
2959 private String srcIn = null;
2960 private String respOut = null;
2961 private String status = "false";
2962
2963 void NfcAlaService()
2964 {
2965 appName = null;
2966 srcIn = null;
2967 respOut = null;
2968 status = "false";
2969 isRecovery = false;
2970 }
2971 private synchronized void LSReexecute()
2972 {
2973 byte[] ret = {0x4E,0x02,(byte)0x69,(byte)0x87};
2974 byte retry = LS_RETRY_CNT;
2975 PrintWriter out= null;
2976 BufferedReader br = null;
2977 Log.i(TAG, "Enter: NfcAlaService constructor");
2978 try{
2979 File f = new File(LS_BACKUP_PATH);
2980
2981 Log.i(TAG, "Enter: NfcAlaService constructor file open");
2982 /*If the file does not exists*/
2983 if(!(f.isFile()))
2984 {
2985 Log.i(TAG, "FileNotFound ls backup");
nxpandroid34627bd2016-05-27 15:52:30 +05302986 this.status = null;
nxpandroid64fd68c2015-09-23 16:45:15 +05302987 }
2988 /*If the file exists*/
2989 else
2990 {
2991 Log.i(TAG, "File Found ls backup");
2992 br = new BufferedReader(new FileReader(LS_BACKUP_PATH));
2993 this.appName = br.readLine();
2994 this.srcIn = br.readLine();
2995 this.respOut = br.readLine();
2996 this.status = br.readLine();
2997 }
2998 }catch(FileNotFoundException f)
2999 {
3000 Log.i(TAG, "FileNotFoundException Raised during LS Initialization");
3001 return;
3002 }
3003 catch(IOException ie)
3004 {
3005 Log.i(TAG, "IOException Raised during LS Initialization ");
3006 return;
3007 }
3008 finally{
3009 try{
nxpandroid64fd68c2015-09-23 16:45:15 +05303010 if(br != null)
3011 br.close();
nxpandroid34627bd2016-05-27 15:52:30 +05303012 /*If the file does not exist or empty file */
3013 if(this.status == null)
3014 {
3015 out = new PrintWriter(LS_BACKUP_PATH);
3016 this.status = "true";
3017 out.println("null");
3018 out.println("null");
3019 out.println("null");
3020 out.println("true");
3021 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303022 }catch(IOException e)
3023 {
3024 Log.i(TAG, "IOException Raised during LS Initialization ");
3025 return;
3026 }
nxpandroid34627bd2016-05-27 15:52:30 +05303027 finally{
3028 if(this.status == null)
3029 this.status = "true";
3030 if(out != null)
3031 out.close();
3032 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303033 }
3034 if(this.status.equals("true"))
3035 {
3036 Log.i(TAG, "LS Script execution completed");
3037 }
3038 else
3039 {
3040 Log.i(TAG, "LS Script execution aborted or tear down happened");
3041 Log.i(TAG, "Input script path"+ this.srcIn);
3042 Log.i(TAG, "Output response path"+ this.respOut);
3043 Log.i(TAG, "Application name which invoked LS"+ this.appName);
3044 try{
3045 File fSrc = new File(this.srcIn);
3046 File fRsp = new File(this.respOut);
3047 if((fSrc.isFile() && fRsp.isFile()))
3048 {
3049 byte[] lsAppletStatus = {0x6F,0x00};
3050 /*Perform lsExecuteScript on tear down*/
3051 WatchDogThread watchDog =
3052 new WatchDogThread("Loader service ", INIT_WATCHDOG_LS_MS);
3053 watchDog.start();
3054 try {
3055 mRoutingWakeLock.acquire();
3056 try {
3057 /*Reset retry counter*/
3058 while((retry-- > 0))
3059 {
3060 Thread.sleep(1000);
3061 lsAppletStatus = mNfcAla.doLsGetAppletStatus();
3062 if((lsAppletStatus[0]==0x63) && (lsAppletStatus[1]==0x40))
3063 {
3064 Log.i(TAG, "Started LS recovery since previous session failed");
3065 this.isRecovery = true;
3066 ret = this.lsExecuteScript(this.srcIn, this.respOut);
3067 }
3068 else
3069 {
3070 break;
3071 }
3072 }
3073 } finally {
3074 this.isRecovery = false;
3075 watchDog.cancel();
3076 mRoutingWakeLock.release();
3077 }
3078 }
3079 catch(RemoteException ie)
3080 {
3081 Log.i(TAG, "LS recovery Exception: ");
3082 }
3083 lsAppletStatus = mNfcAla.doLsGetAppletStatus();
3084 if((lsAppletStatus[0]==(byte)0x90)&&(lsAppletStatus[1]==(byte)0x00))
3085 {
3086 out = new PrintWriter(LS_BACKUP_PATH);
3087 out.println("null");
3088 out.println("null");
3089 out.println("null");
3090 out.println("true");
3091 out.close();
3092 Log.i(TAG, "Commiting Default Values of Loader Service AS RETRY ENDS: ");
3093 }
3094 }
3095 else
3096 {
3097 Log.i(TAG, "LS recovery not required");
3098 }
3099 }catch(InterruptedException re)
3100 {
3101 /*Retry failed todo*/
nxpandroid34627bd2016-05-27 15:52:30 +05303102 Log.i(TAG, "InterruptedException while LS recovery");
nxpandroid64fd68c2015-09-23 16:45:15 +05303103 }catch(FileNotFoundException re)
3104 {
3105 /*Retry failed todo*/
nxpandroid34627bd2016-05-27 15:52:30 +05303106 Log.i(TAG, "FileNotFoundException while LS recovery");
nxpandroid64fd68c2015-09-23 16:45:15 +05303107 }
3108 }
3109 }
3110 private void updateLoaderService() {
3111 byte[] ret = {0x4E,0x02,(byte)0x69,(byte)0x87};
3112 Log.i(TAG, "Enter: NfcAlaService constructor file open");
3113 File f = new File(LS_UPDATE_BACKUP_PATH);
nxpandroid34627bd2016-05-27 15:52:30 +05303114 /*If the file exists*/
nxpandroid64fd68c2015-09-23 16:45:15 +05303115 if((f.isFile()))
3116 {
3117 Log.i(TAG, "File Found LS update required");
3118 WatchDogThread watchDog =
3119 new WatchDogThread("LS Update Loader service ", (INIT_WATCHDOG_LS_MS+INIT_WATCHDOG_LS_MS));
3120 watchDog.start();
3121 try {
3122 try {
3123 /*Reset retry counter*/
3124 {
3125 Log.i(TAG, "Started LS update");
3126 ret = this.lsExecuteScript(LS_UPDATE_BACKUP_PATH, LS_UPDATE_BACKUP_OUT_PATH);
3127 if(ret[2] == (byte)(0x90) && ret[3] == (byte)(0x00))
3128 {
3129 Log.i(TAG, " LS update successfully completed");
3130 f.delete();
3131 } else {
3132 Log.i(TAG, " LS update failed");
3133 }
3134 }
3135 } finally {
3136 watchDog.cancel();
3137 }
3138 }
3139 catch(RemoteException ie)
3140 {
3141 Log.i(TAG, "LS update recovery Exception: ");
3142 }
3143 }
nxpandroid34627bd2016-05-27 15:52:30 +05303144 /*If the file does not exists*/
nxpandroid64fd68c2015-09-23 16:45:15 +05303145 else
3146 {
3147 Log.i(TAG, "No LS update");
3148 }
3149 }
3150
3151 public byte[] lsExecuteScript( String srcIn, String respOut) throws RemoteException {
3152 String pkg_name = getCallingAppPkg(mContext);
3153 byte[] sha_data = CreateSHA(pkg_name, 2);
3154 byte[] respSW = {0x4e,0x02,0x69,(byte)0x87};
3155 InputStream is = null;
3156 OutputStream os = null;
3157 PrintWriter out = null;
3158 FileReader fr = null;
3159 byte[] buffer = new byte[1024];
3160 int length = 0;
3161 String srcBackup = srcIn+"mw";
3162 String rspBackup = null;
3163 File rspFile = null;
3164 if(respOut != null)
3165 rspBackup = respOut+"mw";
3166 File srcFile = new File(srcBackup);
3167 if(respOut != null)
3168 rspFile = new File(rspBackup);
3169
3170
3171 /*If Previously Tear down happened before completion of LS execution*/
3172 if(this.isRecovery != false)
3173 {
3174 try{
3175 fr = new FileReader(LS_BACKUP_PATH);
3176 if(fr != null)
3177 {
3178 BufferedReader br = new BufferedReader(fr);
3179 if(br != null)
3180 {
3181 String appName = br.readLine();
3182 if(appName != null)
3183 {
3184 sha_data = CreateSHA(appName, 2);
3185 pkg_name = appName;
3186 }
3187 }
3188 }
3189 }catch(IOException ioe)
3190 {
3191 Log.i(TAG, "IOException thrown for opening ");
3192 }
3193 finally{
3194 try{
3195 if(fr != null)
3196 fr.close();
3197 }
3198 catch(IOException e)
3199 {
3200 Log.i(TAG, "IOException thrown for opening ");
3201 }
3202 }
3203 }
3204 /*Store it in File*/
3205 try{
3206 out = new PrintWriter(LS_BACKUP_PATH);
3207 out.println(pkg_name);
3208 out.println(srcIn);
3209 out.println(respOut);
3210 out.println(false);
3211 }catch(IOException fe)
3212 {
3213 Log.i(TAG, "IOException thrown during clearing ");
3214 }
3215 finally{
3216 if(out != null)
3217 out.close();
3218 }
3219 try{
3220 /*To avoid rewriting of backup file*/
3221 if(!(this.isRecovery)){
3222 is = new FileInputStream(srcIn);
3223 os = new FileOutputStream(srcBackup);
3224
3225 while((length = is.read(buffer))>0)
3226 {
3227 os.write(buffer,0,length);
3228 }
3229 if(is != null)is.close();
3230 if(os != null)os.close();}
3231 Log.i(TAG, "sha_data len : " + sha_data.length);
3232 Log.i(TAG, "Calling package APP Name is "+ pkg_name);
3233 if(sha_data != null)
3234 {
3235 respSW = mNfcAla.doLsExecuteScript(srcBackup, rspBackup, sha_data);
3236 }
3237 /*resp file is not null*/
3238 if(respOut != null){
3239 is = new FileInputStream(rspBackup);
3240 os = new FileOutputStream(respOut);
3241 length = 0;
3242 while((length = is.read(buffer))>0)
3243 {
3244 os.write(buffer,0,length);
3245 }
3246 }
3247 if(is != null)is.close();
3248 if(os != null)os.close();
3249 }catch(IOException ioe)
3250 {
3251 Log.i(TAG, "LS File not found");
3252 }catch(SecurityException se)
3253 {
3254 Log.i(TAG, "LS File access permission deneied");
3255 }
3256 finally{
3257 byte[] status = mNfcAla.doLsGetStatus();
3258 Log.i(TAG, "LS getStatus return SW1 : "+status[0]);
3259 Log.i(TAG, "LS getStatus return SW2: "+status[1]);
3260 if((status[0]== (byte)0x90) && (status[1] == 0x00))
3261 {
3262 try{
3263 out = new PrintWriter(LS_BACKUP_PATH);
3264 out.println("null");
3265 out.println("null");
3266 out.println("null");
3267 out.println("true");
3268 }catch(IOException fe)
3269 {
3270 Log.i(TAG, "FileNotFoundException thrown during clearing ");
3271 }
3272 finally
3273 {
3274 if(out != null)
3275 out.close();
3276 }
3277 Log.i(TAG, "COMMITTING THE DEFAULT VALUES OF LS : ");
3278 srcFile.delete();
3279 rspFile.delete();
3280 }
3281 else
3282 {
3283 Log.i(TAG, "NOT COMMITTING THE DEFAULT VALUES OF LS : ");
3284 }
3285 }
3286 return respSW;
3287 }
3288 public byte[] lsGetVersion()
3289 {
3290 byte[] respApdu = {0x4e,0x02,0x69,(byte)0x87};
3291
3292 respApdu = mNfcAla.doLsGetVersion();
3293 return respApdu;
3294 }
3295 public int appletLoadApplet(String pkg, String choice) throws RemoteException {
3296 String pkg_name = getCallingAppPkg(mContext);
3297 int state = 0;
3298 byte[] sha_data = CreateSHA(pkg_name, 1);
3299 Log.i(TAG, "sha_data len : " + sha_data.length);
3300
3301 if(sha_data != null)
3302 {
3303 state = mNfcAla.doAppletLoadApplet(choice, sha_data);
3304 return state;
3305 }
3306 else
3307 return 0xFF;
3308 }
3309 public int getListofApplets(String pkg, String[] name) throws RemoteException {
3310 int cnt = mNfcAla.GetAppletsList(name);
3311 Log.i(TAG, "GetListofApplets count : " + cnt);
3312 for(int i=0;i<cnt;i++) {
3313 Log.i(TAG, "GetListofApplets " + name[i]);
3314 }
3315
3316 return cnt;
3317 }
3318
nxpandroide68208c2017-02-24 16:08:04 +05303319 //Just Stub for compilation.
nxpandroid64fd68c2015-09-23 16:45:15 +05303320 public byte[] getKeyCertificate() throws RemoteException {
3321 return null;
3322 }
3323
3324 };
3325
nxpandroid64fd68c2015-09-23 16:45:15 +05303326 final class NxpExtrasService extends INxpExtrasService.Stub {
3327 private Bundle writeNoException() {
3328 Bundle p = new Bundle();
3329 p.putInt("e", 0);
3330 return p;
3331 }
3332
3333 private Bundle writeEeException(int exceptionType, String message) {
3334 Bundle p = new Bundle();
3335 p.putInt("e", exceptionType);
3336 p.putString("m", message);
3337 return p;
3338 }
3339
3340 @Override
nxpandroid5d64ce92016-11-18 19:48:53 +05303341 public Bundle getCallingAppPkg(String pkg, IBinder b) throws RemoteException {
3342 NfcService.this.enforceNfceeAdminPerm(pkg);
3343 Bundle result;
3344 String packageName;
3345 try{
3346 packageName = NfcService.this.getCallingAppPkg(mContext);
3347 result = writeNoException();
3348 result.putString("packageName", packageName);
3349 } catch(Exception e){
3350 result = writeEeException(EE_ERROR_IO, e.getMessage());
3351 }
3352 return result;
3353 }
3354
3355 @Override
nxpandroid64fd68c2015-09-23 16:45:15 +05303356 public boolean isEnabled()
3357 {
3358 try {
3359 return (mState == NfcAdapter.STATE_ON);
3360 } catch (Exception e) {
3361 Log.d(TAG, "Exception " + e.getMessage());
3362 return false;
3363 }
3364 }
3365
3366 @Override
3367 public byte[] getSecureElementUid(String pkg) throws RemoteException {
3368 NfcService.this.enforceNfceeAdminPerm(pkg);
3369 return mDeviceHost.getSecureElementUid();
3370 }
3371
3372 @Override
3373 public Bundle open(String pkg, IBinder b) throws RemoteException {
3374 NfcService.this.enforceNfceeAdminPerm(pkg);
3375
3376 Bundle result;
3377 int handle = _open(b);
3378 if (handle < 0) {
3379 result = writeEeException(handle, "NFCEE open exception.");
3380 } else {
3381 result = writeNoException();
3382 }
3383 return result;
3384 }
3385
3386 /**
3387 * Opens a connection to the secure element.
3388 *
3389 * @return A handle with a value >= 0 in case of success, or a
3390 * negative value in case of failure.
3391 */
3392 private int _open(IBinder b) {
3393 synchronized(NfcService.this) {
3394 if (!isNfcEnabled()) {
3395 return EE_ERROR_NFC_DISABLED;
3396 }
3397 if (mInProvisionMode) {
3398 // Deny access to the NFCEE as long as the device is being setup
3399 return EE_ERROR_IO;
3400 }
nxpandroide68208c2017-02-24 16:08:04 +05303401
nxpandroid64fd68c2015-09-23 16:45:15 +05303402 if (mOpenEe != null) {
3403 return EE_ERROR_ALREADY_OPEN;
3404 }
3405
3406 boolean restorePolling = false;
3407 if (mNfcPollingEnabled) {
3408 // Disable polling for tags/P2P when connecting to the SMX
3409 // on PN544-based devices. Whenever nfceeClose is called,
3410 // the polling configuration will be restored.
3411 mDeviceHost.disableDiscovery();
3412 mNfcPollingEnabled = false;
3413 restorePolling = true;
3414 }
nxpandroid7d44e572016-08-01 19:11:04 +05303415 int handle = doOpenSecureElementConnection(0xF3);
nxpandroid64fd68c2015-09-23 16:45:15 +05303416 if (handle < 0) {
3417
3418 if (restorePolling) {
3419 mDeviceHost.enableDiscovery(mCurrentDiscoveryParameters, true);
3420 mNfcPollingEnabled = true;
3421 }
3422 return handle;
3423 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303424
3425 mOpenEe = new OpenSecureElement(getCallingPid(), handle, b);
3426 try {
3427 b.linkToDeath(mOpenEe, 0);
3428 } catch (RemoteException e) {
3429 mOpenEe.binderDied();
3430 }
3431
3432 // Add the calling package to the list of packages that have accessed
3433 // the secure element.
3434 for (String packageName : mContext.getPackageManager().getPackagesForUid(getCallingUid())) {
3435 mSePackages.add(packageName);
3436 }
3437
3438 return handle;
3439 }
3440 }
3441
3442 @Override
3443 public Bundle close(String pkg, IBinder binder) throws RemoteException {
3444 NfcService.this.enforceNfceeAdminPerm(pkg);
3445
3446 Bundle result;
3447 try {
3448 _nfcEeClose(getCallingPid(), binder);
3449 result = writeNoException();
3450 } catch (IOException e) {
3451 result = writeEeException(EE_ERROR_IO, e.getMessage());
3452 }
3453 return result;
3454 }
3455 @Override
3456 public Bundle transceive(String pkg, byte[] in) throws RemoteException {
3457 NfcService.this.enforceNfceeAdminPerm(pkg);
3458
3459 Bundle result;
3460 byte[] out;
3461 try {
3462 out = _transceive(in);
3463 result = writeNoException();
3464 result.putByteArray("out", out);
3465 } catch (IOException e) {
3466 result = writeEeException(EE_ERROR_IO, e.getMessage());
3467 }
3468 return result;
3469 }
3470
3471 private byte[] _transceive(byte[] data) throws IOException {
3472 synchronized(NfcService.this) {
3473 if (!isNfcEnabled()) {
3474 throw new IOException("NFC is not enabled");
3475 }
3476 if (mOpenEe == null) {
3477 throw new IOException("NFC EE is not open");
3478 }
3479 if (getCallingPid() != mOpenEe.pid) {
3480 throw new SecurityException("Wrong PID");
3481 }
3482 }
3483
3484 return doTransceive(mOpenEe.handle, data);
3485 }
3486 };
nxpandroid64fd68c2015-09-23 16:45:15 +05303487
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05303488
3489 final class NfcDtaService extends INfcDta.Stub {
3490 public void enableDta() throws RemoteException {
nxpandroid64fd68c2015-09-23 16:45:15 +05303491 NfcPermissions.enforceAdminPermissions(mContext);
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05303492 if(!sIsDtaMode) {
nxpandroid64fd68c2015-09-23 16:45:15 +05303493 mDeviceHost.enableDtaMode();
nxpandroid281eb922016-08-25 20:27:46 +05303494 sIsDtaMode = true;
nxpandroid64fd68c2015-09-23 16:45:15 +05303495 Log.d(TAG, "DTA Mode is Enabled ");
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05303496 }
3497 }
3498
3499 public void disableDta() throws RemoteException {
3500 NfcPermissions.enforceAdminPermissions(mContext);
3501 if(sIsDtaMode) {
nxpandroid64fd68c2015-09-23 16:45:15 +05303502 mDeviceHost.disableDtaMode();
nxpandroid281eb922016-08-25 20:27:46 +05303503 sIsDtaMode = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05303504 }
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05303505 }
3506
3507 public boolean enableServer(String serviceName, int serviceSap, int miu,
3508 int rwSize,int testCaseId) throws RemoteException {
3509 NfcPermissions.enforceAdminPermissions(mContext);
3510
3511 if(serviceName.equals(null))
3512 return false;
3513
3514 mP2pLinkManager.enableExtDtaSnepServer(serviceName, serviceSap, miu, rwSize,testCaseId);
nxpandroid64fd68c2015-09-23 16:45:15 +05303515 return true;
3516 }
3517
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05303518 public void disableServer() throws RemoteException {
3519 NfcPermissions.enforceAdminPermissions(mContext);
3520 mP2pLinkManager.disableExtDtaSnepServer();
3521 }
3522
3523 public boolean enableClient(String serviceName, int miu, int rwSize,
3524 int testCaseId) throws RemoteException {
3525 NfcPermissions.enforceAdminPermissions(mContext);
3526
3527 if(testCaseId == 0)
3528 return false;
3529
3530 if (testCaseId>20){
3531 sIsShortRecordLayout=true;
3532 testCaseId=testCaseId-20;
3533 } else {
3534 sIsShortRecordLayout=false;
3535 }
3536 Log.d("testCaseId", ""+testCaseId);
3537 mP2pLinkManager.enableDtaSnepClient(serviceName, miu, rwSize, testCaseId);
3538 return true;
3539 }
3540
3541 public void disableClient() throws RemoteException {
3542 NfcPermissions.enforceAdminPermissions(mContext);
3543 mP2pLinkManager.disableDtaSnepClient();
3544 }
3545
3546 public boolean registerMessageService(String msgServiceName)
3547 throws RemoteException {
3548 NfcPermissions.enforceAdminPermissions(mContext);
3549 if(msgServiceName.equals(null))
3550 return false;
3551
3552 DtaServiceConnector.setMessageService(msgServiceName);
3553 return true;
3554 }
3555 };
nxpandroid64fd68c2015-09-23 16:45:15 +05303556
3557 final class NfcVzwService extends INfcVzw.Stub {
3558 @Override
3559 public void setScreenOffCondition(boolean enable) throws RemoteException {
3560
3561 Message msg = mHandler.obtainMessage();
3562 msg.what=MSG_SET_SCREEN_STATE;
3563 msg.arg1= (enable)?1:0;
3564 mHandler.sendMessage(msg);
3565
3566 }
3567
3568 @Override
3569 public boolean setVzwAidList(RouteEntry[] entries)
3570 throws RemoteException {
nxpandroid64fd68c2015-09-23 16:45:15 +05303571 Log.i(TAG, "setVzwAidList enter");
3572 Log.i(TAG, "setVzwAidList entries length =" + entries.length);
3573 if (mIsHceCapable) {
3574 mAidRoutingManager.ClearVzwCache();
3575 for (int i = 0; i < entries.length; i++) {
3576 RouteEntry routeEntry = entries[i];
3577 mAidRoutingManager.UpdateVzwCache(routeEntry.getAid(),
3578 routeEntry.getLocation(), routeEntry.getPowerState(),
3579 routeEntry.isAllowed());
3580
3581 Log.i(TAG,
3582 "AID" + routeEntry.getAid() + "Location "
3583 + routeEntry.getLocation() + "powerstate "
3584 + routeEntry.getPowerState());
3585 }
3586 mAidRoutingManager.onNfccRoutingTableCleared();
3587 mCardEmulationManager.onRoutingTableChanged();
3588 return true;
3589 } else {
3590 return false;
3591 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303592 }
3593
3594 };
3595
3596 void _nfcEeClose(int callingPid, IBinder binder) throws IOException {
3597 // Blocks until a pending open() or transceive() times out.
3598 //TODO: This is incorrect behavior - the close should interrupt pending
3599 // operations. However this is not supported by current hardware.
3600
3601 synchronized (NfcService.this) {
3602 if (!isNfcEnabledOrShuttingDown()) {
3603 throw new IOException("NFC adapter is disabled");
3604 }
3605 if (mOpenEe == null) {
3606 throw new IOException("NFC EE closed");
3607 }
3608 if (callingPid != -1 && callingPid != mOpenEe.pid) {
3609 throw new SecurityException("Wrong PID");
3610 }
3611 if (mOpenEe.binder != binder) {
3612 throw new SecurityException("Wrong binder handle");
3613 }
3614
3615 binder.unlinkToDeath(mOpenEe, 0);
3616 mDeviceHost.resetTimeouts();
3617 doDisconnect(mOpenEe.handle);
3618 mOpenEe = null;
nxpandroid64fd68c2015-09-23 16:45:15 +05303619 }
3620 }
3621
3622 boolean _nfcEeReset() throws IOException {
3623 synchronized (NfcService.this) {
3624 if (!isNfcEnabledOrShuttingDown()) {
3625 throw new IOException("NFC adapter is disabled");
3626 }
3627 if (mOpenEe == null) {
3628 throw new IOException("NFC EE closed");
3629 }
3630 return mSecureElement.doReset(mOpenEe.handle);
3631 }
3632 }
3633
3634 final class NfcAccessExtrasService extends INxpNfcAccessExtras.Stub {
3635 public boolean checkChannelAdminAccess(String pkg) throws RemoteException {
3636 boolean result = true;
3637 try {
3638 NfcService.this.enforceNfcSccAdminPerm(pkg);
3639 } catch (Exception e) {
3640 e.printStackTrace();
3641 result = false;
3642 }
3643 return result;
3644 }
3645 };
3646
3647 final class NfcAdapterExtrasService extends INfcAdapterExtras.Stub {
3648 private Bundle writeNoException() {
3649 Bundle p = new Bundle();
3650 p.putInt("e", 0);
3651 return p;
3652 }
3653
3654 private Bundle writeEeException(int exceptionType, String message) {
3655 Bundle p = new Bundle();
3656 p.putInt("e", exceptionType);
3657 p.putString("m", message);
3658 return p;
3659 }
3660
3661 @Override
3662 public Bundle open(String pkg, IBinder b) throws RemoteException {
3663 NfcService.this.enforceNfceeAdminPerm(pkg);
3664
3665 Bundle result;
3666 int handle = _open(b);
3667 if (handle < 0) {
3668 result = writeEeException(handle, "NFCEE open exception.");
3669 } else {
3670 result = writeNoException();
3671 }
3672 return result;
3673 }
3674
3675 /**
3676 * Opens a connection to the secure element.
3677 *
3678 * @return A handle with a value >= 0 in case of success, or a
3679 * negative value in case of failure.
3680 */
3681 private int _open(IBinder b) {
3682 synchronized(NfcService.this) {
3683 if (!isNfcEnabled()) {
3684 return EE_ERROR_NFC_DISABLED;
3685 }
3686 if (mInProvisionMode) {
3687 // Deny access to the NFCEE as long as the device is being setup
3688 return EE_ERROR_IO;
3689 }
nxpandroid7d44e572016-08-01 19:11:04 +05303690 /*Concurrent access for DWP transactions to be allowed even when P2P is already ongoing */
3691 /*
nxpandroid64fd68c2015-09-23 16:45:15 +05303692 if (mP2pLinkManager.isLlcpActive()) {
3693 // Don't allow PN544-based devices to open the SE while the LLCP
3694 // link is still up or in a debounce state. This avoids race
3695 // conditions in the NXP stack around P2P/SMX switching.
3696 return EE_ERROR_EXT_FIELD;
nxpandroid7d44e572016-08-01 19:11:04 +05303697 }*/
nxpandroid64fd68c2015-09-23 16:45:15 +05303698 if (mOpenEe != null) {
3699 Log.i(TAG, "SE is Busy. returning..");
3700 return EE_ERROR_ALREADY_OPEN;
3701 }
3702 boolean restorePolling = false;
3703 if (mNfcPollingEnabled) {
3704 // Disable polling for tags/P2P when connecting to the SMX
3705 // on PN544-based devices. Whenever nfceeClose is called,
3706 // the polling configuration will be restored.
3707 mDeviceHost.disableDiscovery();
3708 mNfcPollingEnabled = false;
3709 restorePolling = true;
3710 }
3711
nxpandroid7d44e572016-08-01 19:11:04 +05303712 int handle = doOpenSecureElementConnection(0xF3);
nxpandroid64fd68c2015-09-23 16:45:15 +05303713 if (handle < 0) {
3714
3715 if (restorePolling) {
3716 mDeviceHost.enableDiscovery(mCurrentDiscoveryParameters, true);
3717 mNfcPollingEnabled = true;
3718 }
3719 return handle;
3720 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303721 mOpenEe = new OpenSecureElement(getCallingPid(), handle, b);
3722 try {
3723 b.linkToDeath(mOpenEe, 0);
3724 } catch (RemoteException e) {
3725 mOpenEe.binderDied();
3726 }
3727
3728 // Add the calling package to the list of packages that have accessed
3729 // the secure element.
3730 for (String packageName : mContext.getPackageManager().getPackagesForUid(getCallingUid())) {
3731 mSePackages.add(packageName);
3732 }
3733
3734 return handle;
3735 }
3736 }
3737
3738 @Override
3739 public Bundle close(String pkg, IBinder binder) throws RemoteException {
3740 NfcService.this.enforceNfceeAdminPerm(pkg);
3741
3742 Bundle result;
3743 try {
3744 _nfcEeClose(getCallingPid(), binder);
3745 result = writeNoException();
3746 } catch (IOException e) {
3747 result = writeEeException(EE_ERROR_IO, e.getMessage());
3748 }
3749 return result;
3750 }
3751
nxpandroid64fd68c2015-09-23 16:45:15 +05303752 @Override
3753 public Bundle transceive(String pkg, byte[] in) throws RemoteException {
3754 NfcService.this.enforceNfceeAdminPerm(pkg);
3755
3756 Bundle result;
3757 byte[] out;
3758 try {
3759 out = _transceive(in);
3760 result = writeNoException();
3761 result.putByteArray("out", out);
3762 } catch (IOException e) {
3763 result = writeEeException(EE_ERROR_IO, e.getMessage());
3764 }
3765 return result;
3766 }
3767
3768 private byte[] _transceive(byte[] data) throws IOException {
3769 synchronized(NfcService.this) {
3770 if (!isNfcEnabled()) {
3771 throw new IOException("NFC is not enabled");
3772 }
3773 if (mOpenEe == null) {
3774 throw new IOException("NFC EE is not open");
3775 }
3776 if (getCallingPid() != mOpenEe.pid) {
3777 throw new SecurityException("Wrong PID");
3778 }
3779 }
3780
3781 return doTransceive(mOpenEe.handle, data);
3782 }
3783
nxpandroid64fd68c2015-09-23 16:45:15 +05303784 @Override
3785 public int getCardEmulationRoute(String pkg) throws RemoteException {
3786 NfcService.this.enforceNfceeAdminPerm(pkg);
3787 return mEeRoutingState;
3788 }
3789
3790 @Override
3791 public void setCardEmulationRoute(String pkg, int route) throws RemoteException {
3792 NfcService.this.enforceNfceeAdminPerm(pkg);
3793 mEeRoutingState = route;
3794 ApplyRoutingTask applyRoutingTask = new ApplyRoutingTask();
3795 applyRoutingTask.execute();
3796 try {
3797 // Block until route is set
3798 applyRoutingTask.get();
3799 } catch (ExecutionException e) {
3800 Log.e(TAG, "failed to set card emulation mode");
3801 } catch (InterruptedException e) {
3802 Log.e(TAG, "failed to set card emulation mode");
3803 }
3804 }
3805
3806 @Override
3807 public void authenticate(String pkg, byte[] token) throws RemoteException {
3808 NfcService.this.enforceNfceeAdminPerm(pkg);
3809 }
3810
3811 @Override
3812 public String getDriverName(String pkg) throws RemoteException {
3813 NfcService.this.enforceNfceeAdminPerm(pkg);
3814 return mDeviceHost.getName();
3815 }
3816
3817 }
3818 final class NxpNfcAdapterExtrasService extends INxpNfcAdapterExtras.Stub {
3819 private Bundle writeNoException() {
3820 Bundle p = new Bundle();
3821 p.putInt("e", 0);
3822 return p;
3823 }
3824
3825 private Bundle writeEeException(int exceptionType, String message) {
3826 Bundle p = new Bundle();
3827 p.putInt("e", exceptionType);
3828 p.putString("m", message);
3829 return p;
3830 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303831
nxpandroid5d64ce92016-11-18 19:48:53 +05303832 @Override
3833 public boolean eSEChipReset(String pkg) throws RemoteException {
3834 NfcService.this.enforceNfceeAdminPerm(pkg);
3835 Bundle result;
3836 boolean stat = false;
3837 try {
3838 synchronized (NfcService.this) {
3839 if (!isNfcEnabledOrShuttingDown()) {
3840 throw new IOException("NFC adapter is disabled");
3841 }
3842 if (mOpenEe == null) {
3843 throw new IOException("NFC EE closed");
3844 }
3845 stat = mSecureElement.doeSEChipReset();
3846 }
3847 result = writeNoException();
3848 } catch (IOException e) {
3849 result = writeEeException(EE_ERROR_IO, e.getMessage());
3850 }
3851 return stat;
3852 }
3853
3854 @Override
nxpandroid64fd68c2015-09-23 16:45:15 +05303855 public boolean reset(String pkg) throws RemoteException {
3856 NfcService.this.enforceNfceeAdminPerm(pkg);
3857 Bundle result;
3858 boolean stat = false;
3859 try {
3860 stat = _nfcEeReset();
3861 result = writeNoException();
3862 } catch (IOException e) {
3863 result = writeEeException(EE_ERROR_IO, e.getMessage());
3864 }
3865 Log.d(TAG,"reset" + stat);
3866 return stat;
3867 }
3868
3869 boolean _nfcEeReset() throws IOException {
3870 synchronized (NfcService.this) {
3871 if (!isNfcEnabledOrShuttingDown()) {
3872 throw new IOException("NFC adapter is disabled");
3873 }
3874 if (mOpenEe == null) {
3875 throw new IOException("NFC EE closed");
3876 }
3877 return mSecureElement.doReset(mOpenEe.handle);
3878 }
3879 }
3880
3881 @Override
3882 public int getSecureElementTechList(String pkg) throws RemoteException {
3883 NfcService.this.enforceNfceeAdminPerm(pkg);
3884 return mDeviceHost.doGetSecureElementTechList();
3885 }
3886
3887 @Override
3888 public byte[] getSecureElementUid(String pkg) throws RemoteException {
3889 NfcService.this.enforceNfceeAdminPerm(pkg);
3890 return mDeviceHost.getSecureElementUid();
3891 }
3892
3893 @Override
3894 public void notifyCheckCertResult(String pkg, boolean success)
3895 throws RemoteException {
3896 if (DBG) Log.d(TAG, "notifyCheckCertResult() " + pkg + ", success=" + success);
3897
3898 NfcService.this.enforceNfceeAdminPerm(pkg);
nxpandroid64fd68c2015-09-23 16:45:15 +05303899 mNxpNfcController.setResultForX509Certificates(success);
nxpandroid64fd68c2015-09-23 16:45:15 +05303900 }
3901
3902 @Override
3903 public void deliverSeIntent(String pkg, Intent seIntent)
3904 throws RemoteException {
3905 Log.d(TAG, "deliverSeIntent() " + pkg + " " + seIntent.getAction());
3906 NfcService.this.enforceNfceeAdminPerm(pkg);
nxpandroid64fd68c2015-09-23 16:45:15 +05303907 sendMessage(MSG_SE_DELIVER_INTENT, seIntent);
3908 }
3909
3910 @Override
3911 public byte[] doGetRouting() throws RemoteException {
3912 return mDeviceHost.doGetRouting();
3913 }
3914
3915 @Override
3916 public Bundle getAtr(String pkg) throws RemoteException {
3917 NfcService.this.enforceNfceeAdminPerm(pkg);
3918
3919 Bundle result;
3920 byte[] out;
3921 try {
3922 out = _getAtr();
3923 result = writeNoException();
3924 result.putByteArray("out", out);
3925 } catch (IOException e) {
3926 result = writeEeException(EE_ERROR_IO, e.getMessage());
3927 }
3928 Log.d(TAG,"getAtr result " + result);
3929 return result;
3930 }
3931
3932 private byte[] _getAtr() throws IOException {
3933 synchronized(NfcService.this) {
3934 if (!isNfcEnabled()) {
3935 throw new IOException("NFC is not enabled");
3936 }
3937 if (mOpenEe == null) {
3938 throw new IOException("NFC EE is not open");
3939 }
3940 if (getCallingPid() != mOpenEe.pid) {
3941 throw new SecurityException("Wrong PID");
3942 }
3943 }
3944 return mSecureElement.doGetAtr(mOpenEe.handle);
3945 }
nxpandroid34627bd2016-05-27 15:52:30 +05303946 @Override
3947 public int selectUicc(int uiccSlot) throws RemoteException {
3948 synchronized(NfcService.this) {
3949 if (!isNfcEnabled()) {
3950 throw new RemoteException("NFC is not enabled");
3951 }
3952 int status = mDeviceHost.doselectUicc(uiccSlot);
3953 Log.i(TAG, "Update routing table");
3954 /*In case of UICC connected and Enabled or Removed ,
3955 *Reconfigure the routing table based on current UICC parameters
3956 **/
3957 if((status == 0x00)||(status == 0x01))
3958 {
nxpandroidebf53fb2016-12-22 18:48:59 +05303959 mPrefsEditor.putInt(PREF_CUR_SELECTED_UICC_ID, uiccSlot);
3960 mPrefsEditor.apply();
nxpandroid34627bd2016-05-27 15:52:30 +05303961 if((mAidRoutingManager != null) && (mCardEmulationManager != null))
3962 {
3963 Log.i(TAG, "Update routing table");
3964 mAidRoutingManager.onNfccRoutingTableCleared();
nxpandroid810c4772017-04-10 18:28:54 +05303965 mIsRoutingTableDirty = true;
nxpandroid34627bd2016-05-27 15:52:30 +05303966 mCardEmulationManager.onNfcEnabled();
nxpandroid34627bd2016-05-27 15:52:30 +05303967 }
3968 else
3969 {
3970 Log.i(TAG, "Update only Mifare and Desfire route");
3971 mIsRoutingTableDirty = true;
3972 applyRouting(false);
3973 }
3974 }
3975 return status;
3976 }
3977 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303978
nxpandroid34627bd2016-05-27 15:52:30 +05303979 @Override
3980 public int getSelectedUicc() throws RemoteException {
3981 if (!isNfcEnabled()) {
3982 throw new RemoteException("NFC is not enabled");
3983 }
3984 return mDeviceHost.doGetSelectedUicc();
3985 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303986
nxpandroid7d44e572016-08-01 19:11:04 +05303987 @Override
3988 public Bundle openuicc(String pkg, IBinder b) throws RemoteException {
3989 NfcService.this.enforceNfceeAdminPerm(pkg);
3990
3991 Bundle result;
3992 int handle = _openuicc(b);
3993 if (handle < 0) {
3994 result = writeEeException(handle, "NFCEE UICC open exception.");
3995 } else {
3996 result = writeNoException();
3997 }
3998 return result;
3999 }
4000
4001 /**
4002 * Opens a connection to the UICC element.
4003 *
4004 * @return A handle with a value >= 0 in case of success, or a
4005 * negative value in case of failure.
4006 */
4007 private int _openuicc(IBinder b) {
4008 synchronized(NfcService.this) {
4009 if (!isNfcEnabled()) {
4010 return EE_ERROR_NFC_DISABLED;
4011 }
4012 if (mInProvisionMode) {
4013 // Deny access to the NFCEE as long as the device is being setup
4014 return EE_ERROR_IO;
4015 }
nxpandroid7d44e572016-08-01 19:11:04 +05304016 if (mOpenEe != null) {
4017 return EE_ERROR_ALREADY_OPEN;
4018 }
4019
4020 boolean restorePolling = false;
4021 if (mNfcPollingEnabled) {
4022 // Disable polling for tags/P2P when connecting to the SMX
4023 // on PN544-based devices. Whenever nfceeClose is called,
4024 // the polling configuration will be restored.
4025 mDeviceHost.disableDiscovery();
4026 mNfcPollingEnabled = false;
4027 restorePolling = true;
4028 }
4029
4030 int handle = doOpenSecureElementConnection(0xF4);
4031 if (handle < 0) {
4032
4033 if (restorePolling) {
4034 mDeviceHost.enableDiscovery(mCurrentDiscoveryParameters, true);
4035 mNfcPollingEnabled = true;
4036 }
4037 return handle;
4038 }
nxpandroid7d44e572016-08-01 19:11:04 +05304039
4040 mOpenEe = new OpenSecureElement(getCallingPid(), handle, b);
4041 try {
4042 b.linkToDeath(mOpenEe, 0);
4043 } catch (RemoteException e) {
4044 mOpenEe.binderDied();
4045 }
4046
4047 // Add the calling package to the list of packages that have accessed
4048 // the secure element.
4049 for (String packageName : mContext.getPackageManager().getPackagesForUid(getCallingUid())) {
4050 mSePackages.add(packageName);
4051 }
4052
4053 return handle;
4054 }
4055 }
4056
4057 @Override
4058 public Bundle closeuicc(String pkg, IBinder binder) throws RemoteException {
4059 NfcService.this.enforceNfceeAdminPerm(pkg);
4060
4061 Bundle result;
4062 try {
4063 Log.w("Nxp", "Close UICC!");
4064 _nfcEeClose(getCallingPid(), binder);
4065 result = writeNoException();
4066 } catch (IOException e) {
4067 result = writeEeException(EE_ERROR_IO, e.getMessage());
4068 }
4069 return result;
4070 }
4071
4072 @Override
4073 public Bundle transceiveuicc(String pkg, byte[] in) throws RemoteException {
4074 NfcService.this.enforceNfceeAdminPerm(pkg);
4075
4076 Bundle result;
4077 byte[] out;
4078 try {
4079 out = _transceiveuicc(in);
4080 result = writeNoException();
4081 result.putByteArray("out", out);
4082 } catch (IOException e) {
4083 result = writeEeException(EE_ERROR_IO, e.getMessage());
4084 }
4085 return result;
4086 }
4087
4088 private byte[] _transceiveuicc(byte[] data) throws IOException {
4089 synchronized(NfcService.this) {
4090 if (!isNfcEnabled()) {
4091 throw new IOException("NFC is not enabled");
4092 }
4093 if (mOpenEe == null) {
4094 throw new IOException("NFC EE is not open");
4095 }
4096 if (getCallingPid() != mOpenEe.pid) {
4097 throw new SecurityException("Wrong PID");
4098 }
4099 }
4100
4101 return doTransceive(mOpenEe.handle, data);
4102 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304103 }
4104
4105 /** resources kept while secure element is open */
4106 private class OpenSecureElement implements IBinder.DeathRecipient {
4107 public int pid; // pid that opened SE
4108 // binder handle used for DeathReceipient. Must keep
4109 // a reference to this, otherwise it can get GC'd and
4110 // the binder stub code might create a different BinderProxy
4111 // for the same remote IBinder, causing mismatched
4112 // link()/unlink()
4113 public IBinder binder;
4114 public int handle; // low-level handle
4115 public OpenSecureElement(int pid, int handle, IBinder binder) {
4116 this.pid = pid;
4117 this.handle = handle;
4118 this.binder = binder;
4119 }
4120 @Override
4121 public void binderDied() {
4122 synchronized (NfcService.this) {
4123 Log.i(TAG, "Tracked app " + pid + " died");
4124 pid = -1;
4125 try {
4126 _nfcEeClose(-1, binder);
4127 } catch (IOException e) { /* already closed */ }
4128 }
4129 }
4130 @Override
4131 public String toString() {
4132 return new StringBuilder('@').append(Integer.toHexString(hashCode())).append("[pid=")
4133 .append(pid).append(" handle=").append(handle).append("]").toString();
4134 }
4135 }
4136
4137 boolean isNfcEnabledOrShuttingDown() {
4138 synchronized (this) {
4139 return (mState == NfcAdapter.STATE_ON || mState == NfcAdapter.STATE_TURNING_OFF);
4140 }
4141 }
4142
4143 boolean isNfcEnabled() {
4144 synchronized (this) {
4145 return mState == NfcAdapter.STATE_ON;
4146 }
4147 }
4148
4149 class WatchDogThread extends Thread {
4150 final Object mCancelWaiter = new Object();
4151 final int mTimeout;
4152 boolean mCanceled = false;
4153
4154 public WatchDogThread(String threadName, int timeout) {
4155 super(threadName);
4156 mTimeout = timeout;
4157 }
4158
4159 @Override
4160 public void run() {
4161 try {
4162 synchronized (mCancelWaiter) {
4163 mCancelWaiter.wait(mTimeout);
4164 if (mCanceled) {
4165 return;
4166 }
4167 }
4168 } catch (InterruptedException e) {
4169 // Should not happen; fall-through to abort.
4170 Log.w(TAG, "Watchdog thread interruped.");
4171 interrupt();
4172 }
4173 Log.e(TAG, "Watchdog triggered, aborting.");
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304174 mDeviceHost.doAbort(getName());
nxpandroid64fd68c2015-09-23 16:45:15 +05304175 }
4176
4177 public synchronized void cancel() {
4178 synchronized (mCancelWaiter) {
4179 mCanceled = true;
4180 mCancelWaiter.notify();
4181 }
4182 }
4183 }
4184
4185 /* For Toast from background process*/
4186
4187 public class ToastHandler
4188 {
4189 // General attributes
4190 private Context mContext;
4191 private Handler mHandler;
4192
4193 public ToastHandler(Context _context)
4194 {
4195 this.mContext = _context;
4196 this.mHandler = new Handler();
4197 }
4198
4199 /**
4200 * Runs the <code>Runnable</code> in a separate <code>Thread</code>.
4201 *
4202 * @param _runnable
4203 * The <code>Runnable</code> containing the <code>Toast</code>
4204 */
4205 private void runRunnable(final Runnable _runnable)
4206 {
4207 Thread thread = new Thread()
4208 {
4209 public void run()
4210 {
4211 mHandler.post(_runnable);
4212 }
4213 };
4214
4215 thread.start();
4216 thread.interrupt();
4217 thread = null;
4218 }
4219
4220 public void showToast(final CharSequence _text, final int _duration)
4221 {
4222 final Runnable runnable = new Runnable()
4223 {
4224 @Override
4225 public void run()
4226 {
4227 Toast.makeText(mContext, _text, _duration).show();
4228 }
4229 };
4230
4231 runRunnable(runnable);
4232 }
4233 }
4234
4235 static byte[] hexStringToBytes(String s) {
4236 if (s == null || s.length() == 0) return null;
4237 int len = s.length();
4238 if (len % 2 != 0) {
4239 s = '0' + s;
4240 len++;
4241 }
4242 byte[] data = new byte[len / 2];
4243 for (int i = 0; i < len; i += 2) {
4244 data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
4245 + Character.digit(s.charAt(i + 1), 16));
4246 }
4247 return data;
4248 }
4249
4250 static String toHexString(byte[] buffer, int offset, int length) {
nxpandroid281eb922016-08-25 20:27:46 +05304251 final char[] hexChars = "0123456789abcdef".toCharArray();
nxpandroid64fd68c2015-09-23 16:45:15 +05304252 char[] chars = new char[2 * length];
4253 for (int j = offset; j < offset + length; ++j) {
nxpandroid281eb922016-08-25 20:27:46 +05304254 chars[2 * (j-offset)] = hexChars[(buffer[j] & 0xF0) >>> 4];
4255 chars[2 * (j-offset) + 1] = hexChars[buffer[j] & 0x0F];
nxpandroid64fd68c2015-09-23 16:45:15 +05304256 }
4257 return new String(chars);
4258 }
4259
4260 /**
4261 * Read mScreenState and apply NFC-C polling and NFC-EE routing
4262 */
4263 void applyRouting(boolean force) {
4264 Log.d(TAG, "applyRouting - enter force = " + force + " mScreenState = " + mScreenState);
4265
4266 synchronized (this) {
4267 //Since Reader mode during wired mode is supported
4268 //enableDiscovery or disableDiscovery is allowed
nxpandroid64fd68c2015-09-23 16:45:15 +05304269 if (!isNfcEnabledOrShuttingDown()) {
4270 // PN544 cannot be reconfigured while EE is open
4271 return;
4272 }
4273 WatchDogThread watchDog = new WatchDogThread("applyRouting", ROUTING_WATCHDOG_MS);
4274 if (mInProvisionMode) {
4275 mInProvisionMode = Settings.Secure.getInt(mContentResolver,
4276 Settings.Global.DEVICE_PROVISIONED, 0) == 0;
4277 if (!mInProvisionMode) {
4278 // Notify dispatcher it's fine to dispatch to any package now
4279 // and allow handover transfers.
4280 mNfcDispatcher.disableProvisioningMode();
nxpandroid1153eb32015-11-06 18:46:58 +05304281 /* if provision mode is disabled, then send this info to lower layers as well */
4282 mDeviceHost.doSetProvisionMode(mInProvisionMode);
nxpandroid64fd68c2015-09-23 16:45:15 +05304283 }
4284 }
4285 // Special case: if we're transitioning to unlocked state while
4286 // still talking to a tag, postpone re-configuration.
4287 if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED && isTagPresent()) {
4288 Log.d(TAG, "Not updating discovery parameters, tag connected.");
4289 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESUME_POLLING),
4290 APPLY_ROUTING_RETRY_TIMEOUT_MS);
4291 return;
4292 }
4293
4294 try {
4295 watchDog.start();
4296 // Compute new polling parameters
4297 NfcDiscoveryParameters newParams = computeDiscoveryParameters(mScreenState);
4298 if (force || !newParams.equals(mCurrentDiscoveryParameters)) {
4299 if (newParams.shouldEnableDiscovery()) {
4300 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery();
4301 mDeviceHost.enableDiscovery(newParams, shouldRestart);
4302 } else {
4303 mDeviceHost.disableDiscovery();
4304 }
4305 mCurrentDiscoveryParameters = newParams;
4306 } else {
4307 Log.d(TAG, "Discovery configuration equal, not updating.");
4308 }
4309 } finally {
4310 watchDog.cancel();
4311 }
4312 }
4313 }
4314
4315 private NfcDiscoveryParameters computeDiscoveryParameters(int screenState) {
4316 // Recompute discovery parameters based on screen state
4317 NfcDiscoveryParameters.Builder paramsBuilder = NfcDiscoveryParameters.newBuilder();
nxpandroide66eb092017-07-12 21:36:08 +05304318
nxpandroid64fd68c2015-09-23 16:45:15 +05304319 // Polling
nxpandroid5d64ce92016-11-18 19:48:53 +05304320 if ((screenState >= NFC_POLLING_MODE)||mIsTaskBoot) {
nxpandroid64fd68c2015-09-23 16:45:15 +05304321 // Check if reader-mode is enabled
4322 if (mReaderModeParams != null) {
4323 int techMask = 0;
4324 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_A) != 0)
4325 techMask |= NFC_POLL_A;
4326 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_B) != 0)
4327 techMask |= NFC_POLL_B;
4328 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_F) != 0)
4329 techMask |= NFC_POLL_F;
4330 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_V) != 0)
Nikhil Chhabra288edb02018-01-10 19:36:21 +05304331 techMask |= NFC_POLL_V;
nxpandroid64fd68c2015-09-23 16:45:15 +05304332 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_BARCODE) != 0)
4333 techMask |= NFC_POLL_KOVIO;
4334
4335 paramsBuilder.setTechMask(techMask);
4336 paramsBuilder.setEnableReaderMode(true);
4337 } else {
4338 paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT);
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304339 paramsBuilder.setEnableP2p(true);
nxpandroid64fd68c2015-09-23 16:45:15 +05304340 }
nxpandroide66eb092017-07-12 21:36:08 +05304341 }
4342 if ((screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mInProvisionMode) &&
4343 !mNfcUnlockManager.isLockscreenPollingEnabled()) {
4344 if (mReaderModeParams != null)
nxpandroid64fd68c2015-09-23 16:45:15 +05304345 paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT);
4346 // enable P2P for MFM/EDU/Corp provisioning
4347 paramsBuilder.setEnableP2p(true);
nxpandroide66eb092017-07-12 21:36:08 +05304348 } else if ((screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED) &&
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304349 (mIsLiveCaseEnabled || mNfcUnlockManager.isLockscreenPollingEnabled())) {
4350 int techMask = 0;
4351 // enable polling for Live Case technologies
4352 if (mIsLiveCaseEnabled)
4353 techMask |= mLiveCaseTechnology;
4354 if (mNfcUnlockManager.isLockscreenPollingEnabled())
nxpandroide66eb092017-07-12 21:36:08 +05304355 {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304356 techMask |= mNfcUnlockManager.getLockscreenPollMask();
nxpandroide66eb092017-07-12 21:36:08 +05304357 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304358 paramsBuilder.setTechMask(techMask);
nxpandroid64fd68c2015-09-23 16:45:15 +05304359 paramsBuilder.setEnableLowPowerDiscovery(false);
4360 paramsBuilder.setEnableP2p(false);
4361 }
4362
Nikhil Chhabrae1d07ba2018-01-10 11:33:17 +05304363 if (mIsHceCapable && mScreenState >= ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mReaderModeParams == null) {
4364 // Host routing is always enabled at lock screen or later, provided we aren't in reader mode
4365 paramsBuilder.setEnableHostRouting(true);
4366 }
4367
nxpandroid64fd68c2015-09-23 16:45:15 +05304368 //To make routing table update.
4369 if(mIsRoutingTableDirty) {
4370 mIsRoutingTableDirty = false;
nxpandroida9a68ba2016-01-14 21:12:17 +05304371 int protoRoute = mNxpPrefs.getInt("PREF_MIFARE_DESFIRE_PROTO_ROUTE_ID", GetDefaultMifareDesfireRouteEntry());
4372 int defaultRoute=mNxpPrefs.getInt("PREF_SET_DEFAULT_ROUTE_ID", GetDefaultRouteEntry());
4373 int techRoute=mNxpPrefs.getInt("PREF_MIFARE_CLT_ROUTE_ID", GetDefaultMifateCLTRouteEntry());
nxpandroid281eb922016-08-25 20:27:46 +05304374 if (DBG) Log.d(TAG, "Set default Route Entry");
nxpandroid64fd68c2015-09-23 16:45:15 +05304375 setDefaultRoute(defaultRoute, protoRoute, techRoute);
4376 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304377
nxpandroid64fd68c2015-09-23 16:45:15 +05304378 return paramsBuilder.build();
4379 }
4380
4381 private boolean isTagPresent() {
4382 for (Object object : mObjectMap.values()) {
4383 if (object instanceof TagEndpoint) {
4384 return ((TagEndpoint) object).isPresent();
4385 }
4386 }
4387 return false;
4388 }
4389 /**
4390 * Disconnect any target if present
4391 */
4392 void maybeDisconnectTarget() {
4393 if (!isNfcEnabledOrShuttingDown()) {
4394 return;
4395 }
4396 Object[] objectsToDisconnect;
4397 synchronized (this) {
4398 Object[] objectValues = mObjectMap.values().toArray();
4399 // Copy the array before we clear mObjectMap,
4400 // just in case the HashMap values are backed by the same array
4401 objectsToDisconnect = Arrays.copyOf(objectValues, objectValues.length);
4402 mObjectMap.clear();
4403 }
4404 for (Object o : objectsToDisconnect) {
4405 if (DBG) Log.d(TAG, "disconnecting " + o.getClass().getName());
4406 if (o instanceof TagEndpoint) {
4407 // Disconnect from tags
4408 TagEndpoint tag = (TagEndpoint) o;
4409 tag.disconnect();
4410 } else if (o instanceof NfcDepEndpoint) {
4411 // Disconnect from P2P devices
4412 NfcDepEndpoint device = (NfcDepEndpoint) o;
4413 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) {
4414 // Remote peer is target, request disconnection
4415 device.disconnect();
4416 } else {
4417 // Remote peer is initiator, we cannot disconnect
4418 // Just wait for field removal
4419 }
4420 }
4421 }
4422 }
4423
4424 Object findObject(int key) {
4425 synchronized (this) {
4426 Object device = mObjectMap.get(key);
4427 if (device == null) {
4428 Log.w(TAG, "Handle not found");
4429 }
4430 return device;
4431 }
4432 }
4433
nxpandroid281eb922016-08-25 20:27:46 +05304434 Object findAndRemoveObject(int handle) {
4435 synchronized (this) {
4436 Object device = mObjectMap.get(handle);
4437 if (device == null) {
4438 Log.w(TAG, "Handle not found");
4439 } else {
4440 mObjectMap.remove(handle);
4441 }
4442 return device;
4443 }
4444 }
4445
nxpandroid64fd68c2015-09-23 16:45:15 +05304446 void registerTagObject(TagEndpoint tag) {
4447 synchronized (this) {
4448 mObjectMap.put(tag.getHandle(), tag);
4449 }
4450 }
4451
4452 void unregisterObject(int handle) {
4453 synchronized (this) {
4454 mObjectMap.remove(handle);
4455 }
4456 }
4457
4458 /**
4459 * For use by code in this process
4460 */
4461 public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength)
4462 throws LlcpException {
4463 return mDeviceHost.createLlcpSocket(sap, miu, rw, linearBufferLength);
4464 }
4465
4466 /**
4467 * For use by code in this process
4468 */
4469 public LlcpConnectionlessSocket createLlcpConnectionLessSocket(int sap, String sn)
4470 throws LlcpException {
4471 return mDeviceHost.createLlcpConnectionlessSocket(sap, sn);
4472 }
4473
4474 /**
4475 * For use by code in this process
4476 */
4477 public LlcpServerSocket createLlcpServerSocket(int sap, String sn, int miu, int rw,
4478 int linearBufferLength) throws LlcpException {
4479 return mDeviceHost.createLlcpServerSocket(sap, sn, miu, rw, linearBufferLength);
4480 }
4481
4482 public void sendMockNdefTag(NdefMessage msg) {
4483 sendMessage(MSG_MOCK_NDEF, msg);
4484 }
4485
4486 public void notifyRoutingTableFull()
4487 {
nxpandroidebf53fb2016-12-22 18:48:59 +05304488 if(!mNxpNfcController.isGsmaCommitOffhostService()) {
4489 ComponentName prevPaymentComponent = mAidCache.getPreviousPreferredPaymentService();
4490
4491 mNxpPrefsEditor = mNxpPrefs.edit();
4492 mNxpPrefsEditor.putInt("PREF_SET_AID_ROUTING_TABLE_FULL",0x01);
4493 mNxpPrefsEditor.commit();
4494 //broadcast Aid Routing Table Full intent to the user
4495 Intent aidTableFull = new Intent();
4496 aidTableFull.putExtra(NxpConstants.EXTRA_GSMA_PREV_PAYMENT_COMPONENT,prevPaymentComponent);
4497 aidTableFull.setAction(NxpConstants.ACTION_ROUTING_TABLE_FULL);
4498 if (DBG) {
4499 Log.d(TAG, "notify aid routing table full to the user");
4500 }
4501 mContext.sendBroadcastAsUser(aidTableFull, UserHandle.CURRENT);
4502 mAidCache.setPreviousPreferredPaymentService(null);
nxpandroid64fd68c2015-09-23 16:45:15 +05304503 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304504 }
4505 /**
4506 * set default Aid route entry in case application does not configure this route entry
4507 */
nxpandroidebf53fb2016-12-22 18:48:59 +05304508 public void setDefaultAidRouteLoc( int routeLoc)
nxpandroid64fd68c2015-09-23 16:45:15 +05304509 {
nxpandroida9a68ba2016-01-14 21:12:17 +05304510 mNxpPrefsEditor = mNxpPrefs.edit();
nxpandroidebf53fb2016-12-22 18:48:59 +05304511 Log.d(TAG, "writing to preferences setDefaultAidRouteLoc :" + routeLoc);
4512
4513 int defaultAidRoute = ((mDeviceHost.getDefaultAidPowerState() & 0x1F) | (routeLoc << ROUTE_LOC_MASK));
4514 if(routeLoc == 0x00)
4515 {
4516 /*
4517 bit pos 1 = Power Off
4518 bit pos 2 = Battery Off
4519 bit pos 4 = Screen Off
4520 Set these bits to 0 because in case routeLoc = HOST it can not work on POWER_OFF, BATTERY_OFF and SCREEN_OFF*/
4521 defaultAidRoute &= 0xE9;
4522 }
4523
4524 mNxpPrefsEditor.putInt("PREF_SET_DEFAULT_ROUTE_ID", defaultAidRoute);
nxpandroida9a68ba2016-01-14 21:12:17 +05304525 mNxpPrefsEditor.commit();
4526 int defaultRoute=mNxpPrefs.getInt("PREF_SET_DEFAULT_ROUTE_ID",0xFF);
nxpandroid64fd68c2015-09-23 16:45:15 +05304527 Log.d(TAG, "reading preferences from user :" + defaultRoute);
4528 }
4529
4530 public int getAidRoutingTableSize ()
4531 {
4532 int aidTableSize = 0x00;
4533 aidTableSize = mDeviceHost.getAidTableSize();
4534 return aidTableSize;
4535 }
4536
nxpandroidcbf24822017-07-12 21:37:17 +05304537 public void routeAids(String aid, int route, int powerState, int aidInfo) {
nxpandroid64fd68c2015-09-23 16:45:15 +05304538 Message msg = mHandler.obtainMessage();
4539 msg.what = MSG_ROUTE_AID;
4540 msg.arg1 = route;
4541 msg.arg2 = powerState;
nxpandroidcbf24822017-07-12 21:37:17 +05304542 Bundle aidbundle = new Bundle();
4543 aidbundle.putInt("aidinfo",aidInfo);
4544 msg.setData(aidbundle);
nxpandroid64fd68c2015-09-23 16:45:15 +05304545 msg.obj = aid;
4546 mHandler.sendMessage(msg);
4547 }
4548
4549 public void unrouteAids(String aid) {
4550 sendMessage(MSG_UNROUTE_AID, aid);
4551 }
nxpandroida5fd6622017-07-31 16:15:18 +05304552
4553 public void routeApduPattern(String apdu, String mask ,int route, int powerState) {
4554 Message msg = mHandler.obtainMessage();
4555 msg.what = MSG_ROUTE_APDU;
4556 msg.arg1 = route;
4557 msg.arg2 = powerState;
4558 Bundle apduPatternbundle = new Bundle();
4559 apduPatternbundle.putString("apduData",apdu);
4560 apduPatternbundle.putString("apduMask",mask);
4561 msg.setData(apduPatternbundle);
4562 mHandler.sendMessage(msg);
4563 }
4564
4565 public void unrouteApduPattern(String apdu) {
4566 //sendMessage(MSG_UNROUTE_APDU, apdu);
4567 mDeviceHost.unrouteApduPattern(hexStringToBytes(apdu));
4568 }
4569
nxpandroide66eb092017-07-12 21:36:08 +05304570 public int getNciVersion() {
4571 return mDeviceHost.getNciVersion();
4572 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304573 private byte[] getT3tIdentifierBytes(String systemCode, String nfcId2, String t3tPmm) {
4574 ByteBuffer buffer = ByteBuffer.allocate(2 + 8 + 8);
nxpandroid34627bd2016-05-27 15:52:30 +05304575 buffer.put(hexStringToBytes(systemCode));
4576 buffer.put(hexStringToBytes(nfcId2));
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304577 buffer.put(hexStringToBytes(t3tPmm));
nxpandroid34627bd2016-05-27 15:52:30 +05304578 byte[] t3tIdBytes = new byte[buffer.position()];
4579 buffer.position(0);
4580 buffer.get(t3tIdBytes);
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304581
nxpandroid34627bd2016-05-27 15:52:30 +05304582 return t3tIdBytes;
4583 }
4584
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304585 public void registerT3tIdentifier(String systemCode, String nfcId2, String t3tPmm) {
4586 Log.d(TAG, "request to register LF_T3T_IDENTIFIER");
4587
4588 byte[] t3tIdentifier = getT3tIdentifierBytes(systemCode, nfcId2, t3tPmm);
nxpandroid34627bd2016-05-27 15:52:30 +05304589 sendMessage(MSG_REGISTER_T3T_IDENTIFIER, t3tIdentifier);
4590 }
4591
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304592 public void deregisterT3tIdentifier(String systemCode, String nfcId2, String t3tPmm) {
4593 Log.d(TAG, "request to deregister LF_T3T_IDENTIFIER");
4594
4595 byte[] t3tIdentifier = getT3tIdentifierBytes(systemCode, nfcId2, t3tPmm);
nxpandroid34627bd2016-05-27 15:52:30 +05304596 sendMessage(MSG_DEREGISTER_T3T_IDENTIFIER, t3tIdentifier);
4597 }
4598
4599 public void clearT3tIdentifiersCache() {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304600 Log.d(TAG, "clear T3t Identifiers Cache");
nxpandroid34627bd2016-05-27 15:52:30 +05304601 mDeviceHost.clearT3tIdentifiersCache();
4602 }
4603
4604 public int getLfT3tMax() {
4605 return mDeviceHost.getLfT3tMax();
4606 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304607
4608 public void commitRouting() {
4609 mHandler.sendEmptyMessage(MSG_COMMIT_ROUTING);
4610 }
4611 /**
4612 * get default Aid route entry in case application does not configure this route entry
4613 */
4614 public int GetDefaultRouteLoc()
4615 {
nxpandroida9a68ba2016-01-14 21:12:17 +05304616 int defaultRouteLoc = mNxpPrefs.getInt("PREF_SET_DEFAULT_ROUTE_ID", GetDefaultRouteEntry()) >> ROUTE_LOC_MASK;
nxpandroid64fd68c2015-09-23 16:45:15 +05304617 Log.d(TAG, "GetDefaultRouteLoc :" + defaultRouteLoc);
4618 return defaultRouteLoc ;
4619 }
4620
4621 /**
4622 * get default MifareDesfireRoute route entry in case application does not configure this route entry
4623 */
4624 public int GetDefaultMifareDesfireRouteEntry()
4625 {
nxpandroid7d44e572016-08-01 19:11:04 +05304626 int routeLoc = mDeviceHost.getDefaultDesfireRoute();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304627 int defaultMifareDesfireRoute = ((mDeviceHost.getDefaultDesfirePowerState() & 0x3F) | (routeLoc << ROUTE_LOC_MASK));
nxpandroid7d44e572016-08-01 19:11:04 +05304628 if(routeLoc == 0x00)
4629 {
nxpandroid8aecbf82016-09-16 20:21:47 +05304630 /*
4631 bit pos 1 = Power Off
4632 bit pos 2 = Battery Off
4633 bit pos 4 = Screen Off
4634 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 +05304635 defaultMifareDesfireRoute &= 0xF9;
nxpandroid7d44e572016-08-01 19:11:04 +05304636 }
nxpandroid281eb922016-08-25 20:27:46 +05304637 if (DBG) Log.d(TAG, "defaultMifareDesfireRoute : " + defaultMifareDesfireRoute);
nxpandroid7d44e572016-08-01 19:11:04 +05304638 return defaultMifareDesfireRoute;
nxpandroid64fd68c2015-09-23 16:45:15 +05304639 }
4640 /**
4641 * set default Aid route entry in case application does not configure this route entry
4642 */
4643
4644 public int GetDefaultRouteEntry()
4645 {
nxpandroid7d44e572016-08-01 19:11:04 +05304646 int routeLoc = mDeviceHost.getDefaultAidRoute();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304647 int defaultAidRoute = ((mDeviceHost.getDefaultAidPowerState() & 0x3F) | (routeLoc << ROUTE_LOC_MASK));
nxpandroid7d44e572016-08-01 19:11:04 +05304648 if(routeLoc == 0x00)
4649 {
nxpandroid8aecbf82016-09-16 20:21:47 +05304650 /*
4651 bit pos 1 = Power Off
4652 bit pos 2 = Battery Off
4653 bit pos 4 = Screen Off
4654 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 +05304655 defaultAidRoute &= 0xF9;
nxpandroid7d44e572016-08-01 19:11:04 +05304656 }
nxpandroid281eb922016-08-25 20:27:46 +05304657 if (DBG) Log.d(TAG, "defaultAidRoute : " + defaultAidRoute);
nxpandroid64fd68c2015-09-23 16:45:15 +05304658 return defaultAidRoute;
4659 }
4660
4661 /**
4662 * get default MifateCLT route entry in case application does not configure this route entry
4663 */
4664 public int GetDefaultMifateCLTRouteEntry()
4665 {
nxpandroid7d44e572016-08-01 19:11:04 +05304666 int routeLoc = mDeviceHost.getDefaultMifareCLTRoute();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304667 int defaultMifateCLTRoute = ((mDeviceHost.getDefaultMifareCLTPowerState() & 0x3F) | (routeLoc << ROUTE_LOC_MASK) | (TECH_TYPE_A << TECH_TYPE_MASK));
nxpandroid7d44e572016-08-01 19:11:04 +05304668
nxpandroid281eb922016-08-25 20:27:46 +05304669 if (DBG) Log.d(TAG, "defaultMifateCLTRoute : " + defaultMifateCLTRoute);
nxpandroid7d44e572016-08-01 19:11:04 +05304670 return defaultMifateCLTRoute;
nxpandroid64fd68c2015-09-23 16:45:15 +05304671 }
4672
4673 public boolean setDefaultRoute(int defaultRouteEntry, int defaultProtoRouteEntry, int defaultTechRouteEntry) {
4674 boolean ret = mDeviceHost.setDefaultRoute(defaultRouteEntry, defaultProtoRouteEntry, defaultTechRouteEntry);
4675 return ret;
4676 }
4677
4678 public int getDefaultRoute() {
nxpandroida9a68ba2016-01-14 21:12:17 +05304679 return mNxpPrefs.getInt(PREF_DEFAULT_ROUTE_ID, DEFAULT_ROUTE_ID_DEFAULT);
nxpandroid64fd68c2015-09-23 16:45:15 +05304680 }
4681
4682
4683 public void commitingFelicaRouting() {
4684 mHandler.sendEmptyMessage(MSG_COMMITINF_FELICA_ROUTING);
4685 }
4686
4687 public void commitedFelicaRouting() {
4688 mHandler.sendEmptyMessage(MSG_COMMITED_FELICA_ROUTING);
4689 }
4690
nxpandroida9a68ba2016-01-14 21:12:17 +05304691 public int getAidRoutingTableStatus() {
4692 int aidTableStatus = 0x00;
4693 aidTableStatus = mNxpPrefs.getInt("PREF_SET_AID_ROUTING_TABLE_FULL",0x00);
4694 return aidTableStatus;
4695 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304696
nxpandroid64fd68c2015-09-23 16:45:15 +05304697 public void clearRouting() {
4698 mHandler.sendEmptyMessage(MSG_CLEAR_ROUTING);
4699 }
4700
4701 public boolean isVzwFeatureEnabled(){
4702 return mDeviceHost.isVzwFeatureEnabled();
4703 }
4704
4705 public boolean sendData(byte[] data) {
4706 return mDeviceHost.sendRawFrame(data);
4707 }
4708
4709 public int getDefaultSecureElement() {
4710 int[] seList = mDeviceHost.doGetSecureElementList();
4711 if ( seList == null || seList.length != 1) {
4712 //use default value
4713 return -1;
4714 } else {
4715 return seList[0];
4716 }
4717 }
4718
4719 public void etsiStartConfig(int eeHandle) {
4720 Log.d(TAG, "etsiStartConfig Enter");
4721
4722 Log.d(TAG, "etsiStartConfig : etsiInitConfig");
4723 mDeviceHost.etsiInitConfig();
4724
4725 Log.d(TAG, "etsiStartConfig : disableDiscovery");
4726 mDeviceHost.disableDiscovery();
4727
4728 Log.d(TAG, "etsiStartConfig : etsiReaderConfig");
4729 mDeviceHost.etsiReaderConfig(eeHandle);
4730
4731 Log.d(TAG, "etsiStartConfig : notifyEEReaderEvent");
4732 mDeviceHost.notifyEEReaderEvent(ETSI_READER_REQUESTED);
4733
4734 Log.d(TAG, "etsiStartConfig : setEtsiReaederState");
4735 mDeviceHost.setEtsiReaederState(STATE_SE_RDR_MODE_STARTED);
4736 //broadcast SWP_READER_ACTIVATED evt
nxpandroid5d64ce92016-11-18 19:48:53 +05304737 Intent swpReaderRequestedIntent = new Intent();
4738 swpReaderRequestedIntent.setAction(NxpConstants.ACTION_SWP_READER_REQUESTED);
nxpandroid64fd68c2015-09-23 16:45:15 +05304739 if (DBG) {
4740 Log.d(TAG, "SWP READER - Requested");
4741 }
nxpandroid5d64ce92016-11-18 19:48:53 +05304742 mContext.sendBroadcast(swpReaderRequestedIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05304743
4744 Log.d(TAG, "etsiStartConfig : enableDiscovery");
4745 mDeviceHost.enableDiscovery(mCurrentDiscoveryParameters, true);
4746
4747 Log.d(TAG, "etsiStartConfig Exit");
4748 }
4749
4750 public void etsiStopConfig(int discNtfTimeout) {
4751 Log.d(TAG, "etsiStopConfig Enter");
4752 if( mDeviceHost.getEtsiReaederState() == STATE_SE_RDR_MODE_STOP_IN_PROGRESS)
4753 {
4754 Log.d(TAG, "Attempting etsiStopConfig while STATE_SE_RDR_MODE_STOP_IN_PROGRESS. Returning..");
4755 return;
4756 }
4757 ETSI_STOP_CONFIG = true;
4758 TagRemoveTask tagRemoveTask = new TagRemoveTask();
4759 tagRemoveTask.execute(discNtfTimeout);
4760 Log.d(TAG, "etsiStopConfig : etsiInitConfig");
4761 mDeviceHost.etsiInitConfig();
4762
nxpandroid64fd68c2015-09-23 16:45:15 +05304763 Log.d(TAG, "etsiStopConfig : disableDiscovery");
4764 mDeviceHost.disableDiscovery();
4765
4766 if(mDeviceHost.getEtsiReaederState() == STATE_SE_RDR_MODE_STOPPED)
4767 {
4768 Log.d(TAG, "etsiStopConfig :etsi reader already Stopped. Returning..");
4769 ETSI_STOP_CONFIG = false;
4770 return;
4771 }
4772 Log.d(TAG, "etsiStopConfig : etsiResetReaderConfig");
4773 mDeviceHost.etsiResetReaderConfig();
4774
4775 Log.d(TAG, "etsiStopConfig : notifyEEReaderEvent");
4776 mDeviceHost.notifyEEReaderEvent(ETSI_READER_STOP);
4777
nxpandroid5d64ce92016-11-18 19:48:53 +05304778 Intent swpReaderDeActivatedIntent = new Intent();
nxpandroid64fd68c2015-09-23 16:45:15 +05304779
4780 //broadcast SWP_READER_DEACTIVATED evt
nxpandroid5d64ce92016-11-18 19:48:53 +05304781 swpReaderDeActivatedIntent
nxpandroid64fd68c2015-09-23 16:45:15 +05304782 .setAction(NxpConstants.ACTION_SWP_READER_DEACTIVATED);
4783 if (DBG) {
4784 Log.d(TAG, "SWP READER - DeActivated");
4785 }
nxpandroid5d64ce92016-11-18 19:48:53 +05304786 mContext.sendBroadcast(swpReaderDeActivatedIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05304787
4788 Log.d(TAG, "etsiStopConfig : setEtsiReaederState");
4789 mDeviceHost.setEtsiReaederState(STATE_SE_RDR_MODE_STOPPED);
4790
4791 Log.d(TAG, "etsiStopConfig : enableDiscovery");
4792 mDeviceHost.enableDiscovery(mCurrentDiscoveryParameters, true);
4793 ETSI_STOP_CONFIG = false;
4794
4795 Log.d(TAG, "etsiStopConfig : updateScreenState");
4796 mDeviceHost.updateScreenState();
4797
4798 Log.d(TAG, "etsiStopConfig Exit");
4799 }
4800
4801 void sendMessage(int what, Object obj) {
4802 Message msg = mHandler.obtainMessage();
4803 msg.what = what;
4804 msg.obj = obj;
4805 mHandler.sendMessage(msg);
4806 }
4807
4808 final class NfcServiceHandler extends Handler {
4809 @Override
4810 public void handleMessage(Message msg) {
4811 switch (msg.what) {
4812 case MSG_ROUTE_AID: {
4813 int route = msg.arg1;
4814 int power = msg.arg2;
nxpandroidcbf24822017-07-12 21:37:17 +05304815 int aidInfo = 0x00;
4816 Bundle dataBundle = msg.getData();
4817 if (dataBundle != null)
4818 aidInfo = dataBundle.getInt("aidinfo");
nxpandroid64fd68c2015-09-23 16:45:15 +05304819 String aid = (String) msg.obj;
nxpandroidcbf24822017-07-12 21:37:17 +05304820 String cuttedAid = aid;
4821 if(aid.endsWith("*")||aid.endsWith("#")) {
4822 cuttedAid = aid.substring(0, aid.length() - 1);
nxpandroid64fd68c2015-09-23 16:45:15 +05304823 }
nxpandroidcbf24822017-07-12 21:37:17 +05304824 mDeviceHost.routeAid(hexStringToBytes(cuttedAid), route, power, aidInfo);
nxpandroid64fd68c2015-09-23 16:45:15 +05304825 // Restart polling config
4826 break;
4827 }
nxpandroid34627bd2016-05-27 15:52:30 +05304828 case MSG_REGISTER_T3T_IDENTIFIER: {
4829 Log.d(TAG, "message to register LF_T3T_IDENTIFIER");
4830 mDeviceHost.disableDiscovery();
4831
4832 byte[] t3tIdentifier = (byte[]) msg.obj;
4833 mDeviceHost.registerT3tIdentifier(t3tIdentifier);
4834
4835 NfcDiscoveryParameters params = computeDiscoveryParameters(mScreenState);
4836 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery();
4837 mDeviceHost.enableDiscovery(params, shouldRestart);
4838 break;
4839 }
4840 case MSG_DEREGISTER_T3T_IDENTIFIER: {
4841 Log.d(TAG, "message to deregister LF_T3T_IDENTIFIER");
4842 mDeviceHost.disableDiscovery();
4843
4844 byte[] t3tIdentifier = (byte[]) msg.obj;
4845 mDeviceHost.deregisterT3tIdentifier(t3tIdentifier);
4846
4847 NfcDiscoveryParameters params = computeDiscoveryParameters(mScreenState);
4848 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery();
4849 mDeviceHost.enableDiscovery(params, shouldRestart);
4850 break;
4851 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304852 case MSG_INVOKE_BEAM: {
4853 mP2pLinkManager.onManualBeamInvoke((BeamShareData)msg.obj);
4854 break;
4855 }
nxpandroida5fd6622017-07-31 16:15:18 +05304856
nxpandroid64fd68c2015-09-23 16:45:15 +05304857 case MSG_UNROUTE_AID: {
4858 String aid = (String) msg.obj;
4859 mDeviceHost.unrouteAid(hexStringToBytes(aid));
4860 break;
4861 }
4862
nxpandroid64fd68c2015-09-23 16:45:15 +05304863 case MSG_COMMITINF_FELICA_ROUTING: {
4864 Log.e(TAG, "applyRouting -10");
4865 mIsFelicaOnHostConfiguring = true;
4866 applyRouting(true);
4867 break;
4868 }
4869
4870 case MSG_COMMITED_FELICA_ROUTING: {
4871 Log.e(TAG, "applyRouting -11");
4872 mIsFelicaOnHostConfigured = true;
4873 applyRouting(true);
4874 break;
4875 }
4876
nxpandroid64fd68c2015-09-23 16:45:15 +05304877 case MSG_COMMIT_ROUTING: {
4878 Log.e(TAG, "applyRouting -9");
4879 boolean commit = false;
nxpandroid07d1cc22017-09-14 12:20:58 +05304880 boolean enForced = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05304881 synchronized (NfcService.this) {
4882 if (mCurrentDiscoveryParameters.shouldEnableDiscovery()) {
4883 commit = true;
nxpandroid07d1cc22017-09-14 12:20:58 +05304884 }else if(mAidRoutingManager.isRoutingTableUpdated()){
4885 commit = true;
4886 enForced = true;
4887 Log.d(TAG, "Routing table is updated thus needs to be committed.");
4888 }
4889 else {
nxpandroid64fd68c2015-09-23 16:45:15 +05304890 Log.d(TAG, "Not committing routing because discovery is disabled.");
4891 }
4892 }
4893 if (commit) {
4894 mIsRoutingTableDirty = true;
nxpandroid07d1cc22017-09-14 12:20:58 +05304895 applyRouting(enForced);
nxpandroid64fd68c2015-09-23 16:45:15 +05304896 }
4897
4898
4899 break;
4900 }
4901 case MSG_CLEAR_ROUTING: {
4902 mDeviceHost.clearAidTable();
4903 break;
4904 }
4905
4906 case MSG_CHANGE_DEFAULT_ROUTE:
4907 Log.d(TAG, "Handler: Change default route");
4908 try{
4909 mNxpNfcAdapter.DefaultRouteSet(ROUTE_ID_HOST, true, false, false);
4910 } catch(RemoteException re) {
4911 Log.d(TAG, "NxpNci: onAidRoutingTableFull: Exception to change default route to host!");
4912 }
4913 break;
4914
4915 case MSG_MOCK_NDEF: {
4916 NdefMessage ndefMsg = (NdefMessage) msg.obj;
4917 Bundle extras = new Bundle();
4918 extras.putParcelable(Ndef.EXTRA_NDEF_MSG, ndefMsg);
4919 extras.putInt(Ndef.EXTRA_NDEF_MAXLENGTH, 0);
4920 extras.putInt(Ndef.EXTRA_NDEF_CARDSTATE, Ndef.NDEF_MODE_READ_ONLY);
4921 extras.putInt(Ndef.EXTRA_NDEF_TYPE, Ndef.TYPE_OTHER);
4922 Tag tag = Tag.createMockTag(new byte[]{0x00},
4923 new int[]{TagTechnology.NDEF},
4924 new Bundle[]{extras});
4925 Log.d(TAG, "mock NDEF tag, starting corresponding activity");
4926 Log.d(TAG, tag.toString());
4927 int dispatchStatus = mNfcDispatcher.dispatchTag(tag);
4928 if (dispatchStatus == NfcDispatcher.DISPATCH_SUCCESS) {
4929 playSound(SOUND_END);
4930 } else if (dispatchStatus == NfcDispatcher.DISPATCH_FAIL) {
4931 playSound(SOUND_ERROR);
4932 }
4933 break;
4934 }
4935
4936 case MSG_SE_DELIVER_INTENT: {
4937 Log.d(TAG, "SE DELIVER INTENT");
4938 Intent seIntent = (Intent) msg.obj;
4939
4940 String action = seIntent.getAction();
4941 if (action.equals("com.gsma.services.nfc.action.TRANSACTION_EVENT")) {
4942 byte[] byteAid = seIntent.getByteArrayExtra("com.android.nfc_extras.extra.AID");
4943 byte[] data = seIntent.getByteArrayExtra("com.android.nfc_extras.extra.DATA");
4944 String seName = seIntent.getStringExtra("com.android.nfc_extras.extra.SE_NAME");
4945 StringBuffer strAid = new StringBuffer();
4946 for (int i = 0; i < byteAid.length; i++) {
4947 String hex = Integer.toHexString(0xFF & byteAid[i]);
4948 if (hex.length() == 1)
4949 strAid.append('0');
4950 strAid.append(hex);
4951 }
4952 Intent gsmaIntent = new Intent();
4953 gsmaIntent.setAction("com.gsma.services.nfc.action.TRANSACTION_EVENT");
4954 if (byteAid != null)
4955 gsmaIntent.putExtra("com.gsma.services.nfc.extra.AID", byteAid);
4956 if (data != null)
4957 gsmaIntent.putExtra("com.gsma.services.nfc.extra.DATA", data);
4958
4959 //"nfc://secure:0/<seName>/<strAid>"
4960 String url = new String ("nfc://secure:0/" + seName + "/" + strAid);
4961 gsmaIntent.setData(Uri.parse(url));
4962 gsmaIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
4963 gsmaIntent.setPackage(seIntent.getPackage());
4964
4965 Boolean receptionMode = mNxpNfcController.mMultiReceptionMap.get(seName);
4966 if (receptionMode == null)
4967 receptionMode = defaultTransactionEventReceptionMode;
4968
4969 if (receptionMode == multiReceptionMode) {
4970 // if multicast reception for GSMA
4971 mContext.sendBroadcast(gsmaIntent);
4972 } else {
4973 // if unicast reception for GSMA
4974 try {
4975 if (mIsSentUnicastReception == false) {
4976 //start gsma
4977 gsmaIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4978 mContext.startActivity(gsmaIntent);
4979 mIsSentUnicastReception = true;
4980 }
4981 } catch (Exception e) {
4982 if (DBG) Log.d(TAG, "Exception: " + e.getMessage());
4983 }
4984 }
4985 } else {
4986 mContext.sendBroadcast(seIntent);
4987 }
4988 break;
4989 }
4990
4991 case MSG_NDEF_TAG:
4992 if (DBG) Log.d(TAG, "Tag detected, notifying applications");
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304993 mNumTagsDetected.incrementAndGet();
nxpandroid64fd68c2015-09-23 16:45:15 +05304994 TagEndpoint tag = (TagEndpoint) msg.obj;
nxpandroid281eb922016-08-25 20:27:46 +05304995 byte[] debounceTagUid;
4996 int debounceTagMs;
4997 ITagRemovedCallback debounceTagRemovedCallback;
4998 synchronized (NfcService.this) {
4999 debounceTagUid = mDebounceTagUid;
5000 debounceTagMs = mDebounceTagDebounceMs;
5001 debounceTagRemovedCallback = mDebounceTagRemovedCallback;
5002 }
nxpandroid281eb922016-08-25 20:27:46 +05305003
nxpandroid64fd68c2015-09-23 16:45:15 +05305004 ReaderModeParams readerParams = null;
5005 int presenceCheckDelay = DEFAULT_PRESENCE_CHECK_DELAY;
5006 DeviceHost.TagDisconnectedCallback callback =
5007 new DeviceHost.TagDisconnectedCallback() {
5008 @Override
5009 public void onTagDisconnected(long handle) {
nxpandroid03323c82017-09-14 11:13:16 +05305010 if(nci_version != NCI_VERSION_2_0) {
5011 applyRouting(false);
5012 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305013 }
5014 };
5015 synchronized (NfcService.this) {
5016 readerParams = mReaderModeParams;
5017 }
5018 if (readerParams != null) {
5019 presenceCheckDelay = readerParams.presenceCheckDelay;
5020 if ((readerParams.flags & NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK) != 0) {
5021 if (DBG) Log.d(TAG, "Skipping NDEF detection in reader mode");
5022 tag.startPresenceChecking(presenceCheckDelay, callback);
5023 dispatchTagEndpoint(tag, readerParams);
5024 break;
5025 }
5026 }
5027
nxpandroid64fd68c2015-09-23 16:45:15 +05305028 if (tag.getConnectedTechnology() == TagTechnology.NFC_BARCODE) {
5029 // When these tags start containing NDEF, they will require
5030 // the stack to deal with them in a different way, since
5031 // they are activated only really shortly.
5032 // For now, don't consider NDEF on these.
5033 if (DBG) Log.d(TAG, "Skipping NDEF detection for NFC Barcode");
5034 tag.startPresenceChecking(presenceCheckDelay, callback);
5035 dispatchTagEndpoint(tag, readerParams);
5036 break;
5037 }
5038 NdefMessage ndefMsg = tag.findAndReadNdef();
5039
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305040 if (ndefMsg == null) {
5041 // First try to see if this was a bad tag read
5042 if (!tag.reconnect()) {
nxpandroid64fd68c2015-09-23 16:45:15 +05305043 tag.disconnect();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305044 break;
nxpandroid64fd68c2015-09-23 16:45:15 +05305045 }
5046 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305047
5048 if (debounceTagUid != null) {
5049 // If we're debouncing and the UID or the NDEF message of the tag match,
5050 // don't dispatch but drop it.
5051 if (Arrays.equals(debounceTagUid, tag.getUid()) ||
5052 (ndefMsg != null && ndefMsg.equals(mLastReadNdefMessage))) {
5053 mHandler.removeMessages(MSG_TAG_DEBOUNCE);
5054 mHandler.sendEmptyMessageDelayed(MSG_TAG_DEBOUNCE, debounceTagMs);
5055 tag.disconnect();
5056 return;
5057 } else {
5058 synchronized (NfcService.this) {
5059 mDebounceTagUid = null;
5060 mDebounceTagRemovedCallback = null;
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +05305061 mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE;
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305062 }
5063 if (debounceTagRemovedCallback != null) {
5064 try {
5065 debounceTagRemovedCallback.onTagRemoved();
5066 } catch (RemoteException e) {
5067 // Ignore
5068 }
5069 }
5070 }
5071 }
5072
5073 mLastReadNdefMessage = ndefMsg;
5074
5075 tag.startPresenceChecking(presenceCheckDelay, callback);
5076 dispatchTagEndpoint(tag, readerParams);
nxpandroid64fd68c2015-09-23 16:45:15 +05305077 break;
5078
nxpandroid5387b022017-02-03 18:04:32 +05305079 case MSG_CARD_EMULATION: {
nxpandroid64fd68c2015-09-23 16:45:15 +05305080 if (DBG) Log.d(TAG, "Card Emulation message");
5081 /* Tell the host-emu manager an AID has been selected on
5082 * a secure element.
5083 */
5084 if (mCardEmulationManager != null) {
5085 mCardEmulationManager.onOffHostAidSelected();
5086 }
5087 Pair<byte[], Pair> transactionInfo = (Pair<byte[], Pair>) msg.obj;
5088 Pair<byte[], Integer> dataSrcInfo = (Pair<byte[], Integer>) transactionInfo.second;
nxpandroid5387b022017-02-03 18:04:32 +05305089 String evtSrc = "";
nxpandroid64fd68c2015-09-23 16:45:15 +05305090 String gsmaSrc = "";
5091 String gsmaDataAID = toHexString(transactionInfo.first, 0, transactionInfo.first.length);
5092 {
5093 Log.d(TAG, "Event source " + dataSrcInfo.second);
5094
nxpandroid64fd68c2015-09-23 16:45:15 +05305095 if(dataSrcInfo.second == UICC_ID_TYPE) {
5096 evtSrc = NxpConstants.UICC_ID;
5097 gsmaSrc = "SIM1";
nxpandroid7d44e572016-08-01 19:11:04 +05305098 } else if(dataSrcInfo.second == UICC2_ID_TYPE) {
5099 evtSrc = NxpConstants.UICC2_ID;
5100 gsmaSrc = "SIM2";
nxpandroid64fd68c2015-09-23 16:45:15 +05305101 } else if(dataSrcInfo.second == SMART_MX_ID_TYPE) {
5102 evtSrc = NxpConstants.SMART_MX_ID;
5103 gsmaSrc = "ESE";
5104 }
5105 /* Send broadcast ordered */
nxpandroid281eb922016-08-25 20:27:46 +05305106 Intent transactionIntent = new Intent();
5107 transactionIntent.setAction(NxpConstants.ACTION_TRANSACTION_DETECTED);
5108 transactionIntent.putExtra(NxpConstants.EXTRA_AID, transactionInfo.first);
5109 transactionIntent.putExtra(NxpConstants.EXTRA_DATA, dataSrcInfo.first);
5110 transactionIntent.putExtra(NxpConstants.EXTRA_SOURCE, evtSrc);
nxpandroid64fd68c2015-09-23 16:45:15 +05305111 if (DBG) {
5112 Log.d(TAG, "Start Activity Card Emulation event");
5113 }
5114 mIsSentUnicastReception = false;
nxpandroid281eb922016-08-25 20:27:46 +05305115 mContext.sendBroadcast(transactionIntent, NfcPermissions.NFC_PERMISSION);
nxpandroid64fd68c2015-09-23 16:45:15 +05305116 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305117
5118 /* Send "transaction events" to all authorized/registered components" */
5119 Intent evtIntent = new Intent();
5120 evtIntent.setAction(NxpConstants.ACTION_MULTI_EVT_TRANSACTION);
5121 evtIntent.setData(Uri.parse("nfc://secure:0/"+ gsmaSrc+"/"+ gsmaDataAID));
5122 evtIntent.putExtra(NxpConstants.EXTRA_GSMA_AID, transactionInfo.first);
5123 evtIntent.putExtra(NxpConstants.EXTRA_GSMA_DATA, dataSrcInfo.first);
5124 Log.d(TAG, "Broadcasting " + NxpConstants.ACTION_MULTI_EVT_TRANSACTION);
5125 sendMultiEvtBroadcast(evtIntent);
5126
nxpandroid5387b022017-02-03 18:04:32 +05305127 /* Send broadcast */
5128 if (dataSrcInfo.first != null) {
5129 String evt_data = toHexString(dataSrcInfo.first, 0, dataSrcInfo.first.length);
5130 if (DBG) Log.d(TAG, "Data is :"+evt_data);
5131 }
5132 Intent aidIntent = new Intent();
5133 aidIntent.setAction(ACTION_AID_SELECTED);
5134 aidIntent.putExtra(EXTRA_AID, transactionInfo.first);
5135 aidIntent.putExtra(NxpConstants.EXTRA_SOURCE, evtSrc);
5136 aidIntent.putExtra(NxpConstants.EXTRA_DATA,dataSrcInfo.first);
5137 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_AID_SELECTED);
5138 sendSeBroadcast(aidIntent);
5139 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305140 break;
5141
5142 case MSG_CONNECTIVITY_EVENT:
5143 if (DBG) {
5144 Log.d(TAG, "SE EVENT CONNECTIVITY");
5145 }
5146 Integer evtSrcInfo = (Integer) msg.obj;
5147 Log.d(TAG, "Event source " + evtSrcInfo);
5148 String evtSrc = "";
5149 if(evtSrcInfo == UICC_ID_TYPE) {
5150 evtSrc = NxpConstants.UICC_ID;
nxpandroid7d44e572016-08-01 19:11:04 +05305151 } else if(evtSrcInfo == UICC2_ID_TYPE) {
5152 evtSrc = NxpConstants.UICC2_ID;
nxpandroid64fd68c2015-09-23 16:45:15 +05305153 } else if(evtSrcInfo == SMART_MX_ID_TYPE) {
5154 evtSrc = NxpConstants.SMART_MX_ID;
5155 }
5156
5157 Intent eventConnectivityIntent = new Intent();
5158 eventConnectivityIntent.setAction(NxpConstants.ACTION_CONNECTIVITY_EVENT_DETECTED);
5159 eventConnectivityIntent.putExtra(NxpConstants.EXTRA_SOURCE, evtSrc);
5160 if (DBG) {
5161 Log.d(TAG, "Broadcasting Intent");
5162 }
5163 mContext.sendBroadcast(eventConnectivityIntent, NfcPermissions.NFC_PERMISSION);
5164 break;
5165
5166 case MSG_EMVCO_MULTI_CARD_DETECTED_EVENT:
5167 if (DBG) {
5168 Log.d(TAG, "EMVCO MULTI CARD DETECTED EVENT");
5169 }
5170
5171 Intent eventEmvcoMultiCardIntent = new Intent();
5172 eventEmvcoMultiCardIntent.setAction(ACTION_EMVCO_MULTIPLE_CARD_DETECTED);
5173 if (DBG) {
5174 Log.d(TAG, "Broadcasting Intent");
5175 }
5176 mContext.sendBroadcast(eventEmvcoMultiCardIntent, NFC_PERM);
5177 break;
5178
5179 case MSG_SE_EMV_CARD_REMOVAL:
5180 if (DBG) Log.d(TAG, "Card Removal message");
5181 /* Send broadcast */
5182 Intent cardRemovalIntent = new Intent();
5183 cardRemovalIntent.setAction(ACTION_EMV_CARD_REMOVAL);
5184 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_EMV_CARD_REMOVAL);
5185 sendSeBroadcast(cardRemovalIntent);
5186 break;
5187
5188 case MSG_SE_APDU_RECEIVED:
5189 if (DBG) Log.d(TAG, "APDU Received message");
5190 byte[] apduBytes = (byte[]) msg.obj;
5191 /* Send broadcast */
5192 Intent apduReceivedIntent = new Intent();
5193 apduReceivedIntent.setAction(ACTION_APDU_RECEIVED);
5194 if (apduBytes != null && apduBytes.length > 0) {
5195 apduReceivedIntent.putExtra(EXTRA_APDU_BYTES, apduBytes);
5196 }
5197 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_APDU_RECEIVED);
5198 sendSeBroadcast(apduReceivedIntent);
5199 break;
5200
5201 case MSG_SE_MIFARE_ACCESS:
5202 if (DBG) Log.d(TAG, "MIFARE access message");
5203 /* Send broadcast */
5204 byte[] mifareCmd = (byte[]) msg.obj;
5205 Intent mifareAccessIntent = new Intent();
5206 mifareAccessIntent.setAction(ACTION_MIFARE_ACCESS_DETECTED);
5207 if (mifareCmd != null && mifareCmd.length > 1) {
5208 int mifareBlock = mifareCmd[1] & 0xff;
5209 if (DBG) Log.d(TAG, "Mifare Block=" + mifareBlock);
5210 mifareAccessIntent.putExtra(EXTRA_MIFARE_BLOCK, mifareBlock);
5211 }
5212 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_MIFARE_ACCESS_DETECTED);
5213 sendSeBroadcast(mifareAccessIntent);
5214 break;
5215
5216 case MSG_LLCP_LINK_ACTIVATION:
5217 if (mIsDebugBuild) {
5218 Intent actIntent = new Intent(ACTION_LLCP_UP);
5219 mContext.sendBroadcast(actIntent);
5220 }
5221 llcpActivated((NfcDepEndpoint) msg.obj);
5222 break;
5223
5224 case MSG_LLCP_LINK_DEACTIVATED:
5225 if (mIsDebugBuild) {
5226 Intent deactIntent = new Intent(ACTION_LLCP_DOWN);
5227 mContext.sendBroadcast(deactIntent);
5228 }
5229 NfcDepEndpoint device = (NfcDepEndpoint) msg.obj;
5230 boolean needsDisconnect = false;
5231
5232 Log.d(TAG, "LLCP Link Deactivated message. Restart polling loop.");
5233 synchronized (NfcService.this) {
5234 /* Check if the device has been already unregistered */
5235 if (mObjectMap.remove(device.getHandle()) != null) {
5236 /* Disconnect if we are initiator */
5237 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) {
5238 if (DBG) Log.d(TAG, "disconnecting from target");
5239 needsDisconnect = true;
5240 } else {
5241 if (DBG) Log.d(TAG, "not disconnecting from initiator");
5242 }
5243 }
5244 }
5245 if (needsDisconnect) {
5246 device.disconnect(); // restarts polling loop
5247 }
5248
5249 mP2pLinkManager.onLlcpDeactivated();
5250 break;
5251 case MSG_LLCP_LINK_FIRST_PACKET:
5252 mP2pLinkManager.onLlcpFirstPacketReceived();
5253 break;
5254 case MSG_TARGET_DESELECTED:
5255 /* Broadcast Intent Target Deselected */
5256 if (DBG) Log.d(TAG, "Target Deselected");
5257 Intent intent = new Intent();
5258 intent.setAction(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
5259 if (DBG) Log.d(TAG, "Broadcasting Intent");
5260 mContext.sendOrderedBroadcast(intent, NfcPermissions.NFC_PERMISSION);
5261 break;
5262
5263 case MSG_SE_FIELD_ACTIVATED: {
5264 if (DBG) Log.d(TAG, "SE FIELD ACTIVATED");
5265 Intent eventFieldOnIntent = new Intent();
5266 eventFieldOnIntent.setAction(ACTION_RF_FIELD_ON_DETECTED);
5267 sendSeBroadcast(eventFieldOnIntent);
5268 break;
5269 }
5270 case MSG_RESUME_POLLING:
5271 mNfcAdapter.resumePolling();
5272 break;
5273
5274 case MSG_SE_FIELD_DEACTIVATED: {
5275 if (DBG) Log.d(TAG, "SE FIELD DEACTIVATED");
5276 Intent eventFieldOffIntent = new Intent();
5277 eventFieldOffIntent.setAction(ACTION_RF_FIELD_OFF_DETECTED);
5278 sendSeBroadcast(eventFieldOffIntent);
5279 break;
5280 }
5281
5282 case MSG_SE_LISTEN_ACTIVATED: {
5283 if (DBG) Log.d(TAG, "SE LISTEN MODE ACTIVATED");
5284 Intent listenModeActivated = new Intent();
5285 listenModeActivated.setAction(ACTION_SE_LISTEN_ACTIVATED);
5286 sendSeBroadcast(listenModeActivated);
5287 break;
5288 }
5289
5290 case MSG_SE_LISTEN_DEACTIVATED: {
5291 if (DBG) Log.d(TAG, "SE LISTEN MODE DEACTIVATED");
5292 Intent listenModeDeactivated = new Intent();
5293 listenModeDeactivated.setAction(ACTION_SE_LISTEN_DEACTIVATED);
5294 sendSeBroadcast(listenModeDeactivated);
5295 break;
5296 }
5297
5298 case MSG_SWP_READER_REQUESTED:
5299
5300 /* Send broadcast ordered */
nxpandroid281eb922016-08-25 20:27:46 +05305301 Intent swpReaderRequestedIntent = new Intent();
nxpandroid64fd68c2015-09-23 16:45:15 +05305302 ArrayList<Integer> techList = (ArrayList<Integer>) msg.obj;
nxpandroid281eb922016-08-25 20:27:46 +05305303 Integer[] techs = techList.toArray(new Integer[techList.size()]);
5304 swpReaderRequestedIntent
nxpandroid64fd68c2015-09-23 16:45:15 +05305305 .setAction(NxpConstants.ACTION_SWP_READER_REQUESTED);
5306 if (DBG) {
5307 Log.d(TAG, "SWP READER - Requested");
5308 }
nxpandroid281eb922016-08-25 20:27:46 +05305309 mContext.sendBroadcast(swpReaderRequestedIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05305310 break;
5311
5312 case MSG_SWP_READER_REQUESTED_FAIL:
5313
5314 /* Send broadcast ordered */
nxpandroid281eb922016-08-25 20:27:46 +05305315 Intent swpReaderRequestedFailIntent = new Intent();
nxpandroid64fd68c2015-09-23 16:45:15 +05305316
nxpandroid281eb922016-08-25 20:27:46 +05305317 swpReaderRequestedFailIntent
nxpandroid64fd68c2015-09-23 16:45:15 +05305318 .setAction(NxpConstants.ACTION_SWP_READER_REQUESTED_FAILED);
5319 if (DBG) {
5320 Log.d(TAG, "SWP READER - Requested Fail");
5321 }
nxpandroid281eb922016-08-25 20:27:46 +05305322 mContext.sendBroadcast(swpReaderRequestedFailIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05305323 break;
5324
5325 case MSG_SWP_READER_ACTIVATED:
5326
5327 /* Send broadcast ordered */
nxpandroid281eb922016-08-25 20:27:46 +05305328 Intent swpReaderActivatedIntent = new Intent();
nxpandroid64fd68c2015-09-23 16:45:15 +05305329
nxpandroid281eb922016-08-25 20:27:46 +05305330 swpReaderActivatedIntent
nxpandroid64fd68c2015-09-23 16:45:15 +05305331 .setAction(NxpConstants.ACTION_SWP_READER_ACTIVATED);
5332 if (DBG) {
5333 Log.d(TAG, "SWP READER - Activated");
5334 }
nxpandroid281eb922016-08-25 20:27:46 +05305335 mContext.sendBroadcast(swpReaderActivatedIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05305336 break;
5337
5338 case MSG_ETSI_START_CONFIG:
5339 {
5340 Log.d(TAG, "NfcServiceHandler - MSG_ETSI_START_CONFIG");
5341 ArrayList<Integer> configList = (ArrayList<Integer>) msg.obj;
5342 int eeHandle;
5343 if(configList.contains(0x402))
5344 {
5345 eeHandle = 0x402;
5346 }
5347 else{
5348 eeHandle = 0x4C0;
5349 }
5350 etsiStartConfig(eeHandle);
5351 }
5352 break;
5353
5354 case MSG_ETSI_STOP_CONFIG:
5355
5356 Log.d(TAG, "NfcServiceHandler - MSG_ETSI_STOP_CONFIG");
5357
5358 etsiStopConfig((int)msg.obj);
5359 break;
5360
5361 case MSG_ETSI_SWP_TIMEOUT:
5362
5363 Log.d(TAG, "NfcServiceHandler - MSG_ETSI_SWP_TIMEOUT");
5364
5365 mDeviceHost.setEtsiReaederState(STATE_SE_RDR_MODE_STOP_CONFIG);
5366 etsiStopConfig((int)msg.obj);
5367
5368 break;
nxpandroide66eb092017-07-12 21:36:08 +05305369 case MSG_APPLY_SCREEN_STATE:
nxpandroid64fd68c2015-09-23 16:45:15 +05305370
5371 mScreenState = (int)msg.obj;
Nikhil Chhabra20be8d92018-01-09 18:32:58 +05305372
5373 // If NFC is turning off, we shouldn't need any changes here
5374 synchronized (NfcService.this) {
5375 if (mState == NfcAdapter.STATE_TURNING_OFF)
5376 return;
5377 }
5378
nxpandroide66eb092017-07-12 21:36:08 +05305379 int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ?
5380 (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState;
Suhas Sureshd8a71d22017-11-06 18:48:14 +05305381 mDeviceHost.doSetScreenOrPowerState(screen_state_mask);
nxpandroide66eb092017-07-12 21:36:08 +05305382
Bhupendra Paware1c7ede2018-02-26 11:51:32 +05305383 if(nci_version != NCI_VERSION_2_0) {
5384 applyRouting(false);
5385 } else if(mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED
Suhas Sureshd8a71d22017-11-06 18:48:14 +05305386 || mNfcUnlockManager.isLockscreenPollingEnabled()) {
nxpandroide66eb092017-07-12 21:36:08 +05305387 applyRouting(false);
Suhas Sureshd8a71d22017-11-06 18:48:14 +05305388 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305389 break;
nxpandroid281eb922016-08-25 20:27:46 +05305390 case MSG_TAG_DEBOUNCE:
5391 // Didn't see the tag again, tag is gone
5392 ITagRemovedCallback tagRemovedCallback;
5393 synchronized (NfcService.this) {
5394 mDebounceTagUid = null;
5395 tagRemovedCallback = mDebounceTagRemovedCallback;
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305396 mDebounceTagRemovedCallback = null;
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +05305397 mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE;
nxpandroid281eb922016-08-25 20:27:46 +05305398 }
5399 if (tagRemovedCallback != null) {
5400 try {
5401 tagRemovedCallback.onTagRemoved();
5402 } catch (RemoteException e) {
5403 // Ignore
5404 }
5405 }
5406 break;
nxpandroid5d64ce92016-11-18 19:48:53 +05305407 case MSG_RESTART_WATCHDOG:
5408 int enable = msg.arg1;
5409 disableInternalwatchDog.cancel();
5410 try{
5411 disableInternalwatchDog.join();
5412 } catch (java.lang.InterruptedException e) {
5413 }
5414 disableInternalwatchDog = new WatchDogThread("disableInternal", ROUTING_WATCHDOG_MS);
5415 Log.d(TAG, "New Watchdog: WatchDog Thread ID is "+ disableInternalwatchDog.getId());
5416 disableInternalwatchDog.start();
5417 break;
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305418 case MSG_UPDATE_STATS:
5419 if (mNumTagsDetected.get() > 0) {
5420 MetricsLogger.count(mContext, TRON_NFC_TAG, mNumTagsDetected.get());
5421 mNumTagsDetected.set(0);
5422 }
5423 if (mNumHceDetected.get() > 0) {
5424 MetricsLogger.count(mContext, TRON_NFC_CE, mNumHceDetected.get());
5425 mNumHceDetected.set(0);
5426 }
5427 if (mNumP2pDetected.get() > 0) {
5428 MetricsLogger.count(mContext, TRON_NFC_P2P, mNumP2pDetected.get());
5429 mNumP2pDetected.set(0);
5430 }
5431 removeMessages(MSG_UPDATE_STATS);
5432 sendEmptyMessageDelayed(MSG_UPDATE_STATS, STATS_UPDATE_INTERVAL_MS);
5433 break;
nxpandroida5fd6622017-07-31 16:15:18 +05305434
5435 case MSG_ROUTE_APDU:{
5436 int route = msg.arg1;
5437 int power = msg.arg2;
5438 String apduData = null;
5439 String apduMask = null;
5440 Bundle dataBundle = msg.getData();
5441 if (dataBundle != null) {
5442 apduData = dataBundle.getString("apduData");
5443 apduMask = dataBundle.getString("apduMask");
5444 }
5445 // Send the APDU
5446 if(apduData != null && dataBundle != null)
5447 mDeviceHost.routeApduPattern(route, power, hexStringToBytes(apduData) ,hexStringToBytes(apduMask));
5448 break;
5449 }
5450 case MSG_UNROUTE_APDU: {
5451 String apdu = (String) msg.obj;
5452 mDeviceHost.unrouteApduPattern(hexStringToBytes(apdu));
5453 break;
5454 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305455 default:
5456 Log.e(TAG, "Unknown message received");
5457 break;
5458 }
5459 }
5460
5461 private void sendSeBroadcast(Intent intent) {
5462 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
5463 // Resume app switches so the receivers can start activites without delay
5464 mNfcDispatcher.resumeAppSwitches();
5465 ArrayList<String> matchingPackages = new ArrayList<String>();
5466 ArrayList<String> preferredPackages = new ArrayList<String>();
nxpandroida51b5bd2017-04-10 18:28:21 +05305467 Log.d(TAG, "NFCINTENT sendNfcEeAccessProtectedBroadcast");
nxpandroid64fd68c2015-09-23 16:45:15 +05305468 if(mInstalledPackages == null) {
5469 Log.d(TAG, "No packages to send broadcast.");
5470 return;
5471 }
5472 synchronized(this) {
5473 for (PackageInfo pkg : mInstalledPackages) {
5474 if (pkg != null && pkg.applicationInfo != null) {
nxpandroida51b5bd2017-04-10 18:28:21 +05305475 if (pkg.packageName.equals(PACKAGE_SMART_CARD_SERVICE)) {
5476 preferredPackages.add(pkg.packageName);
5477 Log.d(TAG, "NFCINTENT PACKAGE ADDED");
5478 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305479 if (mNfceeAccessControl.check(pkg.applicationInfo)) {
5480 matchingPackages.add(pkg.packageName);
5481 if (mCardEmulationManager != null &&
5482 mCardEmulationManager.packageHasPreferredService(pkg.packageName)) {
5483 preferredPackages.add(pkg.packageName);
5484 }
5485 }
5486 }
5487 }
5488 if (preferredPackages.size() > 0) {
5489 // If there's any packages in here which are preferred, only
5490 // send field events to those packages, to prevent other apps
5491 // with signatures in nfcee_access.xml from acting upon the events.
5492 for (String packageName : preferredPackages){
5493 intent.setPackage(packageName);
nxpandroida51b5bd2017-04-10 18:28:21 +05305494 Log.d(TAG, "NFCINTENT SENT TO PACKAGE" + packageName);
nxpandroid64fd68c2015-09-23 16:45:15 +05305495 mContext.sendBroadcast(intent);
5496 }
5497 } else {
5498 for (String packageName : matchingPackages){
5499 intent.setPackage(packageName);
5500 mContext.sendBroadcast(intent);
5501 }
5502 }
5503 }
5504 }
5505
5506 private void sendMultiEvtBroadcast(Intent intent) {
5507
5508 ArrayList<String> packageList = mNxpNfcController.getEnabledMultiEvtsPackageList();
nxpandroida9a68ba2016-01-14 21:12:17 +05305509 ComponentName unicastComponent = null;
nxpandroid64fd68c2015-09-23 16:45:15 +05305510 if(packageList.size() == 0) {
5511 Log.d(TAG, "No packages to send broadcast.");
nxpandroida9a68ba2016-01-14 21:12:17 +05305512 unicastComponent = mNxpNfcController.getUnicastPackage();
5513 if(unicastComponent != null)
5514 {
5515 intent.setComponent(unicastComponent);
5516 try {
5517 //start gsma
5518 Log.d(TAG, "Starting activity uincast Pkg"+unicastComponent.flattenToString());
5519 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
5520 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
5521 if(mContext.getPackageManager().resolveActivity(intent, 0) != null)
5522 {
nxpandroid5d64ce92016-11-18 19:48:53 +05305523 mContext.startActivityAsUser(intent, UserHandle.CURRENT);
nxpandroida9a68ba2016-01-14 21:12:17 +05305524 } else {
5525 Log.d(TAG, "Intent not resolved");
5526 }
5527 } catch (Exception e) {
5528 if (DBG) Log.d(TAG, "Exception: " + e.getMessage());
5529 }
5530 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305531 return;
5532 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305533 for(int i=0; i<packageList.size(); i++) {
5534 Log.d(TAG,"MultiEvt Enabled Application packageName: " + packageList.get(i));
5535 intent.setPackage(packageList.get(i));
nxpandroid5d64ce92016-11-18 19:48:53 +05305536 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT,
5537 NxpConstants.PERMISSIONS_TRANSACTION_EVENT);
nxpandroid64fd68c2015-09-23 16:45:15 +05305538 }
5539 }
5540
5541 private boolean llcpActivated(NfcDepEndpoint device) {
5542 Log.d(TAG, "LLCP Activation message");
5543
5544 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) {
5545 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_TARGET");
5546 if (device.connect()) {
5547 /* Check LLCP compliance */
5548 if (mDeviceHost.doCheckLlcp()) {
5549 /* Activate LLCP Link */
5550 if (mDeviceHost.doActivateLlcp()) {
5551 if (DBG) Log.d(TAG, "Initiator Activate LLCP OK");
5552 synchronized (NfcService.this) {
5553 // Register P2P device
5554 mObjectMap.put(device.getHandle(), device);
5555 }
nxpandroid1153eb32015-11-06 18:46:58 +05305556 mP2pLinkManager.onLlcpActivated(device.getLlcpVersion());
nxpandroid64fd68c2015-09-23 16:45:15 +05305557 return true;
5558 } else {
5559 /* should not happen */
5560 Log.w(TAG, "Initiator LLCP activation failed. Disconnect.");
5561 device.disconnect();
5562 }
5563 } else {
5564 if (DBG) Log.d(TAG, "Remote Target does not support LLCP. Disconnect.");
5565 device.disconnect();
5566 }
5567 } else {
5568 if (DBG) Log.d(TAG, "Cannot connect remote Target. Polling loop restarted.");
5569 /*
5570 * The polling loop should have been restarted in failing
5571 * doConnect
5572 */
5573 }
5574 } else if (device.getMode() == NfcDepEndpoint.MODE_P2P_INITIATOR) {
5575 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_INITIATOR");
5576 /* Check LLCP compliancy */
5577 if (mDeviceHost.doCheckLlcp()) {
5578 /* Activate LLCP Link */
5579 if (mDeviceHost.doActivateLlcp()) {
5580 if (DBG) Log.d(TAG, "Target Activate LLCP OK");
5581 synchronized (NfcService.this) {
5582 // Register P2P device
5583 mObjectMap.put(device.getHandle(), device);
5584 }
nxpandroid1153eb32015-11-06 18:46:58 +05305585 mP2pLinkManager.onLlcpActivated(device.getLlcpVersion());
nxpandroid64fd68c2015-09-23 16:45:15 +05305586 return true;
5587 }
5588 } else {
5589 Log.w(TAG, "checkLlcp failed");
5590 }
5591 }
5592
5593 return false;
5594 }
5595
5596 private void dispatchTagEndpoint(TagEndpoint tagEndpoint, ReaderModeParams readerParams) {
5597 Tag tag = new Tag(tagEndpoint.getUid(), tagEndpoint.getTechList(),
5598 tagEndpoint.getTechExtras(), tagEndpoint.getHandle(), mNfcTagService);
5599 registerTagObject(tagEndpoint);
5600 if (readerParams != null) {
5601 try {
5602 if ((readerParams.flags & NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS) == 0) {
5603 playSound(SOUND_END);
5604 }
5605 if (readerParams.callback != null) {
5606 readerParams.callback.onTagDiscovered(tag);
5607 return;
5608 } else {
5609 // Follow normal dispatch below
5610 }
5611 } catch (RemoteException e) {
5612 Log.e(TAG, "Reader mode remote has died, falling back.", e);
5613 // Intentional fall-through
5614 } catch (Exception e) {
5615 // Catch any other exception
5616 Log.e(TAG, "App exception, not dispatching.", e);
5617 return;
5618 }
5619 }
5620 int dispatchResult = mNfcDispatcher.dispatchTag(tag);
5621 if (dispatchResult == NfcDispatcher.DISPATCH_FAIL) {
5622 unregisterObject(tagEndpoint.getHandle());
5623 playSound(SOUND_ERROR);
5624 } else if (dispatchResult == NfcDispatcher.DISPATCH_SUCCESS) {
5625 playSound(SOUND_END);
5626 }
5627 }
5628 }
5629
5630 private NfcServiceHandler mHandler = new NfcServiceHandler();
5631
5632 class ApplyRoutingTask extends AsyncTask<Integer, Void, Void> {
5633 @Override
5634 protected Void doInBackground(Integer... params) {
5635 synchronized (NfcService.this) {
5636 if (params == null || params.length != 1) {
5637 // force apply current routing
5638 Log.e(TAG, "applyRouting -1");
5639 applyRouting(true);
5640 return null;
5641 }
5642 mScreenState = params[0].intValue();
nxpandroid64fd68c2015-09-23 16:45:15 +05305643 mRoutingWakeLock.acquire();
5644 try {
5645 Log.e(TAG, "applyRouting -2");
5646 applyRouting(false);
5647 } finally {
5648 mRoutingWakeLock.release();
5649 }
5650 return null;
5651 }
5652 }
5653 }
5654
5655 class TagRemoveTask extends AsyncTask<Integer, Void, Void> {
5656 @Override
5657 protected Void doInBackground(Integer... params) {
5658
nxpandroid5d64ce92016-11-18 19:48:53 +05305659 Intent swpReaderTagRemoveIntent = new Intent();
nxpandroid64fd68c2015-09-23 16:45:15 +05305660
nxpandroid5d64ce92016-11-18 19:48:53 +05305661 swpReaderTagRemoveIntent.setAction(NxpConstants.ACTION_SWP_READER_TAG_REMOVE);
nxpandroid64fd68c2015-09-23 16:45:15 +05305662
5663 int counter = 0;
5664 int discNtfTimeout = params[0].intValue();
5665
5666 while(ETSI_STOP_CONFIG == true)
5667 { /* Send broadcast ordered */
5668
5669 if(discNtfTimeout == 0)
5670 {
5671 /*Do nothing*/
5672 }
5673 else if(counter < discNtfTimeout)
5674 {
5675 counter++;
5676 }
5677 else
5678 {
5679 ETSI_STOP_CONFIG = false;
5680 break;
5681 }
5682 if (DBG) {
5683 Log.d(TAG, "SWP READER - Tag Remove");
5684 }
nxpandroid5d64ce92016-11-18 19:48:53 +05305685 mContext.sendBroadcast(swpReaderTagRemoveIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05305686 try{
5687 Thread.sleep(1000);
5688 } catch(Exception e) {
5689 e.printStackTrace();
5690 }
5691 }
5692 return null;
5693 }
5694 }
5695
5696
5697 private final BroadcastReceiver x509CertificateReceiver = new BroadcastReceiver() {
5698 @Override
5699 public void onReceive(Context context, Intent intent) {
5700 boolean result = intent.getBooleanExtra(NxpConstants.EXTRA_RESULT, false);
5701 mNxpNfcController.setResultForCertificates(result);
5702 }
5703 };
5704
5705 private final BroadcastReceiver mEnableNfc = new BroadcastReceiver() {
5706 @Override
5707 public void onReceive(Context context, Intent intent) {
5708 String action = intent.getAction();
5709 Intent nfcDialogIntent = new Intent(mContext, EnableNfcDialogActivity.class);
5710 nfcDialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
5711 mContext.startActivityAsUser(nfcDialogIntent, UserHandle.CURRENT);
5712 }
5713 };
5714
Shashank vimal83779082018-02-06 18:10:31 +05305715 private final BroadcastReceiver mActivateSwpInterface = new BroadcastReceiver() {
5716 @Override
5717 public void onReceive(Context context, Intent intent) {
5718
5719 String action = intent.getAction();
5720
5721 if(NxpConstants.CAT_ACTIVATE_NOTIFY_ACTION.equals(action)){
5722
5723 Log.i(TAG, "Received ACTIVATE intent:" + action);
5724
5725 if(mSelectedSeId != ALL_SE_ID_TYPE){
5726 mDeviceHost.doSelectSecureElement(mSelectedSeId);
5727 Log.i(TAG, "Activated:" + mSelectedSeId);
5728 }
5729 else{
5730 int[] seList = mDeviceHost.doGetSecureElementList();
5731 Log.i(TAG, "Activating all SE:");
5732
5733 for(int i = 0; i < seList.length; i++){
5734 mDeviceHost.doActivateSecureElement(seList[i]);
5735 try{
5736 //Delay between two SE selection
5737 Thread.sleep(200);
5738 }catch(Exception e){
5739 e.printStackTrace();
5740 }
5741 }
5742 }
5743 }
5744 }
5745 };
5746
5747
nxpandroid64fd68c2015-09-23 16:45:15 +05305748 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
5749 @Override
5750 public void onReceive(Context context, Intent intent) {
5751 String action = intent.getAction();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305752 Log.e(TAG, "screen state "+action);
nxpandroid64fd68c2015-09-23 16:45:15 +05305753 if (action.equals(
5754 NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) {
5755 // Perform applyRouting() in AsyncTask to serialize blocking calls
5756 new ApplyRoutingTask().execute();
5757 } else if ((action.equals(Intent.ACTION_SCREEN_ON)
5758 || action.equals(Intent.ACTION_SCREEN_OFF)
5759 || action.equals(Intent.ACTION_USER_PRESENT)) &&
5760 mState == NfcAdapter.STATE_ON) {
5761 // Perform applyRouting() in AsyncTask to serialize blocking calls
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305762 int screenState = mScreenStateHelper.checkScreenState();
nxpandroid64fd68c2015-09-23 16:45:15 +05305763 if (action.equals(Intent.ACTION_SCREEN_OFF)) {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305764 if(mScreenState != ScreenStateHelper.SCREEN_STATE_OFF_LOCKED)
nxpandroid64fd68c2015-09-23 16:45:15 +05305765 {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305766 Log.e(TAG, "screen state OFF required");
5767 screenState = mKeyguard.isKeyguardLocked() ?
5768 ScreenStateHelper.SCREEN_STATE_OFF_LOCKED :
5769 ScreenStateHelper.SCREEN_STATE_OFF_UNLOCKED;
nxpandroid64fd68c2015-09-23 16:45:15 +05305770 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305771 } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
5772 screenState = mKeyguard.isKeyguardLocked() ?
5773 ScreenStateHelper.SCREEN_STATE_ON_LOCKED : ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED;
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305774 Log.e(TAG, "screen state on");
5775 /*
nxpandroid64fd68c2015-09-23 16:45:15 +05305776 if(screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mScreenState == ScreenStateHelper.SCREEN_STATE_OFF) {
nxpandroid64fd68c2015-09-23 16:45:15 +05305777 } else if (screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mScreenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED) {
5778 return;
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305779 }*/
nxpandroid64fd68c2015-09-23 16:45:15 +05305780 } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
5781 if (mScreenState != ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305782 Log.e(TAG, "screen state user present");
nxpandroid64fd68c2015-09-23 16:45:15 +05305783 screenState = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED;
nxpandroid64fd68c2015-09-23 16:45:15 +05305784 } else {
5785 return;
5786 }
5787 }
Bhupendra Paware1c7ede2018-02-26 11:51:32 +05305788 /* This piece of code is duplicate as MSG_APPLY_SCREEN_STATE
5789 is already calling applyRouting api */
5790 /*if(nci_version != NCI_VERSION_2_0) {
nxpandroide66eb092017-07-12 21:36:08 +05305791 new ApplyRoutingTask().execute(Integer.valueOf(screenState));
Bhupendra Paware1c7ede2018-02-26 11:51:32 +05305792 }*/
nxpandroide66eb092017-07-12 21:36:08 +05305793 sendMessage(NfcService.MSG_APPLY_SCREEN_STATE, screenState);
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305794 Log.e(TAG, "screen state "+screenState);
5795 Log.e(TAG, "screen state mScreenState "+mScreenState);
nxpandroid64fd68c2015-09-23 16:45:15 +05305796 } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305797 int screenState = mScreenStateHelper.checkScreenState();
nxpandroid64fd68c2015-09-23 16:45:15 +05305798 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
5799 synchronized (this) {
5800 mUserId = userId;
5801 }
5802 mP2pLinkManager.onUserSwitched(getUserId());
5803 if (mIsHceCapable) {
5804 mCardEmulationManager.onUserSwitched(getUserId());
5805 }
nxpandroide66eb092017-07-12 21:36:08 +05305806 screenState = mScreenStateHelper.checkScreenState();
nxpandroid64fd68c2015-09-23 16:45:15 +05305807 new ApplyRoutingTask().execute(Integer.valueOf(screenState));
nxpandroid64fd68c2015-09-23 16:45:15 +05305808 }
5809 }
5810 };
5811
5812 private final BroadcastReceiver mOwnerReceiver = new BroadcastReceiver() {
5813 @Override
5814 public void onReceive(Context context, Intent intent) {
5815 String action = intent.getAction();
5816 if (action.equals(Intent.ACTION_PACKAGE_REMOVED) ||
5817 action.equals(Intent.ACTION_PACKAGE_ADDED) ||
5818 action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE) ||
5819 action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) {
5820 updatePackageCache();
5821
5822 if (action.equals(Intent.ACTION_PACKAGE_REMOVED)) {
5823 // Clear the NFCEE access cache in case a UID gets recycled
5824 mNfceeAccessControl.invalidateCache();
5825 }
nxpandroid5d64ce92016-11-18 19:48:53 +05305826 } else if(action.equals(Intent.ACTION_SHUTDOWN)) {
5827 mPowerShutDown = true;
5828 if (DBG) Log.d(TAG,"Device is shutting down.");
5829 mDeviceHost.doSetScreenOrPowerState(ScreenStateHelper.POWER_STATE_OFF);
nxpandroid64fd68c2015-09-23 16:45:15 +05305830 }
5831 }
5832 };
5833
5834 final BroadcastReceiver mAlaReceiver = new BroadcastReceiver() {
5835 @Override
5836 public void onReceive(Context context, Intent intent) {
5837 String action = intent.getAction();
5838 if (NfcAdapter.ACTION_ADAPTER_STATE_CHANGED.equals(intent.getAction())) {
5839 int state = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE,
5840 NfcAdapter.STATE_OFF);
5841 if (state == NfcAdapter.STATE_ON) {
5842 Log.e(TAG, "Loader service update start from NFC_ON Broadcast");
5843 NfcAlaService nas = new NfcAlaService();
nxpandroid5d3fdf82017-07-31 16:11:33 +05305844 int lsVersion = mNfcAla.doGetLSConfigVersion();
5845
5846 if(lsVersion >= LOADER_SERVICE_VERSION_LOW_LIMIT &&
5847 lsVersion <= LOADER_SERVICE_VERSION_HIGH_LIMIT)
nxpandroid64fd68c2015-09-23 16:45:15 +05305848 nas.updateLoaderService();
5849 }
5850 }
5851 }
5852 };
5853
5854 private final BroadcastReceiver mPolicyReceiver = new BroadcastReceiver() {
5855 @Override
5856 public void onReceive(Context context, Intent intent){
5857 String action = intent.getAction();
5858 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
5859 .equals(action)) {
5860 enforceBeamShareActivityPolicy(context,
5861 new UserHandle(getSendingUserId()), mIsNdefPushEnabled);
5862 }
5863 }
5864 };
5865
Nikhil Chhabrafc8f3f62018-01-08 20:48:49 +05305866 private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
5867 @Override
5868 public void onVrStateChanged(boolean enabled) {
5869 synchronized (this) {
5870 mIsVrModeEnabled = enabled;
5871 }
5872 }
5873 };
5874
nxpandroid64fd68c2015-09-23 16:45:15 +05305875 /**
nxpandroid64fd68c2015-09-23 16:45:15 +05305876 * for debugging only - no i18n
5877 */
5878 static String stateToString(int state) {
5879 switch (state) {
5880 case NfcAdapter.STATE_OFF:
5881 return "off";
5882 case NfcAdapter.STATE_TURNING_ON:
5883 return "turning on";
5884 case NfcAdapter.STATE_ON:
5885 return "on";
5886 case NfcAdapter.STATE_TURNING_OFF:
5887 return "turning off";
5888 default:
5889 return "<error>";
5890 }
5891 }
5892
5893 void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
5894 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
5895 != PackageManager.PERMISSION_GRANTED) {
5896 pw.println("Permission Denial: can't dump nfc from from pid="
5897 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5898 + " without permission " + android.Manifest.permission.DUMP);
5899 return;
5900 }
5901
5902 synchronized (this) {
5903 pw.println("mState=" + stateToString(mState));
5904 pw.println("mIsZeroClickRequested=" + mIsNdefPushEnabled);
5905 pw.println("mScreenState=" + ScreenStateHelper.screenStateToString(mScreenState));
5906 pw.println("mNfcPollingEnabled=" + mNfcPollingEnabled);
5907 pw.println("mNfceeRouteEnabled=" + mNfceeRouteEnabled);
5908 pw.println("mOpenEe=" + mOpenEe);
nxpandroid64fd68c2015-09-23 16:45:15 +05305909 pw.println("mLockscreenPollMask=" + mLockscreenPollMask);
5910 pw.println(mCurrentDiscoveryParameters);
5911 mP2pLinkManager.dump(fd, pw, args);
5912 if (mIsHceCapable) {
5913 mCardEmulationManager.dump(fd, pw, args);
5914 }
5915 mNfceeAccessControl.dump(fd, pw, args);
5916 mNfcDispatcher.dump(fd, pw, args);
Nikhil Chhabra9645ab62018-01-09 18:44:05 +05305917 pw.flush();
Nikhil Chhabra1e1ac462018-01-10 12:53:43 +05305918 mDeviceHost.dump(fd);
nxpandroid64fd68c2015-09-23 16:45:15 +05305919
5920 }
5921 }
nxpandroid34627bd2016-05-27 15:52:30 +05305922 /**
5923 * Update the status of all the services which were populated to commit to routing table
5924 */
5925 public void updateStatusOfServices(boolean commitStatus) {
nxpandroidebf53fb2016-12-22 18:48:59 +05305926 if(commitStatus == true)
5927 {
5928 mAidCache.setPreviousPreferredPaymentService(null);
5929 }
nxpandroid34627bd2016-05-27 15:52:30 +05305930 mCardEmulationManager.updateStatusOfServices(commitStatus);
5931 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305932}