blob: aaa42af8434b86329fe0584e7baf08acc107ee7c [file] [log] [blame]
nxpandroid64fd68c2015-09-23 16:45:15 +05301 /*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16/******************************************************************************
17 *
18 * The original Work has been changed by NXP Semiconductors.
19 *
nxf35421aca166a2018-02-06 16:00:50 +053020 * Copyright (C) 2015-2018 NXP Semiconductors
nxpandroid64fd68c2015-09-23 16:45:15 +053021 *
22 * Licensed under the Apache License, Version 2.0 (the "License");
23 * you may not use this file except in compliance with the License.
24 * You may obtain a copy of the License at
25 *
26 * http://www.apache.org/licenses/LICENSE-2.0
27 *
28 * Unless required by applicable law or agreed to in writing, software
29 * distributed under the License is distributed on an "AS IS" BASIS,
30 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 * See the License for the specific language governing permissions and
32 * limitations under the License.
33 *
34 ******************************************************************************/
35package com.android.nfc;
36
37import android.app.ActivityManager;
38import android.app.Application;
nxpandroid6fd9cdb2017-07-12 18:25:41 +053039import android.app.backup.BackupManager;
nxpandroid64fd68c2015-09-23 16:45:15 +053040import android.app.KeyguardManager;
41import android.app.PendingIntent;
42import android.app.admin.DevicePolicyManager;
43import android.content.BroadcastReceiver;
44import android.content.ComponentName;
45import android.content.ContentResolver;
46import android.content.Context;
47import android.content.Intent;
48import android.content.IntentFilter;
49import android.content.SharedPreferences;
nxpandroid3649b762017-02-24 15:44:54 +053050
Suhas Sureshca6584b2018-04-27 17:17:22 +053051import android.content.pm.ApplicationInfo;
nxpandroid64fd68c2015-09-23 16:45:15 +053052import android.content.pm.IPackageManager;
53import android.content.pm.PackageInfo;
nxpandroid64fd68c2015-09-23 16:45:15 +053054import android.content.pm.PackageManager;
55import android.content.pm.UserInfo;
56import android.content.res.Resources.NotFoundException;
57import android.media.AudioManager;
58import android.media.SoundPool;
59import android.net.Uri;
60import android.nfc.BeamShareData;
61import android.nfc.ErrorCodes;
62import android.nfc.FormatException;
63import android.nfc.IAppCallback;
64import android.nfc.INfcAdapter;
65import android.nfc.INfcAdapterExtras;
66import android.nfc.INfcCardEmulation;
nxpandroid34627bd2016-05-27 15:52:30 +053067import android.nfc.INfcFCardEmulation;
nxpandroid64fd68c2015-09-23 16:45:15 +053068import android.nfc.INfcTag;
69import android.nfc.INfcUnlockHandler;
nxpandroid281eb922016-08-25 20:27:46 +053070import android.nfc.ITagRemovedCallback;
nxpandroid64fd68c2015-09-23 16:45:15 +053071import android.nfc.NdefMessage;
72import android.nfc.NfcAdapter;
73import android.nfc.Tag;
74import android.nfc.TechListParcel;
75import android.nfc.TransceiveResult;
76import android.nfc.tech.Ndef;
77import android.nfc.tech.TagTechnology;
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +053078import android.nfc.INfcDta;
nxpandroid64fd68c2015-09-23 16:45:15 +053079import android.os.AsyncTask;
80import android.os.Binder;
81import android.os.Build;
82import android.os.Bundle;
83import android.os.Handler;
84import android.os.IBinder;
85import android.os.Message;
86import android.os.PowerManager;
87import android.os.Process;
88import android.os.RemoteException;
89import android.os.ServiceManager;
90import android.os.SystemClock;
Nikhil Chhabraa9e399a2018-01-09 11:47:13 +053091import android.os.SystemProperties;
nxpandroid64fd68c2015-09-23 16:45:15 +053092import android.os.UserHandle;
93import android.os.UserManager;
Suhas Suresh6e05ee02018-04-25 12:19:35 +053094import android.os.VibrationEffect;
95import android.os.Vibrator;
nxpandroid64fd68c2015-09-23 16:45:15 +053096import android.provider.Settings;
Suhas Sureshca6584b2018-04-27 17:17:22 +053097import android.se.omapi.ISecureElementService;
Nikhil Chhabrafc8f3f62018-01-08 20:48:49 +053098import android.service.vr.IVrManager;
99import android.service.vr.IVrStateCallbacks;
nxpandroid64fd68c2015-09-23 16:45:15 +0530100import android.util.Log;
101
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530102import com.android.internal.logging.MetricsLogger;
nxpandroid64fd68c2015-09-23 16:45:15 +0530103import com.android.nfc.DeviceHost.DeviceHostListener;
104import com.android.nfc.DeviceHost.LlcpConnectionlessSocket;
105import com.android.nfc.DeviceHost.LlcpServerSocket;
106import com.android.nfc.DeviceHost.LlcpSocket;
107import com.android.nfc.DeviceHost.NfcDepEndpoint;
108import com.android.nfc.DeviceHost.TagEndpoint;
109
110import com.android.nfc.dhimpl.NativeNfcSecureElement;
111import com.android.nfc.dhimpl.NativeNfcAla;
112import java.security.MessageDigest;
113
114import android.widget.Toast;
115
116import com.android.nfc.cardemulation.AidRoutingManager;
117import com.android.nfc.cardemulation.CardEmulationManager;
nxpandroidebf53fb2016-12-22 18:48:59 +0530118import com.android.nfc.cardemulation.RegisteredAidCache;
nxpandroid64fd68c2015-09-23 16:45:15 +0530119import com.android.nfc.dhimpl.NativeNfcManager;
120import com.android.nfc.handover.HandoverDataParser;
121
122import java.io.FileDescriptor;
123import java.io.PrintWriter;
Suhas Suresh061c9b02018-05-15 17:45:06 +0530124import java.io.UnsupportedEncodingException;
nxpandroid34627bd2016-05-27 15:52:30 +0530125import java.nio.ByteBuffer;
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530126import java.util.concurrent.atomic.AtomicInteger;
nxpandroid64fd68c2015-09-23 16:45:15 +0530127import java.io.InputStream;
128import java.io.OutputStream;
129import java.io.FileInputStream;
130import java.io.FileOutputStream;
131import java.io.File;
nxpandroid281eb922016-08-25 20:27:46 +0530132import java.io.FileWriter;
nxpandroid64fd68c2015-09-23 16:45:15 +0530133import java.io.BufferedReader;
134import java.io.FileReader;
135import java.util.Arrays;
136import java.util.ArrayList;
137import java.util.HashMap;
138import java.util.List;
139import java.util.Map;
140import java.util.NoSuchElementException;
Pratap Reddy49abbe32018-03-27 16:51:59 +0530141import java.util.TimerTask;
142import java.util.Timer;
nxpandroid64fd68c2015-09-23 16:45:15 +0530143import java.io.IOException;
144import java.io.FileNotFoundException;
nxpandroid3649b762017-02-24 15:44:54 +0530145
nxpandroid64fd68c2015-09-23 16:45:15 +0530146import android.util.Pair;
147import java.util.HashSet;
nxpandroid64fd68c2015-09-23 16:45:15 +0530148import java.util.concurrent.ExecutionException;
149
150import com.nxp.nfc.INxpNfcAdapter;
151import com.nxp.intf.ILoaderService;
152import com.nxp.intf.IJcopService;
153import com.nxp.intf.INxpExtrasService;
154import com.nxp.intf.IeSEClientServicesAdapter;
nxpandroid64fd68c2015-09-23 16:45:15 +0530155import com.nxp.nfc.INfcVzw;
156import com.nxp.nfc.INxpNfcAdapterExtras;
157import com.nxp.nfc.INxpNfcAccessExtras;
nxpandroid64fd68c2015-09-23 16:45:15 +0530158import com.nxp.nfc.NxpConstants;
159import com.vzw.nfc.RouteEntry;
160import com.gsma.nfc.internal.NxpNfcController;
161import com.nxp.nfc.gsma.internal.INxpNfcController;
Suhas Suresh9139dc22018-05-09 15:48:37 +0530162import android.hardware.secure_element.V1_0.ISecureElementHalCallback;
163import android.hardware.secure_element.V1_0.ISecureElement;
164import android.hardware.secure_element.V1_0.SecureElementStatus;
165import android.hardware.secure_element.V1_0.LogicalChannelResponse;
Shashank vimal83779082018-02-06 18:10:31 +0530166
nxpandroid64fd68c2015-09-23 16:45:15 +0530167public class NfcService implements DeviceHostListener {
168 private static final String ACTION_MASTER_CLEAR_NOTIFICATION = "android.intent.action.MASTER_CLEAR_NOTIFICATION";
169
170 static final boolean DBG = true;
171 static final String TAG = "NfcService";
172
173 public static final String SERVICE_NAME = "nfc";
174
175 /** Regular NFC permission */
176 private static final String NFC_PERM = android.Manifest.permission.NFC;
177 private static final String NFC_PERM_ERROR = "NFC permission required";
178
179 public static final String PREF = "NfcServicePrefs";
nxpandroida9a68ba2016-01-14 21:12:17 +0530180 public static final String NXP_PREF = "NfcServiceNxpPrefs";
nxpandroid64fd68c2015-09-23 16:45:15 +0530181
182 static final String PREF_NFC_ON = "nfc_on";
183 static final boolean NFC_ON_DEFAULT = true;
184 static final String PREF_NDEF_PUSH_ON = "ndef_push_on";
185 static final boolean NDEF_PUSH_ON_DEFAULT = true;
186 static final String PREF_FIRST_BEAM = "first_beam";
187 static final String PREF_FIRST_BOOT = "first_boot";
nxpandroid64fd68c2015-09-23 16:45:15 +0530188 private static final String PREF_SECURE_ELEMENT_ON = "secure_element_on";
189 private boolean SECURE_ELEMENT_ON_DEFAULT = false;
190 private int SECURE_ELEMENT_ID_DEFAULT = 0;
nxpandroidebf53fb2016-12-22 18:48:59 +0530191 private int SECURE_ELEMENT_UICC_SLOT_DEFAULT = 1;
nxpandroid64fd68c2015-09-23 16:45:15 +0530192 private static final String PREF_DEFAULT_ROUTE_ID = "default_route_id";
193 private static final String PREF_MIFARE_DESFIRE_PROTO_ROUTE_ID = "mifare_desfire_proto_route";
194 private static final String PREF_SET_DEFAULT_ROUTE_ID ="set_default_route";
195 private static final String PREF_MIFARE_CLT_ROUTE_ID= "mifare_clt_route";
nxpandroidf1f54f52017-07-31 16:08:06 +0530196 private static final String LS_BACKUP_PATH = "/data/vendor/nfc/ls_backup.txt";
197 private static final String LS_UPDATE_BACKUP_PATH = "/data/vendor/nfc/loaderservice_updater.txt";
198 private static final String LS_UPDATE_BACKUP_OUT_PATH = "/data/vendor/nfc/loaderservice_updater_out.txt";
nxpandroid64fd68c2015-09-23 16:45:15 +0530199
nxpandroidf1f54f52017-07-31 16:08:06 +0530200 private static final String[] path = {"/data/vendor/nfc/JcopOs_Update1.apdu",
201 "/data/vendor/nfc/JcopOs_Update2.apdu",
202 "/data/vendor/nfc/JcopOs_Update3.apdu"};
nxpandroid64fd68c2015-09-23 16:45:15 +0530203
204 private static final String[] PREF_JCOP_MODTIME = {"jcop file1 modtime",
205 "jcop file2 modtime",
206 "jcop file3 modtime"};
207 private static final long[] JCOP_MODTIME_DEFAULT = {-1,-1,-1};
208 private static final long[] JCOP_MODTIME_TEMP = {-1,-1,-1};
209
210 private boolean ETSI_STOP_CONFIG = false;
nxpandroid7d44e572016-08-01 19:11:04 +0530211 private int ROUTE_ID_HOST = 0x00;
212 private int ROUTE_ID_SMX = 0x01;
213 private int ROUTE_ID_UICC = 0x02;
214 private int ROUTE_ID_UICC2 = 0x04;
nxpandroid64fd68c2015-09-23 16:45:15 +0530215
216 private int ROUTE_SWITCH_ON = 0x01;
217 private int ROUTE_SWITCH_OFF = 0x02;
218 private int ROUTE_BATT_OFF= 0x04;
219
220 private int TECH_TYPE_A= 0x01;
221 private int TECH_TYPE_B= 0x02;
222 private int TECH_TYPE_F= 0x04;
223
224 //TODO: Refer L_OSP_EXT [PN547C2]
225// private int DEFAULT_ROUTE_ID_DEFAULT = AidRoutingManager.DEFAULT_ROUTE;
226 private int DEFAULT_ROUTE_ID_DEFAULT = 0x00;
227 static final boolean SE_BROADCASTS_WITH_HCE = true;
228
229 private static final String PREF_SECURE_ELEMENT_ID = "secure_element_id";
nxpandroidebf53fb2016-12-22 18:48:59 +0530230 private static final String PREF_CUR_SELECTED_UICC_ID = "current_selected_uicc_id";
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530231 public static final int ROUTE_LOC_MASK=8;
232 public static final int TECH_TYPE_MASK=11;
233
234 static final String TRON_NFC_CE = "nfc_ce";
235 static final String TRON_NFC_P2P = "nfc_p2p";
236 static final String TRON_NFC_TAG = "nfc_tag";
nxpandroid64fd68c2015-09-23 16:45:15 +0530237
238 static final int MSG_NDEF_TAG = 0;
nxpandroid64fd68c2015-09-23 16:45:15 +0530239 static final int MSG_LLCP_LINK_ACTIVATION = 2;
240 static final int MSG_LLCP_LINK_DEACTIVATED = 3;
241 static final int MSG_TARGET_DESELECTED = 4;
242 static final int MSG_MOCK_NDEF = 7;
243 static final int MSG_SE_FIELD_ACTIVATED = 8;
244 static final int MSG_SE_FIELD_DEACTIVATED = 9;
245 static final int MSG_SE_APDU_RECEIVED = 10;
246 static final int MSG_SE_EMV_CARD_REMOVAL = 11;
247 static final int MSG_SE_MIFARE_ACCESS = 12;
248 static final int MSG_SE_LISTEN_ACTIVATED = 13;
249 static final int MSG_SE_LISTEN_DEACTIVATED = 14;
250 static final int MSG_LLCP_LINK_FIRST_PACKET = 15;
251 static final int MSG_ROUTE_AID = 16;
252 static final int MSG_UNROUTE_AID = 17;
253 static final int MSG_COMMIT_ROUTING = 18;
254 static final int MSG_INVOKE_BEAM = 19;
255
256 static final int MSG_SWP_READER_REQUESTED = 20;
nxpandroid64fd68c2015-09-23 16:45:15 +0530257 static final int MSG_SWP_READER_DEACTIVATED = 22;
258 static final int MSG_CLEAR_ROUTING = 23;
259 static final int MSG_SET_SCREEN_STATE = 25;
260
261
262 static final int MSG_RF_FIELD_ACTIVATED = 26;
263 static final int MSG_RF_FIELD_DEACTIVATED = 27;
264 static final int MSG_RESUME_POLLING = 28;
265 static final int MSG_SWP_READER_REQUESTED_FAIL =29 ;
266 static final int MSG_SWP_READER_TAG_PRESENT = 30;
267 static final int MSG_SWP_READER_TAG_REMOVE = 31;
268 static final int MSG_CONNECTIVITY_EVENT = 40;
269 static final int MSG_VZW_ROUTE_AID = 41;
270 static final int MSG_VZW_COMMIT_ROUTING = 42;
271 static final int MSG_ROUTE_NFCID2 = 43;
272 static final int MSG_UNROUTE_NFCID2 = 44;
273 static final int MSG_COMMITINF_FELICA_ROUTING = 45;
274 static final int MSG_COMMITED_FELICA_ROUTING = 46;
275 static final int MSG_EMVCO_MULTI_CARD_DETECTED_EVENT = 47;
276 static final int MSG_ETSI_START_CONFIG = 48;
277 static final int MSG_ETSI_STOP_CONFIG = 49;
278 static final int MSG_ETSI_SWP_TIMEOUT = 50;
nxpandroide66eb092017-07-12 21:36:08 +0530279 static final int MSG_APPLY_SCREEN_STATE = 51;
nxpandroid34627bd2016-05-27 15:52:30 +0530280 static final int MSG_REGISTER_T3T_IDENTIFIER = 54;
281 static final int MSG_DEREGISTER_T3T_IDENTIFIER = 55;
nxpandroid281eb922016-08-25 20:27:46 +0530282 static final int MSG_TAG_DEBOUNCE = 56;
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530283 static final int MSG_UPDATE_STATS = 57;
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530284 static final int MSG_SWP_READER_RESTART = 58;
nxpandroid5d64ce92016-11-18 19:48:53 +0530285 /*Restart Nfc disbale watchdog timer*/
286 static final int MSG_RESTART_WATCHDOG = 60;
nxpandroida5fd6622017-07-31 16:15:18 +0530287 static final int MSG_ROUTE_APDU = 61;
288 static final int MSG_UNROUTE_APDU = 62;
Suhas Sureshca6584b2018-04-27 17:17:22 +0530289 static final int MSG_TRANSACTION_EVENT = 63;
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530290 // Update stats every 4 hours
291 static final long STATS_UPDATE_INTERVAL_MS = 4 * 60 * 60 * 1000;
nxpandroid64fd68c2015-09-23 16:45:15 +0530292 static final long MAX_POLLING_PAUSE_TIMEOUT = 40000;
293 static final int TASK_ENABLE = 1;
294 static final int TASK_DISABLE = 2;
295 static final int TASK_BOOT = 3;
296 static final int TASK_EE_WIPE = 4;
nxpandroid1680a6d2017-01-13 19:13:14 +0530297 static final int TASK_RESTART = 0x1F;
nxpandroid64fd68c2015-09-23 16:45:15 +0530298 static final int MSG_CHANGE_DEFAULT_ROUTE = 52;
299 static final int MSG_SE_DELIVER_INTENT = 53;
300
301 // Copied from com.android.nfc_extras to avoid library dependency
302 // Must keep in sync with com.android.nfc_extras
303 static final int ROUTE_OFF = 1;
304 static final int ROUTE_ON_WHEN_SCREEN_ON = 2;
305
306 // Return values from NfcEe.open() - these are 1:1 mapped
307 // to the thrown EE_EXCEPTION_ exceptions in nfc-extras.
308 static final int EE_ERROR_IO = -1;
309 static final int EE_ERROR_ALREADY_OPEN = -2;
310 static final int EE_ERROR_INIT = -3;
311 static final int EE_ERROR_LISTEN_MODE = -4;
312 static final int EE_ERROR_EXT_FIELD = -5;
313 static final int EE_ERROR_NFC_DISABLED = -6;
314
315 // Polling technology masks
316 static final int NFC_POLL_A = 0x01;
317 static final int NFC_POLL_B = 0x02;
318 static final int NFC_POLL_F = 0x04;
Nikhil Chhabra288edb02018-01-10 19:36:21 +0530319 static final int NFC_POLL_V = 0x08;
nxpandroid64fd68c2015-09-23 16:45:15 +0530320 static final int NFC_POLL_B_PRIME = 0x10;
321 static final int NFC_POLL_KOVIO = 0x20;
322
323 // minimum screen state that enables NFC polling
324 static final int NFC_POLLING_MODE = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED;
325
326 // Time to wait for NFC controller to initialize before watchdog
327 // goes off. This time is chosen large, because firmware download
328 // may be a part of initialization.
329 static final int INIT_WATCHDOG_MS = 90000;
330 static final int INIT_WATCHDOG_LS_MS = 180000;
331 // Time to wait for routing to be applied before watchdog
332 // goes off
333 static final int ROUTING_WATCHDOG_MS = 10000;
334
335 // Amount of time to wait before closing the NFCEE connection
336 // in a disable/shutdown scenario.
337 static final int WAIT_FOR_NFCEE_OPERATIONS_MS = 5000;
338 // Polling interval for waiting on NFCEE operations
339 static final int WAIT_FOR_NFCEE_POLL_MS = 100;
340
341 // Default delay used for presence checks
342 static final int DEFAULT_PRESENCE_CHECK_DELAY = 125;
343
344 //Delay used for presence checks of NFC_F non-Ndef
345 //Make secure communication done or tranceive next request response command
346 //to pause timer before presence check command is sent
347 static final int NFC_F_TRANSCEIVE_PRESENCE_CHECK_DELAY = 500;
348
349 // The amount of time we wait before manually launching
350 // the Beam animation when called through the share menu.
351 static final int INVOKE_BEAM_DELAY_MS = 1000;
Pratap Reddy49abbe32018-03-27 16:51:59 +0530352 // Default delay used for presence checks in ETSI mode
353 static final int ETSI_PRESENCE_CHECK_DELAY = 1000;
nxpandroid64fd68c2015-09-23 16:45:15 +0530354 // for use with playSound()
355 public static final int SOUND_START = 0;
356 public static final int SOUND_END = 1;
357 public static final int SOUND_ERROR = 2;
358
nxpandroide66eb092017-07-12 21:36:08 +0530359 public static final int NCI_VERSION_2_0 = 0x20;
360
361 public static final int NCI_VERSION_1_0 = 0x10;
nxpandroid64fd68c2015-09-23 16:45:15 +0530362 //ETSI Reader Events
Pratap Reddy49abbe32018-03-27 16:51:59 +0530363 public static final int ETSI_READER_START_SUCCESS = 0;
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530364 public static final int ETSI_READER_START_FAIL = 1;
365 public static final int ETSI_READER_ACTIVATED = 2;
366 public static final int ETSI_READER_STOP = 3;
nxpandroid64fd68c2015-09-23 16:45:15 +0530367
368 //ETSI Reader Req States
369 public static final int STATE_SE_RDR_MODE_INVALID = 0x00;
370 public static final int STATE_SE_RDR_MODE_START_CONFIG = 0x01;
371 public static final int STATE_SE_RDR_MODE_START_IN_PROGRESS = 0x02;
372 public static final int STATE_SE_RDR_MODE_STARTED = 0x03;
373 public static final int STATE_SE_RDR_MODE_ACTIVATED = 0x04;
374 public static final int STATE_SE_RDR_MODE_STOP_CONFIG = 0x05;
375 public static final int STATE_SE_RDR_MODE_STOP_IN_PROGRESS = 0x06;
376 public static final int STATE_SE_RDR_MODE_STOPPED = 0x07;
377
nxpandroid281eb922016-08-25 20:27:46 +0530378 //Transit setconfig status
379 public static final int TRANSIT_SETCONFIG_STAT_SUCCESS = 0x00;
380 public static final int TRANSIT_SETCONFIG_STAT_FAILED = 0xFF;
381
Nikhil Chhabraefd6b092018-04-11 15:28:06 +0530382 //for NfcWiredSe service
383 static final byte DEFAULT_BASIC_CHANNEL = 0;
384 static final byte MAX_LOGICAL_CHANNELS = 4;
385 static final byte INVALID_LOGICAL_CHANNEL = (byte)0xff;
386
nxpandroid64fd68c2015-09-23 16:45:15 +0530387 public static final String ACTION_RF_FIELD_ON_DETECTED =
388 "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED";
389 public static final String ACTION_RF_FIELD_OFF_DETECTED =
390 "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED";
391 public static final String ACTION_AID_SELECTED =
392 "com.android.nfc_extras.action.AID_SELECTED";
393 public static final String EXTRA_AID = "com.android.nfc_extras.extra.AID";
394
395 public static final String ACTION_LLCP_UP =
396 "com.android.nfc.action.LLCP_UP";
397
398 public static final String ACTION_LLCP_DOWN =
399 "com.android.nfc.action.LLCP_DOWN";
400
401 public static final String ACTION_APDU_RECEIVED =
402 "com.android.nfc_extras.action.APDU_RECEIVED";
403 public static final String EXTRA_APDU_BYTES =
404 "com.android.nfc_extras.extra.APDU_BYTES";
405
406 public static final String ACTION_EMV_CARD_REMOVAL =
407 "com.android.nfc_extras.action.EMV_CARD_REMOVAL";
408
409 public static final String ACTION_MIFARE_ACCESS_DETECTED =
410 "com.android.nfc_extras.action.MIFARE_ACCESS_DETECTED";
411 public static final String EXTRA_MIFARE_BLOCK =
412 "com.android.nfc_extras.extra.MIFARE_BLOCK";
413
414 public static final String ACTION_SE_LISTEN_ACTIVATED =
415 "com.android.nfc_extras.action.SE_LISTEN_ACTIVATED";
416 public static final String ACTION_SE_LISTEN_DEACTIVATED =
417 "com.android.nfc_extras.action.SE_LISTEN_DEACTIVATED";
418
419 public static final String ACTION_EMVCO_MULTIPLE_CARD_DETECTED =
420 "com.nxp.action.EMVCO_MULTIPLE_CARD_DETECTED";
421
nxpandroid34627bd2016-05-27 15:52:30 +0530422 public static final String ACTION_UICC_STATUS_RECEIVED =
423 "com.nxp.action.UICC_STATUS_RECEIVED";
424
nxpandroid1680a6d2017-01-13 19:13:14 +0530425 public static final String ACTION_FLASH_SUCCESS =
426 "com.android.nfc_extras.action.ACTION_FLASH_SUCCESS";
427
nxpandroid34627bd2016-05-27 15:52:30 +0530428 public static final String EXTRA_UICC_STATUS = "com.nxp.extra.UICC_STATUS";
429
nxpandroid64fd68c2015-09-23 16:45:15 +0530430 private static final String PACKAGE_SMART_CARD_SERVICE = "org.simalliance.openmobileapi.service";
431 /**
432 * SMART MX ID to be able to select it as the default Secure Element
433 */
434 public static final int SMART_MX_ID_TYPE = 1;
435
436 /**
437 * UICC ID to be able to select it as the default Secure Element
438 */
439 public static final int UICC_ID_TYPE = 2;
440
441 /**
nxpandroid7d44e572016-08-01 19:11:04 +0530442 * UICC2 ID to be able to select it as the default Secure Element
443 */
444 public static final int UICC2_ID_TYPE = 4;
445 /**
nxpandroid64fd68c2015-09-23 16:45:15 +0530446 * ID to be able to select all Secure Elements
447 */
nxpandroid0232af22017-07-12 21:40:33 +0530448 private static int ALL_SE_ID_TYPE = 7;
nxpandroid64fd68c2015-09-23 16:45:15 +0530449
450 public static final int PN547C2_ID = 1;
451 public static final int PN65T_ID = 2;
nxpandroidebf53fb2016-12-22 18:48:59 +0530452 public static final int PN548C2_ID = 3;
nxpandroid64fd68c2015-09-23 16:45:15 +0530453 public static final int PN66T_ID = 4;
nxpandroid34627bd2016-05-27 15:52:30 +0530454 public static final int PN551_ID = 5;
455 public static final int PN67T_ID = 6;
nxpandroid281eb922016-08-25 20:27:46 +0530456 public static final int PN553_ID = 7;
457 public static final int PN80T_ID = 8;
nxpandroid64fd68c2015-09-23 16:45:15 +0530458
459 public static final int LS_RETRY_CNT = 3;
nxpandroid5d3fdf82017-07-31 16:11:33 +0530460 public static final int LOADER_SERVICE_VERSION_LOW_LIMIT = 0x21;
461 public static final int LOADER_SERVICE_VERSION_HIGH_LIMIT = 0x24;
462
nxpandroid64fd68c2015-09-23 16:45:15 +0530463 private int mSelectedSeId = 0;
464 private boolean mNfcSecureElementState;
465 private boolean mIsSmartCardServiceSupported = false;
466 // Timeout to re-apply routing if a tag was present and we postponed it
467 private static final int APPLY_ROUTING_RETRY_TIMEOUT_MS = 5000;
468
Nikhil Chhabrad6957c72018-03-09 11:44:48 +0530469 // these states are for making enable and disable nfc atomic
470 private int NXP_NFC_STATE_OFF = 0;
471 private int NXP_NFC_STATE_TURNING_ON = 1;
472 private int NXP_NFC_STATE_ON = 2;
473 private int NXP_NFC_STATE_TURNING_OFF = 3;
474
nxpandroid64fd68c2015-09-23 16:45:15 +0530475 private final UserManager mUserManager;
nxpandroide66eb092017-07-12 21:36:08 +0530476 private static int nci_version = NCI_VERSION_1_0;
nxpandroid64fd68c2015-09-23 16:45:15 +0530477 // NFC Execution Environment
478 // fields below are protected by this
479 private NativeNfcSecureElement mSecureElement;
480 private OpenSecureElement mOpenEe; // null when EE closed
481 private final ReaderModeDeathRecipient mReaderModeDeathRecipient =
482 new ReaderModeDeathRecipient();
483 private final NfcUnlockManager mNfcUnlockManager;
484
485 private int mEeRoutingState; // contactless interface routing
486 private int mLockscreenPollMask;
Suhas Sureshca6584b2018-04-27 17:17:22 +0530487 // cached version of installed packages requesting Android.permission.NFC_TRANSACTION_EVENTS
Suhas Suresh140f7ac2018-05-15 14:59:11 +0530488 List<String> mNfcEventInstalledPackages = new ArrayList<String>();
nxpandroid64fd68c2015-09-23 16:45:15 +0530489 private NativeNfcAla mNfcAla;
490
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530491 private final BackupManager mBackupManager;
492
nxpandroid64fd68c2015-09-23 16:45:15 +0530493 NfcAccessExtrasService mNfcAccessExtrasService;
494
495 // fields below are used in multiple threads and protected by synchronized(this)
496 final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>();
497 // mSePackages holds packages that accessed the SE, but only for the owner user,
498 // as SE access is not granted for non-owner users.
499 HashSet<String> mSePackages = new HashSet<String>();
500 int mScreenState;
nxf32288d12785b2017-11-17 15:18:31 +0530501 int mChipVer;
nxpandroid5d64ce92016-11-18 19:48:53 +0530502 boolean mIsTaskBoot = false;
nxpandroid64fd68c2015-09-23 16:45:15 +0530503 boolean mInProvisionMode; // whether we're in setup wizard and enabled NFC provisioning
504 boolean mIsNdefPushEnabled;
505 boolean mNfcPollingEnabled; // current Device Host state of NFC-C polling
506 boolean mHostRouteEnabled; // current Device Host state of host-based routing
507 boolean mReaderModeEnabled; // current Device Host state of reader mode
508 boolean mNfceeRouteEnabled; // current Device Host state of NFC-EE routing
509 NfcDiscoveryParameters mCurrentDiscoveryParameters =
510 NfcDiscoveryParameters.getNfcOffParameters();
511 ReaderModeParams mReaderModeParams;
nxpandroid281eb922016-08-25 20:27:46 +0530512 private int mUserId;
513 boolean mPollingPaused;
514
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +0530515 static final int INVALID_NATIVE_HANDLE = -1;
Nikhil Chhabraefd6b092018-04-11 15:28:06 +0530516 static final int SE_ACCESS_DENIED = -2;
nxpandroid623a3632017-04-10 18:27:16 +0530517 byte[] mDebounceTagUid;
nxpandroid281eb922016-08-25 20:27:46 +0530518 int mDebounceTagDebounceMs;
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +0530519 int mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE;
nxpandroid281eb922016-08-25 20:27:46 +0530520 ITagRemovedCallback mDebounceTagRemovedCallback;
nxpandroid64fd68c2015-09-23 16:45:15 +0530521
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530522 // Only accessed on one thread so doesn't need locking
523 NdefMessage mLastReadNdefMessage;
524
525 // Metrics
526 AtomicInteger mNumTagsDetected;
527 AtomicInteger mNumP2pDetected;
528 AtomicInteger mNumHceDetected;
529
nxpandroid64fd68c2015-09-23 16:45:15 +0530530 // mState is protected by this, however it is only modified in onCreate()
531 // and the default AsyncTask thread so it is read unprotected from that
532 // thread
533 int mState; // one of NfcAdapter.STATE_ON, STATE_TURNING_ON, etc
Nikhil Chhabrad6957c72018-03-09 11:44:48 +0530534 int mNxpNfcState = NXP_NFC_STATE_OFF;
535
nxpandroid64fd68c2015-09-23 16:45:15 +0530536 boolean mPowerShutDown = false; // State for power shut down state
537
538 // fields below are final after onCreate()
539 Context mContext;
540 private DeviceHost mDeviceHost;
541 private SharedPreferences mPrefs;
nxpandroida9a68ba2016-01-14 21:12:17 +0530542 private SharedPreferences mNxpPrefs;
nxpandroid64fd68c2015-09-23 16:45:15 +0530543 private SharedPreferences.Editor mPrefsEditor;
nxpandroida9a68ba2016-01-14 21:12:17 +0530544 private SharedPreferences.Editor mNxpPrefsEditor;
nxpandroid64fd68c2015-09-23 16:45:15 +0530545 private PowerManager.WakeLock mRoutingWakeLock;
546 private PowerManager.WakeLock mEeWakeLock;
547
548 int mStartSound;
549 int mEndSound;
550 int mErrorSound;
551 SoundPool mSoundPool; // playback synchronized on this
552 P2pLinkManager mP2pLinkManager;
553 TagService mNfcTagService;
554 NfcAdapterService mNfcAdapter;
555 NfcAdapterExtrasService mExtrasService;
556// CardEmulationService mCardEmulationService;
557 NxpNfcAdapterService mNxpNfcAdapter;
558 NxpNfcAdapterExtrasService mNxpExtrasService;
559 NxpExtrasService mNxpExtras;
560 EseClientServicesAdapter mEseClientServicesAdapter;
nxpandroid64fd68c2015-09-23 16:45:15 +0530561 boolean mIsDebugBuild;
562 boolean mIsHceCapable;
nxpandroid34627bd2016-05-27 15:52:30 +0530563 boolean mIsHceFCapable;
Pratap Reddy8f473f02018-04-23 15:18:30 +0530564 public boolean mIsRoutingTableDirty;
nxpandroid64fd68c2015-09-23 16:45:15 +0530565 boolean mIsFelicaOnHostConfigured;
566 boolean mIsFelicaOnHostConfiguring;
567
568 public boolean mIsRouteForced;
nxpandroid64fd68c2015-09-23 16:45:15 +0530569 NfcSccAccessControl mNfcSccAccessControl;
570 NfcSeAccessControl mNfcSeAccessControl;
571 NfcAlaService mAlaService;
572 NfcJcopService mJcopService;
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +0530573 NfcDtaService mNfcDtaService;
nxpandroid64fd68c2015-09-23 16:45:15 +0530574 NfcVzwService mVzwService;
575 private NfcDispatcher mNfcDispatcher;
576 private PowerManager mPowerManager;
577 private KeyguardManager mKeyguard;
578 ToastHandler mToastHandler;
579 private HandoverDataParser mHandoverDataParser;
580 private ContentResolver mContentResolver;
nxpandroidebf53fb2016-12-22 18:48:59 +0530581 private RegisteredAidCache mAidCache;
nxpandroid64fd68c2015-09-23 16:45:15 +0530582 private CardEmulationManager mCardEmulationManager;
Suhas Suresh6e05ee02018-04-25 12:19:35 +0530583 private Vibrator mVibrator;
584 private VibrationEffect mVibrationEffect;
nxpandroid64fd68c2015-09-23 16:45:15 +0530585 private AidRoutingManager mAidRoutingManager;
Suhas Sureshca6584b2018-04-27 17:17:22 +0530586 private ISecureElementService mSEService;
nxpandroid64fd68c2015-09-23 16:45:15 +0530587 private ScreenStateHelper mScreenStateHelper;
588 private ForegroundUtils mForegroundUtils;
589 private boolean mClearNextTapDefault;
590 private NxpNfcController mNxpNfcController;
591
nxpandroid64fd68c2015-09-23 16:45:15 +0530592 private static NfcService sService;
nxpandroid281eb922016-08-25 20:27:46 +0530593 public static boolean sIsDtaMode = false;
594 public static boolean sIsShortRecordLayout = false;
595 public static boolean sAidTableFull = false;
nxpandroid5d64ce92016-11-18 19:48:53 +0530596 private WatchDogThread disableInternalwatchDog;
nxpandroid64fd68c2015-09-23 16:45:15 +0530597
598 //GSMA
599 private final Boolean defaultTransactionEventReceptionMode = Boolean.FALSE;
nxpandroid623a3632017-04-10 18:27:16 +0530600 private static final Boolean multiReceptionMode = Boolean.TRUE;
601 private static final Boolean unicastReceptionMode = Boolean.FALSE;
nxpandroid64fd68c2015-09-23 16:45:15 +0530602 boolean mIsSentUnicastReception = false;
603
Nikhil Chhabraefd6b092018-04-11 15:28:06 +0530604 NfcWiredSe mNfcSeService;
Nikhil Chhabraf9453292018-04-18 11:18:35 +0530605 ISecureElementHalCallback mSecureElementclientCallback = null;
Nikhil Chhabraefd6b092018-04-11 15:28:06 +0530606
nxpandroid64fd68c2015-09-23 16:45:15 +0530607 public void enforceNfcSeAdminPerm(String pkg) {
608 if (pkg == null) {
609 throw new SecurityException("caller must pass a package name");
610 }
611 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
612 if (!mNfcSeAccessControl.check(Binder.getCallingUid(), pkg)) {
613 throw new SecurityException(NfcSeAccessControl.NFCSE_ACCESS_PATH +
614 " denies NFCSe access to " + pkg);
615 }
616 if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
617 throw new SecurityException("only the owner is allowed to act as SCC admin");
618 }
619 }
620 public void enforceNfceeAdminPerm(String pkg) {
621 if (pkg == null) {
622 throw new SecurityException("caller must pass a package name");
623 }
624 NfcPermissions.enforceUserPermissions(mContext);
nxpandroid64fd68c2015-09-23 16:45:15 +0530625 if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
626 throw new SecurityException("only the owner is allowed to call SE APIs");
627 }
628 }
629
630
631 /* SCC Access Control */
632 public void enforceNfcSccAdminPerm(String pkg) {
633 if (pkg == null) {
634 throw new SecurityException("caller must pass a package name");
635 }
636 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
637 if (!mNfcSccAccessControl.check(Binder.getCallingUid(), pkg)) {
638 throw new SecurityException(NfcSccAccessControl.NFCSCC_ACCESS_PATH +
639 " denies NFCSCC access to " + pkg);
640 }
641 if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
642 throw new SecurityException("only the owner is allowed to act as SCC admin");
643 }
644 }
645
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530646 boolean mIsLiveCaseEnabled; // whether live cases are enabled
647 int mLiveCaseTechnology; // Technology mask of accepted NFC tags
648
Nikhil Chhabrafc8f3f62018-01-08 20:48:49 +0530649 private IVrManager vrManager;
650 boolean mIsVrModeEnabled;
651
nxpandroid64fd68c2015-09-23 16:45:15 +0530652 public static NfcService getInstance() {
653 return sService;
654 }
655
656 @Override
657 public void onRemoteEndpointDiscovered(TagEndpoint tag) {
658 sendMessage(NfcService.MSG_NDEF_TAG, tag);
659 }
660
661 public int getRemainingAidTableSize() {
662 return mDeviceHost.getRemainingAidTableSize();
663 }
664
nxpandroidebf53fb2016-12-22 18:48:59 +0530665 public boolean getLastCommitRoutingStatus() {
666 return mAidRoutingManager.getLastCommitRoutingStatus();
667 }
668
nxpandroid64fd68c2015-09-23 16:45:15 +0530669 public int getChipVer() {
670 return mDeviceHost.getChipVer();
671 }
672 /**
673 * Notifies Card emulation deselect
674 */
675 @Override
676 public void onCardEmulationDeselected() {
677 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
678 sendMessage(NfcService.MSG_TARGET_DESELECTED, null);
679 }
680 }
681
682 /**
nxpandroid64fd68c2015-09-23 16:45:15 +0530683 * Notifies connectivity
684 */
685 @Override
686 public void onConnectivityEvent(int evtSrc) {
687 Log.d(TAG, "onConnectivityEvent : Source" + evtSrc);
688 sendMessage(NfcService.MSG_CONNECTIVITY_EVENT, evtSrc);
689 }
690
691 @Override
692 public void onEmvcoMultiCardDetectedEvent() {
693 Log.d(TAG, "onEmvcoMultiCardDetectedEvent");
694 sendMessage(NfcService.MSG_EMVCO_MULTI_CARD_DETECTED_EVENT,null);
695 }
696
697 /**
698 * Notifies transaction
699 */
700 @Override
nxpandroid34627bd2016-05-27 15:52:30 +0530701 public void onHostCardEmulationActivated(int technology) {
nxpandroid64fd68c2015-09-23 16:45:15 +0530702 if (mCardEmulationManager != null) {
nxpandroid34627bd2016-05-27 15:52:30 +0530703 mCardEmulationManager.onHostCardEmulationActivated(technology);
nxpandroid64fd68c2015-09-23 16:45:15 +0530704 }
705 }
706
707 @Override
708 public void onAidRoutingTableFull() {
709 Log.d(TAG, "NxpNci: onAidRoutingTableFull: AID Routing Table is FULL!");
nxpandroid281eb922016-08-25 20:27:46 +0530710 /*if((ROUTE_ID_HOST != GetDefaultRouteLoc())&&(sAidTableFull == false))
nxpandroid64fd68c2015-09-23 16:45:15 +0530711 {
712 Log.d(TAG, "NxpNci: onAidRoutingTableFull: Making Default Route to HOST!");
nxpandroid281eb922016-08-25 20:27:46 +0530713 sAidTableFull = true;
nxpandroid64fd68c2015-09-23 16:45:15 +0530714 mHandler.sendEmptyMessage(NfcService.MSG_CHANGE_DEFAULT_ROUTE);
715 }*/
716 if (mIsHceCapable) {
717 mAidRoutingManager.onNfccRoutingTableCleared();
718 mCardEmulationManager.onRoutingTableChanged();
719 }
720 }
721
722 @Override
nxpandroid5d64ce92016-11-18 19:48:53 +0530723 public void onNotifyT3tConfigure() {
724 if (mCardEmulationManager != null) {
725 mCardEmulationManager.onT3tConfigure();
726 }
727 }
728
729 @Override
730 public void onNotifyReRoutingEntry() {
731 if (mCardEmulationManager != null) {
732 mCardEmulationManager.onReRoutingEntry();
733 }
734 }
735
736 @Override
nxpandroid34627bd2016-05-27 15:52:30 +0530737 public void onHostCardEmulationData(int technology, byte[] data) {
nxpandroid64fd68c2015-09-23 16:45:15 +0530738 if (mCardEmulationManager != null) {
nxpandroid34627bd2016-05-27 15:52:30 +0530739 mCardEmulationManager.onHostCardEmulationData(technology, data);
nxpandroid64fd68c2015-09-23 16:45:15 +0530740 }
741 }
742
743 @Override
nxpandroid34627bd2016-05-27 15:52:30 +0530744 public void onHostCardEmulationDeactivated(int technology) {
nxpandroid64fd68c2015-09-23 16:45:15 +0530745 if (mCardEmulationManager != null) {
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530746 // Do metrics here so we don't slow the CE path down
747 mNumHceDetected.incrementAndGet();
nxpandroid34627bd2016-05-27 15:52:30 +0530748 mCardEmulationManager.onHostCardEmulationDeactivated(technology);
nxpandroid64fd68c2015-09-23 16:45:15 +0530749 }
750 }
751
752 /**
753 * Notifies P2P Device detected, to activate LLCP link
754 */
755 @Override
756 public void onLlcpLinkActivated(NfcDepEndpoint device) {
757 sendMessage(NfcService.MSG_LLCP_LINK_ACTIVATION, device);
758 }
759
760 /**
761 * Notifies P2P Device detected, to activate LLCP link
762 */
763 @Override
764 public void onLlcpLinkDeactivated(NfcDepEndpoint device) {
765 sendMessage(NfcService.MSG_LLCP_LINK_DEACTIVATED, device);
766 }
767
768 /**
769 * Notifies P2P Device detected, first packet received over LLCP link
770 */
771 @Override
772 public void onLlcpFirstPacketReceived(NfcDepEndpoint device) {
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530773 mNumP2pDetected.incrementAndGet();
nxpandroid64fd68c2015-09-23 16:45:15 +0530774 sendMessage(NfcService.MSG_LLCP_LINK_FIRST_PACKET, device);
775 }
776
777 @Override
778 public void onRemoteFieldActivated() {
779 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
780 sendMessage(NfcService.MSG_SE_FIELD_ACTIVATED, null);
781 }
782 }
783
784 @Override
785 public void onRemoteFieldDeactivated() {
786 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
787 sendMessage(NfcService.MSG_SE_FIELD_DEACTIVATED, null);
788 }
789 }
790
791 @Override
792 public void onSeListenActivated() {
793 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
794 sendMessage(NfcService.MSG_SE_LISTEN_ACTIVATED, null);
795 }
796 if (mIsHceCapable) {
nxpandroid34627bd2016-05-27 15:52:30 +0530797 mCardEmulationManager.onHostCardEmulationActivated(TagTechnology.NFC_A);
nxpandroid64fd68c2015-09-23 16:45:15 +0530798 }
799 }
800
801 @Override
802 public void onSeListenDeactivated() {
803 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
804 sendMessage(NfcService.MSG_SE_LISTEN_DEACTIVATED, null);
805 }
806 if( mIsHceCapable) {
nxpandroid34627bd2016-05-27 15:52:30 +0530807 mCardEmulationManager.onHostCardEmulationDeactivated(TagTechnology.NFC_A);
nxpandroid64fd68c2015-09-23 16:45:15 +0530808 }
809 }
810
nxpandroid64fd68c2015-09-23 16:45:15 +0530811 @Override
812 public void onSeApduReceived(byte[] apdu) {
813 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
814 sendMessage(NfcService.MSG_SE_APDU_RECEIVED, apdu);
815 }
816 }
817
818 @Override
819 public void onSeEmvCardRemoval() {
820 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
821 sendMessage(NfcService.MSG_SE_EMV_CARD_REMOVAL, null);
822 }
823 }
824
825 @Override
826 public void onSeMifareAccess(byte[] block) {
827 if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) {
828 sendMessage(NfcService.MSG_SE_MIFARE_ACCESS, block);
829 }
830 }
831
832 @Override
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530833 public void onETSIReaderRequestedEvent(boolean istechA, boolean istechB)
nxpandroid64fd68c2015-09-23 16:45:15 +0530834 {
835 int size=0;
836 ArrayList<Integer> techList = new ArrayList<Integer>();
837 if(istechA)
838 techList.add(TagTechnology.NFC_A);
839 if(istechB)
840 techList.add(TagTechnology.NFC_B);
841
842 sendMessage(NfcService.MSG_SWP_READER_REQUESTED , techList);
843 }
844
845 @Override
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530846 public void onETSIReaderRequestedFail(int FailCause)
nxpandroid64fd68c2015-09-23 16:45:15 +0530847 {
848 sendMessage(NfcService.MSG_SWP_READER_REQUESTED_FAIL , FailCause);
849 }
850
851 @Override
nxpandroid64fd68c2015-09-23 16:45:15 +0530852 public void onETSIReaderModeStartConfig(int eeHandle)
853 {
Pratap Reddy49abbe32018-03-27 16:51:59 +0530854 // Check if NFC is enabled
855 if (!isNfcEnabled()) {
856 return;
857 }
nxpandroid64fd68c2015-09-23 16:45:15 +0530858 ArrayList<Integer> configList = new ArrayList<Integer>();
859 configList.add(eeHandle);
860 sendMessage(NfcService.MSG_ETSI_START_CONFIG, configList);
861 }
862
863 @Override
864 public void onETSIReaderModeStopConfig(int disc_ntf_timeout)
865 {
Pratap Reddy49abbe32018-03-27 16:51:59 +0530866 // Check if NFC is enabled
867 if (!isNfcEnabled()) {
868 return;
869 }
870 EtsiStopConfigTask task = new EtsiStopConfigTask();
871 task.execute(disc_ntf_timeout);
872
nxpandroid64fd68c2015-09-23 16:45:15 +0530873 }
874
875 @Override
876 public void onETSIReaderModeSwpTimeout(int disc_ntf_timeout)
877 {
878 sendMessage(NfcService.MSG_ETSI_SWP_TIMEOUT, disc_ntf_timeout);
879 }
880
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530881 @Override
882 public void onETSIReaderModeRestart() {
883 sendMessage(NfcService.MSG_SWP_READER_RESTART, null);
884 }
885
886 @Override
nxpandroid34627bd2016-05-27 15:52:30 +0530887 public void onUiccStatusEvent(int uiccStat)
888 {
889 Log.i(TAG, "Broadcasting UICC Status : " + uiccStat);
890 Intent uiccStatusIntent = new Intent();
891 uiccStatusIntent.setAction(ACTION_UICC_STATUS_RECEIVED);
892 uiccStatusIntent.putExtra(EXTRA_UICC_STATUS, uiccStat);
893 mContext.sendBroadcast(uiccStatusIntent);
894 }
895
nxpandroid5d64ce92016-11-18 19:48:53 +0530896 @Override
897 public void onRestartWatchDog(int enable) {
898 Log.d(TAG, "Restart Watchdog: WatchDog Thread ID is "+ disableInternalwatchDog.getId());
899 sendMessage(NfcService.MSG_RESTART_WATCHDOG, enable);
900 }
nxpandroid1680a6d2017-01-13 19:13:14 +0530901 @Override
902 public void onFwDwnldReqRestartNfc() {
903 Log.d(TAG, "Restart NFC:When Fw dwnld request was stored during SPI onGoing");
904 new EnableDisableTask().execute(TASK_RESTART);
905 }
nxpandroid5d64ce92016-11-18 19:48:53 +0530906
Suhas Sureshca6584b2018-04-27 17:17:22 +0530907 @Override
908 public void onNfcTransactionEvent(byte[] aid, byte[] data, String seName) {
909 byte[][] dataObj = {aid, data, seName.getBytes()};
910 sendMessage(NfcService.MSG_TRANSACTION_EVENT, dataObj);
911 }
912
nxpandroid64fd68c2015-09-23 16:45:15 +0530913 final class ReaderModeParams {
914 public int flags;
915 public IAppCallback callback;
916 public int presenceCheckDelay;
917 }
918
919 public NfcService(Application nfcApplication) {
920 mUserId = ActivityManager.getCurrentUser();
921 mContext = nfcApplication;
922
923 mNfcTagService = new TagService();
924 mNfcAdapter = new NfcAdapterService();
925 mNxpNfcAdapter = new NxpNfcAdapterService();
926 mExtrasService = new NfcAdapterExtrasService();
927 mNxpExtrasService = new NxpNfcAdapterExtrasService();
928 // mCardEmulationService = new CardEmulationService();
929
930 Log.i(TAG, "Starting NFC service");
931
932 sService = this;
933
934 mScreenStateHelper = new ScreenStateHelper(mContext);
935 mContentResolver = mContext.getContentResolver();
936 mDeviceHost = new NativeNfcManager(mContext, this);
937
938 mNfcUnlockManager = NfcUnlockManager.getInstance();
939
940 mHandoverDataParser = new HandoverDataParser();
941 boolean isNfcProvisioningEnabled = false;
942 try {
943 isNfcProvisioningEnabled = mContext.getResources().getBoolean(
944 R.bool.enable_nfc_provisioning);
945 } catch (NotFoundException e) {
946 }
947
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530948 try {
949 mIsLiveCaseEnabled = mContext.getResources().getBoolean(R.bool.enable_live_cases);
950 } catch (NotFoundException e) {
951 mIsLiveCaseEnabled = false;
952 }
953
954 mLiveCaseTechnology = 0;
955 String[] liveCaseTechList;
956 try {
957 liveCaseTechList = mContext.getResources().getStringArray(R.array.live_case_tag_types);
958 for (int i=0; i < liveCaseTechList.length; i++) {
959 if (liveCaseTechList[i].equals("TypeA")) {
960 mLiveCaseTechnology |= NFC_POLL_A;
961 } else if (liveCaseTechList[i].equals("TypeB")) {
962 mLiveCaseTechnology |= NFC_POLL_B;
963 } else if (liveCaseTechList[i].equals("TypeF")) {
964 mLiveCaseTechnology |= NFC_POLL_F;
965 } else if (liveCaseTechList[i].equals("TypeV")) {
Nikhil Chhabra288edb02018-01-10 19:36:21 +0530966 mLiveCaseTechnology |= NFC_POLL_V;
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530967 }
968 }
969 } catch (NotFoundException e) {
970 mLiveCaseTechnology = 0;
971 }
972
nxpandroid64fd68c2015-09-23 16:45:15 +0530973 if (isNfcProvisioningEnabled) {
974 mInProvisionMode = Settings.Secure.getInt(mContentResolver,
975 Settings.Global.DEVICE_PROVISIONED, 0) == 0;
976 } else {
977 mInProvisionMode = false;
978 }
979
nxpandroid1153eb32015-11-06 18:46:58 +0530980 if(mInProvisionMode)
981 {
982 /* if device is in provision mode, set this mode at lower layers */
983 mDeviceHost.doSetProvisionMode(mInProvisionMode);
984 }
985
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530986 mNfcDispatcher = new NfcDispatcher(mContext, mHandoverDataParser, mInProvisionMode,
987 mIsLiveCaseEnabled);
nxpandroid64fd68c2015-09-23 16:45:15 +0530988 mP2pLinkManager = new P2pLinkManager(mContext, mHandoverDataParser,
989 mDeviceHost.getDefaultLlcpMiu(), mDeviceHost.getDefaultLlcpRwSize());
990
991 mSecureElement = new NativeNfcSecureElement(mContext);
992 mEeRoutingState = ROUTE_OFF;
993 mToastHandler = new ToastHandler(mContext);
994
nxpandroid64fd68c2015-09-23 16:45:15 +0530995 mNfcSccAccessControl = new NfcSccAccessControl(mContext);
996 mNfcSeAccessControl = new NfcSeAccessControl(mContext);
997 mNfcAla = new NativeNfcAla();
998
999 mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE);
1000 mPrefsEditor = mPrefs.edit();
nxpandroida9a68ba2016-01-14 21:12:17 +05301001 mNxpPrefs = mContext.getSharedPreferences(NXP_PREF, Context.MODE_PRIVATE);
1002 mNxpPrefsEditor = mNxpPrefs.edit();
nxpandroid64fd68c2015-09-23 16:45:15 +05301003
1004 mState = NfcAdapter.STATE_OFF;
1005 mIsNdefPushEnabled = mPrefs.getBoolean(PREF_NDEF_PUSH_ON, NDEF_PUSH_ON_DEFAULT);
Suhas Suresha18dee02018-04-27 15:28:04 +05301006 enforceBeamShareActivityPolicy(mContext, new UserHandle(mUserId));
nxpandroid64fd68c2015-09-23 16:45:15 +05301007
1008 mIsDebugBuild = "userdebug".equals(Build.TYPE) || "eng".equals(Build.TYPE);
1009
1010 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
1011
1012 mRoutingWakeLock = mPowerManager.newWakeLock(
1013 PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mRoutingWakeLock");
1014 mEeWakeLock = mPowerManager.newWakeLock(
1015 PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mEeWakeLock");
1016
1017 mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
1018 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Suhas Suresh6e05ee02018-04-25 12:19:35 +05301019 mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
1020 mVibrationEffect = VibrationEffect.createOneShot(200, VibrationEffect.DEFAULT_AMPLITUDE);
nxpandroid64fd68c2015-09-23 16:45:15 +05301021
1022 mScreenState = mScreenStateHelper.checkScreenState();
1023
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301024 mNumTagsDetected = new AtomicInteger();
1025 mNumP2pDetected = new AtomicInteger();
1026 mNumHceDetected = new AtomicInteger();
1027
1028 mBackupManager = new BackupManager(mContext);
1029
nxpandroid64fd68c2015-09-23 16:45:15 +05301030 // Intents for all users
1031 IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
1032 filter.addAction(Intent.ACTION_SCREEN_OFF);
1033 filter.addAction(Intent.ACTION_SCREEN_ON);
1034 filter.addAction(Intent.ACTION_USER_PRESENT);
1035 filter.addAction(Intent.ACTION_USER_SWITCHED);
nxpandroid64fd68c2015-09-23 16:45:15 +05301036 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null);
1037
nxpandroid5d64ce92016-11-18 19:48:53 +05301038 filter = new IntentFilter(Intent.ACTION_SHUTDOWN);
1039 mContext.registerReceiver(mOwnerReceiver, filter);
1040
nxpandroid64fd68c2015-09-23 16:45:15 +05301041 IntentFilter ownerFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1042 ownerFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
Suhas Sureshc9772c82018-04-27 15:41:19 +05301043 ownerFilter.addAction(Intent.ACTION_SHUTDOWN);
nxpandroid64fd68c2015-09-23 16:45:15 +05301044 mContext.registerReceiver(mOwnerReceiver, ownerFilter);
1045
1046 ownerFilter = new IntentFilter();
1047 ownerFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
1048 ownerFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
1049 ownerFilter.addDataScheme("package");
1050 mContext.registerReceiver(mOwnerReceiver, ownerFilter);
1051
1052 IntentFilter x509CertificateFilter = new IntentFilter();
1053 x509CertificateFilter.addAction(NxpConstants.ACTION_CHECK_X509_RESULT);
nxpandroid5d64ce92016-11-18 19:48:53 +05301054 mContext.registerReceiverAsUser(x509CertificateReceiver, UserHandle.ALL,
1055 x509CertificateFilter, NfcPermissions.ADMIN_PERM, null);
nxpandroid64fd68c2015-09-23 16:45:15 +05301056
Shashank vimal83779082018-02-06 18:10:31 +05301057 IntentFilter activateStkFilter = new IntentFilter();
1058 activateStkFilter.addAction(NxpConstants.CAT_ACTIVATE_NOTIFY_ACTION);
1059 mContext.registerReceiver(mActivateSwpInterface, activateStkFilter);
1060
nxpandroid64fd68c2015-09-23 16:45:15 +05301061 IntentFilter enableNfc = new IntentFilter();
1062 enableNfc.addAction(NxpConstants.ACTION_GSMA_ENABLE_NFC);
nxpandroid5d64ce92016-11-18 19:48:53 +05301063 mContext.registerReceiverAsUser(mEnableNfc, UserHandle.ALL, enableNfc, null, null);
nxpandroid64fd68c2015-09-23 16:45:15 +05301064
1065 IntentFilter lsFilter = new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
1066 //mContext.registerReceiver(mAlaReceiver, lsFilter);
1067 mContext.registerReceiverAsUser(mAlaReceiver, UserHandle.ALL, lsFilter, null, null);
1068
1069 IntentFilter policyFilter = new IntentFilter(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1070 mContext.registerReceiverAsUser(mPolicyReceiver, UserHandle.ALL, policyFilter, null, null);
1071
1072 updatePackageCache();
1073
1074 PackageManager pm = mContext.getPackageManager();
nxpandroid34627bd2016-05-27 15:52:30 +05301075 mIsHceCapable =
1076 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION) ||
1077 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF);
1078 mIsHceFCapable =
1079 pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF);
1080
nxpandroid64fd68c2015-09-23 16:45:15 +05301081 if (mIsHceCapable) {
1082 mAidRoutingManager = new AidRoutingManager();
nxpandroid1680a6d2017-01-13 19:13:14 +05301083 mCardEmulationManager = new CardEmulationManager(mContext, mAidRoutingManager);
1084 mAidCache = mCardEmulationManager.getRegisteredAidCache();
nxpandroid64fd68c2015-09-23 16:45:15 +05301085 //mCardEmulationManager = new CardEmulationManager(mContext);
1086 Log.d("NfcService", "Before mIsHceCapable");
1087 mNxpNfcController = new NxpNfcController(mContext, mCardEmulationManager);
1088 }
1089
1090 mForegroundUtils = ForegroundUtils.getInstance();
nxpandroid281eb922016-08-25 20:27:46 +05301091
1092 // Make sure this is only called when object construction is complete.
1093 ServiceManager.addService(SERVICE_NAME, mNfcAdapter);
1094
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05301095 ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
1096 if (activityManager.isLowRamDevice()) {
1097 Log.d(TAG,"Low RAM device");
1098 mNfcSeService = new NfcWiredSe();
1099 try {
1100 mNfcSeService.registerAsService("wiredse");
1101 } catch (Exception e) {
1102 Log.e(TAG, "WiredSe: Registration of service failed");
1103 }
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05301104 }
1105
nxpandroid64fd68c2015-09-23 16:45:15 +05301106 new EnableDisableTask().execute(TASK_BOOT); // do blocking boot tasks
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301107
1108 mHandler.sendEmptyMessageDelayed(MSG_UPDATE_STATS, STATS_UPDATE_INTERVAL_MS);
Nikhil Chhabrafc8f3f62018-01-08 20:48:49 +05301109
1110 IVrManager mVrManager = IVrManager.Stub.asInterface(ServiceManager.getService(
1111 mContext.VR_SERVICE));
1112 if (mVrManager != null) {
1113 try {
1114 mVrManager.registerListener(mVrStateCallbacks);
1115 mIsVrModeEnabled = mVrManager.getVrModeState();
1116 } catch (RemoteException e) {
1117 Log.e(TAG, "Failed to register VR mode state listener: " + e);
1118 }
1119 }
Suhas Sureshca6584b2018-04-27 17:17:22 +05301120 mSEService = ISecureElementService.Stub.asInterface(ServiceManager.getService(
1121 Context.SECURE_ELEMENT_SERVICE));
nxpandroid5c5b2152017-09-14 12:30:17 +05301122 /*SoundPool clean up before NFC state updated*/
1123 initSoundPool();
nxpandroid64fd68c2015-09-23 16:45:15 +05301124 }
1125
1126 void initSoundPool() {
1127 synchronized(this) {
1128 if (mSoundPool == null) {
1129 mSoundPool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0);
1130 mStartSound = mSoundPool.load(mContext, R.raw.start, 1);
1131 mEndSound = mSoundPool.load(mContext, R.raw.end, 1);
1132 mErrorSound = mSoundPool.load(mContext, R.raw.error, 1);
1133 }
1134 }
1135 }
1136
1137 void releaseSoundPool() {
1138 synchronized (this) {
1139 if (mSoundPool != null) {
1140 mSoundPool.release();
1141 mSoundPool = null;
1142 }
1143 }
1144 }
1145
nxpandroid64fd68c2015-09-23 16:45:15 +05301146 void updatePackageCache() {
1147 PackageManager pm = mContext.getPackageManager();
Suhas Sureshca6584b2018-04-27 17:17:22 +05301148 List<PackageInfo> packagesNfcEvents = pm.getPackagesHoldingPermissions(
1149 new String[] {android.Manifest.permission.NFC_TRANSACTION_EVENT},
1150 PackageManager.GET_ACTIVITIES);
nxpandroid64fd68c2015-09-23 16:45:15 +05301151 synchronized (this) {
Suhas Suresh140f7ac2018-05-15 14:59:11 +05301152 mNfcEventInstalledPackages.clear();
1153 for (int i = 0; i < packagesNfcEvents.size(); i++) {
1154 mNfcEventInstalledPackages.add(packagesNfcEvents.get(i).packageName);
1155 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301156 }
1157 }
1158
nxpandroid7d44e572016-08-01 19:11:04 +05301159 int doOpenSecureElementConnection(int seId) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301160 mEeWakeLock.acquire();
1161 try {
nxpandroid7d44e572016-08-01 19:11:04 +05301162 return mSecureElement.doOpenSecureElementConnection(seId);
nxpandroid64fd68c2015-09-23 16:45:15 +05301163 } finally {
1164 mEeWakeLock.release();
1165 }
1166 }
1167
1168 byte[] doTransceive(int handle, byte[] cmd) {
1169 mEeWakeLock.acquire();
1170 try {
1171 return doTransceiveNoLock(handle, cmd);
1172 } finally {
1173 mEeWakeLock.release();
1174 }
1175 }
1176
1177 byte[] doTransceiveNoLock(int handle, byte[] cmd) {
1178 return mSecureElement.doTransceive(handle, cmd);
1179 }
1180
1181 void doDisconnect(int handle) {
1182 mEeWakeLock.acquire();
1183 try {
1184 mSecureElement.doDisconnect(handle);
1185 } finally {
1186 mEeWakeLock.release();
1187 }
1188 }
1189
1190 boolean doReset(int handle) {
1191 mEeWakeLock.acquire();
1192 try {
1193 return mSecureElement.doReset(handle);
1194 } finally {
1195 mEeWakeLock.release();
1196 }
1197 }
1198
1199 public static byte[] CreateSHA(String pkg, int alaVer){
nxpandroid281eb922016-08-25 20:27:46 +05301200 String localTAG = "Utils:CreateSHA";
nxpandroid64fd68c2015-09-23 16:45:15 +05301201 StringBuffer sb = new StringBuffer();
1202 try {
1203 MessageDigest md;
1204 if(alaVer == 1)
1205 md = MessageDigest.getInstance("SHA-256");
1206 else
1207 md = MessageDigest.getInstance("SHA-1");
1208
1209 md.update(pkg.getBytes());
1210
nxpandroid281eb922016-08-25 20:27:46 +05301211 byte[] byteData = md.digest();
1212 Log.i(localTAG, "byteData len : " + byteData.length);
nxpandroid64fd68c2015-09-23 16:45:15 +05301213 /*
1214 for (int i = 0; i < byteData.length; i++) {
1215 sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
1216 }
1217 // Log.i(TAG, "sb.toString()" + sb.toString());*/
1218 return byteData;
1219 } catch (Exception e) {
1220 e.printStackTrace();
1221 }
1222 return null;
1223 }
1224
1225 public static String getCallingAppPkg(Context context) {
nxpandroid281eb922016-08-25 20:27:46 +05301226 String localTAG = "getCallingAppPkg";
nxpandroid64fd68c2015-09-23 16:45:15 +05301227 ActivityManager am = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
1228
1229 // get the info from the currently running task
1230 List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1);
1231
1232 Log.d("topActivity", "CURRENT Activity ::"
1233 + taskInfo.get(0).topActivity.getClassName());
1234 String s = taskInfo.get(0).topActivity.getClassName();
1235
1236 ComponentName componentInfo = taskInfo.get(0).topActivity;
1237 componentInfo.getPackageName();
nxpandroid281eb922016-08-25 20:27:46 +05301238 Log.i(localTAG,"componentInfo.getPackageName()" + componentInfo.getPackageName());
nxpandroid64fd68c2015-09-23 16:45:15 +05301239 return componentInfo.getPackageName();
1240 }
1241
1242 /**
1243 * Manages tasks that involve turning on/off the NFC controller.
1244 * <p/>
1245 * <p>All work that might turn the NFC adapter on or off must be done
1246 * through this task, to keep the handling of mState simple.
1247 * In other words, mState is only modified in these tasks (and we
1248 * don't need a lock to read it in these tasks).
1249 * <p/>
1250 * <p>These tasks are all done on the same AsyncTask background
1251 * thread, so they are serialized. Each task may temporarily transition
1252 * mState to STATE_TURNING_OFF or STATE_TURNING_ON, but must exit in
1253 * either STATE_ON or STATE_OFF. This way each task can be guaranteed
1254 * of starting in either STATE_OFF or STATE_ON, without needing to hold
1255 * NfcService.this for the entire task.
1256 * <p/>
1257 * <p>AsyncTask's are also implicitly queued. This is useful for corner
1258 * cases like turning airplane mode on while TASK_ENABLE is in progress.
1259 * The TASK_DISABLE triggered by airplane mode will be correctly executed
1260 * immediately after TASK_ENABLE is complete. This seems like the most sane
1261 * way to deal with these situations.
1262 * <p/>
1263 * <p>{@link #TASK_ENABLE} enables the NFC adapter, without changing
1264 * preferences
1265 * <p>{@link #TASK_DISABLE} disables the NFC adapter, without changing
1266 * preferences
1267 * <p>{@link #TASK_BOOT} does first boot work and may enable NFC
1268 */
1269 class EnableDisableTask extends AsyncTask<Integer, Void, Void> {
1270 @Override
1271 protected Void doInBackground(Integer... params) {
1272 // Sanity check mState
1273 switch (mState) {
1274 case NfcAdapter.STATE_TURNING_OFF:
1275 case NfcAdapter.STATE_TURNING_ON:
1276 Log.e(TAG, "Processing EnableDisable task " + params[0] + " from bad state " +
1277 mState);
1278 return null;
1279 }
1280
1281 /* AsyncTask sets this thread to THREAD_PRIORITY_BACKGROUND,
1282 * override with the default. THREAD_PRIORITY_BACKGROUND causes
1283 * us to service software I2C too slow for firmware download
1284 * with the NXP PN544.
1285 * TODO: move this to the DAL I2C layer in libnfc-nxp, since this
1286 * problem only occurs on I2C platforms using PN544
1287 */
1288 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1289
1290 switch (params[0].intValue()) {
1291 case TASK_ENABLE:
1292 enableInternal();
1293 break;
1294 case TASK_DISABLE:
1295 disableInternal();
1296 break;
1297 case TASK_BOOT:
Suhas Suresh1fe09dc2018-05-07 11:55:06 +05301298 if (mPrefs.getBoolean(PREF_FIRST_BOOT, true)) {
1299 Log.i(TAG, "First Boot");
1300 mPrefsEditor.putBoolean(PREF_FIRST_BOOT, false);
1301 mPrefsEditor.apply();
1302 mDeviceHost.factoryReset();
1303 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301304 Log.d(TAG, "checking on firmware download");
nxpandroid7d44e572016-08-01 19:11:04 +05301305 if (mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT)) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301306 Log.d(TAG, "NFC is on. Doing normal stuff");
nxpandroid5d64ce92016-11-18 19:48:53 +05301307 mIsTaskBoot = true;
nxpandroid64fd68c2015-09-23 16:45:15 +05301308 enableInternal();
nxpandroid5d64ce92016-11-18 19:48:53 +05301309 mIsTaskBoot = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05301310 } else {
1311 Log.d(TAG, "NFC is off. Checking firmware version");
1312 mDeviceHost.checkFirmware();
1313 }
Nikhil Chhabraa9e399a2018-01-09 11:47:13 +05301314 SystemProperties.set("nfc.initialized", "true");
nxpandroid64fd68c2015-09-23 16:45:15 +05301315 break;
nxpandroid1680a6d2017-01-13 19:13:14 +05301316 case TASK_RESTART:
1317 restartInternal();
1318
nxpandroid64fd68c2015-09-23 16:45:15 +05301319 }
1320
1321 // Restore default AsyncTask priority
1322 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1323 return null;
1324 }
1325
1326 @Override
1327 protected void onPostExecute(Void result) {
1328
1329 if(mState == NfcAdapter.STATE_ON){
1330 IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
1331 filter.addAction(Intent.ACTION_SCREEN_OFF);
1332 filter.addAction(Intent.ACTION_SCREEN_ON);
1333 filter.addAction(Intent.ACTION_USER_PRESENT);
1334 filter.addAction(Intent.ACTION_USER_SWITCHED);
nxpandroid64fd68c2015-09-23 16:45:15 +05301335 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null);
1336 }else if (mState == NfcAdapter.STATE_OFF){
1337 mContext.unregisterReceiver(mReceiver);
1338 IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
1339 filter.addAction(Intent.ACTION_USER_SWITCHED);
nxpandroid64fd68c2015-09-23 16:45:15 +05301340 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null);
1341 }
1342
1343
1344 }
1345
1346 /**
1347 * Check the default Secure Element configuration.
1348 */
1349 void checkSecureElementConfuration() {
1350
1351 /* Get SE List */
nxpandroid281eb922016-08-25 20:27:46 +05301352 int[] seList = mDeviceHost.doGetSecureElementList();
nxpandroidebf53fb2016-12-22 18:48:59 +05301353 int uiccSlot = 0;
1354 uiccSlot = mPrefs.getInt(PREF_CUR_SELECTED_UICC_ID, SECURE_ELEMENT_UICC_SLOT_DEFAULT);
1355 int status = mDeviceHost.setPreferredSimSlot(uiccSlot);
nxpandroid64fd68c2015-09-23 16:45:15 +05301356 /* Check Secure Element setting */
nxpandroid281eb922016-08-25 20:27:46 +05301357 int seNum=mDeviceHost.GetDefaultSE();
1358 if(seNum != 0)
nxpandroid64fd68c2015-09-23 16:45:15 +05301359 {
1360 SECURE_ELEMENT_ON_DEFAULT=true;
nxpandroid281eb922016-08-25 20:27:46 +05301361 SECURE_ELEMENT_ID_DEFAULT=seNum;
nxpandroid64fd68c2015-09-23 16:45:15 +05301362 } else {
nxpandroid281eb922016-08-25 20:27:46 +05301363 if (seList != null) {
1364 for (int i = 0; i < seList.length; i++) {
1365 mDeviceHost.doDeselectSecureElement(seList[i]);
nxpandroid64fd68c2015-09-23 16:45:15 +05301366 }
1367 }
1368 }
1369
1370 mNfcSecureElementState =
nxpandroida9a68ba2016-01-14 21:12:17 +05301371 mNxpPrefs.getBoolean(PREF_SECURE_ELEMENT_ON, SECURE_ELEMENT_ON_DEFAULT);
nxpandroid64fd68c2015-09-23 16:45:15 +05301372
1373 if (mNfcSecureElementState) {
1374 int secureElementId =
nxpandroida9a68ba2016-01-14 21:12:17 +05301375 mNxpPrefs.getInt(PREF_SECURE_ELEMENT_ID, SECURE_ELEMENT_ID_DEFAULT);
nxpandroid64fd68c2015-09-23 16:45:15 +05301376
nxpandroid281eb922016-08-25 20:27:46 +05301377 if (seList != null) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301378 if (secureElementId != ALL_SE_ID_TYPE/* SECURE_ELEMENT_ALL */) {
1379 mDeviceHost.doDeselectSecureElement(UICC_ID_TYPE);
nxpandroid7d44e572016-08-01 19:11:04 +05301380 mDeviceHost.doDeselectSecureElement(UICC2_ID_TYPE);
nxpandroid64fd68c2015-09-23 16:45:15 +05301381 mDeviceHost.doDeselectSecureElement(SMART_MX_ID_TYPE);
1382
nxpandroid281eb922016-08-25 20:27:46 +05301383 for (int i = 0; i < seList.length; i++) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301384
nxpandroid281eb922016-08-25 20:27:46 +05301385 if (seList[i] == secureElementId) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301386 if (secureElementId == SMART_MX_ID_TYPE) { // SECURE_ELEMENT_SMX_ID
nxpandroid281eb922016-08-25 20:27:46 +05301387 if (seList.length > 1) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301388 if (DBG) {
1389 Log.d(TAG, "Deselect UICC");
1390 }
1391 }
1392 Log.d(TAG, "Select SMX");
1393 mDeviceHost.doSelectSecureElement(secureElementId);
1394 mSelectedSeId = secureElementId;
1395 break;
1396 } else if (secureElementId == UICC_ID_TYPE/* SECURE_ELEMENT_UICC_ID */) {
nxpandroid281eb922016-08-25 20:27:46 +05301397 if (seList.length > 1) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301398 if (DBG) {
1399 Log.d(TAG, "Deselect SMX");
1400 }
1401 }
1402 Log.d(TAG, "Select UICC");
1403 mDeviceHost.doSelectSecureElement(secureElementId);
1404 mSelectedSeId = secureElementId;
1405 break;
nxpandroid7d44e572016-08-01 19:11:04 +05301406 }else if (secureElementId == UICC2_ID_TYPE/* SECURE_ELEMENT_UICC_ID */) {
nxpandroid281eb922016-08-25 20:27:46 +05301407 if (seList.length > 1) {
nxpandroid7d44e572016-08-01 19:11:04 +05301408 if (DBG) {
1409 Log.d(TAG, "Deselect SMX");
1410 }
1411 }
1412 Log.d(TAG, "Select UICC2");
1413 mDeviceHost.doSelectSecureElement(secureElementId);
1414 mSelectedSeId = secureElementId;
1415 break;
nxpandroid64fd68c2015-09-23 16:45:15 +05301416 } else if (secureElementId == SECURE_ELEMENT_ID_DEFAULT) {
nxpandroid281eb922016-08-25 20:27:46 +05301417 if (seList.length > 1) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301418 if (DBG) {
1419 Log.d(TAG, "UICC deselected by default");
1420 }
1421 }
1422 }
1423 }
1424 }
1425 } else {
1426 if (DBG) {
1427 Log.d(TAG, "Select ALL_SE");
1428 }
1429
nxpandroid281eb922016-08-25 20:27:46 +05301430 if (seList.length > 1) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301431
nxpandroid281eb922016-08-25 20:27:46 +05301432 for (int i = 0; i < seList.length; i++) {
1433 mDeviceHost.doSelectSecureElement(seList[i]);
nxpandroid64fd68c2015-09-23 16:45:15 +05301434 try{
1435 //Delay b/w two SE selection.
1436 Thread.sleep(200);
1437 } catch(Exception e) {
1438 e.printStackTrace();
1439 }
1440 }
1441 mSelectedSeId = secureElementId;
1442 }
1443 }
1444 }
1445 } else {
nxpandroid281eb922016-08-25 20:27:46 +05301446 if (seList != null && seList.length > 0) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301447 if (DBG) {
1448 Log.d(TAG, "UICC/eSE deselected by default");
1449 }
1450 mDeviceHost.doDeselectSecureElement(UICC_ID_TYPE);
nxpandroid7d44e572016-08-01 19:11:04 +05301451 mDeviceHost.doDeselectSecureElement(UICC2_ID_TYPE);
nxpandroid64fd68c2015-09-23 16:45:15 +05301452 mDeviceHost.doDeselectSecureElement(SMART_MX_ID_TYPE);
1453 }
1454 }
1455 }
1456
1457 boolean getJcopOsFileInfo() {
1458 File jcopOsFile;
1459 Log.i(TAG, "getJcopOsFileInfo");
1460
1461 for (int num = 0; num < 3; num++) {
1462 try{
1463 jcopOsFile = new File(path[num]);
1464 }catch(NullPointerException npe) {
1465 Log.e(TAG,"path to jcop os file was null");
1466 return false;
1467 }
1468 long modtime = jcopOsFile.lastModified();
1469 SharedPreferences prefs = mContext.getSharedPreferences(PREF,Context.MODE_PRIVATE);
1470 long prev_modtime = prefs.getLong(PREF_JCOP_MODTIME[num], JCOP_MODTIME_DEFAULT[num]);
1471 Log.d(TAG,"prev_modtime:" + prev_modtime);
1472 Log.d(TAG,"new_modtime:" + modtime);
1473 if(prev_modtime == modtime){
1474 return false;
1475 }
1476 JCOP_MODTIME_TEMP[num] = modtime;
1477 }
1478 return true;
1479 }
1480
1481 /* jcop os Download at boot time */
1482 void jcopOsDownload() {
1483 int status = ErrorCodes.SUCCESS;
1484 boolean jcopStatus;
1485 Log.i(TAG, "Jcop Download starts");
1486
1487 SharedPreferences prefs = mContext.getSharedPreferences(PREF,Context.MODE_PRIVATE);
1488 jcopStatus = getJcopOsFileInfo();
1489
1490 if( jcopStatus == true) {
1491 Log.i(TAG, "Starting getChipName");
1492 int Ver = mDeviceHost.getChipVer();
nxpandroid281eb922016-08-25 20:27:46 +05301493 if(Ver == PN80T_ID || Ver == PN67T_ID || Ver == PN66T_ID || Ver == PN65T_ID) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301494 status = mDeviceHost.JCOSDownload();
1495 }
1496 if(status != ErrorCodes.SUCCESS) {
1497 Log.i(TAG, "Jcop Download failed");
1498 }
1499 else {
1500 Log.i(TAG, "Jcop Download success");
1501 prefs.edit().putLong(PREF_JCOP_MODTIME[0],JCOP_MODTIME_TEMP[0]).apply();
1502 prefs.edit().putLong(PREF_JCOP_MODTIME[1],JCOP_MODTIME_TEMP[1]).apply();
1503 prefs.edit().putLong(PREF_JCOP_MODTIME[2],JCOP_MODTIME_TEMP[2]).apply();
1504 }
1505 }
1506 }
1507 /**
1508 * Enable NFC adapter functions.
1509 * Does not toggle preferences.
1510 */
1511 boolean enableInternal() {
1512 if (mState == NfcAdapter.STATE_ON) {
1513 return true;
1514 }
1515 Log.i(TAG, "Enabling NFC");
1516 updateState(NfcAdapter.STATE_TURNING_ON);
1517 int timeout = mDeviceHost.getNfcInitTimeout();
1518 if (timeout < INIT_WATCHDOG_MS)
1519 {
1520 timeout = INIT_WATCHDOG_MS;
1521 }
1522 Log.i(TAG, "Enabling NFC timeout" +timeout);
1523 WatchDogThread watchDog = new WatchDogThread("enableInternal", timeout);
1524 watchDog.start();
1525 try {
1526 mRoutingWakeLock.acquire();
1527 try {
1528 if (!mDeviceHost.initialize()) {
1529 Log.w(TAG, "Error enabling NFC");
1530 updateState(NfcAdapter.STATE_OFF);
1531 return false;
1532 }
1533 } finally {
1534 mRoutingWakeLock.release();
1535 }
1536 } finally {
1537 watchDog.cancel();
1538 }
nxf32288d12785b2017-11-17 15:18:31 +05301539 mChipVer = mDeviceHost.getChipVer();
1540 if(mChipVer < PN553_ID) {
nxf322881754ee02017-10-24 13:33:24 +05301541 ALL_SE_ID_TYPE &= ~UICC2_ID_TYPE;
nxpandroid5d64ce92016-11-18 19:48:53 +05301542 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301543 checkSecureElementConfuration();
1544
1545 mIsRouteForced = true;
1546 if (mIsHceCapable) {
1547 // Generate the initial card emulation routing table
nxpandroid281eb922016-08-25 20:27:46 +05301548 sAidTableFull = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05301549 mCardEmulationManager.onNfcEnabled();
1550 }
1551 mIsRouteForced = false;
nxpandroide66eb092017-07-12 21:36:08 +05301552 nci_version = getNciVersion();
nxpandroid64fd68c2015-09-23 16:45:15 +05301553
1554 synchronized (NfcService.this) {
1555 mObjectMap.clear();
1556 mP2pLinkManager.enableDisable(mIsNdefPushEnabled, true);
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301557 if(mChipVer == PN80T_ID || mChipVer == PN67T_ID || mChipVer == PN66T_ID || mChipVer == PN65T_ID) {
1558 /*Added for Loader service recover during NFC Off/On*/
1559 NfcAlaService nas = new NfcAlaService();
1560 nas.LSReexecute();
1561 IntentFilter lsFilter = new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
1562 mContext.registerReceiverAsUser(mAlaReceiver, UserHandle.ALL, lsFilter, null, null);
1563 } else {
1564 // do nothing
1565 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301566 }
1567
1568 synchronized (NfcService.this) {
1569 if(mDeviceHost.doCheckJcopDlAtBoot()) {
1570 /* start jcop download */
1571 Log.i(TAG, "Calling Jcop Download");
1572 jcopOsDownload();
1573 }
1574 }
1575
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301576 synchronized (NfcService.this) {
1577 updateState(NfcAdapter.STATE_ON);
1578 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301579 /* Start polling loop */
1580 Log.e(TAG, "applyRouting -3");
1581 mScreenState = mScreenStateHelper.checkScreenState();
nxpandroide66eb092017-07-12 21:36:08 +05301582 int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ?
1583 (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState;
1584
1585 if(mNfcUnlockManager.isLockscreenPollingEnabled())
1586 applyRouting(false);
1587
1588 mDeviceHost.doSetScreenOrPowerState(screen_state_mask);
nxpandroid64fd68c2015-09-23 16:45:15 +05301589 mIsRoutingTableDirty = true;
nxpandroid5d64ce92016-11-18 19:48:53 +05301590 if((mScreenState < NFC_POLLING_MODE) && mIsTaskBoot)
1591 {
1592 /*During device boot if screen state is other ON_UNLOCKED,
1593 *first send discovery command with poll and linsten enabled
1594 *for DC/DC pass through mode activation.
1595 *Then send normal discovery according to screen state*/
1596 applyRouting(true);
1597 mIsTaskBoot = false;
1598 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301599 applyRouting(true);
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301600 synchronized (NfcService.this) {
1601 mNxpNfcState = NXP_NFC_STATE_ON;
1602 }
1603
nxpandroid64fd68c2015-09-23 16:45:15 +05301604 return true;
1605 }
1606
1607 /**
1608 * Disable all NFC adapter functions.
1609 * Does not toggle preferences.
1610 */
1611 boolean disableInternal() {
1612 if (mState == NfcAdapter.STATE_OFF) {
1613 return true;
1614 }
1615 Log.i(TAG, "Disabling NFC");
1616 updateState(NfcAdapter.STATE_TURNING_OFF);
nxpandroid5c5b2152017-09-14 12:30:17 +05301617 /*SoundPool clean up before NFC state updated
1618 releaseSoundPool();*/
nxpandroid64fd68c2015-09-23 16:45:15 +05301619
1620 /* Sometimes mDeviceHost.deinitialize() hangs, use a watch-dog.
1621 * Implemented with a new thread (instead of a Handler or AsyncTask),
1622 * because the UI Thread and AsyncTask thread-pools can also get hung
1623 * when the NFC controller stops responding */
nxpandroid5d64ce92016-11-18 19:48:53 +05301624 disableInternalwatchDog = new WatchDogThread("disableInternal", ROUTING_WATCHDOG_MS);
1625 disableInternalwatchDog.start();
nxpandroid64fd68c2015-09-23 16:45:15 +05301626
1627 if (mIsHceCapable) {
1628 mCardEmulationManager.onNfcDisabled();
1629 }
1630
1631 mP2pLinkManager.enableDisable(false, false);
1632
1633 /* The NFC-EE may still be opened by another process,
1634 * and a transceive() could still be in progress on
1635 * another Binder thread.
1636 * Give it a while to finish existing operations
1637 * before we close it.
1638 */
1639 Long startTime = SystemClock.elapsedRealtime();
1640 do {
1641 synchronized (NfcService.this) {
1642 if (mOpenEe == null)
1643 break;
1644 }
1645 try {
1646 Thread.sleep(WAIT_FOR_NFCEE_POLL_MS);
1647 } catch (InterruptedException e) {
1648 // Ignore
1649 }
1650 } while (SystemClock.elapsedRealtime() - startTime < WAIT_FOR_NFCEE_OPERATIONS_MS);
1651
1652 synchronized (NfcService.this) {
1653 if (mOpenEe != null) {
1654 try {
1655 _nfcEeClose(-1, mOpenEe.binder);
1656 } catch (IOException e) { }
1657 }
1658 }
1659
1660 // Stop watchdog if tag present
1661 // A convenient way to stop the watchdog properly consists of
1662 // disconnecting the tag. The polling loop shall be stopped before
1663 // to avoid the tag being discovered again.
1664 maybeDisconnectTarget();
1665
1666 mNfcDispatcher.setForegroundDispatch(null, null, null);
1667
1668 boolean result = mDeviceHost.deinitialize();
1669 if (DBG) Log.d(TAG, "mDeviceHost.deinitialize() = " + result);
1670
nxpandroid5d64ce92016-11-18 19:48:53 +05301671 disableInternalwatchDog.cancel();
nxpandroid64fd68c2015-09-23 16:45:15 +05301672
1673 synchronized (NfcService.this) {
1674 mCurrentDiscoveryParameters = NfcDiscoveryParameters.getNfcOffParameters();
1675 updateState(NfcAdapter.STATE_OFF);
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301676 mNxpNfcState = NXP_NFC_STATE_OFF;
nxpandroid64fd68c2015-09-23 16:45:15 +05301677 }
1678
nxpandroid64fd68c2015-09-23 16:45:15 +05301679
1680 return result;
1681 }
1682
nxpandroid1680a6d2017-01-13 19:13:14 +05301683 boolean restartInternal()
1684 {
1685 boolean result;
1686 result = disableInternal();
1687 if (DBG) Log.d(TAG, "disableInternal status = " + result);
1688 while(true)
1689 {
1690 if(mState == NfcAdapter.STATE_OFF)
1691 {
1692 if (DBG) Log.d(TAG, "disableInternal is success = " + result);
1693 break;
1694 }
1695 }
1696 result = enableInternal();
1697 if (DBG) Log.d(TAG, "enableInternal status = " + result);
1698 while(true)
1699 {
1700 if(mState == NfcAdapter.STATE_ON)
1701 {
1702 if (DBG) Log.d(TAG, "enableInternal is success = " + result);
1703 break;
1704 }
1705 }
1706 Intent flashIntent = new Intent();
1707 flashIntent.setAction(ACTION_FLASH_SUCCESS);
1708 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_FLASH_SUCCESS);
1709 mContext.sendBroadcast(flashIntent);
1710 return result;
1711 }
1712
nxpandroid64fd68c2015-09-23 16:45:15 +05301713 void updateState(int newState) {
1714 synchronized (NfcService.this) {
1715 if (newState == mState) {
1716 return;
1717 }
Nikhil Chhabraf9453292018-04-18 11:18:35 +05301718 if (newState == NfcAdapter.STATE_TURNING_OFF) {
Suhas Suresh9139dc22018-05-09 15:48:37 +05301719 if(mNfcSeService != null)
1720 mNfcSeService.closeNfcWiredSeService();
Nikhil Chhabraf9453292018-04-18 11:18:35 +05301721 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301722 mState = newState;
1723 Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
1724 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1725 intent.putExtra(NfcAdapter.EXTRA_ADAPTER_STATE, mState);
1726 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
1727 }
1728 }
1729 }
1730
1731 void saveNfcOnSetting(boolean on) {
1732 synchronized (NfcService.this) {
1733 mPrefsEditor.putBoolean(PREF_NFC_ON, on);
1734 mPrefsEditor.apply();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301735 mBackupManager.dataChanged();
nxpandroid64fd68c2015-09-23 16:45:15 +05301736 }
1737 }
1738
1739 public void playSound(int sound) {
1740 synchronized (this) {
1741 if (mSoundPool == null) {
1742 Log.w(TAG, "Not playing sound when NFC is disabled");
1743 return;
1744 }
Nikhil Chhabrafc8f3f62018-01-08 20:48:49 +05301745
1746 if (mIsVrModeEnabled) {
1747 Log.d(TAG, "Not playing NFC sound when Vr Mode is enabled");
1748 return;
1749 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301750 switch (sound) {
1751 case SOUND_START:
1752 mSoundPool.play(mStartSound, 1.0f, 1.0f, 0, 0, 1.0f);
1753 break;
1754 case SOUND_END:
1755 mSoundPool.play(mEndSound, 1.0f, 1.0f, 0, 0, 1.0f);
1756 break;
1757 case SOUND_ERROR:
1758 mSoundPool.play(mErrorSound, 1.0f, 1.0f, 0, 0, 1.0f);
1759 break;
1760 }
1761 }
1762 }
1763
1764 synchronized int getUserId() {
1765 return mUserId;
1766 }
1767
Suhas Suresha18dee02018-04-27 15:28:04 +05301768 void enforceBeamShareActivityPolicy(Context context, UserHandle uh) {
nxpandroid64fd68c2015-09-23 16:45:15 +05301769 UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
1770 IPackageManager mIpm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
Suhas Suresha18dee02018-04-27 15:28:04 +05301771 boolean isGlobalEnabled = mIsNdefPushEnabled;
1772 if (uh.getIdentifier() != mUserId) {
1773 try {
1774 int userSetting = mIpm.getComponentEnabledSetting(new ComponentName(
1775 BeamShareActivity.class.getPackageName$(),
1776 BeamShareActivity.class.getName()), uh.getIdentifier());
1777 isGlobalEnabled = (userSetting == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) ? false : true;
1778 } catch (RemoteException e) {
1779 Log.w(TAG, "Unable to get Beam status for user " + uh);
1780 }
1781 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301782 boolean isActiveForUser =
1783 (!um.hasUserRestriction(UserManager.DISALLOW_OUTGOING_BEAM, uh)) &&
1784 isGlobalEnabled;
Suhas Sureshe2a2ff02018-04-27 12:21:19 +05301785 if (DBG) {
Suhas Suresha18dee02018-04-27 15:28:04 +05301786 Log.d(TAG, "Enforcing a policy change on user: " + uh.toString() +
nxpandroid64fd68c2015-09-23 16:45:15 +05301787 ", isActiveForUser = " + isActiveForUser);
1788 }
1789 try {
1790 mIpm.setComponentEnabledSetting(new ComponentName(
1791 BeamShareActivity.class.getPackageName$(),
1792 BeamShareActivity.class.getName()),
1793 isActiveForUser ?
1794 PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
1795 PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
1796 PackageManager.DONT_KILL_APP,
Suhas Suresha18dee02018-04-27 15:28:04 +05301797 uh.getIdentifier());
nxpandroid64fd68c2015-09-23 16:45:15 +05301798 } catch (RemoteException e) {
1799 Log.w(TAG, "Unable to change Beam status for user " + uh);
1800 }
1801 }
1802
1803 final class NfcAdapterService extends INfcAdapter.Stub {
1804 @Override
1805 public boolean enable() throws RemoteException {
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301806
1807 if (mNxpNfcState != NXP_NFC_STATE_OFF) {
1808 return true;
1809 } else {
1810 // do nothing
1811 }
1812
1813 synchronized (NfcService.this) {
1814 mNxpNfcState = NXP_NFC_STATE_TURNING_ON;
1815 }
1816
nxpandroid64fd68c2015-09-23 16:45:15 +05301817 NfcPermissions.enforceAdminPermissions(mContext);
1818 int val = mDeviceHost.GetDefaultSE();
1819 Log.i(TAG, "getDefaultSE " + val);
1820
1821 saveNfcOnSetting(true);
1822
nxpandroid64fd68c2015-09-23 16:45:15 +05301823 new EnableDisableTask().execute(TASK_ENABLE);
1824
1825 return true;
1826 }
1827
nxpandroid64fd68c2015-09-23 16:45:15 +05301828 @Override
1829 public boolean disable(boolean saveState) throws RemoteException {
Nikhil Chhabrad6957c72018-03-09 11:44:48 +05301830
1831 if (mNxpNfcState != NXP_NFC_STATE_ON) {
1832 return true;
1833 } else {
1834 // do nothing
1835 }
1836
1837 synchronized (NfcService.this) {
1838 mNxpNfcState = NXP_NFC_STATE_TURNING_OFF;
1839 }
1840
nxpandroid64fd68c2015-09-23 16:45:15 +05301841 NfcPermissions.enforceAdminPermissions(mContext);
1842 Log.d(TAG,"Disabling Nfc.");
1843
1844 //Check if this a device shutdown or Nfc only Nfc disable.
1845 if(!mPowerShutDown)
1846 {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301847 int[] seList = mDeviceHost.doGetSecureElementList();
nxpandroid64fd68c2015-09-23 16:45:15 +05301848 Log.i(TAG, "Disabling NFC Disabling ESE/UICC");
nxpandroid64fd68c2015-09-23 16:45:15 +05301849 //Since only Nfc is getting disabled so disable CE from EE.
nxpandroida9a68ba2016-01-14 21:12:17 +05301850 mDeviceHost.doSetScreenOrPowerState(ScreenStateHelper.POWER_STATE_ON);
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301851 if (seList != null) {
1852 for (int i = 0; i < seList.length; i++) {
1853 mDeviceHost.doDeselectSecureElement(seList[i]);
1854 }
1855 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301856 } else {
1857 Log.i(TAG, "Power off : Disabling NFC Disabling ESE/UICC");
1858 mPowerShutDown = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05301859 mCardEmulationManager.onPreferredForegroundServiceChanged(null);
1860 }
1861
1862 if (saveState) {
1863 saveNfcOnSetting(false);
1864 }
1865
1866 new EnableDisableTask().execute(TASK_DISABLE);
1867
1868 return true;
1869 }
1870
1871 @Override
1872 public void pausePolling(int timeoutInMs) {
1873 NfcPermissions.enforceAdminPermissions(mContext);
1874
1875 if (timeoutInMs <= 0 || timeoutInMs > MAX_POLLING_PAUSE_TIMEOUT) {
1876 Log.e(TAG, "Refusing to pause polling for " + timeoutInMs + "ms.");
1877 return;
1878 }
1879
1880 synchronized (NfcService.this) {
1881 mPollingPaused = true;
1882 mDeviceHost.disableDiscovery();
1883 mHandler.sendMessageDelayed(
1884 mHandler.obtainMessage(MSG_RESUME_POLLING), timeoutInMs);
1885 }
1886 }
1887
1888 @Override
1889 public void resumePolling() {
1890 NfcPermissions.enforceAdminPermissions(mContext);
1891
1892 synchronized (NfcService.this) {
1893 if (!mPollingPaused) {
1894 return;
1895 }
1896
1897 mHandler.removeMessages(MSG_RESUME_POLLING);
1898 mPollingPaused = false;
1899 new ApplyRoutingTask().execute();
1900 }
1901 }
1902
1903 @Override
1904 public boolean isNdefPushEnabled() throws RemoteException {
1905 synchronized (NfcService.this) {
1906 return mState == NfcAdapter.STATE_ON && mIsNdefPushEnabled;
1907 }
1908 }
1909
1910 @Override
1911 public boolean enableNdefPush() throws RemoteException {
1912 NfcPermissions.enforceAdminPermissions(mContext);
1913 synchronized (NfcService.this) {
1914 if (mIsNdefPushEnabled) {
1915 return true;
1916 }
1917 Log.i(TAG, "enabling NDEF Push");
1918 mPrefsEditor.putBoolean(PREF_NDEF_PUSH_ON, true);
1919 mPrefsEditor.apply();
1920 mIsNdefPushEnabled = true;
Suhas Suresha18dee02018-04-27 15:28:04 +05301921 enforceBeamShareActivityPolicy(mContext, new UserHandle(mUserId));
nxpandroid64fd68c2015-09-23 16:45:15 +05301922 if (isNfcEnabled()) {
nxpandroid5d64ce92016-11-18 19:48:53 +05301923 mDeviceHost.doEnablep2p(mIsNdefPushEnabled);
nxpandroid64fd68c2015-09-23 16:45:15 +05301924 mP2pLinkManager.enableDisable(true, true);
1925 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301926 mBackupManager.dataChanged();
nxpandroid64fd68c2015-09-23 16:45:15 +05301927 }
1928 return true;
1929 }
1930
1931 @Override
1932 public boolean disableNdefPush() throws RemoteException {
1933 NfcPermissions.enforceAdminPermissions(mContext);
1934 synchronized (NfcService.this) {
1935 if (!mIsNdefPushEnabled) {
1936 return true;
1937 }
1938 Log.i(TAG, "disabling NDEF Push");
1939 mPrefsEditor.putBoolean(PREF_NDEF_PUSH_ON, false);
1940 mPrefsEditor.apply();
1941 mIsNdefPushEnabled = false;
Suhas Suresha18dee02018-04-27 15:28:04 +05301942 enforceBeamShareActivityPolicy(mContext, new UserHandle(mUserId));
nxpandroid64fd68c2015-09-23 16:45:15 +05301943 if (isNfcEnabled()) {
1944 mP2pLinkManager.enableDisable(false, true);
1945 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05301946 mBackupManager.dataChanged();
nxpandroid64fd68c2015-09-23 16:45:15 +05301947 }
1948 return true;
1949 }
1950
1951 @Override
1952 public void setForegroundDispatch(PendingIntent intent,
1953 IntentFilter[] filters, TechListParcel techListsParcel) {
1954 NfcPermissions.enforceUserPermissions(mContext);
nxpandroid281eb922016-08-25 20:27:46 +05301955 if (!mForegroundUtils.isInForeground(Binder.getCallingUid())) {
1956 Log.e(TAG, "setForegroundDispatch: Caller not in foreground.");
1957 return;
1958 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301959 // Short-cut the disable path
1960 if (intent == null && filters == null && techListsParcel == null) {
1961 mNfcDispatcher.setForegroundDispatch(null, null, null);
1962 return;
1963 }
1964
1965 // Validate the IntentFilters
1966 if (filters != null) {
1967 if (filters.length == 0) {
1968 filters = null;
1969 } else {
1970 for (IntentFilter filter : filters) {
1971 if (filter == null) {
1972 throw new IllegalArgumentException("null IntentFilter");
1973 }
1974 }
1975 }
1976 }
1977
1978 // Validate the tech lists
1979 String[][] techLists = null;
1980 if (techListsParcel != null) {
1981 techLists = techListsParcel.getTechLists();
1982 }
1983
1984 mNfcDispatcher.setForegroundDispatch(intent, filters, techLists);
1985 }
1986
1987 @Override
1988 public void setAppCallback(IAppCallback callback) {
1989 NfcPermissions.enforceUserPermissions(mContext);
1990
1991 // don't allow Beam for managed profiles, or devices with a device owner or policy owner
1992 UserInfo userInfo = mUserManager.getUserInfo(UserHandle.getCallingUserId());
1993 if(!mUserManager.hasUserRestriction(
1994 UserManager.DISALLOW_OUTGOING_BEAM, userInfo.getUserHandle())) {
1995 mP2pLinkManager.setNdefCallback(callback, Binder.getCallingUid());
1996 } else if (DBG) {
1997 Log.d(TAG, "Disabling default Beam behavior");
1998 }
1999 }
2000
2001 @Override
2002 public INfcAdapterExtras getNfcAdapterExtrasInterface(String pkg) {
nxpandroida51b5bd2017-04-10 18:28:21 +05302003
2004 if (pkg.equals(PACKAGE_SMART_CARD_SERVICE)){
2005 Log.d(TAG, "wildcard for SmartcardService");
2006 return mExtrasService;
2007 }
2008
nxpandroid64fd68c2015-09-23 16:45:15 +05302009 NfcService.this.enforceNfceeAdminPerm(pkg);
2010 return mExtrasService;
2011 }
2012
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05302013 @Override
2014 public INfcDta getNfcDtaInterface(String pkg) throws RemoteException {
2015 NfcPermissions.enforceAdminPermissions(mContext);
2016 if (mNfcDtaService == null) {
2017 mNfcDtaService = new NfcDtaService();
2018 }
2019 return mNfcDtaService;
2020 }
2021
nxpandroid281eb922016-08-25 20:27:46 +05302022 @Override
2023 public boolean ignore(int nativeHandle, int debounceMs, ITagRemovedCallback callback)
2024 throws RemoteException {
2025 NfcPermissions.enforceUserPermissions(mContext);
2026
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +05302027 if (debounceMs == 0 && mDebounceTagNativeHandle != INVALID_NATIVE_HANDLE
2028 && nativeHandle == mDebounceTagNativeHandle) {
2029 // Remove any previous messages and immediately debounce.
2030 mHandler.removeMessages(MSG_TAG_DEBOUNCE);
2031 mHandler.sendEmptyMessage(MSG_TAG_DEBOUNCE);
2032 return true;
2033 }
2034
nxpandroid281eb922016-08-25 20:27:46 +05302035 TagEndpoint tag = (TagEndpoint) findAndRemoveObject(nativeHandle);
2036 if (tag != null) {
2037 // Store UID and params
2038 int uidLength = tag.getUid().length;
2039 synchronized (NfcService.this) {
2040 mDebounceTagDebounceMs = debounceMs;
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +05302041 mDebounceTagNativeHandle = nativeHandle;
nxpandroid281eb922016-08-25 20:27:46 +05302042 mDebounceTagUid = new byte[uidLength];
2043 mDebounceTagRemovedCallback = callback;
2044 System.arraycopy(tag.getUid(), 0, mDebounceTagUid, 0, uidLength);
2045 }
2046
2047 // Disconnect from this tag; this should resume the normal
2048 // polling loop (and enter listen mode for a while), before
2049 // we pick up any tags again.
2050 tag.disconnect();
2051 mHandler.sendEmptyMessageDelayed(MSG_TAG_DEBOUNCE, debounceMs);
2052 return true;
2053 } else {
2054 return false;
2055 }
2056 }
2057
nxpandroid64fd68c2015-09-23 16:45:15 +05302058 @Override
2059 public void verifyNfcPermission() {
2060 NfcPermissions.enforceUserPermissions(mContext);
2061 }
2062
2063 @Override
2064 public void invokeBeam() {
2065 NfcPermissions.enforceUserPermissions(mContext);
2066
2067 if (mForegroundUtils.isInForeground(Binder.getCallingUid())) {
2068 mP2pLinkManager.onManualBeamInvoke(null);
2069 } else {
2070 Log.e(TAG, "Calling activity not in foreground.");
2071 }
2072 }
2073
2074 @Override
2075 public void invokeBeamInternal(BeamShareData shareData) {
2076 NfcPermissions.enforceAdminPermissions(mContext);
2077 Message msg = Message.obtain();
2078 msg.what = MSG_INVOKE_BEAM;
2079 msg.obj = shareData;
2080 // We have to send this message delayed for two reasons:
2081 // 1) This is an IPC call from BeamShareActivity, which is
2082 // running when the user has invoked Beam through the
2083 // share menu. As soon as BeamShareActivity closes, the UI
2084 // will need some time to rebuild the original Activity.
2085 // Waiting here for a while gives a better chance of the UI
2086 // having been rebuilt, which means the screenshot that the
2087 // Beam animation is using will be more accurate.
2088 // 2) Similarly, because the Activity that launched BeamShareActivity
2089 // with an ACTION_SEND intent is now in paused state, the NDEF
2090 // callbacks that it has registered may no longer be valid.
2091 // Allowing the original Activity to resume will make sure we
2092 // it has a chance to re-register the NDEF message / callback,
2093 // so we share the right data.
2094 //
2095 // Note that this is somewhat of a hack because the delay may not actually
2096 // be long enough for 2) on very slow devices, but there's no better
2097 // way to do this right now without additional framework changes.
2098 mHandler.sendMessageDelayed(msg, INVOKE_BEAM_DELAY_MS);
2099 }
2100
2101 @Override
2102 public INfcTag getNfcTagInterface() throws RemoteException {
2103 return mNfcTagService;
2104 }
2105
2106 @Override
2107 public INfcCardEmulation getNfcCardEmulationInterface() {
2108 if (mIsHceCapable) {
2109 return mCardEmulationManager.getNfcCardEmulationInterface();
2110 } else {
2111 return null;
2112 }
2113 }
2114
nxpandroid34627bd2016-05-27 15:52:30 +05302115 @Override
2116 public INfcFCardEmulation getNfcFCardEmulationInterface() {
2117 if (mIsHceFCapable) {
2118 return mCardEmulationManager.getNfcFCardEmulationInterface();
2119 } else {
2120 return null;
2121 }
2122 }
2123
nxpandroid64fd68c2015-09-23 16:45:15 +05302124
2125 @Override
2126 public int getState() throws RemoteException {
2127 synchronized (NfcService.this) {
2128 return mState;
2129 }
2130 }
2131
2132 @Override
2133 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2134 NfcService.this.dump(fd, pw, args);
2135 }
2136
2137 @Override
2138 public void dispatch(Tag tag) throws RemoteException {
2139 NfcPermissions.enforceAdminPermissions(mContext);
2140 mNfcDispatcher.dispatchTag(tag);
2141 }
2142
2143 @Override
2144 public void setP2pModes(int initiatorModes, int targetModes) throws RemoteException {
2145 NfcPermissions.enforceAdminPermissions(mContext);
2146 mDeviceHost.setP2pInitiatorModes(initiatorModes);
2147 mDeviceHost.setP2pTargetModes(targetModes);
2148 applyRouting(true);
2149 }
2150
2151 @Override
2152 public void setReaderMode(IBinder binder, IAppCallback callback, int flags, Bundle extras)
2153 throws RemoteException {
nxpandroid281eb922016-08-25 20:27:46 +05302154 int callingUid = Binder.getCallingUid();
2155 if (callingUid != Process.SYSTEM_UID && !mForegroundUtils.isInForeground(callingUid)) {
2156 Log.e(TAG, "setReaderMode: Caller is not in foreground and is not system process.");
2157 return;
2158 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302159 synchronized (NfcService.this) {
nxpandroid34627bd2016-05-27 15:52:30 +05302160 if (!isNfcEnabled()) {
2161 Log.e(TAG, "setReaderMode() called while NFC is not enabled.");
2162 return;
2163 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302164 if (flags != 0) {
2165 try {
2166 mReaderModeParams = new ReaderModeParams();
2167 mReaderModeParams.callback = callback;
2168 mReaderModeParams.flags = flags;
2169 mReaderModeParams.presenceCheckDelay = extras != null
2170 ? (extras.getInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY,
2171 DEFAULT_PRESENCE_CHECK_DELAY))
2172 : DEFAULT_PRESENCE_CHECK_DELAY;
2173 binder.linkToDeath(mReaderModeDeathRecipient, 0);
2174 } catch (RemoteException e) {
2175 Log.e(TAG, "Remote binder has already died.");
2176 return;
2177 }
2178 } else {
2179 try {
2180 mReaderModeParams = null;
Suhas Suresh5efc5432018-04-27 15:31:02 +05302181 StopPresenceChecking();
nxpandroid64fd68c2015-09-23 16:45:15 +05302182 binder.unlinkToDeath(mReaderModeDeathRecipient, 0);
2183 } catch (NoSuchElementException e) {
2184 Log.e(TAG, "Reader mode Binder was never registered.");
2185 }
2186 }
2187 Log.e(TAG, "applyRouting -4");
2188 applyRouting(false);
2189 }
2190 }
2191
2192
2193 @Override
2194 public void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, int[] techList) {
2195 NfcPermissions.enforceAdminPermissions(mContext);
2196
2197 int lockscreenPollMask = computeLockscreenPollMask(techList);
2198 synchronized (NfcService.this) {
2199 mNfcUnlockManager.addUnlockHandler(unlockHandler, lockscreenPollMask);
2200 }
2201
2202 applyRouting(false);
2203 }
2204
2205 @Override
2206 public void removeNfcUnlockHandler(INfcUnlockHandler token) throws RemoteException {
2207 synchronized (NfcService.this) {
2208 mNfcUnlockManager.removeUnlockHandler(token.asBinder());
2209 }
2210
2211 applyRouting(false);
2212 }
2213 private int computeLockscreenPollMask(int[] techList) {
2214
2215 Map<Integer, Integer> techCodeToMask = new HashMap<Integer, Integer>();
2216
2217 techCodeToMask.put(TagTechnology.NFC_A, NfcService.NFC_POLL_A);
2218 techCodeToMask.put(TagTechnology.NFC_B, NfcService.NFC_POLL_B);
Nikhil Chhabra288edb02018-01-10 19:36:21 +05302219 techCodeToMask.put(TagTechnology.NFC_V, NfcService.NFC_POLL_V);
nxpandroid64fd68c2015-09-23 16:45:15 +05302220 techCodeToMask.put(TagTechnology.NFC_F, NfcService.NFC_POLL_F);
2221 techCodeToMask.put(TagTechnology.NFC_BARCODE, NfcService.NFC_POLL_KOVIO);
2222 techCodeToMask.put(TagTechnology.MIFARE_CLASSIC, NfcService.NFC_POLL_A);
2223 techCodeToMask.put(TagTechnology.MIFARE_ULTRALIGHT, NfcService.NFC_POLL_A);
2224
2225 int mask = 0;
2226
2227 for (int i = 0; i < techList.length; i++) {
2228 if (techCodeToMask.containsKey(techList[i])) {
2229 mask |= techCodeToMask.get(techList[i]).intValue();
2230 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05302231 int screenState = mScreenStateHelper.checkScreenState();
2232 if (screenState != mScreenState) {
2233 new ApplyRoutingTask().execute(Integer.valueOf(screenState));
2234 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302235 }
2236
2237 return mask;
2238 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05302239
2240 /**
2241 * An interface for nxp extensions
2242 */
nxpandroid64fd68c2015-09-23 16:45:15 +05302243 @Override
nxpandroid6fd9cdb2017-07-12 18:25:41 +05302244 public IBinder getNfcAdapterVendorInterface(String vendor) {
2245 if(vendor.equalsIgnoreCase("nxp")) {
2246 return (IBinder) mNxpNfcAdapter;
2247 } else {
2248 return null;
2249 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302250 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05302251
nxpandroid64fd68c2015-09-23 16:45:15 +05302252 }
2253 final class NxpNfcAdapterService extends INxpNfcAdapter.Stub {
2254 @Override
2255 public INxpNfcAdapterExtras getNxpNfcAdapterExtrasInterface() throws RemoteException {
2256 return mNxpExtrasService;
2257 }
2258 @Override
2259 public IeSEClientServicesAdapter getNfcEseClientServicesAdapterInterface() {
2260 if(mEseClientServicesAdapter == null){
2261 mEseClientServicesAdapter = new EseClientServicesAdapter();
2262 }
2263 return mEseClientServicesAdapter;
2264 }
2265
2266 //GSMA Changes
2267 @Override
2268 public INxpNfcController getNxpNfcControllerInterface() {
2269 return mNxpNfcController.getNxpNfcControllerInterface();
2270 }
2271
2272 @Override
nxpandroid64fd68c2015-09-23 16:45:15 +05302273 public INfcVzw getNfcVzwInterface() {
2274 NfcPermissions.enforceAdminPermissions(mContext);
2275 //begin
2276 if(mVzwService == null){
2277 mVzwService = new NfcVzwService();
2278 }
2279 //end
2280 return mVzwService;
2281 }
2282
2283 @Override
2284 public int setEmvCoPollProfile(boolean enable, int route) throws RemoteException {
2285 return mDeviceHost.setEmvCoPollProfile(enable, route);
2286 }
2287
2288 @Override
2289 public int[] getSecureElementList(String pkg) throws RemoteException {
2290 NfcService.this.enforceNfcSeAdminPerm(pkg);
2291
2292 int[] list = null;
2293 if (isNfcEnabled()) {
2294 list = mDeviceHost.doGetSecureElementList();
2295 }
2296 return list;
2297 }
2298
2299 @Override
2300 public int[] getActiveSecureElementList(String pkg) throws RemoteException {
nxpandroid64fd68c2015-09-23 16:45:15 +05302301
2302 int[] list = null;
2303 if (isNfcEnabled()) {
2304 list = mDeviceHost.doGetActiveSecureElementList();
2305 }
2306 for(int i=0; i< list.length; i++) {
2307 Log.d(TAG, "Active element = "+ list[i]);
2308 }
2309 return list;
2310 }
2311
2312 public INxpNfcAccessExtras getNxpNfcAccessExtrasInterface(String pkg) {
2313 NfcService.this.enforceNfcSccAdminPerm(pkg);
2314 Log.d(TAG, "getNxpNfcAccessExtrasInterface1");
2315 if(mNfcAccessExtrasService == null){
2316 mNfcAccessExtrasService = new NfcAccessExtrasService();
2317 }
2318 return mNfcAccessExtrasService;
2319 }
2320
2321 @Override
2322 public int getSelectedSecureElement(String pkg) throws RemoteException {
2323 NfcService.this.enforceNfcSeAdminPerm(pkg);
2324 return mSelectedSeId;
2325 }
2326 @Override
2327 public int deselectSecureElement(String pkg) throws RemoteException {
2328 NfcService.this.enforceNfcSeAdminPerm(pkg);
nxf32288d12785b2017-11-17 15:18:31 +05302329 if(mChipVer < PN553_ID) {
2330 mSelectedSeId &= ~UICC2_ID_TYPE;
2331 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302332 // Check if NFC is enabled
2333 if (!isNfcEnabled()) {
2334 return ErrorCodes.ERROR_NOT_INITIALIZED;
2335 }
2336
2337 if (mSelectedSeId == 0) {
2338 return ErrorCodes.ERROR_NO_SE_CONNECTED;
2339 }
2340
2341 if (mSelectedSeId != ALL_SE_ID_TYPE/* SECURE_ELEMENT_ALL */) {
2342 mDeviceHost.doDeselectSecureElement(mSelectedSeId);
2343 } else {
2344
2345 /* Get SE List */
nxpandroid281eb922016-08-25 20:27:46 +05302346 int[] seList = mDeviceHost.doGetSecureElementList();
nxpandroid64fd68c2015-09-23 16:45:15 +05302347
nxpandroid281eb922016-08-25 20:27:46 +05302348 for (int i = 0; i < seList.length; i++) {
2349 mDeviceHost.doDeselectSecureElement(seList[i]);
nxpandroid64fd68c2015-09-23 16:45:15 +05302350 }
2351
2352 // mDeviceHost.doSetMultiSEState(false);
2353 }
2354 mNfcSecureElementState = false;
2355 mSelectedSeId = 0;
2356
2357 /* store preference */
nxpandroida9a68ba2016-01-14 21:12:17 +05302358 mNxpPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, false);
2359 mNxpPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, 0);
2360 mNxpPrefsEditor.apply();
nxpandroid64fd68c2015-09-23 16:45:15 +05302361
2362 return ErrorCodes.SUCCESS;
2363 }
2364
2365
2366
2367
2368
2369 @Override
2370 public void storeSePreference(int seId) {
nxf32288d12785b2017-11-17 15:18:31 +05302371 if(mChipVer < PN553_ID) {
2372 seId &= ~UICC2_ID_TYPE;
2373 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302374 NfcPermissions.enforceAdminPermissions(mContext);
2375 /* store */
2376 Log.d(TAG, "SE Preference stored");
nxpandroida9a68ba2016-01-14 21:12:17 +05302377 mNxpPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, true);
2378 mNxpPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, seId);
2379 mNxpPrefsEditor.apply();
nxpandroid64fd68c2015-09-23 16:45:15 +05302380 }
2381
2382 @Override
2383 public int selectSecureElement(String pkg,int seId) throws RemoteException {
2384 NfcService.this.enforceNfcSeAdminPerm(pkg);
2385
nxf32288d12785b2017-11-17 15:18:31 +05302386 if(mChipVer < PN553_ID) {
2387 seId &= ~UICC2_ID_TYPE;
2388 }
2389
nxpandroid64fd68c2015-09-23 16:45:15 +05302390 // Check if NFC is enabled
2391 if (!isNfcEnabled()) {
2392 return ErrorCodes.ERROR_NOT_INITIALIZED;
2393 }
2394
2395 if (mSelectedSeId == seId) {
2396 return ErrorCodes.ERROR_SE_ALREADY_SELECTED;
2397 }
2398
2399 if (mSelectedSeId != 0) {
2400 return ErrorCodes.ERROR_SE_CONNECTED;
2401 }
2402 /* Get SE List */
nxpandroid281eb922016-08-25 20:27:46 +05302403 int[] seList = mDeviceHost.doGetSecureElementList();
nxpandroid64fd68c2015-09-23 16:45:15 +05302404
2405 mSelectedSeId = seId;
2406 if (seId != ALL_SE_ID_TYPE/* SECURE_ELEMENT_ALL */) {
2407 mDeviceHost.doSelectSecureElement(mSelectedSeId);
2408 } else {
nxpandroid281eb922016-08-25 20:27:46 +05302409 if (seList.length > 1) {
2410 for (int i = 0; i < seList.length; i++) {
2411 mDeviceHost.doSelectSecureElement(seList[i]);
nxpandroid64fd68c2015-09-23 16:45:15 +05302412 try{
2413 //Delay b/w two SE selection.
2414 Thread.sleep(200);
2415 } catch(Exception e) {
2416 e.printStackTrace();
2417 }
2418 }
2419 }
2420 }
2421 /* store */
nxpandroida9a68ba2016-01-14 21:12:17 +05302422 mNxpPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, true);
2423 mNxpPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, mSelectedSeId);
2424 mNxpPrefsEditor.apply();
nxpandroid64fd68c2015-09-23 16:45:15 +05302425
2426 mNfcSecureElementState = true;
2427
2428 return ErrorCodes.SUCCESS;
2429 }
2430
2431 public void MifareDesfireRouteSet(int routeLoc, boolean fullPower, boolean lowPower, boolean noPower)
2432 throws RemoteException
2433 {
anil.hiranniah3cb5a1f2018-02-07 19:29:55 +05302434 if((mChipVer < PN553_ID) && (routeLoc == UICC2_ID_TYPE)) {
2435 throw new RemoteException("UICC2 is not supported");
2436 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302437 int protoRouteEntry = 0;
anil.hiranniah3cb5a1f2018-02-07 19:29:55 +05302438 /*UICC2 ID-4(fromApp) mapped to 3 (JNI)*/
2439 protoRouteEntry=((routeLoc & 0x07) == 0x04) ? (0x03 << ROUTE_LOC_MASK) : /*UICC2*/
2440 ((routeLoc & 0x07) == 0x02) ? (0x02 << ROUTE_LOC_MASK) : /*UICC1*/
2441 ((routeLoc & 0x07) == 0x01) ? (0x01 << ROUTE_LOC_MASK) : /*eSE*/
2442 0x00;
nxpandroid8aecbf82016-09-16 20:21:47 +05302443 protoRouteEntry |= ((fullPower ? (mDeviceHost.getDefaultDesfirePowerState() & 0x1F) | 0x01 : 0) | (lowPower ? 0x01 << 1 :0 ) | (noPower ? 0x01 << 2 :0));
2444
nxpandroid7d44e572016-08-01 19:11:04 +05302445 if(routeLoc == 0x00)
nxpandroid7d44e572016-08-01 19:11:04 +05302446 {
nxpandroid8aecbf82016-09-16 20:21:47 +05302447 /*
2448 bit pos 1 = Power Off
2449 bit pos 2 = Battery Off
2450 bit pos 4 = Screen Off
2451 Set these bits to 0 because in case routeLoc = HOST it can not work on POWER_OFF, BATTERY_OFF and SCREEN_OFF*/
2452 protoRouteEntry &= 0xE9;
nxpandroid7d44e572016-08-01 19:11:04 +05302453 }
nxpandroid8aecbf82016-09-16 20:21:47 +05302454
nxpandroid7d44e572016-08-01 19:11:04 +05302455 Log.i(TAG,"MifareDesfireRouteSet : " + protoRouteEntry);
nxpandroida9a68ba2016-01-14 21:12:17 +05302456 mNxpPrefsEditor = mNxpPrefs.edit();
2457 mNxpPrefsEditor.putInt("PREF_MIFARE_DESFIRE_PROTO_ROUTE_ID", protoRouteEntry);
2458 mNxpPrefsEditor.commit();
nxpandroid64fd68c2015-09-23 16:45:15 +05302459 Log.i(TAG,"MifareDesfireRouteSet function in");
2460 commitRouting();
2461 }
2462
2463 public void DefaultRouteSet(int routeLoc, boolean fullPower, boolean lowPower, boolean noPower)
2464 throws RemoteException
2465 {
anil.hiranniah3cb5a1f2018-02-07 19:29:55 +05302466 if((mChipVer < PN553_ID) && (routeLoc == UICC2_ID_TYPE)) {
2467 throw new RemoteException("UICC2 is not supported");
2468 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302469 if (mIsHceCapable) {
2470 int protoRouteEntry = 0;
anil.hiranniah3cb5a1f2018-02-07 19:29:55 +05302471 protoRouteEntry=((routeLoc & 0x07) == 0x04) ? (0x03 << ROUTE_LOC_MASK) : /*UICC2*/
2472 ((routeLoc & 0x07) == 0x02) ? (0x02 << ROUTE_LOC_MASK) : /*UICC1*/
2473 ((routeLoc & 0x07) == 0x01) ? (0x01 << ROUTE_LOC_MASK) : /*eSE*/
2474 0x00;
nxpandroid8aecbf82016-09-16 20:21:47 +05302475 protoRouteEntry |= ((fullPower ? (mDeviceHost.getDefaultAidPowerState() & 0x1F) | 0x01 : 0) | (lowPower ? 0x01 << 1 :0 ) | (noPower ? 0x01 << 2 :0));
2476
nxpandroid7d44e572016-08-01 19:11:04 +05302477 if(routeLoc == 0x00)
nxpandroid7d44e572016-08-01 19:11:04 +05302478 {
nxpandroid8aecbf82016-09-16 20:21:47 +05302479 /*
2480 bit pos 1 = Power Off
2481 bit pos 2 = Battery Off
2482 bit pos 4 = Screen Off
2483 Set these bits to 0 because in case routeLoc = HOST it can not work on POWER_OFF, BATTERY_OFF and SCREEN_OFF*/
2484 protoRouteEntry &= 0xE9;
nxpandroid7d44e572016-08-01 19:11:04 +05302485 }
2486 Log.i(TAG,"DefaultRouteSet : " + protoRouteEntry);
nxpandroid64fd68c2015-09-23 16:45:15 +05302487 if(GetDefaultRouteLoc() != routeLoc)
2488 {
nxpandroida9a68ba2016-01-14 21:12:17 +05302489 mNxpPrefsEditor = mNxpPrefs.edit();
2490 mNxpPrefsEditor.putInt("PREF_SET_DEFAULT_ROUTE_ID", protoRouteEntry );
2491 mNxpPrefsEditor.commit();
nxpandroid64fd68c2015-09-23 16:45:15 +05302492 mIsRouteForced = true;
2493 if (mIsHceCapable) {
2494 mAidRoutingManager.onNfccRoutingTableCleared();
2495 mCardEmulationManager.onRoutingTableChanged();
2496 }
2497 mIsRouteForced = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05302498 }
2499 }
2500 else{
2501 Log.i(TAG,"DefaultRoute can not be set. mIsHceCapable = flase");
2502 }
2503 }
2504
2505 public void MifareCLTRouteSet(int routeLoc, boolean fullPower, boolean lowPower, boolean noPower)
2506 throws RemoteException
2507 {
anil.hiranniah3cb5a1f2018-02-07 19:29:55 +05302508 if((mChipVer < PN553_ID) && (routeLoc == UICC2_ID_TYPE)) {
2509 throw new RemoteException("UICC2 is not supported");
2510 }
2511
nxpandroid64fd68c2015-09-23 16:45:15 +05302512 int techRouteEntry=0;
anil.hiranniah3cb5a1f2018-02-07 19:29:55 +05302513 techRouteEntry=((routeLoc & 0x07) == 0x04) ? (0x03 << ROUTE_LOC_MASK) : /*UICC2*/
2514 ((routeLoc & 0x07) == 0x02) ? (0x02 << ROUTE_LOC_MASK) : /*UICC1*/
2515 ((routeLoc & 0x07) == 0x01) ? (0x01 << ROUTE_LOC_MASK) : /*eSE*/
2516 0x00;
nxpandroid7d44e572016-08-01 19:11:04 +05302517 techRouteEntry |= ((fullPower ? (mDeviceHost.getDefaultMifareCLTPowerState() & 0x1F) | 0x01 : 0) | (lowPower ? 0x01 << 1 :0 ) | (noPower ? 0x01 << 2 :0));
2518 techRouteEntry |= (TECH_TYPE_A << TECH_TYPE_MASK);
2519
2520 Log.i(TAG,"MifareCLTRouteSet : " + techRouteEntry);
nxpandroida9a68ba2016-01-14 21:12:17 +05302521 mNxpPrefsEditor = mNxpPrefs.edit();
2522 mNxpPrefsEditor.putInt("PREF_MIFARE_CLT_ROUTE_ID", techRouteEntry);
2523 mNxpPrefsEditor.commit();
nxpandroid64fd68c2015-09-23 16:45:15 +05302524 commitRouting();
2525 }
2526 @Override
2527 public byte[] getFWVersion()
2528 {
nxpandroid5d64ce92016-11-18 19:48:53 +05302529 byte[] buf = new byte[3];
nxpandroid64fd68c2015-09-23 16:45:15 +05302530 Log.i(TAG, "Starting getFwVersion");
2531 int fwver = mDeviceHost.getFWVersion();
2532 buf[0] = (byte)((fwver&0xFF00)>>8);
2533 buf[1] = (byte)((fwver&0xFF));
nxpandroid5d64ce92016-11-18 19:48:53 +05302534 buf[2] = (byte)((fwver&0xFF0000)>>16);
nxpandroid64fd68c2015-09-23 16:45:15 +05302535 Log.i(TAG, "Firmware version is 0x"+ buf[0]+" 0x"+buf[1]);
2536 return buf;
2537 }
2538
2539 @Override
2540 public Map<String,Integer> getServicesAidCacheSize(int userId, String category){
2541 return mCardEmulationManager.getServicesAidCacheSize(userId, category);
2542 }
nxpandroida9a68ba2016-01-14 21:12:17 +05302543
2544 @Override
2545 public int updateServiceState(int userId , Map serviceState) {
2546 return mCardEmulationManager.updateServiceState(userId ,serviceState);
2547 }
2548
nxpandroid64fd68c2015-09-23 16:45:15 +05302549 @Override
2550 public int getSeInterface(int type) throws RemoteException {
2551 return mDeviceHost.doGetSeInterface(type);
2552 }
2553
nxpandroid34627bd2016-05-27 15:52:30 +05302554 @Override
2555 public int getMaxAidRoutingTableSize() throws RemoteException {
nxpandroid5d64ce92016-11-18 19:48:53 +05302556 NfcPermissions.enforceUserPermissions(mContext);
nxpandroid34627bd2016-05-27 15:52:30 +05302557 return getAidRoutingTableSize();
2558 }
2559
nxpandroid281eb922016-08-25 20:27:46 +05302560
nxpandroid34627bd2016-05-27 15:52:30 +05302561 @Override
2562 public int getCommittedAidRoutingTableSize() throws RemoteException {
nxpandroid5d64ce92016-11-18 19:48:53 +05302563 NfcPermissions.enforceUserPermissions(mContext);
nxpandroid34627bd2016-05-27 15:52:30 +05302564 return (getAidRoutingTableSize() - getRemainingAidTableSize());
2565 }
nxpandroid281eb922016-08-25 20:27:46 +05302566
2567 @Override
2568 public int setConfig(String configs , String pkg) {
2569 Log.e(TAG, "Setting configs for Transit" );
2570 /*Check permissions*/
2571 NfcPermissions.enforceAdminPermissions(mContext);
2572 /*Check if any NFC transactions are ongoing*/
2573 if(mDeviceHost.isNfccBusy())
2574 {
2575 Log.e(TAG, "NFCC is busy.." );
2576 return TRANSIT_SETCONFIG_STAT_FAILED;
2577 }
2578 /*check if format of configs is fine*/
2579 /*Save configurations to file*/
2580 try {
nxpandroidf1f54f52017-07-31 16:08:06 +05302581 File newTextFile = new File("/data/vendor/nfc/libnfc-nxpTransit.conf");
nxpandroid281eb922016-08-25 20:27:46 +05302582 if(configs == null)
2583 {
2584 if(newTextFile.delete()){
2585 Log.e(TAG, "Removing transit config file. Taking default Value" );
2586 }else{
2587 System.out.println("Error taking defualt value");
2588 }
2589 }
2590 else
2591 {
2592 FileWriter fw = new FileWriter(newTextFile);
2593 fw.write(configs);
2594 fw.close();
2595 Log.e(TAG, "File Written to libnfc-nxpTransit.conf successfully" );
2596 }
2597 } catch (Exception e) {
2598 e.printStackTrace();
2599 return TRANSIT_SETCONFIG_STAT_FAILED;
2600 }
2601
2602 /*restart NFC service*/
2603 try {
2604 mNfcAdapter.disable(true);
2605 mNfcAdapter.enable();
2606 } catch (Exception e) {
2607 Log.e(TAG, "Unable to restart NFC Service");
2608 e.printStackTrace();
2609 return TRANSIT_SETCONFIG_STAT_FAILED;
2610 }
2611 return TRANSIT_SETCONFIG_STAT_SUCCESS;
2612 }
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05302613
2614 @Override
2615 public int mPOSSetReaderMode (String pkg, boolean on) {
2616 NfcService.this.enforceNfceeAdminPerm(pkg);
Pratap Reddy49abbe32018-03-27 16:51:59 +05302617 // Check if NFC is enabled
2618 if (!isNfcEnabled()) {
2619 return NxpConstants.MPOS_STATUS_REJECTED;
2620 }
2621
2622 synchronized(NfcService.this) {
2623 int status = mDeviceHost.mposSetReaderMode(on);
2624 if(!on) {
2625 if(nci_version != NCI_VERSION_2_0) {
2626 applyRouting(true);
2627 } else if(mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED
2628 || mNfcUnlockManager.isLockscreenPollingEnabled()) {
2629 applyRouting(false);
2630 }
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05302631 }
Pratap Reddy49abbe32018-03-27 16:51:59 +05302632 return status;
2633 }
2634 }
2635
2636 @Override
2637 public boolean mPOSGetReaderMode (String pkg) {
2638 NfcService.this.enforceNfceeAdminPerm(pkg);
2639 // Check if NFC is enabled
2640 if (!isNfcEnabled()) {
2641 return false;
2642 }
2643
2644 boolean status = false;
2645 synchronized(NfcService.this) {
2646 status = mDeviceHost.mposGetReaderMode();
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05302647 }
2648 return status;
2649 }
2650
2651 @Override
2652 public void stopPoll(String pkg, int mode) {
2653 NfcService.this.enforceNfceeAdminPerm(pkg);
Pratap Reddy49abbe32018-03-27 16:51:59 +05302654 // Check if NFC is enabled
2655 if (!isNfcEnabled()) {
2656 return;
2657 }
2658
2659 synchronized(NfcService.this) {
2660 mDeviceHost.stopPoll(mode);
2661 }
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05302662 }
2663
2664 @Override
2665 public void startPoll(String pkg) {
2666 NfcService.this.enforceNfceeAdminPerm(pkg);
Pratap Reddy49abbe32018-03-27 16:51:59 +05302667 // Check if NFC is enabled
2668 if (!isNfcEnabled()) {
2669 return;
2670 }
2671
2672 synchronized(NfcService.this) {
2673 mDeviceHost.startPoll();
2674 }
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05302675 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302676 }
2677
2678 final class ReaderModeDeathRecipient implements IBinder.DeathRecipient {
2679 @Override
2680 public void binderDied() {
2681 synchronized (NfcService.this) {
2682 if (mReaderModeParams != null) {
2683 mReaderModeParams = null;
2684 Log.e(TAG, "applyRouting -5");
2685 applyRouting(false);
2686 }
2687 }
2688 }
2689 }
2690
2691 final class TagService extends INfcTag.Stub {
2692 @Override
nxpandroid64fd68c2015-09-23 16:45:15 +05302693 public int connect(int nativeHandle, int technology) throws RemoteException {
2694 NfcPermissions.enforceUserPermissions(mContext);
2695
2696 TagEndpoint tag = null;
2697
2698 if (!isNfcEnabled()) {
2699 return ErrorCodes.ERROR_NOT_INITIALIZED;
2700 }
2701
2702 /* find the tag in the hmap */
2703 tag = (TagEndpoint) findObject(nativeHandle);
2704 if (tag == null) {
2705 return ErrorCodes.ERROR_DISCONNECT;
2706 }
2707
2708 if (!tag.isPresent()) {
2709 return ErrorCodes.ERROR_DISCONNECT;
2710 }
2711
2712 // Note that on most tags, all technologies are behind a single
2713 // handle. This means that the connect at the lower levels
2714 // will do nothing, as the tag is already connected to that handle.
2715 if (tag.connect(technology)) {
2716 return ErrorCodes.SUCCESS;
2717 } else {
2718 return ErrorCodes.ERROR_DISCONNECT;
2719 }
2720 }
2721
2722 @Override
2723 public int reconnect(int nativeHandle) throws RemoteException {
2724 NfcPermissions.enforceUserPermissions(mContext);
2725
2726 TagEndpoint tag = null;
2727
2728 // Check if NFC is enabled
2729 if (!isNfcEnabled()) {
2730 return ErrorCodes.ERROR_NOT_INITIALIZED;
2731 }
2732
2733 /* find the tag in the hmap */
2734 tag = (TagEndpoint) findObject(nativeHandle);
2735 if (tag != null) {
2736 if (tag.reconnect()) {
2737 return ErrorCodes.SUCCESS;
2738 } else {
2739 return ErrorCodes.ERROR_DISCONNECT;
2740 }
2741 }
2742 return ErrorCodes.ERROR_DISCONNECT;
2743 }
2744
2745 @Override
2746 public int[] getTechList(int nativeHandle) throws RemoteException {
2747 NfcPermissions.enforceUserPermissions(mContext);
2748
2749 // Check if NFC is enabled
2750 if (!isNfcEnabled()) {
2751 return null;
2752 }
2753
2754 /* find the tag in the hmap */
2755 TagEndpoint tag = (TagEndpoint) findObject(nativeHandle);
2756 if (tag != null) {
2757 return tag.getTechList();
2758 }
2759 return null;
2760 }
2761
2762 @Override
2763 public boolean isPresent(int nativeHandle) throws RemoteException {
2764 TagEndpoint tag = null;
2765
2766 // Check if NFC is enabled
2767 if (!isNfcEnabled()) {
2768 return false;
2769 }
2770
2771 /* find the tag in the hmap */
2772 tag = (TagEndpoint) findObject(nativeHandle);
2773 if (tag == null) {
2774 return false;
2775 }
2776
2777 return tag.isPresent();
2778 }
2779
2780 @Override
2781 public boolean isNdef(int nativeHandle) throws RemoteException {
2782 NfcPermissions.enforceUserPermissions(mContext);
2783
2784 TagEndpoint tag = null;
2785
2786 // Check if NFC is enabled
2787 if (!isNfcEnabled()) {
2788 return false;
2789 }
2790
2791 /* find the tag in the hmap */
2792 tag = (TagEndpoint) findObject(nativeHandle);
2793 int[] ndefInfo = new int[2];
2794 if (tag == null) {
2795 return false;
2796 }
2797 return tag.checkNdef(ndefInfo);
2798 }
2799
2800 @Override
2801 public TransceiveResult transceive(int nativeHandle, byte[] data, boolean raw)
2802 throws RemoteException {
2803 NfcPermissions.enforceUserPermissions(mContext);
2804
2805 TagEndpoint tag = null;
2806 byte[] response;
2807
2808 // Check if NFC is enabled
2809 if (!isNfcEnabled()) {
2810 return null;
2811 }
2812
2813 /* find the tag in the hmap */
2814 tag = (TagEndpoint) findObject(nativeHandle);
2815 if (tag != null) {
2816 // Check if length is within limits
2817 if (data.length > getMaxTransceiveLength(tag.getConnectedTechnology())) {
2818 return new TransceiveResult(TransceiveResult.RESULT_EXCEEDED_LENGTH, null);
2819 }
2820 int[] targetLost = new int[1];
2821 response = tag.transceive(data, raw, targetLost);
2822 int result;
2823 if (response != null) {
2824 result = TransceiveResult.RESULT_SUCCESS;
2825 } else if (targetLost[0] == 1) {
2826 result = TransceiveResult.RESULT_TAGLOST;
2827 } else {
2828 result = TransceiveResult.RESULT_FAILURE;
2829 }
2830 return new TransceiveResult(result, response);
2831 }
2832 return null;
2833 }
2834
2835 @Override
2836 public NdefMessage ndefRead(int nativeHandle) throws RemoteException {
2837 NfcPermissions.enforceUserPermissions(mContext);
2838
2839 TagEndpoint tag;
2840
2841 // Check if NFC is enabled
2842 if (!isNfcEnabled()) {
2843 return null;
2844 }
2845
2846 /* find the tag in the hmap */
2847 tag = (TagEndpoint) findObject(nativeHandle);
2848 if (tag != null) {
2849 byte[] buf = tag.readNdef();
2850 if (buf == null) {
2851 return null;
2852 }
2853
2854 /* Create an NdefMessage */
2855 try {
2856 return new NdefMessage(buf);
2857 } catch (FormatException e) {
2858 return null;
2859 }
2860 }
2861 return null;
2862 }
2863
2864 @Override
2865 public int ndefWrite(int nativeHandle, NdefMessage msg) throws RemoteException {
2866 NfcPermissions.enforceUserPermissions(mContext);
2867
2868 TagEndpoint tag;
2869
2870 // Check if NFC is enabled
2871 if (!isNfcEnabled()) {
2872 return ErrorCodes.ERROR_NOT_INITIALIZED;
2873 }
2874
2875 /* find the tag in the hmap */
2876 tag = (TagEndpoint) findObject(nativeHandle);
2877 if (tag == null) {
2878 return ErrorCodes.ERROR_IO;
2879 }
2880
2881 if (msg == null) return ErrorCodes.ERROR_INVALID_PARAM;
2882
2883 if (tag.writeNdef(msg.toByteArray())) {
2884 return ErrorCodes.SUCCESS;
2885 } else {
2886 return ErrorCodes.ERROR_IO;
2887 }
2888
2889 }
2890
2891 @Override
2892 public boolean ndefIsWritable(int nativeHandle) throws RemoteException {
2893 throw new UnsupportedOperationException();
2894 }
2895
2896 @Override
2897 public int ndefMakeReadOnly(int nativeHandle) throws RemoteException {
2898 NfcPermissions.enforceUserPermissions(mContext);
2899
2900 TagEndpoint tag;
2901
2902 // Check if NFC is enabled
2903 if (!isNfcEnabled()) {
2904 return ErrorCodes.ERROR_NOT_INITIALIZED;
2905 }
2906
2907 /* find the tag in the hmap */
2908 tag = (TagEndpoint) findObject(nativeHandle);
2909 if (tag == null) {
2910 return ErrorCodes.ERROR_IO;
2911 }
2912
2913 if (tag.makeReadOnly()) {
2914 return ErrorCodes.SUCCESS;
2915 } else {
2916 return ErrorCodes.ERROR_IO;
2917 }
2918 }
2919
2920 @Override
2921 public int formatNdef(int nativeHandle, byte[] key) throws RemoteException {
2922 NfcPermissions.enforceUserPermissions(mContext);
2923
2924 TagEndpoint tag;
2925
2926 // Check if NFC is enabled
2927 if (!isNfcEnabled()) {
2928 return ErrorCodes.ERROR_NOT_INITIALIZED;
2929 }
2930
2931 /* find the tag in the hmap */
2932 tag = (TagEndpoint) findObject(nativeHandle);
2933 if (tag == null) {
2934 return ErrorCodes.ERROR_IO;
2935 }
2936
2937 if (tag.formatNdef(key)) {
2938 return ErrorCodes.SUCCESS;
2939 } else {
2940 return ErrorCodes.ERROR_IO;
2941 }
2942 }
2943
2944 @Override
2945 public Tag rediscover(int nativeHandle) throws RemoteException {
2946 NfcPermissions.enforceUserPermissions(mContext);
2947
2948 TagEndpoint tag = null;
2949
2950 // Check if NFC is enabled
2951 if (!isNfcEnabled()) {
2952 return null;
2953 }
2954
2955 /* find the tag in the hmap */
2956 tag = (TagEndpoint) findObject(nativeHandle);
2957 if (tag != null) {
2958 // For now the prime usecase for rediscover() is to be able
2959 // to access the NDEF technology after formatting without
2960 // having to remove the tag from the field, or similar
2961 // to have access to NdefFormatable in case low-level commands
2962 // were used to remove NDEF. So instead of doing a full stack
2963 // rediscover (which is poorly supported at the moment anyway),
2964 // we simply remove these two technologies and detect them
2965 // again.
2966 tag.removeTechnology(TagTechnology.NDEF);
2967 tag.removeTechnology(TagTechnology.NDEF_FORMATABLE);
2968 tag.findAndReadNdef();
2969 // Build a new Tag object to return
2970 Tag newTag = new Tag(tag.getUid(), tag.getTechList(),
2971 tag.getTechExtras(), tag.getHandle(), this);
2972 return newTag;
2973 }
2974 return null;
2975 }
2976
2977 @Override
2978 public int setTimeout(int tech, int timeout) throws RemoteException {
2979 NfcPermissions.enforceUserPermissions(mContext);
2980 boolean success = mDeviceHost.setTimeout(tech, timeout);
2981 if (success) {
2982 return ErrorCodes.SUCCESS;
2983 } else {
2984 return ErrorCodes.ERROR_INVALID_PARAM;
2985 }
2986 }
2987
2988 @Override
2989 public int getTimeout(int tech) throws RemoteException {
2990 NfcPermissions.enforceUserPermissions(mContext);
2991
2992 return mDeviceHost.getTimeout(tech);
2993 }
2994
2995 @Override
2996 public void resetTimeouts() throws RemoteException {
2997 NfcPermissions.enforceUserPermissions(mContext);
2998
2999 mDeviceHost.resetTimeouts();
3000 }
3001
3002 @Override
3003 public boolean canMakeReadOnly(int ndefType) throws RemoteException {
3004 return mDeviceHost.canMakeReadOnly(ndefType);
3005 }
3006
3007 @Override
3008 public int getMaxTransceiveLength(int tech) throws RemoteException {
3009 return mDeviceHost.getMaxTransceiveLength(tech);
3010 }
3011
3012 @Override
3013 public boolean getExtendedLengthApdusSupported() throws RemoteException {
3014 return mDeviceHost.getExtendedLengthApdusSupported();
3015 }
3016 }
3017
3018 final class NfcJcopService extends IJcopService.Stub{
3019
3020 public int jcopOsDownload(String pkg) throws RemoteException
3021 {
3022 NfcService.this.enforceNfceeAdminPerm(pkg);
3023 int status = ErrorCodes.SUCCESS;
3024 boolean mode;
3025 mode = mDeviceHost.doCheckJcopDlAtBoot();
3026 if(mode == false) {
3027 Log.i(TAG, "Starting getChipName");
3028 int Ver = mDeviceHost.getChipVer();
nxpandroid281eb922016-08-25 20:27:46 +05303029 if(Ver == PN80T_ID || Ver == PN67T_ID || Ver == PN66T_ID || Ver == PN65T_ID) {
nxpandroid64fd68c2015-09-23 16:45:15 +05303030 status = mDeviceHost.JCOSDownload();
nxpandroid7d44e572016-08-01 19:11:04 +05303031 }
3032 else {
3033 status = ErrorCodes.ERROR_NOT_SUPPORTED;
nxpandroid64fd68c2015-09-23 16:45:15 +05303034 }
Suhas Suresh9139dc22018-05-09 15:48:37 +05303035 } else {
nxpandroid64fd68c2015-09-23 16:45:15 +05303036 status = ErrorCodes.ERROR_NOT_SUPPORTED;
3037 }
3038 return status;
3039 }
3040 }
3041 final class EseClientServicesAdapter extends IeSEClientServicesAdapter.Stub{
3042 @Override
3043 public IJcopService getJcopService() {
3044 if(mJcopService == null){
3045 mJcopService = new NfcJcopService();
3046 }
3047 return mJcopService;
3048 }
3049 @Override
3050 public ILoaderService getLoaderService() {
3051 if(mAlaService == null){
3052 mAlaService = new NfcAlaService();
3053 }
3054 return mAlaService;
3055 }
3056 @Override
3057 public INxpExtrasService getNxpExtrasService() {
3058 if(mNxpExtras == null){
3059 mNxpExtras = new NxpExtrasService();
3060 }
3061 return mNxpExtras;
3062 }
3063 };
3064
3065 final class NfcAlaService extends ILoaderService.Stub{
3066 private boolean isRecovery = false;
3067 private String appName = null;
3068 private String srcIn = null;
3069 private String respOut = null;
3070 private String status = "false";
3071
3072 void NfcAlaService()
3073 {
3074 appName = null;
3075 srcIn = null;
3076 respOut = null;
3077 status = "false";
3078 isRecovery = false;
3079 }
3080 private synchronized void LSReexecute()
3081 {
3082 byte[] ret = {0x4E,0x02,(byte)0x69,(byte)0x87};
3083 byte retry = LS_RETRY_CNT;
3084 PrintWriter out= null;
3085 BufferedReader br = null;
3086 Log.i(TAG, "Enter: NfcAlaService constructor");
3087 try{
3088 File f = new File(LS_BACKUP_PATH);
3089
3090 Log.i(TAG, "Enter: NfcAlaService constructor file open");
3091 /*If the file does not exists*/
3092 if(!(f.isFile()))
3093 {
3094 Log.i(TAG, "FileNotFound ls backup");
nxpandroid34627bd2016-05-27 15:52:30 +05303095 this.status = null;
nxpandroid64fd68c2015-09-23 16:45:15 +05303096 }
3097 /*If the file exists*/
3098 else
3099 {
3100 Log.i(TAG, "File Found ls backup");
3101 br = new BufferedReader(new FileReader(LS_BACKUP_PATH));
3102 this.appName = br.readLine();
3103 this.srcIn = br.readLine();
3104 this.respOut = br.readLine();
3105 this.status = br.readLine();
3106 }
3107 }catch(FileNotFoundException f)
3108 {
3109 Log.i(TAG, "FileNotFoundException Raised during LS Initialization");
3110 return;
3111 }
3112 catch(IOException ie)
3113 {
3114 Log.i(TAG, "IOException Raised during LS Initialization ");
3115 return;
3116 }
3117 finally{
3118 try{
nxpandroid64fd68c2015-09-23 16:45:15 +05303119 if(br != null)
3120 br.close();
nxpandroid34627bd2016-05-27 15:52:30 +05303121 /*If the file does not exist or empty file */
3122 if(this.status == null)
3123 {
3124 out = new PrintWriter(LS_BACKUP_PATH);
3125 this.status = "true";
3126 out.println("null");
3127 out.println("null");
3128 out.println("null");
3129 out.println("true");
3130 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303131 }catch(IOException e)
3132 {
3133 Log.i(TAG, "IOException Raised during LS Initialization ");
3134 return;
3135 }
nxpandroid34627bd2016-05-27 15:52:30 +05303136 finally{
3137 if(this.status == null)
3138 this.status = "true";
3139 if(out != null)
3140 out.close();
3141 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303142 }
3143 if(this.status.equals("true"))
3144 {
3145 Log.i(TAG, "LS Script execution completed");
3146 }
3147 else
3148 {
3149 Log.i(TAG, "LS Script execution aborted or tear down happened");
3150 Log.i(TAG, "Input script path"+ this.srcIn);
3151 Log.i(TAG, "Output response path"+ this.respOut);
3152 Log.i(TAG, "Application name which invoked LS"+ this.appName);
3153 try{
3154 File fSrc = new File(this.srcIn);
3155 File fRsp = new File(this.respOut);
3156 if((fSrc.isFile() && fRsp.isFile()))
3157 {
3158 byte[] lsAppletStatus = {0x6F,0x00};
3159 /*Perform lsExecuteScript on tear down*/
3160 WatchDogThread watchDog =
3161 new WatchDogThread("Loader service ", INIT_WATCHDOG_LS_MS);
3162 watchDog.start();
3163 try {
3164 mRoutingWakeLock.acquire();
3165 try {
3166 /*Reset retry counter*/
3167 while((retry-- > 0))
3168 {
3169 Thread.sleep(1000);
3170 lsAppletStatus = mNfcAla.doLsGetAppletStatus();
3171 if((lsAppletStatus[0]==0x63) && (lsAppletStatus[1]==0x40))
3172 {
3173 Log.i(TAG, "Started LS recovery since previous session failed");
3174 this.isRecovery = true;
3175 ret = this.lsExecuteScript(this.srcIn, this.respOut);
3176 }
3177 else
3178 {
3179 break;
3180 }
3181 }
3182 } finally {
3183 this.isRecovery = false;
3184 watchDog.cancel();
3185 mRoutingWakeLock.release();
3186 }
3187 }
3188 catch(RemoteException ie)
3189 {
3190 Log.i(TAG, "LS recovery Exception: ");
3191 }
3192 lsAppletStatus = mNfcAla.doLsGetAppletStatus();
3193 if((lsAppletStatus[0]==(byte)0x90)&&(lsAppletStatus[1]==(byte)0x00))
3194 {
3195 out = new PrintWriter(LS_BACKUP_PATH);
3196 out.println("null");
3197 out.println("null");
3198 out.println("null");
3199 out.println("true");
3200 out.close();
3201 Log.i(TAG, "Commiting Default Values of Loader Service AS RETRY ENDS: ");
3202 }
3203 }
3204 else
3205 {
3206 Log.i(TAG, "LS recovery not required");
3207 }
3208 }catch(InterruptedException re)
3209 {
3210 /*Retry failed todo*/
nxpandroid34627bd2016-05-27 15:52:30 +05303211 Log.i(TAG, "InterruptedException while LS recovery");
nxpandroid64fd68c2015-09-23 16:45:15 +05303212 }catch(FileNotFoundException re)
3213 {
3214 /*Retry failed todo*/
nxpandroid34627bd2016-05-27 15:52:30 +05303215 Log.i(TAG, "FileNotFoundException while LS recovery");
nxpandroid64fd68c2015-09-23 16:45:15 +05303216 }
3217 }
3218 }
3219 private void updateLoaderService() {
3220 byte[] ret = {0x4E,0x02,(byte)0x69,(byte)0x87};
3221 Log.i(TAG, "Enter: NfcAlaService constructor file open");
3222 File f = new File(LS_UPDATE_BACKUP_PATH);
nxpandroid34627bd2016-05-27 15:52:30 +05303223 /*If the file exists*/
nxpandroid64fd68c2015-09-23 16:45:15 +05303224 if((f.isFile()))
3225 {
3226 Log.i(TAG, "File Found LS update required");
3227 WatchDogThread watchDog =
3228 new WatchDogThread("LS Update Loader service ", (INIT_WATCHDOG_LS_MS+INIT_WATCHDOG_LS_MS));
3229 watchDog.start();
3230 try {
3231 try {
3232 /*Reset retry counter*/
3233 {
3234 Log.i(TAG, "Started LS update");
3235 ret = this.lsExecuteScript(LS_UPDATE_BACKUP_PATH, LS_UPDATE_BACKUP_OUT_PATH);
3236 if(ret[2] == (byte)(0x90) && ret[3] == (byte)(0x00))
3237 {
3238 Log.i(TAG, " LS update successfully completed");
3239 f.delete();
3240 } else {
3241 Log.i(TAG, " LS update failed");
3242 }
3243 }
3244 } finally {
3245 watchDog.cancel();
3246 }
3247 }
3248 catch(RemoteException ie)
3249 {
3250 Log.i(TAG, "LS update recovery Exception: ");
3251 }
3252 }
nxpandroid34627bd2016-05-27 15:52:30 +05303253 /*If the file does not exists*/
nxpandroid64fd68c2015-09-23 16:45:15 +05303254 else
3255 {
3256 Log.i(TAG, "No LS update");
3257 }
3258 }
3259
3260 public byte[] lsExecuteScript( String srcIn, String respOut) throws RemoteException {
3261 String pkg_name = getCallingAppPkg(mContext);
3262 byte[] sha_data = CreateSHA(pkg_name, 2);
3263 byte[] respSW = {0x4e,0x02,0x69,(byte)0x87};
3264 InputStream is = null;
3265 OutputStream os = null;
3266 PrintWriter out = null;
3267 FileReader fr = null;
3268 byte[] buffer = new byte[1024];
3269 int length = 0;
3270 String srcBackup = srcIn+"mw";
3271 String rspBackup = null;
3272 File rspFile = null;
3273 if(respOut != null)
3274 rspBackup = respOut+"mw";
3275 File srcFile = new File(srcBackup);
3276 if(respOut != null)
3277 rspFile = new File(rspBackup);
3278
3279
3280 /*If Previously Tear down happened before completion of LS execution*/
3281 if(this.isRecovery != false)
3282 {
3283 try{
3284 fr = new FileReader(LS_BACKUP_PATH);
3285 if(fr != null)
3286 {
3287 BufferedReader br = new BufferedReader(fr);
3288 if(br != null)
3289 {
3290 String appName = br.readLine();
3291 if(appName != null)
3292 {
3293 sha_data = CreateSHA(appName, 2);
3294 pkg_name = appName;
3295 }
3296 }
3297 }
3298 }catch(IOException ioe)
3299 {
3300 Log.i(TAG, "IOException thrown for opening ");
3301 }
3302 finally{
3303 try{
3304 if(fr != null)
3305 fr.close();
3306 }
3307 catch(IOException e)
3308 {
3309 Log.i(TAG, "IOException thrown for opening ");
3310 }
3311 }
3312 }
3313 /*Store it in File*/
3314 try{
3315 out = new PrintWriter(LS_BACKUP_PATH);
3316 out.println(pkg_name);
3317 out.println(srcIn);
3318 out.println(respOut);
3319 out.println(false);
3320 }catch(IOException fe)
3321 {
3322 Log.i(TAG, "IOException thrown during clearing ");
3323 }
3324 finally{
3325 if(out != null)
3326 out.close();
3327 }
3328 try{
3329 /*To avoid rewriting of backup file*/
3330 if(!(this.isRecovery)){
3331 is = new FileInputStream(srcIn);
3332 os = new FileOutputStream(srcBackup);
3333
3334 while((length = is.read(buffer))>0)
3335 {
3336 os.write(buffer,0,length);
3337 }
3338 if(is != null)is.close();
3339 if(os != null)os.close();}
3340 Log.i(TAG, "sha_data len : " + sha_data.length);
3341 Log.i(TAG, "Calling package APP Name is "+ pkg_name);
3342 if(sha_data != null)
3343 {
3344 respSW = mNfcAla.doLsExecuteScript(srcBackup, rspBackup, sha_data);
3345 }
3346 /*resp file is not null*/
3347 if(respOut != null){
3348 is = new FileInputStream(rspBackup);
3349 os = new FileOutputStream(respOut);
3350 length = 0;
3351 while((length = is.read(buffer))>0)
3352 {
3353 os.write(buffer,0,length);
3354 }
3355 }
3356 if(is != null)is.close();
3357 if(os != null)os.close();
3358 }catch(IOException ioe)
3359 {
3360 Log.i(TAG, "LS File not found");
3361 }catch(SecurityException se)
3362 {
3363 Log.i(TAG, "LS File access permission deneied");
3364 }
3365 finally{
3366 byte[] status = mNfcAla.doLsGetStatus();
3367 Log.i(TAG, "LS getStatus return SW1 : "+status[0]);
3368 Log.i(TAG, "LS getStatus return SW2: "+status[1]);
3369 if((status[0]== (byte)0x90) && (status[1] == 0x00))
3370 {
3371 try{
3372 out = new PrintWriter(LS_BACKUP_PATH);
3373 out.println("null");
3374 out.println("null");
3375 out.println("null");
3376 out.println("true");
3377 }catch(IOException fe)
3378 {
3379 Log.i(TAG, "FileNotFoundException thrown during clearing ");
3380 }
3381 finally
3382 {
3383 if(out != null)
3384 out.close();
3385 }
3386 Log.i(TAG, "COMMITTING THE DEFAULT VALUES OF LS : ");
3387 srcFile.delete();
3388 rspFile.delete();
3389 }
3390 else
3391 {
3392 Log.i(TAG, "NOT COMMITTING THE DEFAULT VALUES OF LS : ");
3393 }
3394 }
3395 return respSW;
3396 }
3397 public byte[] lsGetVersion()
3398 {
3399 byte[] respApdu = {0x4e,0x02,0x69,(byte)0x87};
3400
3401 respApdu = mNfcAla.doLsGetVersion();
3402 return respApdu;
3403 }
3404 public int appletLoadApplet(String pkg, String choice) throws RemoteException {
3405 String pkg_name = getCallingAppPkg(mContext);
3406 int state = 0;
3407 byte[] sha_data = CreateSHA(pkg_name, 1);
3408 Log.i(TAG, "sha_data len : " + sha_data.length);
3409
3410 if(sha_data != null)
3411 {
3412 state = mNfcAla.doAppletLoadApplet(choice, sha_data);
3413 return state;
3414 }
3415 else
3416 return 0xFF;
3417 }
3418 public int getListofApplets(String pkg, String[] name) throws RemoteException {
3419 int cnt = mNfcAla.GetAppletsList(name);
3420 Log.i(TAG, "GetListofApplets count : " + cnt);
3421 for(int i=0;i<cnt;i++) {
3422 Log.i(TAG, "GetListofApplets " + name[i]);
3423 }
3424
3425 return cnt;
3426 }
3427
nxpandroide68208c2017-02-24 16:08:04 +05303428 //Just Stub for compilation.
nxpandroid64fd68c2015-09-23 16:45:15 +05303429 public byte[] getKeyCertificate() throws RemoteException {
3430 return null;
3431 }
3432
3433 };
3434
nxpandroid64fd68c2015-09-23 16:45:15 +05303435 final class NxpExtrasService extends INxpExtrasService.Stub {
3436 private Bundle writeNoException() {
3437 Bundle p = new Bundle();
3438 p.putInt("e", 0);
3439 return p;
3440 }
3441
3442 private Bundle writeEeException(int exceptionType, String message) {
3443 Bundle p = new Bundle();
3444 p.putInt("e", exceptionType);
3445 p.putString("m", message);
3446 return p;
3447 }
3448
3449 @Override
nxpandroid5d64ce92016-11-18 19:48:53 +05303450 public Bundle getCallingAppPkg(String pkg, IBinder b) throws RemoteException {
3451 NfcService.this.enforceNfceeAdminPerm(pkg);
3452 Bundle result;
3453 String packageName;
3454 try{
3455 packageName = NfcService.this.getCallingAppPkg(mContext);
3456 result = writeNoException();
3457 result.putString("packageName", packageName);
3458 } catch(Exception e){
3459 result = writeEeException(EE_ERROR_IO, e.getMessage());
3460 }
3461 return result;
3462 }
3463
3464 @Override
nxpandroid64fd68c2015-09-23 16:45:15 +05303465 public boolean isEnabled()
3466 {
3467 try {
3468 return (mState == NfcAdapter.STATE_ON);
3469 } catch (Exception e) {
3470 Log.d(TAG, "Exception " + e.getMessage());
3471 return false;
3472 }
3473 }
3474
3475 @Override
3476 public byte[] getSecureElementUid(String pkg) throws RemoteException {
3477 NfcService.this.enforceNfceeAdminPerm(pkg);
3478 return mDeviceHost.getSecureElementUid();
3479 }
3480
3481 @Override
3482 public Bundle open(String pkg, IBinder b) throws RemoteException {
3483 NfcService.this.enforceNfceeAdminPerm(pkg);
3484
3485 Bundle result;
3486 int handle = _open(b);
3487 if (handle < 0) {
3488 result = writeEeException(handle, "NFCEE open exception.");
3489 } else {
3490 result = writeNoException();
3491 }
3492 return result;
3493 }
3494
3495 /**
3496 * Opens a connection to the secure element.
3497 *
3498 * @return A handle with a value >= 0 in case of success, or a
3499 * negative value in case of failure.
3500 */
3501 private int _open(IBinder b) {
3502 synchronized(NfcService.this) {
3503 if (!isNfcEnabled()) {
3504 return EE_ERROR_NFC_DISABLED;
3505 }
3506 if (mInProvisionMode) {
3507 // Deny access to the NFCEE as long as the device is being setup
3508 return EE_ERROR_IO;
3509 }
nxpandroide68208c2017-02-24 16:08:04 +05303510
nxpandroid64fd68c2015-09-23 16:45:15 +05303511 if (mOpenEe != null) {
3512 return EE_ERROR_ALREADY_OPEN;
3513 }
3514
3515 boolean restorePolling = false;
3516 if (mNfcPollingEnabled) {
3517 // Disable polling for tags/P2P when connecting to the SMX
3518 // on PN544-based devices. Whenever nfceeClose is called,
3519 // the polling configuration will be restored.
3520 mDeviceHost.disableDiscovery();
3521 mNfcPollingEnabled = false;
3522 restorePolling = true;
3523 }
nxpandroid7d44e572016-08-01 19:11:04 +05303524 int handle = doOpenSecureElementConnection(0xF3);
nxpandroid64fd68c2015-09-23 16:45:15 +05303525 if (handle < 0) {
3526
3527 if (restorePolling) {
3528 mDeviceHost.enableDiscovery(mCurrentDiscoveryParameters, true);
3529 mNfcPollingEnabled = true;
3530 }
3531 return handle;
3532 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303533
3534 mOpenEe = new OpenSecureElement(getCallingPid(), handle, b);
3535 try {
3536 b.linkToDeath(mOpenEe, 0);
3537 } catch (RemoteException e) {
3538 mOpenEe.binderDied();
3539 }
3540
3541 // Add the calling package to the list of packages that have accessed
3542 // the secure element.
3543 for (String packageName : mContext.getPackageManager().getPackagesForUid(getCallingUid())) {
3544 mSePackages.add(packageName);
3545 }
3546
3547 return handle;
3548 }
3549 }
3550
3551 @Override
3552 public Bundle close(String pkg, IBinder binder) throws RemoteException {
3553 NfcService.this.enforceNfceeAdminPerm(pkg);
3554
3555 Bundle result;
3556 try {
3557 _nfcEeClose(getCallingPid(), binder);
3558 result = writeNoException();
3559 } catch (IOException e) {
3560 result = writeEeException(EE_ERROR_IO, e.getMessage());
3561 }
3562 return result;
3563 }
3564 @Override
3565 public Bundle transceive(String pkg, byte[] in) throws RemoteException {
3566 NfcService.this.enforceNfceeAdminPerm(pkg);
3567
3568 Bundle result;
3569 byte[] out;
3570 try {
3571 out = _transceive(in);
3572 result = writeNoException();
3573 result.putByteArray("out", out);
3574 } catch (IOException e) {
3575 result = writeEeException(EE_ERROR_IO, e.getMessage());
3576 }
3577 return result;
3578 }
3579
3580 private byte[] _transceive(byte[] data) throws IOException {
3581 synchronized(NfcService.this) {
3582 if (!isNfcEnabled()) {
3583 throw new IOException("NFC is not enabled");
3584 }
3585 if (mOpenEe == null) {
3586 throw new IOException("NFC EE is not open");
3587 }
3588 if (getCallingPid() != mOpenEe.pid) {
3589 throw new SecurityException("Wrong PID");
3590 }
3591 }
3592
3593 return doTransceive(mOpenEe.handle, data);
3594 }
3595 };
nxpandroid64fd68c2015-09-23 16:45:15 +05303596
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05303597
3598 final class NfcDtaService extends INfcDta.Stub {
3599 public void enableDta() throws RemoteException {
nxpandroid64fd68c2015-09-23 16:45:15 +05303600 NfcPermissions.enforceAdminPermissions(mContext);
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05303601 if(!sIsDtaMode) {
nxpandroid64fd68c2015-09-23 16:45:15 +05303602 mDeviceHost.enableDtaMode();
nxpandroid281eb922016-08-25 20:27:46 +05303603 sIsDtaMode = true;
nxpandroid64fd68c2015-09-23 16:45:15 +05303604 Log.d(TAG, "DTA Mode is Enabled ");
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05303605 }
3606 }
3607
3608 public void disableDta() throws RemoteException {
3609 NfcPermissions.enforceAdminPermissions(mContext);
3610 if(sIsDtaMode) {
nxpandroid64fd68c2015-09-23 16:45:15 +05303611 mDeviceHost.disableDtaMode();
nxpandroid281eb922016-08-25 20:27:46 +05303612 sIsDtaMode = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05303613 }
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05303614 }
3615
3616 public boolean enableServer(String serviceName, int serviceSap, int miu,
3617 int rwSize,int testCaseId) throws RemoteException {
3618 NfcPermissions.enforceAdminPermissions(mContext);
3619
3620 if(serviceName.equals(null))
3621 return false;
3622
3623 mP2pLinkManager.enableExtDtaSnepServer(serviceName, serviceSap, miu, rwSize,testCaseId);
nxpandroid64fd68c2015-09-23 16:45:15 +05303624 return true;
3625 }
3626
Bhupendra Pawar9f0c8382018-01-11 17:05:27 +05303627 public void disableServer() throws RemoteException {
3628 NfcPermissions.enforceAdminPermissions(mContext);
3629 mP2pLinkManager.disableExtDtaSnepServer();
3630 }
3631
3632 public boolean enableClient(String serviceName, int miu, int rwSize,
3633 int testCaseId) throws RemoteException {
3634 NfcPermissions.enforceAdminPermissions(mContext);
3635
3636 if(testCaseId == 0)
3637 return false;
3638
3639 if (testCaseId>20){
3640 sIsShortRecordLayout=true;
3641 testCaseId=testCaseId-20;
3642 } else {
3643 sIsShortRecordLayout=false;
3644 }
3645 Log.d("testCaseId", ""+testCaseId);
3646 mP2pLinkManager.enableDtaSnepClient(serviceName, miu, rwSize, testCaseId);
3647 return true;
3648 }
3649
3650 public void disableClient() throws RemoteException {
3651 NfcPermissions.enforceAdminPermissions(mContext);
3652 mP2pLinkManager.disableDtaSnepClient();
3653 }
3654
3655 public boolean registerMessageService(String msgServiceName)
3656 throws RemoteException {
3657 NfcPermissions.enforceAdminPermissions(mContext);
3658 if(msgServiceName.equals(null))
3659 return false;
3660
3661 DtaServiceConnector.setMessageService(msgServiceName);
3662 return true;
3663 }
3664 };
nxpandroid64fd68c2015-09-23 16:45:15 +05303665
3666 final class NfcVzwService extends INfcVzw.Stub {
3667 @Override
3668 public void setScreenOffCondition(boolean enable) throws RemoteException {
3669
3670 Message msg = mHandler.obtainMessage();
3671 msg.what=MSG_SET_SCREEN_STATE;
3672 msg.arg1= (enable)?1:0;
3673 mHandler.sendMessage(msg);
3674
3675 }
3676
3677 @Override
3678 public boolean setVzwAidList(RouteEntry[] entries)
3679 throws RemoteException {
nxpandroid64fd68c2015-09-23 16:45:15 +05303680 Log.i(TAG, "setVzwAidList enter");
3681 Log.i(TAG, "setVzwAidList entries length =" + entries.length);
3682 if (mIsHceCapable) {
3683 mAidRoutingManager.ClearVzwCache();
3684 for (int i = 0; i < entries.length; i++) {
3685 RouteEntry routeEntry = entries[i];
3686 mAidRoutingManager.UpdateVzwCache(routeEntry.getAid(),
3687 routeEntry.getLocation(), routeEntry.getPowerState(),
3688 routeEntry.isAllowed());
3689
3690 Log.i(TAG,
3691 "AID" + routeEntry.getAid() + "Location "
3692 + routeEntry.getLocation() + "powerstate "
3693 + routeEntry.getPowerState());
3694 }
3695 mAidRoutingManager.onNfccRoutingTableCleared();
3696 mCardEmulationManager.onRoutingTableChanged();
3697 return true;
3698 } else {
3699 return false;
3700 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303701 }
3702
3703 };
3704
3705 void _nfcEeClose(int callingPid, IBinder binder) throws IOException {
3706 // Blocks until a pending open() or transceive() times out.
3707 //TODO: This is incorrect behavior - the close should interrupt pending
3708 // operations. However this is not supported by current hardware.
3709
3710 synchronized (NfcService.this) {
3711 if (!isNfcEnabledOrShuttingDown()) {
3712 throw new IOException("NFC adapter is disabled");
3713 }
3714 if (mOpenEe == null) {
3715 throw new IOException("NFC EE closed");
3716 }
3717 if (callingPid != -1 && callingPid != mOpenEe.pid) {
3718 throw new SecurityException("Wrong PID");
3719 }
3720 if (mOpenEe.binder != binder) {
3721 throw new SecurityException("Wrong binder handle");
3722 }
3723
3724 binder.unlinkToDeath(mOpenEe, 0);
3725 mDeviceHost.resetTimeouts();
3726 doDisconnect(mOpenEe.handle);
3727 mOpenEe = null;
nxpandroid64fd68c2015-09-23 16:45:15 +05303728 }
3729 }
3730
3731 boolean _nfcEeReset() throws IOException {
3732 synchronized (NfcService.this) {
3733 if (!isNfcEnabledOrShuttingDown()) {
3734 throw new IOException("NFC adapter is disabled");
3735 }
3736 if (mOpenEe == null) {
3737 throw new IOException("NFC EE closed");
3738 }
3739 return mSecureElement.doReset(mOpenEe.handle);
3740 }
3741 }
3742
3743 final class NfcAccessExtrasService extends INxpNfcAccessExtras.Stub {
3744 public boolean checkChannelAdminAccess(String pkg) throws RemoteException {
3745 boolean result = true;
3746 try {
3747 NfcService.this.enforceNfcSccAdminPerm(pkg);
3748 } catch (Exception e) {
3749 e.printStackTrace();
3750 result = false;
3751 }
3752 return result;
3753 }
3754 };
3755
3756 final class NfcAdapterExtrasService extends INfcAdapterExtras.Stub {
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05303757 ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
nxpandroid64fd68c2015-09-23 16:45:15 +05303758 private Bundle writeNoException() {
3759 Bundle p = new Bundle();
3760 p.putInt("e", 0);
3761 return p;
3762 }
3763
3764 private Bundle writeEeException(int exceptionType, String message) {
3765 Bundle p = new Bundle();
3766 p.putInt("e", exceptionType);
3767 p.putString("m", message);
3768 return p;
3769 }
3770
3771 @Override
3772 public Bundle open(String pkg, IBinder b) throws RemoteException {
3773 NfcService.this.enforceNfceeAdminPerm(pkg);
3774
3775 Bundle result;
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05303776 if (activityManager.isLowRamDevice()) {
3777 result = writeEeException(SE_ACCESS_DENIED, "SE open access denied.");
nxpandroid64fd68c2015-09-23 16:45:15 +05303778 } else {
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05303779 int handle = _open(b);
3780 if (handle < 0) {
3781 result = writeEeException(handle, "NFCEE open exception.");
3782 } else {
3783 result = writeNoException();
3784 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303785 }
3786 return result;
3787 }
3788
3789 /**
3790 * Opens a connection to the secure element.
3791 *
3792 * @return A handle with a value >= 0 in case of success, or a
3793 * negative value in case of failure.
3794 */
3795 private int _open(IBinder b) {
3796 synchronized(NfcService.this) {
3797 if (!isNfcEnabled()) {
3798 return EE_ERROR_NFC_DISABLED;
3799 }
3800 if (mInProvisionMode) {
3801 // Deny access to the NFCEE as long as the device is being setup
3802 return EE_ERROR_IO;
3803 }
nxpandroid7d44e572016-08-01 19:11:04 +05303804 /*Concurrent access for DWP transactions to be allowed even when P2P is already ongoing */
3805 /*
nxpandroid64fd68c2015-09-23 16:45:15 +05303806 if (mP2pLinkManager.isLlcpActive()) {
3807 // Don't allow PN544-based devices to open the SE while the LLCP
3808 // link is still up or in a debounce state. This avoids race
3809 // conditions in the NXP stack around P2P/SMX switching.
3810 return EE_ERROR_EXT_FIELD;
nxpandroid7d44e572016-08-01 19:11:04 +05303811 }*/
nxpandroid64fd68c2015-09-23 16:45:15 +05303812 if (mOpenEe != null) {
3813 Log.i(TAG, "SE is Busy. returning..");
3814 return EE_ERROR_ALREADY_OPEN;
3815 }
3816 boolean restorePolling = false;
3817 if (mNfcPollingEnabled) {
3818 // Disable polling for tags/P2P when connecting to the SMX
3819 // on PN544-based devices. Whenever nfceeClose is called,
3820 // the polling configuration will be restored.
3821 mDeviceHost.disableDiscovery();
3822 mNfcPollingEnabled = false;
3823 restorePolling = true;
3824 }
3825
nxpandroid7d44e572016-08-01 19:11:04 +05303826 int handle = doOpenSecureElementConnection(0xF3);
nxpandroid64fd68c2015-09-23 16:45:15 +05303827 if (handle < 0) {
3828
3829 if (restorePolling) {
3830 mDeviceHost.enableDiscovery(mCurrentDiscoveryParameters, true);
3831 mNfcPollingEnabled = true;
3832 }
3833 return handle;
3834 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303835 mOpenEe = new OpenSecureElement(getCallingPid(), handle, b);
3836 try {
3837 b.linkToDeath(mOpenEe, 0);
3838 } catch (RemoteException e) {
3839 mOpenEe.binderDied();
3840 }
3841
3842 // Add the calling package to the list of packages that have accessed
3843 // the secure element.
3844 for (String packageName : mContext.getPackageManager().getPackagesForUid(getCallingUid())) {
3845 mSePackages.add(packageName);
3846 }
3847
3848 return handle;
3849 }
3850 }
3851
3852 @Override
3853 public Bundle close(String pkg, IBinder binder) throws RemoteException {
3854 NfcService.this.enforceNfceeAdminPerm(pkg);
3855
3856 Bundle result;
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05303857
3858 if (activityManager.isLowRamDevice()) {
3859 result = writeEeException(SE_ACCESS_DENIED, "SE close access denied.");
3860 } else {
3861 try {
3862 _nfcEeClose(getCallingPid(), binder);
3863 result = writeNoException();
3864 } catch (IOException e) {
3865 result = writeEeException(EE_ERROR_IO, e.getMessage());
3866 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303867 }
3868 return result;
3869 }
3870
nxpandroid64fd68c2015-09-23 16:45:15 +05303871 @Override
3872 public Bundle transceive(String pkg, byte[] in) throws RemoteException {
3873 NfcService.this.enforceNfceeAdminPerm(pkg);
3874
3875 Bundle result;
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05303876
3877 if (activityManager.isLowRamDevice()) {
3878 result = writeEeException(SE_ACCESS_DENIED, "SE transceive access denied.");
3879 } else {
3880 byte[] out;
3881 try {
3882 out = _transceive(in);
3883 result = writeNoException();
3884 result.putByteArray("out", out);
3885 } catch (IOException e) {
3886 result = writeEeException(EE_ERROR_IO, e.getMessage());
3887 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303888 }
3889 return result;
3890 }
3891
3892 private byte[] _transceive(byte[] data) throws IOException {
3893 synchronized(NfcService.this) {
3894 if (!isNfcEnabled()) {
3895 throw new IOException("NFC is not enabled");
3896 }
3897 if (mOpenEe == null) {
3898 throw new IOException("NFC EE is not open");
3899 }
3900 if (getCallingPid() != mOpenEe.pid) {
3901 throw new SecurityException("Wrong PID");
3902 }
3903 }
3904
3905 return doTransceive(mOpenEe.handle, data);
3906 }
3907
nxpandroid64fd68c2015-09-23 16:45:15 +05303908 @Override
3909 public int getCardEmulationRoute(String pkg) throws RemoteException {
3910 NfcService.this.enforceNfceeAdminPerm(pkg);
3911 return mEeRoutingState;
3912 }
3913
3914 @Override
3915 public void setCardEmulationRoute(String pkg, int route) throws RemoteException {
3916 NfcService.this.enforceNfceeAdminPerm(pkg);
3917 mEeRoutingState = route;
3918 ApplyRoutingTask applyRoutingTask = new ApplyRoutingTask();
3919 applyRoutingTask.execute();
3920 try {
3921 // Block until route is set
3922 applyRoutingTask.get();
3923 } catch (ExecutionException e) {
3924 Log.e(TAG, "failed to set card emulation mode");
3925 } catch (InterruptedException e) {
3926 Log.e(TAG, "failed to set card emulation mode");
3927 }
3928 }
3929
3930 @Override
3931 public void authenticate(String pkg, byte[] token) throws RemoteException {
3932 NfcService.this.enforceNfceeAdminPerm(pkg);
3933 }
3934
3935 @Override
3936 public String getDriverName(String pkg) throws RemoteException {
3937 NfcService.this.enforceNfceeAdminPerm(pkg);
3938 return mDeviceHost.getName();
3939 }
3940
3941 }
3942 final class NxpNfcAdapterExtrasService extends INxpNfcAdapterExtras.Stub {
3943 private Bundle writeNoException() {
3944 Bundle p = new Bundle();
3945 p.putInt("e", 0);
3946 return p;
3947 }
3948
3949 private Bundle writeEeException(int exceptionType, String message) {
3950 Bundle p = new Bundle();
3951 p.putInt("e", exceptionType);
3952 p.putString("m", message);
3953 return p;
3954 }
nxpandroid64fd68c2015-09-23 16:45:15 +05303955
nxpandroid5d64ce92016-11-18 19:48:53 +05303956 @Override
3957 public boolean eSEChipReset(String pkg) throws RemoteException {
3958 NfcService.this.enforceNfceeAdminPerm(pkg);
3959 Bundle result;
3960 boolean stat = false;
3961 try {
3962 synchronized (NfcService.this) {
3963 if (!isNfcEnabledOrShuttingDown()) {
3964 throw new IOException("NFC adapter is disabled");
3965 }
3966 if (mOpenEe == null) {
3967 throw new IOException("NFC EE closed");
3968 }
3969 stat = mSecureElement.doeSEChipReset();
3970 }
3971 result = writeNoException();
3972 } catch (IOException e) {
3973 result = writeEeException(EE_ERROR_IO, e.getMessage());
3974 }
3975 return stat;
3976 }
3977
3978 @Override
nxpandroid64fd68c2015-09-23 16:45:15 +05303979 public boolean reset(String pkg) throws RemoteException {
3980 NfcService.this.enforceNfceeAdminPerm(pkg);
3981 Bundle result;
3982 boolean stat = false;
3983 try {
3984 stat = _nfcEeReset();
3985 result = writeNoException();
3986 } catch (IOException e) {
3987 result = writeEeException(EE_ERROR_IO, e.getMessage());
3988 }
3989 Log.d(TAG,"reset" + stat);
3990 return stat;
3991 }
3992
3993 boolean _nfcEeReset() throws IOException {
3994 synchronized (NfcService.this) {
3995 if (!isNfcEnabledOrShuttingDown()) {
3996 throw new IOException("NFC adapter is disabled");
3997 }
3998 if (mOpenEe == null) {
3999 throw new IOException("NFC EE closed");
4000 }
4001 return mSecureElement.doReset(mOpenEe.handle);
4002 }
4003 }
4004
4005 @Override
4006 public int getSecureElementTechList(String pkg) throws RemoteException {
4007 NfcService.this.enforceNfceeAdminPerm(pkg);
4008 return mDeviceHost.doGetSecureElementTechList();
4009 }
4010
4011 @Override
4012 public byte[] getSecureElementUid(String pkg) throws RemoteException {
4013 NfcService.this.enforceNfceeAdminPerm(pkg);
4014 return mDeviceHost.getSecureElementUid();
4015 }
4016
4017 @Override
4018 public void notifyCheckCertResult(String pkg, boolean success)
4019 throws RemoteException {
4020 if (DBG) Log.d(TAG, "notifyCheckCertResult() " + pkg + ", success=" + success);
4021
4022 NfcService.this.enforceNfceeAdminPerm(pkg);
nxpandroid64fd68c2015-09-23 16:45:15 +05304023 mNxpNfcController.setResultForX509Certificates(success);
nxpandroid64fd68c2015-09-23 16:45:15 +05304024 }
4025
4026 @Override
4027 public void deliverSeIntent(String pkg, Intent seIntent)
4028 throws RemoteException {
4029 Log.d(TAG, "deliverSeIntent() " + pkg + " " + seIntent.getAction());
4030 NfcService.this.enforceNfceeAdminPerm(pkg);
nxpandroid64fd68c2015-09-23 16:45:15 +05304031 sendMessage(MSG_SE_DELIVER_INTENT, seIntent);
4032 }
4033
4034 @Override
4035 public byte[] doGetRouting() throws RemoteException {
4036 return mDeviceHost.doGetRouting();
4037 }
4038
4039 @Override
4040 public Bundle getAtr(String pkg) throws RemoteException {
4041 NfcService.this.enforceNfceeAdminPerm(pkg);
4042
4043 Bundle result;
4044 byte[] out;
4045 try {
4046 out = _getAtr();
4047 result = writeNoException();
4048 result.putByteArray("out", out);
4049 } catch (IOException e) {
4050 result = writeEeException(EE_ERROR_IO, e.getMessage());
4051 }
4052 Log.d(TAG,"getAtr result " + result);
4053 return result;
4054 }
4055
4056 private byte[] _getAtr() throws IOException {
4057 synchronized(NfcService.this) {
4058 if (!isNfcEnabled()) {
4059 throw new IOException("NFC is not enabled");
4060 }
4061 if (mOpenEe == null) {
4062 throw new IOException("NFC EE is not open");
4063 }
4064 if (getCallingPid() != mOpenEe.pid) {
4065 throw new SecurityException("Wrong PID");
4066 }
4067 }
4068 return mSecureElement.doGetAtr(mOpenEe.handle);
4069 }
nxpandroid34627bd2016-05-27 15:52:30 +05304070 @Override
4071 public int selectUicc(int uiccSlot) throws RemoteException {
4072 synchronized(NfcService.this) {
4073 if (!isNfcEnabled()) {
4074 throw new RemoteException("NFC is not enabled");
4075 }
4076 int status = mDeviceHost.doselectUicc(uiccSlot);
4077 Log.i(TAG, "Update routing table");
4078 /*In case of UICC connected and Enabled or Removed ,
4079 *Reconfigure the routing table based on current UICC parameters
4080 **/
4081 if((status == 0x00)||(status == 0x01))
4082 {
nxpandroidebf53fb2016-12-22 18:48:59 +05304083 mPrefsEditor.putInt(PREF_CUR_SELECTED_UICC_ID, uiccSlot);
4084 mPrefsEditor.apply();
nxpandroid34627bd2016-05-27 15:52:30 +05304085 if((mAidRoutingManager != null) && (mCardEmulationManager != null))
4086 {
4087 Log.i(TAG, "Update routing table");
4088 mAidRoutingManager.onNfccRoutingTableCleared();
nxpandroid810c4772017-04-10 18:28:54 +05304089 mIsRoutingTableDirty = true;
nxpandroid34627bd2016-05-27 15:52:30 +05304090 mCardEmulationManager.onNfcEnabled();
nxpandroid34627bd2016-05-27 15:52:30 +05304091 }
4092 else
4093 {
4094 Log.i(TAG, "Update only Mifare and Desfire route");
4095 mIsRoutingTableDirty = true;
4096 applyRouting(false);
4097 }
4098 }
4099 return status;
4100 }
4101 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304102
nxpandroid34627bd2016-05-27 15:52:30 +05304103 @Override
4104 public int getSelectedUicc() throws RemoteException {
4105 if (!isNfcEnabled()) {
4106 throw new RemoteException("NFC is not enabled");
4107 }
4108 return mDeviceHost.doGetSelectedUicc();
4109 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304110
nxpandroid7d44e572016-08-01 19:11:04 +05304111 @Override
4112 public Bundle openuicc(String pkg, IBinder b) throws RemoteException {
4113 NfcService.this.enforceNfceeAdminPerm(pkg);
4114
4115 Bundle result;
4116 int handle = _openuicc(b);
4117 if (handle < 0) {
4118 result = writeEeException(handle, "NFCEE UICC open exception.");
4119 } else {
4120 result = writeNoException();
4121 }
4122 return result;
4123 }
4124
4125 /**
4126 * Opens a connection to the UICC element.
4127 *
4128 * @return A handle with a value >= 0 in case of success, or a
4129 * negative value in case of failure.
4130 */
4131 private int _openuicc(IBinder b) {
4132 synchronized(NfcService.this) {
4133 if (!isNfcEnabled()) {
4134 return EE_ERROR_NFC_DISABLED;
4135 }
4136 if (mInProvisionMode) {
4137 // Deny access to the NFCEE as long as the device is being setup
4138 return EE_ERROR_IO;
4139 }
nxpandroid7d44e572016-08-01 19:11:04 +05304140 if (mOpenEe != null) {
4141 return EE_ERROR_ALREADY_OPEN;
4142 }
4143
4144 boolean restorePolling = false;
4145 if (mNfcPollingEnabled) {
4146 // Disable polling for tags/P2P when connecting to the SMX
4147 // on PN544-based devices. Whenever nfceeClose is called,
4148 // the polling configuration will be restored.
4149 mDeviceHost.disableDiscovery();
4150 mNfcPollingEnabled = false;
4151 restorePolling = true;
4152 }
4153
4154 int handle = doOpenSecureElementConnection(0xF4);
4155 if (handle < 0) {
4156
4157 if (restorePolling) {
4158 mDeviceHost.enableDiscovery(mCurrentDiscoveryParameters, true);
4159 mNfcPollingEnabled = true;
4160 }
4161 return handle;
4162 }
nxpandroid7d44e572016-08-01 19:11:04 +05304163
4164 mOpenEe = new OpenSecureElement(getCallingPid(), handle, b);
4165 try {
4166 b.linkToDeath(mOpenEe, 0);
4167 } catch (RemoteException e) {
4168 mOpenEe.binderDied();
4169 }
4170
4171 // Add the calling package to the list of packages that have accessed
4172 // the secure element.
4173 for (String packageName : mContext.getPackageManager().getPackagesForUid(getCallingUid())) {
4174 mSePackages.add(packageName);
4175 }
4176
4177 return handle;
4178 }
4179 }
4180
4181 @Override
4182 public Bundle closeuicc(String pkg, IBinder binder) throws RemoteException {
4183 NfcService.this.enforceNfceeAdminPerm(pkg);
4184
4185 Bundle result;
4186 try {
4187 Log.w("Nxp", "Close UICC!");
4188 _nfcEeClose(getCallingPid(), binder);
4189 result = writeNoException();
4190 } catch (IOException e) {
4191 result = writeEeException(EE_ERROR_IO, e.getMessage());
4192 }
4193 return result;
4194 }
4195
4196 @Override
4197 public Bundle transceiveuicc(String pkg, byte[] in) throws RemoteException {
4198 NfcService.this.enforceNfceeAdminPerm(pkg);
4199
4200 Bundle result;
4201 byte[] out;
4202 try {
4203 out = _transceiveuicc(in);
4204 result = writeNoException();
4205 result.putByteArray("out", out);
4206 } catch (IOException e) {
4207 result = writeEeException(EE_ERROR_IO, e.getMessage());
4208 }
4209 return result;
4210 }
4211
4212 private byte[] _transceiveuicc(byte[] data) throws IOException {
4213 synchronized(NfcService.this) {
4214 if (!isNfcEnabled()) {
4215 throw new IOException("NFC is not enabled");
4216 }
4217 if (mOpenEe == null) {
4218 throw new IOException("NFC EE is not open");
4219 }
4220 if (getCallingPid() != mOpenEe.pid) {
4221 throw new SecurityException("Wrong PID");
4222 }
4223 }
4224
4225 return doTransceive(mOpenEe.handle, data);
4226 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304227 }
4228
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05304229 final class NfcWiredSe extends ISecureElement.Stub {
4230
4231 int mNfcWiredSeHandle = 0;
4232 byte mOpenedchannelCount = 0;
Nikhil Chhabraf9453292018-04-18 11:18:35 +05304233 boolean mIsSecureElementOpened = false;
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05304234
Nikhil Chhabraf9453292018-04-18 11:18:35 +05304235 private void closeNfcWiredSeService() {
4236 if (mSecureElementclientCallback != null) {
4237 try {
4238 mSecureElementclientCallback.onStateChange(false);
4239 } catch (RemoteException re) {
4240 Log.e(TAG, "Exception while executing NfcWiredSe callback");
4241 }
4242 }
4243 mNfcSeService.nfcWiredSeDeInit();
4244 mNfcSeService.mOpenedchannelCount = 0;
4245 mSecureElementclientCallback = null;
4246 }
4247
4248 private boolean isSecureElementPresent(int secureElementId) {
4249 int[] seList = mDeviceHost.doGetSecureElementList();
4250 boolean isSePresent = false;
4251 for (int i = 0; i < seList.length; i++) {
4252 if (seList[i] == secureElementId) {
4253 isSePresent = true;
4254 break;
4255 }
4256 }
4257 return isSePresent;
4258 }
4259
4260 private byte nfcWiredSeDeInit() {
4261 if (mIsSecureElementOpened) {
4262 doDisconnect(mNfcWiredSeHandle);
4263 }
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05304264 mNfcWiredSeHandle = 0;
4265 mIsSecureElementOpened = false;
4266 return SecureElementStatus.SUCCESS;
4267 }
4268
4269 @Override
4270 public byte closeChannel(byte channelNumber) throws android.os.RemoteException {
4271 byte status = SecureElementStatus.FAILED;
4272 if(channelNumber < DEFAULT_BASIC_CHANNEL ||
4273 channelNumber >= MAX_LOGICAL_CHANNELS) {
4274 status = SecureElementStatus.FAILED;
4275 } else if(channelNumber > DEFAULT_BASIC_CHANNEL) {
4276 byte[] closeCommand = new byte[5];
4277 closeCommand[0] = channelNumber;
4278 closeCommand[1] = (byte)0x70;
4279 closeCommand[2] = (byte)0x80;
4280 closeCommand[3] = channelNumber;
4281 closeCommand[4] = 0x00;
4282 byte[] resp = doTransceive(mNfcWiredSeHandle, closeCommand);
4283 if (resp == null || resp.length < 0) {
4284 Log.e(TAG, "WiredSe: error in close channel: IO Error");
4285 status = SecureElementStatus.IOERROR;
4286 } else if(resp[resp.length - 2] == (byte)0x90 &&
4287 resp[resp.length - 1] == (byte)0x00) {
4288 status = SecureElementStatus.SUCCESS;
4289 } else {
4290 Log.e(TAG, "WiredSe: error in close channel: "+Arrays.toString(resp));
4291 status = SecureElementStatus.FAILED;
4292 }
4293 }
4294
4295 if ((channelNumber == DEFAULT_BASIC_CHANNEL) ||
4296 (status == SecureElementStatus.SUCCESS)) {
4297 mOpenedchannelCount--;
4298 /*If there are no channels remaining close secureElement*/
4299 if (mOpenedchannelCount == 0) {
4300 Log.e(TAG, "WiredSe: channel count is 0, deinit wired se");
4301 status = nfcWiredSeDeInit();
4302 } else {
4303 status = SecureElementStatus.SUCCESS;
4304 }
4305 }
4306 return status;
4307 }
4308
4309 @Override
4310 public void openBasicChannel(java.util.ArrayList<Byte> aid, byte p2, openBasicChannelCallback _hidl_cb)
4311 throws android.os.RemoteException {
4312 if(!mIsSecureElementOpened) {
4313 mNfcWiredSeHandle = doOpenSecureElementConnection(0xF3);
4314 if (mNfcWiredSeHandle < 0) {
4315 Log.e(TAG, "open secure element fails.");
4316 mNfcWiredSeHandle = 0;
4317 _hidl_cb.onValues(null, SecureElementStatus.IOERROR);
4318 return;
4319 } else {
4320 mIsSecureElementOpened = true;
4321 }
4322 }
4323 byte[] selectCommand = new byte[5 + aid.size()];
4324 selectCommand[0] = 0x00;
4325 selectCommand[1] = (byte) 0xA4;
4326 selectCommand[2] = 0x04;
4327 selectCommand[3] = 0x00; // next occurrence
4328 selectCommand[4] = (byte) aid.size();
4329 System.arraycopy(arrayListToByteArray(aid), 0, selectCommand, 5, aid.size());
4330
4331 byte[] resp = doTransceive(mNfcWiredSeHandle, selectCommand);
4332 byte status = SecureElementStatus.FAILED;
4333 if(resp == null || resp.length < 0) {
4334 Log.e(TAG, "WiredSe: error in open basic channel : IO Error");
4335 status = SecureElementStatus.IOERROR;
4336 return;
4337 } else if(resp[resp.length - 2] == (byte)0x90 &&
4338 resp[resp.length - 1] == (byte)0x00) {
4339 mOpenedchannelCount++;
4340 status = SecureElementStatus.SUCCESS;
4341 } else if(resp[resp.length - 2] == (byte)0x6A &&
4342 resp[resp.length - 1] == (byte)0x82) {
4343 status = SecureElementStatus.NO_SUCH_ELEMENT_ERROR;
4344 } else if(resp[resp.length - 2] == (byte)0x6A &&
4345 resp[resp.length - 1] == (byte)0x86) {
4346 status = SecureElementStatus.UNSUPPORTED_OPERATION;
4347 } else {
4348 Log.e(TAG, "WiredSe: open basic channel failed, response: "+Arrays.toString(resp));
4349 status = SecureElementStatus.FAILED;
4350 }
4351 if (status != SecureElementStatus.SUCCESS) {
4352 if(mOpenedchannelCount > DEFAULT_BASIC_CHANNEL) {
4353 closeChannel((byte)DEFAULT_BASIC_CHANNEL);
4354 }
4355 }
4356 _hidl_cb.onValues(byteArrayToArrayList(resp), (byte)status);
4357 return;
4358 }
4359
4360 @Override
4361 public void openLogicalChannel(java.util.ArrayList<Byte> aid,
4362 byte p1, openLogicalChannelCallback _hidl_cb)
4363 throws android.os.RemoteException {
4364 if(!mIsSecureElementOpened) {
4365 Log.i(TAG, "WiredSe: Opening SecureElementConnection");
4366 mNfcWiredSeHandle = doOpenSecureElementConnection(0xF3);
4367 if (mNfcWiredSeHandle < 0) {
Nikhil Chhabraf9453292018-04-18 11:18:35 +05304368 Log.e(TAG, "open secure element fails.");
4369 mNfcWiredSeHandle = 0;
4370 _hidl_cb.onValues(null, SecureElementStatus.IOERROR);
4371 return;
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05304372 } else {
4373 mIsSecureElementOpened = true;
4374 }
4375 }
4376 /* Send Manage channel command */
4377 byte[] manageChannelCommand = {0x00, 0x70, 0x00, 0x00, 0x01};
4378 byte[] respManageChannel = doTransceive(mNfcWiredSeHandle, manageChannelCommand);
4379 byte status = SecureElementStatus.FAILED;
4380 LogicalChannelResponse logicalChannelResp = new LogicalChannelResponse();
4381 logicalChannelResp.channelNumber = (byte) 0;/* To be modified after Manage Channel command*/
4382 if (respManageChannel == null || respManageChannel.length < 0) {
4383 Log.e(TAG, "WiredSe: error in open logical channel : IO Error");
4384 status = SecureElementStatus.IOERROR;
4385 logicalChannelResp.channelNumber = INVALID_LOGICAL_CHANNEL;
4386 return;
4387 } else if(respManageChannel[respManageChannel.length - 2] == (byte)0x6A &&
4388 respManageChannel[respManageChannel.length - 1] == (byte)0x81) {
4389 Log.e(TAG, "WiredSe: error in open logical channel : Channel Not Available");
4390 status = SecureElementStatus.CHANNEL_NOT_AVAILABLE;
4391 logicalChannelResp.channelNumber = INVALID_LOGICAL_CHANNEL;
4392 return;
4393 } else if(respManageChannel[respManageChannel.length - 2] == (byte)0x90 &&
4394 respManageChannel[respManageChannel.length - 1] ==(byte) 0x00) {
4395 logicalChannelResp.channelNumber = respManageChannel[0];
4396 mOpenedchannelCount++;
4397 status = SecureElementStatus.SUCCESS;
4398 } else if(((respManageChannel[respManageChannel.length - 2] == (byte)0x6E) ||
4399 (respManageChannel[respManageChannel.length - 2] == (byte)0x6D)) &&
4400 respManageChannel[respManageChannel.length - 1] == 0x00) {
4401 Log.e(TAG, "WiredSe: error in open logical channel : Unsupported operation");
4402 status = SecureElementStatus.UNSUPPORTED_OPERATION;
4403 logicalChannelResp.channelNumber = INVALID_LOGICAL_CHANNEL;
4404 }
4405
4406 if(status != SecureElementStatus.SUCCESS) {
4407 Log.e(TAG, "WiredSe: error in open logical channel : manage channel command failed");
4408 _hidl_cb.onValues(null, status);
4409 return;
4410 }
4411 byte[] selectCommand = new byte[5 + aid.size()];
4412 logicalChannelResp.channelNumber = respManageChannel[0];
4413 selectCommand[0] = respManageChannel[0];
4414 selectCommand[1] = (byte) 0xA4;
4415 selectCommand[2] = 0x04;
4416 selectCommand[3] = 0x00; // next occurrence
4417 selectCommand[4] = (byte) aid.size();
4418 System.arraycopy(arrayListToByteArray(aid), 0, selectCommand, 5, aid.size());
4419 byte[] resp = doTransceive(mNfcWiredSeHandle, selectCommand);
4420 byte sestatus = SecureElementStatus.FAILED;
4421 if(resp[resp.length - 2] == (byte)0x90 &&
4422 resp[resp.length - 1] == (byte)0x00) {
4423 sestatus = SecureElementStatus.SUCCESS;
4424 } else if(resp[resp.length - 2] == (byte)0x6A &&
4425 resp[resp.length - 1] == (byte)0x82) {
4426 sestatus = SecureElementStatus.NO_SUCH_ELEMENT_ERROR;
4427 } else if(resp[resp.length - 2] == (byte)0x6A &&
4428 resp[resp.length - 1] == (byte)0x86) {
4429 sestatus = SecureElementStatus.UNSUPPORTED_OPERATION;
4430 }
4431 if (sestatus != SecureElementStatus.SUCCESS) {
4432 closeChannel(logicalChannelResp.channelNumber);
4433 }
4434 for(int i=0; i< resp.length; i++) {
4435 logicalChannelResp.selectResponse.add(resp[i]);
4436 }
4437 _hidl_cb.onValues(logicalChannelResp, sestatus);
4438 return;
4439 }
4440
4441 @Override
4442 public java.util.ArrayList<Byte> transmit(java.util.ArrayList<Byte> data)
4443 throws android.os.RemoteException {
4444 if (mNfcWiredSeHandle < 0) {
4445 Log.e(TAG, "WiredSe: Secure Element handle NULL");
4446 return null;
4447 } else {
4448 byte[] resp = doTransceive(mNfcWiredSeHandle, arrayListToByteArray(data));
4449 return byteArrayToArrayList(resp);
4450 }
4451 }
4452
4453 @Override
4454 public boolean isCardPresent()
4455 throws android.os.RemoteException {
Nikhil Chhabraf9453292018-04-18 11:18:35 +05304456 return isSecureElementPresent(SMART_MX_ID_TYPE);
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05304457 }
4458
4459 @Override
4460 public java.util.ArrayList<Byte> getAtr()
4461 throws android.os.RemoteException {
4462 synchronized(NfcService.this) {
4463 return byteArrayToArrayList(mSecureElement.doGetAtr(mNfcWiredSeHandle));
4464 }
4465 }
4466
4467 @Override
4468 public void init(ISecureElementHalCallback clientCallback)
4469 throws android.os.RemoteException {
4470 synchronized(NfcService.this) {
4471 if(clientCallback == null) {
4472 Log.e(TAG, "WiredSe: clientCallback NULL");
4473 return;
4474 }
4475 mSecureElementclientCallback = clientCallback;
4476 mNfcWiredSeHandle = doOpenSecureElementConnection(0xF3);
4477 if (mNfcWiredSeHandle < 0) {
4478 Log.i(TAG, "open secure element fails.");
4479 clientCallback.onStateChange(false);
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05304480 mNfcWiredSeHandle = 0;
4481 } else {
4482 mIsSecureElementOpened = true;
4483 clientCallback.onStateChange(true);
Nikhil Chhabraefd6b092018-04-11 15:28:06 +05304484 Log.i(TAG, "WiredSe: Completed Opening Secure Element");
4485 }
4486 }
4487 return;
4488 }
4489
4490 private ArrayList<Byte> byteArrayToArrayList(byte[] array) {
4491 ArrayList<Byte> list = new ArrayList<Byte>();
4492 int i = 0;
4493 for (Byte b : array) {
4494 list.add(b);
4495 }
4496 return list;
4497 }
4498
4499 private byte[] arrayListToByteArray(ArrayList<Byte> list) {
4500 Byte[] byteArray = list.toArray(new Byte[list.size()]);
4501 int i = 0;
4502 byte[] result = new byte[list.size()];
4503 for (Byte b : byteArray) {
4504 result[i++] = b.byteValue();
4505 }
4506 return result;
4507 }
4508 }
4509
nxpandroid64fd68c2015-09-23 16:45:15 +05304510 /** resources kept while secure element is open */
4511 private class OpenSecureElement implements IBinder.DeathRecipient {
4512 public int pid; // pid that opened SE
4513 // binder handle used for DeathReceipient. Must keep
4514 // a reference to this, otherwise it can get GC'd and
4515 // the binder stub code might create a different BinderProxy
4516 // for the same remote IBinder, causing mismatched
4517 // link()/unlink()
4518 public IBinder binder;
4519 public int handle; // low-level handle
4520 public OpenSecureElement(int pid, int handle, IBinder binder) {
4521 this.pid = pid;
4522 this.handle = handle;
4523 this.binder = binder;
4524 }
4525 @Override
4526 public void binderDied() {
4527 synchronized (NfcService.this) {
4528 Log.i(TAG, "Tracked app " + pid + " died");
4529 pid = -1;
4530 try {
4531 _nfcEeClose(-1, binder);
4532 } catch (IOException e) { /* already closed */ }
4533 }
4534 }
4535 @Override
4536 public String toString() {
4537 return new StringBuilder('@').append(Integer.toHexString(hashCode())).append("[pid=")
4538 .append(pid).append(" handle=").append(handle).append("]").toString();
4539 }
4540 }
4541
4542 boolean isNfcEnabledOrShuttingDown() {
4543 synchronized (this) {
4544 return (mState == NfcAdapter.STATE_ON || mState == NfcAdapter.STATE_TURNING_OFF);
4545 }
4546 }
4547
4548 boolean isNfcEnabled() {
4549 synchronized (this) {
4550 return mState == NfcAdapter.STATE_ON;
4551 }
4552 }
4553
4554 class WatchDogThread extends Thread {
4555 final Object mCancelWaiter = new Object();
4556 final int mTimeout;
4557 boolean mCanceled = false;
4558
4559 public WatchDogThread(String threadName, int timeout) {
4560 super(threadName);
4561 mTimeout = timeout;
4562 }
4563
4564 @Override
4565 public void run() {
4566 try {
4567 synchronized (mCancelWaiter) {
4568 mCancelWaiter.wait(mTimeout);
4569 if (mCanceled) {
4570 return;
4571 }
4572 }
4573 } catch (InterruptedException e) {
4574 // Should not happen; fall-through to abort.
4575 Log.w(TAG, "Watchdog thread interruped.");
4576 interrupt();
4577 }
4578 Log.e(TAG, "Watchdog triggered, aborting.");
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304579 mDeviceHost.doAbort(getName());
nxpandroid64fd68c2015-09-23 16:45:15 +05304580 }
4581
4582 public synchronized void cancel() {
4583 synchronized (mCancelWaiter) {
4584 mCanceled = true;
4585 mCancelWaiter.notify();
4586 }
4587 }
4588 }
4589
4590 /* For Toast from background process*/
4591
4592 public class ToastHandler
4593 {
4594 // General attributes
4595 private Context mContext;
4596 private Handler mHandler;
4597
4598 public ToastHandler(Context _context)
4599 {
4600 this.mContext = _context;
4601 this.mHandler = new Handler();
4602 }
4603
4604 /**
4605 * Runs the <code>Runnable</code> in a separate <code>Thread</code>.
4606 *
4607 * @param _runnable
4608 * The <code>Runnable</code> containing the <code>Toast</code>
4609 */
4610 private void runRunnable(final Runnable _runnable)
4611 {
4612 Thread thread = new Thread()
4613 {
4614 public void run()
4615 {
4616 mHandler.post(_runnable);
4617 }
4618 };
4619
4620 thread.start();
4621 thread.interrupt();
4622 thread = null;
4623 }
4624
4625 public void showToast(final CharSequence _text, final int _duration)
4626 {
4627 final Runnable runnable = new Runnable()
4628 {
4629 @Override
4630 public void run()
4631 {
4632 Toast.makeText(mContext, _text, _duration).show();
4633 }
4634 };
4635
4636 runRunnable(runnable);
4637 }
4638 }
4639
4640 static byte[] hexStringToBytes(String s) {
4641 if (s == null || s.length() == 0) return null;
4642 int len = s.length();
4643 if (len % 2 != 0) {
4644 s = '0' + s;
4645 len++;
4646 }
4647 byte[] data = new byte[len / 2];
4648 for (int i = 0; i < len; i += 2) {
4649 data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
4650 + Character.digit(s.charAt(i + 1), 16));
4651 }
4652 return data;
4653 }
4654
4655 static String toHexString(byte[] buffer, int offset, int length) {
nxpandroid281eb922016-08-25 20:27:46 +05304656 final char[] hexChars = "0123456789abcdef".toCharArray();
nxpandroid64fd68c2015-09-23 16:45:15 +05304657 char[] chars = new char[2 * length];
4658 for (int j = offset; j < offset + length; ++j) {
nxpandroid281eb922016-08-25 20:27:46 +05304659 chars[2 * (j-offset)] = hexChars[(buffer[j] & 0xF0) >>> 4];
4660 chars[2 * (j-offset) + 1] = hexChars[buffer[j] & 0x0F];
nxpandroid64fd68c2015-09-23 16:45:15 +05304661 }
4662 return new String(chars);
4663 }
4664
4665 /**
4666 * Read mScreenState and apply NFC-C polling and NFC-EE routing
4667 */
4668 void applyRouting(boolean force) {
4669 Log.d(TAG, "applyRouting - enter force = " + force + " mScreenState = " + mScreenState);
4670
4671 synchronized (this) {
4672 //Since Reader mode during wired mode is supported
4673 //enableDiscovery or disableDiscovery is allowed
nxpandroid64fd68c2015-09-23 16:45:15 +05304674 if (!isNfcEnabledOrShuttingDown()) {
4675 // PN544 cannot be reconfigured while EE is open
4676 return;
4677 }
4678 WatchDogThread watchDog = new WatchDogThread("applyRouting", ROUTING_WATCHDOG_MS);
4679 if (mInProvisionMode) {
4680 mInProvisionMode = Settings.Secure.getInt(mContentResolver,
4681 Settings.Global.DEVICE_PROVISIONED, 0) == 0;
4682 if (!mInProvisionMode) {
4683 // Notify dispatcher it's fine to dispatch to any package now
4684 // and allow handover transfers.
4685 mNfcDispatcher.disableProvisioningMode();
nxpandroid1153eb32015-11-06 18:46:58 +05304686 /* if provision mode is disabled, then send this info to lower layers as well */
4687 mDeviceHost.doSetProvisionMode(mInProvisionMode);
nxpandroid64fd68c2015-09-23 16:45:15 +05304688 }
4689 }
4690 // Special case: if we're transitioning to unlocked state while
4691 // still talking to a tag, postpone re-configuration.
4692 if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED && isTagPresent()) {
4693 Log.d(TAG, "Not updating discovery parameters, tag connected.");
4694 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESUME_POLLING),
4695 APPLY_ROUTING_RETRY_TIMEOUT_MS);
4696 return;
4697 }
4698
4699 try {
4700 watchDog.start();
4701 // Compute new polling parameters
4702 NfcDiscoveryParameters newParams = computeDiscoveryParameters(mScreenState);
4703 if (force || !newParams.equals(mCurrentDiscoveryParameters)) {
4704 if (newParams.shouldEnableDiscovery()) {
4705 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery();
4706 mDeviceHost.enableDiscovery(newParams, shouldRestart);
4707 } else {
4708 mDeviceHost.disableDiscovery();
4709 }
4710 mCurrentDiscoveryParameters = newParams;
4711 } else {
4712 Log.d(TAG, "Discovery configuration equal, not updating.");
4713 }
4714 } finally {
4715 watchDog.cancel();
4716 }
4717 }
4718 }
4719
4720 private NfcDiscoveryParameters computeDiscoveryParameters(int screenState) {
4721 // Recompute discovery parameters based on screen state
4722 NfcDiscoveryParameters.Builder paramsBuilder = NfcDiscoveryParameters.newBuilder();
nxpandroide66eb092017-07-12 21:36:08 +05304723
nxpandroid64fd68c2015-09-23 16:45:15 +05304724 // Polling
nxpandroid5d64ce92016-11-18 19:48:53 +05304725 if ((screenState >= NFC_POLLING_MODE)||mIsTaskBoot) {
nxpandroid64fd68c2015-09-23 16:45:15 +05304726 // Check if reader-mode is enabled
4727 if (mReaderModeParams != null) {
4728 int techMask = 0;
4729 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_A) != 0)
4730 techMask |= NFC_POLL_A;
4731 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_B) != 0)
4732 techMask |= NFC_POLL_B;
4733 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_F) != 0)
4734 techMask |= NFC_POLL_F;
4735 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_V) != 0)
Nikhil Chhabra288edb02018-01-10 19:36:21 +05304736 techMask |= NFC_POLL_V;
nxpandroid64fd68c2015-09-23 16:45:15 +05304737 if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_BARCODE) != 0)
4738 techMask |= NFC_POLL_KOVIO;
4739
4740 paramsBuilder.setTechMask(techMask);
4741 paramsBuilder.setEnableReaderMode(true);
4742 } else {
4743 paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT);
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304744 paramsBuilder.setEnableP2p(true);
nxpandroid64fd68c2015-09-23 16:45:15 +05304745 }
nxpandroide66eb092017-07-12 21:36:08 +05304746 }
4747 if ((screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mInProvisionMode) &&
4748 !mNfcUnlockManager.isLockscreenPollingEnabled()) {
4749 if (mReaderModeParams != null)
nxpandroid64fd68c2015-09-23 16:45:15 +05304750 paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT);
4751 // enable P2P for MFM/EDU/Corp provisioning
4752 paramsBuilder.setEnableP2p(true);
nxpandroide66eb092017-07-12 21:36:08 +05304753 } else if ((screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED) &&
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304754 (mIsLiveCaseEnabled || mNfcUnlockManager.isLockscreenPollingEnabled())) {
4755 int techMask = 0;
4756 // enable polling for Live Case technologies
4757 if (mIsLiveCaseEnabled)
4758 techMask |= mLiveCaseTechnology;
4759 if (mNfcUnlockManager.isLockscreenPollingEnabled())
nxpandroide66eb092017-07-12 21:36:08 +05304760 {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304761 techMask |= mNfcUnlockManager.getLockscreenPollMask();
nxpandroide66eb092017-07-12 21:36:08 +05304762 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304763 paramsBuilder.setTechMask(techMask);
nxpandroid64fd68c2015-09-23 16:45:15 +05304764 paramsBuilder.setEnableLowPowerDiscovery(false);
4765 paramsBuilder.setEnableP2p(false);
4766 }
4767
Suhas Sureshca6584b2018-04-27 17:17:22 +05304768 if (mIsHceCapable && mReaderModeParams == null) {
Nikhil Chhabrae1d07ba2018-01-10 11:33:17 +05304769 // Host routing is always enabled at lock screen or later, provided we aren't in reader mode
4770 paramsBuilder.setEnableHostRouting(true);
4771 }
4772
nxpandroid64fd68c2015-09-23 16:45:15 +05304773 //To make routing table update.
4774 if(mIsRoutingTableDirty) {
4775 mIsRoutingTableDirty = false;
nxpandroida9a68ba2016-01-14 21:12:17 +05304776 int protoRoute = mNxpPrefs.getInt("PREF_MIFARE_DESFIRE_PROTO_ROUTE_ID", GetDefaultMifareDesfireRouteEntry());
4777 int defaultRoute=mNxpPrefs.getInt("PREF_SET_DEFAULT_ROUTE_ID", GetDefaultRouteEntry());
4778 int techRoute=mNxpPrefs.getInt("PREF_MIFARE_CLT_ROUTE_ID", GetDefaultMifateCLTRouteEntry());
nxpandroid281eb922016-08-25 20:27:46 +05304779 if (DBG) Log.d(TAG, "Set default Route Entry");
nxpandroid64fd68c2015-09-23 16:45:15 +05304780 setDefaultRoute(defaultRoute, protoRoute, techRoute);
4781 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304782
nxpandroid64fd68c2015-09-23 16:45:15 +05304783 return paramsBuilder.build();
4784 }
4785
4786 private boolean isTagPresent() {
4787 for (Object object : mObjectMap.values()) {
4788 if (object instanceof TagEndpoint) {
4789 return ((TagEndpoint) object).isPresent();
4790 }
4791 }
4792 return false;
4793 }
Suhas Suresh5efc5432018-04-27 15:31:02 +05304794
4795 private void StopPresenceChecking() {
4796 Object[] objectValues = mObjectMap.values().toArray();
4797 for (Object object : objectValues) {
4798 if (object instanceof TagEndpoint) {
4799 TagEndpoint tag = (TagEndpoint)object;
4800 ((TagEndpoint) object).stopPresenceChecking();
4801 }
4802 }
4803 }
4804
nxpandroid64fd68c2015-09-23 16:45:15 +05304805 /**
4806 * Disconnect any target if present
4807 */
4808 void maybeDisconnectTarget() {
4809 if (!isNfcEnabledOrShuttingDown()) {
4810 return;
4811 }
4812 Object[] objectsToDisconnect;
4813 synchronized (this) {
4814 Object[] objectValues = mObjectMap.values().toArray();
4815 // Copy the array before we clear mObjectMap,
4816 // just in case the HashMap values are backed by the same array
4817 objectsToDisconnect = Arrays.copyOf(objectValues, objectValues.length);
4818 mObjectMap.clear();
4819 }
4820 for (Object o : objectsToDisconnect) {
4821 if (DBG) Log.d(TAG, "disconnecting " + o.getClass().getName());
4822 if (o instanceof TagEndpoint) {
4823 // Disconnect from tags
4824 TagEndpoint tag = (TagEndpoint) o;
4825 tag.disconnect();
4826 } else if (o instanceof NfcDepEndpoint) {
4827 // Disconnect from P2P devices
4828 NfcDepEndpoint device = (NfcDepEndpoint) o;
4829 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) {
4830 // Remote peer is target, request disconnection
4831 device.disconnect();
4832 } else {
4833 // Remote peer is initiator, we cannot disconnect
4834 // Just wait for field removal
4835 }
4836 }
4837 }
4838 }
4839
4840 Object findObject(int key) {
4841 synchronized (this) {
4842 Object device = mObjectMap.get(key);
4843 if (device == null) {
4844 Log.w(TAG, "Handle not found");
4845 }
4846 return device;
4847 }
4848 }
4849
nxpandroid281eb922016-08-25 20:27:46 +05304850 Object findAndRemoveObject(int handle) {
4851 synchronized (this) {
4852 Object device = mObjectMap.get(handle);
4853 if (device == null) {
4854 Log.w(TAG, "Handle not found");
4855 } else {
4856 mObjectMap.remove(handle);
4857 }
4858 return device;
4859 }
4860 }
4861
nxpandroid64fd68c2015-09-23 16:45:15 +05304862 void registerTagObject(TagEndpoint tag) {
4863 synchronized (this) {
4864 mObjectMap.put(tag.getHandle(), tag);
4865 }
4866 }
4867
4868 void unregisterObject(int handle) {
4869 synchronized (this) {
4870 mObjectMap.remove(handle);
4871 }
4872 }
4873
4874 /**
4875 * For use by code in this process
4876 */
4877 public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength)
4878 throws LlcpException {
4879 return mDeviceHost.createLlcpSocket(sap, miu, rw, linearBufferLength);
4880 }
4881
4882 /**
4883 * For use by code in this process
4884 */
4885 public LlcpConnectionlessSocket createLlcpConnectionLessSocket(int sap, String sn)
4886 throws LlcpException {
4887 return mDeviceHost.createLlcpConnectionlessSocket(sap, sn);
4888 }
4889
4890 /**
4891 * For use by code in this process
4892 */
4893 public LlcpServerSocket createLlcpServerSocket(int sap, String sn, int miu, int rw,
4894 int linearBufferLength) throws LlcpException {
4895 return mDeviceHost.createLlcpServerSocket(sap, sn, miu, rw, linearBufferLength);
4896 }
4897
4898 public void sendMockNdefTag(NdefMessage msg) {
4899 sendMessage(MSG_MOCK_NDEF, msg);
4900 }
4901
4902 public void notifyRoutingTableFull()
4903 {
nxpandroidebf53fb2016-12-22 18:48:59 +05304904 if(!mNxpNfcController.isGsmaCommitOffhostService()) {
4905 ComponentName prevPaymentComponent = mAidCache.getPreviousPreferredPaymentService();
4906
4907 mNxpPrefsEditor = mNxpPrefs.edit();
4908 mNxpPrefsEditor.putInt("PREF_SET_AID_ROUTING_TABLE_FULL",0x01);
4909 mNxpPrefsEditor.commit();
4910 //broadcast Aid Routing Table Full intent to the user
4911 Intent aidTableFull = new Intent();
4912 aidTableFull.putExtra(NxpConstants.EXTRA_GSMA_PREV_PAYMENT_COMPONENT,prevPaymentComponent);
4913 aidTableFull.setAction(NxpConstants.ACTION_ROUTING_TABLE_FULL);
4914 if (DBG) {
4915 Log.d(TAG, "notify aid routing table full to the user");
4916 }
4917 mContext.sendBroadcastAsUser(aidTableFull, UserHandle.CURRENT);
4918 mAidCache.setPreviousPreferredPaymentService(null);
nxpandroid64fd68c2015-09-23 16:45:15 +05304919 }
nxpandroid64fd68c2015-09-23 16:45:15 +05304920 }
4921 /**
4922 * set default Aid route entry in case application does not configure this route entry
4923 */
nxpandroidebf53fb2016-12-22 18:48:59 +05304924 public void setDefaultAidRouteLoc( int routeLoc)
nxpandroid64fd68c2015-09-23 16:45:15 +05304925 {
nxpandroida9a68ba2016-01-14 21:12:17 +05304926 mNxpPrefsEditor = mNxpPrefs.edit();
nxpandroidebf53fb2016-12-22 18:48:59 +05304927 Log.d(TAG, "writing to preferences setDefaultAidRouteLoc :" + routeLoc);
4928
4929 int defaultAidRoute = ((mDeviceHost.getDefaultAidPowerState() & 0x1F) | (routeLoc << ROUTE_LOC_MASK));
4930 if(routeLoc == 0x00)
4931 {
4932 /*
4933 bit pos 1 = Power Off
4934 bit pos 2 = Battery Off
4935 bit pos 4 = Screen Off
4936 Set these bits to 0 because in case routeLoc = HOST it can not work on POWER_OFF, BATTERY_OFF and SCREEN_OFF*/
4937 defaultAidRoute &= 0xE9;
4938 }
4939
4940 mNxpPrefsEditor.putInt("PREF_SET_DEFAULT_ROUTE_ID", defaultAidRoute);
nxpandroida9a68ba2016-01-14 21:12:17 +05304941 mNxpPrefsEditor.commit();
4942 int defaultRoute=mNxpPrefs.getInt("PREF_SET_DEFAULT_ROUTE_ID",0xFF);
nxpandroid64fd68c2015-09-23 16:45:15 +05304943 Log.d(TAG, "reading preferences from user :" + defaultRoute);
4944 }
4945
4946 public int getAidRoutingTableSize ()
4947 {
4948 int aidTableSize = 0x00;
4949 aidTableSize = mDeviceHost.getAidTableSize();
4950 return aidTableSize;
4951 }
4952
nxpandroidcbf24822017-07-12 21:37:17 +05304953 public void routeAids(String aid, int route, int powerState, int aidInfo) {
nxpandroid64fd68c2015-09-23 16:45:15 +05304954 Message msg = mHandler.obtainMessage();
4955 msg.what = MSG_ROUTE_AID;
4956 msg.arg1 = route;
4957 msg.arg2 = powerState;
nxpandroidcbf24822017-07-12 21:37:17 +05304958 Bundle aidbundle = new Bundle();
4959 aidbundle.putInt("aidinfo",aidInfo);
4960 msg.setData(aidbundle);
nxpandroid64fd68c2015-09-23 16:45:15 +05304961 msg.obj = aid;
4962 mHandler.sendMessage(msg);
4963 }
4964
4965 public void unrouteAids(String aid) {
4966 sendMessage(MSG_UNROUTE_AID, aid);
4967 }
nxpandroida5fd6622017-07-31 16:15:18 +05304968
4969 public void routeApduPattern(String apdu, String mask ,int route, int powerState) {
4970 Message msg = mHandler.obtainMessage();
4971 msg.what = MSG_ROUTE_APDU;
4972 msg.arg1 = route;
4973 msg.arg2 = powerState;
4974 Bundle apduPatternbundle = new Bundle();
4975 apduPatternbundle.putString("apduData",apdu);
4976 apduPatternbundle.putString("apduMask",mask);
4977 msg.setData(apduPatternbundle);
4978 mHandler.sendMessage(msg);
4979 }
4980
4981 public void unrouteApduPattern(String apdu) {
4982 //sendMessage(MSG_UNROUTE_APDU, apdu);
4983 mDeviceHost.unrouteApduPattern(hexStringToBytes(apdu));
4984 }
4985
nxpandroide66eb092017-07-12 21:36:08 +05304986 public int getNciVersion() {
4987 return mDeviceHost.getNciVersion();
4988 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304989 private byte[] getT3tIdentifierBytes(String systemCode, String nfcId2, String t3tPmm) {
4990 ByteBuffer buffer = ByteBuffer.allocate(2 + 8 + 8);
nxpandroid34627bd2016-05-27 15:52:30 +05304991 buffer.put(hexStringToBytes(systemCode));
4992 buffer.put(hexStringToBytes(nfcId2));
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304993 buffer.put(hexStringToBytes(t3tPmm));
nxpandroid34627bd2016-05-27 15:52:30 +05304994 byte[] t3tIdBytes = new byte[buffer.position()];
4995 buffer.position(0);
4996 buffer.get(t3tIdBytes);
nxpandroid6fd9cdb2017-07-12 18:25:41 +05304997
nxpandroid34627bd2016-05-27 15:52:30 +05304998 return t3tIdBytes;
4999 }
5000
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305001 public void registerT3tIdentifier(String systemCode, String nfcId2, String t3tPmm) {
5002 Log.d(TAG, "request to register LF_T3T_IDENTIFIER");
5003
5004 byte[] t3tIdentifier = getT3tIdentifierBytes(systemCode, nfcId2, t3tPmm);
nxpandroid34627bd2016-05-27 15:52:30 +05305005 sendMessage(MSG_REGISTER_T3T_IDENTIFIER, t3tIdentifier);
5006 }
5007
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305008 public void deregisterT3tIdentifier(String systemCode, String nfcId2, String t3tPmm) {
5009 Log.d(TAG, "request to deregister LF_T3T_IDENTIFIER");
5010
5011 byte[] t3tIdentifier = getT3tIdentifierBytes(systemCode, nfcId2, t3tPmm);
nxpandroid34627bd2016-05-27 15:52:30 +05305012 sendMessage(MSG_DEREGISTER_T3T_IDENTIFIER, t3tIdentifier);
5013 }
5014
5015 public void clearT3tIdentifiersCache() {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305016 Log.d(TAG, "clear T3t Identifiers Cache");
nxpandroid34627bd2016-05-27 15:52:30 +05305017 mDeviceHost.clearT3tIdentifiersCache();
5018 }
5019
5020 public int getLfT3tMax() {
5021 return mDeviceHost.getLfT3tMax();
5022 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305023
5024 public void commitRouting() {
5025 mHandler.sendEmptyMessage(MSG_COMMIT_ROUTING);
5026 }
5027 /**
5028 * get default Aid route entry in case application does not configure this route entry
5029 */
5030 public int GetDefaultRouteLoc()
5031 {
nxpandroida9a68ba2016-01-14 21:12:17 +05305032 int defaultRouteLoc = mNxpPrefs.getInt("PREF_SET_DEFAULT_ROUTE_ID", GetDefaultRouteEntry()) >> ROUTE_LOC_MASK;
nxpandroid64fd68c2015-09-23 16:45:15 +05305033 Log.d(TAG, "GetDefaultRouteLoc :" + defaultRouteLoc);
5034 return defaultRouteLoc ;
5035 }
5036
5037 /**
5038 * get default MifareDesfireRoute route entry in case application does not configure this route entry
5039 */
5040 public int GetDefaultMifareDesfireRouteEntry()
5041 {
nxpandroid7d44e572016-08-01 19:11:04 +05305042 int routeLoc = mDeviceHost.getDefaultDesfireRoute();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305043 int defaultMifareDesfireRoute = ((mDeviceHost.getDefaultDesfirePowerState() & 0x3F) | (routeLoc << ROUTE_LOC_MASK));
nxpandroid7d44e572016-08-01 19:11:04 +05305044 if(routeLoc == 0x00)
5045 {
nxpandroid8aecbf82016-09-16 20:21:47 +05305046 /*
5047 bit pos 1 = Power Off
5048 bit pos 2 = Battery Off
5049 bit pos 4 = Screen Off
5050 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 +05305051 defaultMifareDesfireRoute &= 0xF9;
nxpandroid7d44e572016-08-01 19:11:04 +05305052 }
nxpandroid281eb922016-08-25 20:27:46 +05305053 if (DBG) Log.d(TAG, "defaultMifareDesfireRoute : " + defaultMifareDesfireRoute);
nxpandroid7d44e572016-08-01 19:11:04 +05305054 return defaultMifareDesfireRoute;
nxpandroid64fd68c2015-09-23 16:45:15 +05305055 }
5056 /**
5057 * set default Aid route entry in case application does not configure this route entry
5058 */
5059
5060 public int GetDefaultRouteEntry()
5061 {
nxpandroid7d44e572016-08-01 19:11:04 +05305062 int routeLoc = mDeviceHost.getDefaultAidRoute();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305063 int defaultAidRoute = ((mDeviceHost.getDefaultAidPowerState() & 0x3F) | (routeLoc << ROUTE_LOC_MASK));
nxpandroid7d44e572016-08-01 19:11:04 +05305064 if(routeLoc == 0x00)
5065 {
nxpandroid8aecbf82016-09-16 20:21:47 +05305066 /*
5067 bit pos 1 = Power Off
5068 bit pos 2 = Battery Off
5069 bit pos 4 = Screen Off
5070 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 +05305071 defaultAidRoute &= 0xF9;
nxpandroid7d44e572016-08-01 19:11:04 +05305072 }
nxpandroid281eb922016-08-25 20:27:46 +05305073 if (DBG) Log.d(TAG, "defaultAidRoute : " + defaultAidRoute);
nxpandroid64fd68c2015-09-23 16:45:15 +05305074 return defaultAidRoute;
5075 }
5076
5077 /**
5078 * get default MifateCLT route entry in case application does not configure this route entry
5079 */
5080 public int GetDefaultMifateCLTRouteEntry()
5081 {
nxpandroid7d44e572016-08-01 19:11:04 +05305082 int routeLoc = mDeviceHost.getDefaultMifareCLTRoute();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305083 int defaultMifateCLTRoute = ((mDeviceHost.getDefaultMifareCLTPowerState() & 0x3F) | (routeLoc << ROUTE_LOC_MASK) | (TECH_TYPE_A << TECH_TYPE_MASK));
nxpandroid7d44e572016-08-01 19:11:04 +05305084
nxpandroid281eb922016-08-25 20:27:46 +05305085 if (DBG) Log.d(TAG, "defaultMifateCLTRoute : " + defaultMifateCLTRoute);
nxpandroid7d44e572016-08-01 19:11:04 +05305086 return defaultMifateCLTRoute;
nxpandroid64fd68c2015-09-23 16:45:15 +05305087 }
5088
5089 public boolean setDefaultRoute(int defaultRouteEntry, int defaultProtoRouteEntry, int defaultTechRouteEntry) {
5090 boolean ret = mDeviceHost.setDefaultRoute(defaultRouteEntry, defaultProtoRouteEntry, defaultTechRouteEntry);
5091 return ret;
5092 }
5093
5094 public int getDefaultRoute() {
nxpandroida9a68ba2016-01-14 21:12:17 +05305095 return mNxpPrefs.getInt(PREF_DEFAULT_ROUTE_ID, DEFAULT_ROUTE_ID_DEFAULT);
nxpandroid64fd68c2015-09-23 16:45:15 +05305096 }
5097
5098
5099 public void commitingFelicaRouting() {
5100 mHandler.sendEmptyMessage(MSG_COMMITINF_FELICA_ROUTING);
5101 }
5102
5103 public void commitedFelicaRouting() {
5104 mHandler.sendEmptyMessage(MSG_COMMITED_FELICA_ROUTING);
5105 }
5106
nxpandroida9a68ba2016-01-14 21:12:17 +05305107 public int getAidRoutingTableStatus() {
5108 int aidTableStatus = 0x00;
5109 aidTableStatus = mNxpPrefs.getInt("PREF_SET_AID_ROUTING_TABLE_FULL",0x00);
5110 return aidTableStatus;
5111 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305112
nxpandroid64fd68c2015-09-23 16:45:15 +05305113 public void clearRouting() {
5114 mHandler.sendEmptyMessage(MSG_CLEAR_ROUTING);
5115 }
5116
5117 public boolean isVzwFeatureEnabled(){
5118 return mDeviceHost.isVzwFeatureEnabled();
5119 }
5120
5121 public boolean sendData(byte[] data) {
5122 return mDeviceHost.sendRawFrame(data);
5123 }
5124
5125 public int getDefaultSecureElement() {
5126 int[] seList = mDeviceHost.doGetSecureElementList();
5127 if ( seList == null || seList.length != 1) {
5128 //use default value
5129 return -1;
5130 } else {
5131 return seList[0];
5132 }
5133 }
5134
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05305135 public void updateLastScreenState()
5136 {
5137 Log.d(TAG, "updateLastScreenState");
5138 int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ?
5139 (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState;
5140 mDeviceHost.doSetScreenOrPowerState(screen_state_mask);
5141 }
5142
nxpandroid64fd68c2015-09-23 16:45:15 +05305143 public void etsiStartConfig(int eeHandle) {
5144 Log.d(TAG, "etsiStartConfig Enter");
5145
5146 Log.d(TAG, "etsiStartConfig : etsiInitConfig");
5147 mDeviceHost.etsiInitConfig();
5148
5149 Log.d(TAG, "etsiStartConfig : disableDiscovery");
5150 mDeviceHost.disableDiscovery();
5151
5152 Log.d(TAG, "etsiStartConfig : etsiReaderConfig");
5153 mDeviceHost.etsiReaderConfig(eeHandle);
5154
5155 Log.d(TAG, "etsiStartConfig : notifyEEReaderEvent");
Pratap Reddy49abbe32018-03-27 16:51:59 +05305156 mDeviceHost.notifyEEReaderEvent(ETSI_READER_START_SUCCESS);
nxpandroid64fd68c2015-09-23 16:45:15 +05305157
5158 Log.d(TAG, "etsiStartConfig : setEtsiReaederState");
5159 mDeviceHost.setEtsiReaederState(STATE_SE_RDR_MODE_STARTED);
5160 //broadcast SWP_READER_ACTIVATED evt
nxpandroid5d64ce92016-11-18 19:48:53 +05305161 Intent swpReaderRequestedIntent = new Intent();
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05305162 swpReaderRequestedIntent.setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_START_SUCCESS);
nxpandroid64fd68c2015-09-23 16:45:15 +05305163 if (DBG) {
5164 Log.d(TAG, "SWP READER - Requested");
5165 }
nxpandroid5d64ce92016-11-18 19:48:53 +05305166 mContext.sendBroadcast(swpReaderRequestedIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05305167
5168 Log.d(TAG, "etsiStartConfig : enableDiscovery");
5169 mDeviceHost.enableDiscovery(mCurrentDiscoveryParameters, true);
5170
5171 Log.d(TAG, "etsiStartConfig Exit");
5172 }
5173
5174 public void etsiStopConfig(int discNtfTimeout) {
5175 Log.d(TAG, "etsiStopConfig Enter");
5176 if( mDeviceHost.getEtsiReaederState() == STATE_SE_RDR_MODE_STOP_IN_PROGRESS)
5177 {
5178 Log.d(TAG, "Attempting etsiStopConfig while STATE_SE_RDR_MODE_STOP_IN_PROGRESS. Returning..");
5179 return;
5180 }
5181 ETSI_STOP_CONFIG = true;
nxpandroid64fd68c2015-09-23 16:45:15 +05305182 Log.d(TAG, "etsiStopConfig : etsiInitConfig");
5183 mDeviceHost.etsiInitConfig();
5184
Pratap Reddy49abbe32018-03-27 16:51:59 +05305185 Timer mTimer = new Timer();
5186 TagRemoveTaskTimer tagRemoveTask = new TagRemoveTaskTimer();
5187 mTimer.schedule(tagRemoveTask, ETSI_PRESENCE_CHECK_DELAY, ETSI_PRESENCE_CHECK_DELAY);
5188
nxpandroid64fd68c2015-09-23 16:45:15 +05305189 Log.d(TAG, "etsiStopConfig : disableDiscovery");
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05305190 mDeviceHost.stopPoll(NxpConstants.ULTRA_LOW_POWER);
Pratap Reddy49abbe32018-03-27 16:51:59 +05305191 mTimer.cancel();
nxpandroid64fd68c2015-09-23 16:45:15 +05305192
5193 if(mDeviceHost.getEtsiReaederState() == STATE_SE_RDR_MODE_STOPPED)
5194 {
5195 Log.d(TAG, "etsiStopConfig :etsi reader already Stopped. Returning..");
5196 ETSI_STOP_CONFIG = false;
5197 return;
5198 }
5199 Log.d(TAG, "etsiStopConfig : etsiResetReaderConfig");
5200 mDeviceHost.etsiResetReaderConfig();
5201
5202 Log.d(TAG, "etsiStopConfig : notifyEEReaderEvent");
5203 mDeviceHost.notifyEEReaderEvent(ETSI_READER_STOP);
5204
nxpandroid5d64ce92016-11-18 19:48:53 +05305205 Intent swpReaderDeActivatedIntent = new Intent();
nxpandroid64fd68c2015-09-23 16:45:15 +05305206
5207 //broadcast SWP_READER_DEACTIVATED evt
nxpandroid5d64ce92016-11-18 19:48:53 +05305208 swpReaderDeActivatedIntent
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05305209 .setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_STOP_SUCCESS);
nxpandroid64fd68c2015-09-23 16:45:15 +05305210 if (DBG) {
5211 Log.d(TAG, "SWP READER - DeActivated");
5212 }
nxpandroid5d64ce92016-11-18 19:48:53 +05305213 mContext.sendBroadcast(swpReaderDeActivatedIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05305214
5215 Log.d(TAG, "etsiStopConfig : setEtsiReaederState");
5216 mDeviceHost.setEtsiReaederState(STATE_SE_RDR_MODE_STOPPED);
5217
nxpandroid64fd68c2015-09-23 16:45:15 +05305218 ETSI_STOP_CONFIG = false;
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05305219 updateLastScreenState();
nxpandroid64fd68c2015-09-23 16:45:15 +05305220
5221 Log.d(TAG, "etsiStopConfig Exit");
5222 }
5223
5224 void sendMessage(int what, Object obj) {
5225 Message msg = mHandler.obtainMessage();
5226 msg.what = what;
5227 msg.obj = obj;
5228 mHandler.sendMessage(msg);
5229 }
5230
5231 final class NfcServiceHandler extends Handler {
5232 @Override
5233 public void handleMessage(Message msg) {
5234 switch (msg.what) {
5235 case MSG_ROUTE_AID: {
5236 int route = msg.arg1;
5237 int power = msg.arg2;
nxpandroidcbf24822017-07-12 21:37:17 +05305238 int aidInfo = 0x00;
5239 Bundle dataBundle = msg.getData();
5240 if (dataBundle != null)
5241 aidInfo = dataBundle.getInt("aidinfo");
nxpandroid64fd68c2015-09-23 16:45:15 +05305242 String aid = (String) msg.obj;
nxpandroidcbf24822017-07-12 21:37:17 +05305243 String cuttedAid = aid;
5244 if(aid.endsWith("*")||aid.endsWith("#")) {
5245 cuttedAid = aid.substring(0, aid.length() - 1);
nxpandroid64fd68c2015-09-23 16:45:15 +05305246 }
nxpandroidcbf24822017-07-12 21:37:17 +05305247 mDeviceHost.routeAid(hexStringToBytes(cuttedAid), route, power, aidInfo);
nxpandroid64fd68c2015-09-23 16:45:15 +05305248 // Restart polling config
5249 break;
5250 }
nxpandroid34627bd2016-05-27 15:52:30 +05305251 case MSG_REGISTER_T3T_IDENTIFIER: {
5252 Log.d(TAG, "message to register LF_T3T_IDENTIFIER");
5253 mDeviceHost.disableDiscovery();
5254
5255 byte[] t3tIdentifier = (byte[]) msg.obj;
5256 mDeviceHost.registerT3tIdentifier(t3tIdentifier);
5257
5258 NfcDiscoveryParameters params = computeDiscoveryParameters(mScreenState);
5259 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery();
5260 mDeviceHost.enableDiscovery(params, shouldRestart);
5261 break;
5262 }
5263 case MSG_DEREGISTER_T3T_IDENTIFIER: {
5264 Log.d(TAG, "message to deregister LF_T3T_IDENTIFIER");
5265 mDeviceHost.disableDiscovery();
5266
5267 byte[] t3tIdentifier = (byte[]) msg.obj;
5268 mDeviceHost.deregisterT3tIdentifier(t3tIdentifier);
5269
5270 NfcDiscoveryParameters params = computeDiscoveryParameters(mScreenState);
5271 boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery();
5272 mDeviceHost.enableDiscovery(params, shouldRestart);
5273 break;
5274 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305275 case MSG_INVOKE_BEAM: {
5276 mP2pLinkManager.onManualBeamInvoke((BeamShareData)msg.obj);
5277 break;
5278 }
nxpandroida5fd6622017-07-31 16:15:18 +05305279
nxpandroid64fd68c2015-09-23 16:45:15 +05305280 case MSG_UNROUTE_AID: {
5281 String aid = (String) msg.obj;
5282 mDeviceHost.unrouteAid(hexStringToBytes(aid));
5283 break;
5284 }
5285
nxpandroid64fd68c2015-09-23 16:45:15 +05305286 case MSG_COMMITINF_FELICA_ROUTING: {
5287 Log.e(TAG, "applyRouting -10");
5288 mIsFelicaOnHostConfiguring = true;
5289 applyRouting(true);
5290 break;
5291 }
5292
5293 case MSG_COMMITED_FELICA_ROUTING: {
5294 Log.e(TAG, "applyRouting -11");
5295 mIsFelicaOnHostConfigured = true;
5296 applyRouting(true);
5297 break;
5298 }
5299
nxpandroid64fd68c2015-09-23 16:45:15 +05305300 case MSG_COMMIT_ROUTING: {
5301 Log.e(TAG, "applyRouting -9");
5302 boolean commit = false;
nxpandroid07d1cc22017-09-14 12:20:58 +05305303 boolean enForced = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05305304 synchronized (NfcService.this) {
5305 if (mCurrentDiscoveryParameters.shouldEnableDiscovery()) {
5306 commit = true;
nxpandroid07d1cc22017-09-14 12:20:58 +05305307 }else if(mAidRoutingManager.isRoutingTableUpdated()){
5308 commit = true;
5309 enForced = true;
5310 Log.d(TAG, "Routing table is updated thus needs to be committed.");
5311 }
5312 else {
nxpandroid64fd68c2015-09-23 16:45:15 +05305313 Log.d(TAG, "Not committing routing because discovery is disabled.");
5314 }
5315 }
5316 if (commit) {
5317 mIsRoutingTableDirty = true;
nxpandroid07d1cc22017-09-14 12:20:58 +05305318 applyRouting(enForced);
nxpandroid64fd68c2015-09-23 16:45:15 +05305319 }
5320
5321
5322 break;
5323 }
5324 case MSG_CLEAR_ROUTING: {
5325 mDeviceHost.clearAidTable();
5326 break;
5327 }
5328
5329 case MSG_CHANGE_DEFAULT_ROUTE:
5330 Log.d(TAG, "Handler: Change default route");
5331 try{
5332 mNxpNfcAdapter.DefaultRouteSet(ROUTE_ID_HOST, true, false, false);
5333 } catch(RemoteException re) {
5334 Log.d(TAG, "NxpNci: onAidRoutingTableFull: Exception to change default route to host!");
5335 }
5336 break;
5337
5338 case MSG_MOCK_NDEF: {
5339 NdefMessage ndefMsg = (NdefMessage) msg.obj;
5340 Bundle extras = new Bundle();
5341 extras.putParcelable(Ndef.EXTRA_NDEF_MSG, ndefMsg);
5342 extras.putInt(Ndef.EXTRA_NDEF_MAXLENGTH, 0);
5343 extras.putInt(Ndef.EXTRA_NDEF_CARDSTATE, Ndef.NDEF_MODE_READ_ONLY);
5344 extras.putInt(Ndef.EXTRA_NDEF_TYPE, Ndef.TYPE_OTHER);
5345 Tag tag = Tag.createMockTag(new byte[]{0x00},
5346 new int[]{TagTechnology.NDEF},
5347 new Bundle[]{extras});
5348 Log.d(TAG, "mock NDEF tag, starting corresponding activity");
5349 Log.d(TAG, tag.toString());
5350 int dispatchStatus = mNfcDispatcher.dispatchTag(tag);
5351 if (dispatchStatus == NfcDispatcher.DISPATCH_SUCCESS) {
5352 playSound(SOUND_END);
5353 } else if (dispatchStatus == NfcDispatcher.DISPATCH_FAIL) {
5354 playSound(SOUND_ERROR);
5355 }
5356 break;
5357 }
5358
5359 case MSG_SE_DELIVER_INTENT: {
5360 Log.d(TAG, "SE DELIVER INTENT");
5361 Intent seIntent = (Intent) msg.obj;
5362
5363 String action = seIntent.getAction();
5364 if (action.equals("com.gsma.services.nfc.action.TRANSACTION_EVENT")) {
5365 byte[] byteAid = seIntent.getByteArrayExtra("com.android.nfc_extras.extra.AID");
5366 byte[] data = seIntent.getByteArrayExtra("com.android.nfc_extras.extra.DATA");
5367 String seName = seIntent.getStringExtra("com.android.nfc_extras.extra.SE_NAME");
5368 StringBuffer strAid = new StringBuffer();
5369 for (int i = 0; i < byteAid.length; i++) {
5370 String hex = Integer.toHexString(0xFF & byteAid[i]);
5371 if (hex.length() == 1)
5372 strAid.append('0');
5373 strAid.append(hex);
5374 }
5375 Intent gsmaIntent = new Intent();
5376 gsmaIntent.setAction("com.gsma.services.nfc.action.TRANSACTION_EVENT");
5377 if (byteAid != null)
5378 gsmaIntent.putExtra("com.gsma.services.nfc.extra.AID", byteAid);
5379 if (data != null)
5380 gsmaIntent.putExtra("com.gsma.services.nfc.extra.DATA", data);
5381
5382 //"nfc://secure:0/<seName>/<strAid>"
5383 String url = new String ("nfc://secure:0/" + seName + "/" + strAid);
5384 gsmaIntent.setData(Uri.parse(url));
5385 gsmaIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
5386 gsmaIntent.setPackage(seIntent.getPackage());
5387
5388 Boolean receptionMode = mNxpNfcController.mMultiReceptionMap.get(seName);
5389 if (receptionMode == null)
5390 receptionMode = defaultTransactionEventReceptionMode;
5391
5392 if (receptionMode == multiReceptionMode) {
5393 // if multicast reception for GSMA
5394 mContext.sendBroadcast(gsmaIntent);
5395 } else {
5396 // if unicast reception for GSMA
5397 try {
5398 if (mIsSentUnicastReception == false) {
5399 //start gsma
5400 gsmaIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
5401 mContext.startActivity(gsmaIntent);
5402 mIsSentUnicastReception = true;
5403 }
5404 } catch (Exception e) {
5405 if (DBG) Log.d(TAG, "Exception: " + e.getMessage());
5406 }
5407 }
5408 } else {
5409 mContext.sendBroadcast(seIntent);
5410 }
5411 break;
5412 }
5413
5414 case MSG_NDEF_TAG:
5415 if (DBG) Log.d(TAG, "Tag detected, notifying applications");
Suhas Suresh31963a02018-04-25 12:14:23 +05305416 mPowerManager.userActivity(SystemClock.uptimeMillis(),
5417 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0);
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305418 mNumTagsDetected.incrementAndGet();
nxpandroid64fd68c2015-09-23 16:45:15 +05305419 TagEndpoint tag = (TagEndpoint) msg.obj;
nxpandroid281eb922016-08-25 20:27:46 +05305420 byte[] debounceTagUid;
5421 int debounceTagMs;
5422 ITagRemovedCallback debounceTagRemovedCallback;
5423 synchronized (NfcService.this) {
5424 debounceTagUid = mDebounceTagUid;
5425 debounceTagMs = mDebounceTagDebounceMs;
5426 debounceTagRemovedCallback = mDebounceTagRemovedCallback;
5427 }
nxpandroid281eb922016-08-25 20:27:46 +05305428
nxpandroid64fd68c2015-09-23 16:45:15 +05305429 ReaderModeParams readerParams = null;
5430 int presenceCheckDelay = DEFAULT_PRESENCE_CHECK_DELAY;
5431 DeviceHost.TagDisconnectedCallback callback =
5432 new DeviceHost.TagDisconnectedCallback() {
5433 @Override
5434 public void onTagDisconnected(long handle) {
nxpandroid03323c82017-09-14 11:13:16 +05305435 if(nci_version != NCI_VERSION_2_0) {
5436 applyRouting(false);
5437 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305438 }
5439 };
5440 synchronized (NfcService.this) {
5441 readerParams = mReaderModeParams;
5442 }
5443 if (readerParams != null) {
5444 presenceCheckDelay = readerParams.presenceCheckDelay;
5445 if ((readerParams.flags & NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK) != 0) {
5446 if (DBG) Log.d(TAG, "Skipping NDEF detection in reader mode");
5447 tag.startPresenceChecking(presenceCheckDelay, callback);
5448 dispatchTagEndpoint(tag, readerParams);
5449 break;
5450 }
5451 }
5452
nxpandroid64fd68c2015-09-23 16:45:15 +05305453 if (tag.getConnectedTechnology() == TagTechnology.NFC_BARCODE) {
5454 // When these tags start containing NDEF, they will require
5455 // the stack to deal with them in a different way, since
5456 // they are activated only really shortly.
5457 // For now, don't consider NDEF on these.
5458 if (DBG) Log.d(TAG, "Skipping NDEF detection for NFC Barcode");
5459 tag.startPresenceChecking(presenceCheckDelay, callback);
5460 dispatchTagEndpoint(tag, readerParams);
5461 break;
5462 }
5463 NdefMessage ndefMsg = tag.findAndReadNdef();
5464
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305465 if (ndefMsg == null) {
5466 // First try to see if this was a bad tag read
5467 if (!tag.reconnect()) {
nxpandroid64fd68c2015-09-23 16:45:15 +05305468 tag.disconnect();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305469 break;
nxpandroid64fd68c2015-09-23 16:45:15 +05305470 }
5471 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305472
5473 if (debounceTagUid != null) {
5474 // If we're debouncing and the UID or the NDEF message of the tag match,
5475 // don't dispatch but drop it.
5476 if (Arrays.equals(debounceTagUid, tag.getUid()) ||
5477 (ndefMsg != null && ndefMsg.equals(mLastReadNdefMessage))) {
5478 mHandler.removeMessages(MSG_TAG_DEBOUNCE);
5479 mHandler.sendEmptyMessageDelayed(MSG_TAG_DEBOUNCE, debounceTagMs);
5480 tag.disconnect();
5481 return;
5482 } else {
5483 synchronized (NfcService.this) {
5484 mDebounceTagUid = null;
5485 mDebounceTagRemovedCallback = null;
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +05305486 mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE;
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305487 }
5488 if (debounceTagRemovedCallback != null) {
5489 try {
5490 debounceTagRemovedCallback.onTagRemoved();
5491 } catch (RemoteException e) {
5492 // Ignore
5493 }
5494 }
5495 }
5496 }
5497
5498 mLastReadNdefMessage = ndefMsg;
5499
5500 tag.startPresenceChecking(presenceCheckDelay, callback);
5501 dispatchTagEndpoint(tag, readerParams);
nxpandroid64fd68c2015-09-23 16:45:15 +05305502 break;
5503
nxpandroid64fd68c2015-09-23 16:45:15 +05305504 case MSG_CONNECTIVITY_EVENT:
5505 if (DBG) {
5506 Log.d(TAG, "SE EVENT CONNECTIVITY");
5507 }
5508 Integer evtSrcInfo = (Integer) msg.obj;
5509 Log.d(TAG, "Event source " + evtSrcInfo);
5510 String evtSrc = "";
5511 if(evtSrcInfo == UICC_ID_TYPE) {
5512 evtSrc = NxpConstants.UICC_ID;
nxpandroid7d44e572016-08-01 19:11:04 +05305513 } else if(evtSrcInfo == UICC2_ID_TYPE) {
5514 evtSrc = NxpConstants.UICC2_ID;
nxpandroid64fd68c2015-09-23 16:45:15 +05305515 } else if(evtSrcInfo == SMART_MX_ID_TYPE) {
5516 evtSrc = NxpConstants.SMART_MX_ID;
5517 }
5518
5519 Intent eventConnectivityIntent = new Intent();
5520 eventConnectivityIntent.setAction(NxpConstants.ACTION_CONNECTIVITY_EVENT_DETECTED);
5521 eventConnectivityIntent.putExtra(NxpConstants.EXTRA_SOURCE, evtSrc);
5522 if (DBG) {
5523 Log.d(TAG, "Broadcasting Intent");
5524 }
5525 mContext.sendBroadcast(eventConnectivityIntent, NfcPermissions.NFC_PERMISSION);
5526 break;
5527
5528 case MSG_EMVCO_MULTI_CARD_DETECTED_EVENT:
5529 if (DBG) {
5530 Log.d(TAG, "EMVCO MULTI CARD DETECTED EVENT");
5531 }
5532
5533 Intent eventEmvcoMultiCardIntent = new Intent();
5534 eventEmvcoMultiCardIntent.setAction(ACTION_EMVCO_MULTIPLE_CARD_DETECTED);
5535 if (DBG) {
5536 Log.d(TAG, "Broadcasting Intent");
5537 }
5538 mContext.sendBroadcast(eventEmvcoMultiCardIntent, NFC_PERM);
5539 break;
5540
5541 case MSG_SE_EMV_CARD_REMOVAL:
5542 if (DBG) Log.d(TAG, "Card Removal message");
5543 /* Send broadcast */
5544 Intent cardRemovalIntent = new Intent();
5545 cardRemovalIntent.setAction(ACTION_EMV_CARD_REMOVAL);
5546 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_EMV_CARD_REMOVAL);
5547 sendSeBroadcast(cardRemovalIntent);
5548 break;
5549
5550 case MSG_SE_APDU_RECEIVED:
5551 if (DBG) Log.d(TAG, "APDU Received message");
5552 byte[] apduBytes = (byte[]) msg.obj;
5553 /* Send broadcast */
5554 Intent apduReceivedIntent = new Intent();
5555 apduReceivedIntent.setAction(ACTION_APDU_RECEIVED);
5556 if (apduBytes != null && apduBytes.length > 0) {
5557 apduReceivedIntent.putExtra(EXTRA_APDU_BYTES, apduBytes);
5558 }
5559 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_APDU_RECEIVED);
5560 sendSeBroadcast(apduReceivedIntent);
5561 break;
5562
5563 case MSG_SE_MIFARE_ACCESS:
5564 if (DBG) Log.d(TAG, "MIFARE access message");
5565 /* Send broadcast */
5566 byte[] mifareCmd = (byte[]) msg.obj;
5567 Intent mifareAccessIntent = new Intent();
5568 mifareAccessIntent.setAction(ACTION_MIFARE_ACCESS_DETECTED);
5569 if (mifareCmd != null && mifareCmd.length > 1) {
5570 int mifareBlock = mifareCmd[1] & 0xff;
5571 if (DBG) Log.d(TAG, "Mifare Block=" + mifareBlock);
5572 mifareAccessIntent.putExtra(EXTRA_MIFARE_BLOCK, mifareBlock);
5573 }
5574 if (DBG) Log.d(TAG, "Broadcasting " + ACTION_MIFARE_ACCESS_DETECTED);
5575 sendSeBroadcast(mifareAccessIntent);
5576 break;
5577
5578 case MSG_LLCP_LINK_ACTIVATION:
Suhas Suresh31963a02018-04-25 12:14:23 +05305579 mPowerManager.userActivity(SystemClock.uptimeMillis(),
5580 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0);
nxpandroid64fd68c2015-09-23 16:45:15 +05305581 if (mIsDebugBuild) {
5582 Intent actIntent = new Intent(ACTION_LLCP_UP);
5583 mContext.sendBroadcast(actIntent);
5584 }
5585 llcpActivated((NfcDepEndpoint) msg.obj);
5586 break;
5587
5588 case MSG_LLCP_LINK_DEACTIVATED:
5589 if (mIsDebugBuild) {
5590 Intent deactIntent = new Intent(ACTION_LLCP_DOWN);
5591 mContext.sendBroadcast(deactIntent);
5592 }
5593 NfcDepEndpoint device = (NfcDepEndpoint) msg.obj;
5594 boolean needsDisconnect = false;
5595
5596 Log.d(TAG, "LLCP Link Deactivated message. Restart polling loop.");
5597 synchronized (NfcService.this) {
5598 /* Check if the device has been already unregistered */
5599 if (mObjectMap.remove(device.getHandle()) != null) {
5600 /* Disconnect if we are initiator */
5601 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) {
5602 if (DBG) Log.d(TAG, "disconnecting from target");
5603 needsDisconnect = true;
5604 } else {
5605 if (DBG) Log.d(TAG, "not disconnecting from initiator");
5606 }
5607 }
5608 }
5609 if (needsDisconnect) {
5610 device.disconnect(); // restarts polling loop
5611 }
5612
5613 mP2pLinkManager.onLlcpDeactivated();
5614 break;
5615 case MSG_LLCP_LINK_FIRST_PACKET:
5616 mP2pLinkManager.onLlcpFirstPacketReceived();
5617 break;
5618 case MSG_TARGET_DESELECTED:
5619 /* Broadcast Intent Target Deselected */
5620 if (DBG) Log.d(TAG, "Target Deselected");
5621 Intent intent = new Intent();
5622 intent.setAction(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
5623 if (DBG) Log.d(TAG, "Broadcasting Intent");
5624 mContext.sendOrderedBroadcast(intent, NfcPermissions.NFC_PERMISSION);
5625 break;
5626
5627 case MSG_SE_FIELD_ACTIVATED: {
5628 if (DBG) Log.d(TAG, "SE FIELD ACTIVATED");
5629 Intent eventFieldOnIntent = new Intent();
5630 eventFieldOnIntent.setAction(ACTION_RF_FIELD_ON_DETECTED);
5631 sendSeBroadcast(eventFieldOnIntent);
5632 break;
5633 }
5634 case MSG_RESUME_POLLING:
5635 mNfcAdapter.resumePolling();
5636 break;
5637
5638 case MSG_SE_FIELD_DEACTIVATED: {
5639 if (DBG) Log.d(TAG, "SE FIELD DEACTIVATED");
5640 Intent eventFieldOffIntent = new Intent();
5641 eventFieldOffIntent.setAction(ACTION_RF_FIELD_OFF_DETECTED);
5642 sendSeBroadcast(eventFieldOffIntent);
5643 break;
5644 }
5645
5646 case MSG_SE_LISTEN_ACTIVATED: {
5647 if (DBG) Log.d(TAG, "SE LISTEN MODE ACTIVATED");
5648 Intent listenModeActivated = new Intent();
5649 listenModeActivated.setAction(ACTION_SE_LISTEN_ACTIVATED);
5650 sendSeBroadcast(listenModeActivated);
5651 break;
5652 }
5653
5654 case MSG_SE_LISTEN_DEACTIVATED: {
5655 if (DBG) Log.d(TAG, "SE LISTEN MODE DEACTIVATED");
5656 Intent listenModeDeactivated = new Intent();
5657 listenModeDeactivated.setAction(ACTION_SE_LISTEN_DEACTIVATED);
5658 sendSeBroadcast(listenModeDeactivated);
5659 break;
5660 }
5661
5662 case MSG_SWP_READER_REQUESTED:
5663
5664 /* Send broadcast ordered */
nxpandroid281eb922016-08-25 20:27:46 +05305665 Intent swpReaderRequestedIntent = new Intent();
nxpandroid64fd68c2015-09-23 16:45:15 +05305666 ArrayList<Integer> techList = (ArrayList<Integer>) msg.obj;
nxpandroid281eb922016-08-25 20:27:46 +05305667 Integer[] techs = techList.toArray(new Integer[techList.size()]);
5668 swpReaderRequestedIntent
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05305669 .setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_START_SUCCESS);
nxpandroid64fd68c2015-09-23 16:45:15 +05305670 if (DBG) {
5671 Log.d(TAG, "SWP READER - Requested");
5672 }
nxpandroid281eb922016-08-25 20:27:46 +05305673 mContext.sendBroadcast(swpReaderRequestedIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05305674 break;
5675
5676 case MSG_SWP_READER_REQUESTED_FAIL:
5677
5678 /* Send broadcast ordered */
nxpandroid281eb922016-08-25 20:27:46 +05305679 Intent swpReaderRequestedFailIntent = new Intent();
nxpandroid64fd68c2015-09-23 16:45:15 +05305680
nxpandroid281eb922016-08-25 20:27:46 +05305681 swpReaderRequestedFailIntent
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05305682 .setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_START_FAIL);
nxpandroid64fd68c2015-09-23 16:45:15 +05305683 if (DBG) {
5684 Log.d(TAG, "SWP READER - Requested Fail");
5685 }
nxpandroid281eb922016-08-25 20:27:46 +05305686 mContext.sendBroadcast(swpReaderRequestedFailIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05305687 break;
5688
nxpandroid64fd68c2015-09-23 16:45:15 +05305689 case MSG_ETSI_START_CONFIG:
5690 {
5691 Log.d(TAG, "NfcServiceHandler - MSG_ETSI_START_CONFIG");
5692 ArrayList<Integer> configList = (ArrayList<Integer>) msg.obj;
5693 int eeHandle;
5694 if(configList.contains(0x402))
5695 {
5696 eeHandle = 0x402;
5697 }
5698 else{
5699 eeHandle = 0x4C0;
5700 }
Pratap Reddy49abbe32018-03-27 16:51:59 +05305701 synchronized (NfcService.this) {
5702 etsiStartConfig(eeHandle);
5703 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305704 }
5705 break;
5706
5707 case MSG_ETSI_STOP_CONFIG:
5708
5709 Log.d(TAG, "NfcServiceHandler - MSG_ETSI_STOP_CONFIG");
5710
5711 etsiStopConfig((int)msg.obj);
5712 break;
5713
5714 case MSG_ETSI_SWP_TIMEOUT:
5715
5716 Log.d(TAG, "NfcServiceHandler - MSG_ETSI_SWP_TIMEOUT");
5717
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05305718 /* Send broadcast ordered */
5719 Intent swpReaderTimeoutIntent = new Intent();
nxpandroid64fd68c2015-09-23 16:45:15 +05305720
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05305721 swpReaderTimeoutIntent
5722 .setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_TIMEOUT);
5723 if (DBG) {
5724 Log.d(TAG, "SWP READER - Timeout");
5725 }
5726 mContext.sendBroadcast(swpReaderTimeoutIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05305727 break;
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05305728
5729 case MSG_SWP_READER_RESTART:
5730
5731 Log.d(TAG, "NfcServiceHandler - MSG_SWP_READER_RESTART");
5732
5733 /* Send broadcast ordered */
5734 Intent swpReaderRestartIntent = new Intent();
5735
5736 swpReaderRestartIntent
5737 .setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_RESTART);
5738 if (DBG) {
5739 Log.d(TAG, "SWP READER - RESTART");
5740 }
5741 mContext.sendBroadcast(swpReaderRestartIntent);
5742 break;
5743
nxpandroide66eb092017-07-12 21:36:08 +05305744 case MSG_APPLY_SCREEN_STATE:
nxpandroid64fd68c2015-09-23 16:45:15 +05305745
5746 mScreenState = (int)msg.obj;
Nikhil Chhabra20be8d92018-01-09 18:32:58 +05305747
5748 // If NFC is turning off, we shouldn't need any changes here
5749 synchronized (NfcService.this) {
5750 if (mState == NfcAdapter.STATE_TURNING_OFF)
5751 return;
5752 }
5753
nxpandroide66eb092017-07-12 21:36:08 +05305754 int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ?
5755 (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState;
Suhas Sureshd8a71d22017-11-06 18:48:14 +05305756 mDeviceHost.doSetScreenOrPowerState(screen_state_mask);
nxpandroide66eb092017-07-12 21:36:08 +05305757
Bhupendra Paware1c7ede2018-02-26 11:51:32 +05305758 if(nci_version != NCI_VERSION_2_0) {
5759 applyRouting(false);
5760 } else if(mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED
Suhas Sureshd8a71d22017-11-06 18:48:14 +05305761 || mNfcUnlockManager.isLockscreenPollingEnabled()) {
nxpandroide66eb092017-07-12 21:36:08 +05305762 applyRouting(false);
Suhas Sureshd8a71d22017-11-06 18:48:14 +05305763 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305764 break;
nxpandroid281eb922016-08-25 20:27:46 +05305765 case MSG_TAG_DEBOUNCE:
5766 // Didn't see the tag again, tag is gone
5767 ITagRemovedCallback tagRemovedCallback;
5768 synchronized (NfcService.this) {
5769 mDebounceTagUid = null;
5770 tagRemovedCallback = mDebounceTagRemovedCallback;
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305771 mDebounceTagRemovedCallback = null;
Nikhil Chhabra1b2368f2018-01-09 18:34:21 +05305772 mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE;
nxpandroid281eb922016-08-25 20:27:46 +05305773 }
5774 if (tagRemovedCallback != null) {
5775 try {
5776 tagRemovedCallback.onTagRemoved();
5777 } catch (RemoteException e) {
5778 // Ignore
5779 }
5780 }
5781 break;
nxpandroid5d64ce92016-11-18 19:48:53 +05305782 case MSG_RESTART_WATCHDOG:
5783 int enable = msg.arg1;
5784 disableInternalwatchDog.cancel();
5785 try{
5786 disableInternalwatchDog.join();
5787 } catch (java.lang.InterruptedException e) {
5788 }
5789 disableInternalwatchDog = new WatchDogThread("disableInternal", ROUTING_WATCHDOG_MS);
5790 Log.d(TAG, "New Watchdog: WatchDog Thread ID is "+ disableInternalwatchDog.getId());
5791 disableInternalwatchDog.start();
5792 break;
nxpandroid6fd9cdb2017-07-12 18:25:41 +05305793 case MSG_UPDATE_STATS:
5794 if (mNumTagsDetected.get() > 0) {
5795 MetricsLogger.count(mContext, TRON_NFC_TAG, mNumTagsDetected.get());
5796 mNumTagsDetected.set(0);
5797 }
5798 if (mNumHceDetected.get() > 0) {
5799 MetricsLogger.count(mContext, TRON_NFC_CE, mNumHceDetected.get());
5800 mNumHceDetected.set(0);
5801 }
5802 if (mNumP2pDetected.get() > 0) {
5803 MetricsLogger.count(mContext, TRON_NFC_P2P, mNumP2pDetected.get());
5804 mNumP2pDetected.set(0);
5805 }
5806 removeMessages(MSG_UPDATE_STATS);
5807 sendEmptyMessageDelayed(MSG_UPDATE_STATS, STATS_UPDATE_INTERVAL_MS);
5808 break;
nxpandroida5fd6622017-07-31 16:15:18 +05305809
5810 case MSG_ROUTE_APDU:{
5811 int route = msg.arg1;
5812 int power = msg.arg2;
5813 String apduData = null;
5814 String apduMask = null;
5815 Bundle dataBundle = msg.getData();
5816 if (dataBundle != null) {
5817 apduData = dataBundle.getString("apduData");
5818 apduMask = dataBundle.getString("apduMask");
5819 }
5820 // Send the APDU
5821 if(apduData != null && dataBundle != null)
5822 mDeviceHost.routeApduPattern(route, power, hexStringToBytes(apduData) ,hexStringToBytes(apduMask));
5823 break;
5824 }
5825 case MSG_UNROUTE_APDU: {
5826 String apdu = (String) msg.obj;
5827 mDeviceHost.unrouteApduPattern(hexStringToBytes(apdu));
5828 break;
5829 }
Suhas Sureshca6584b2018-04-27 17:17:22 +05305830 case MSG_TRANSACTION_EVENT:
5831 if (mCardEmulationManager != null) {
5832 mCardEmulationManager.onOffHostAidSelected();
5833 }
5834 byte[][] data = (byte[][]) msg.obj;
Suhas Suresh061c9b02018-05-15 17:45:06 +05305835 sendOffHostTransactionEvent(data[0], data[1], data[2]);
5836 break;
nxpandroid64fd68c2015-09-23 16:45:15 +05305837 default:
5838 Log.e(TAG, "Unknown message received");
5839 break;
5840 }
5841 }
5842
Suhas Suresh061c9b02018-05-15 17:45:06 +05305843 private void sendOffHostTransactionEvent(byte[] aid, byte[] data, byte[] readerByteArray) {
Suhas Suresh38249952018-05-18 00:03:00 +05305844
Suhas Sureshca6584b2018-04-27 17:17:22 +05305845 if (mSEService == null || mNfcEventInstalledPackages.isEmpty()) {
5846 return;
5847 }
Suhas Sureshca6584b2018-04-27 17:17:22 +05305848 try {
Suhas Suresh061c9b02018-05-15 17:45:06 +05305849 String reader = new String(readerByteArray, "UTF-8");
5850 String[] installedPackages = new String[mNfcEventInstalledPackages.size()];
Suhas Sureshca6584b2018-04-27 17:17:22 +05305851 boolean[] nfcAccess = mSEService.isNFCEventAllowed(reader, aid,
5852 mNfcEventInstalledPackages.toArray(installedPackages));
5853 if (nfcAccess == null) {
5854 return;
5855 }
5856 ArrayList<String> packages = new ArrayList<String>();
Suhas Suresh9139dc22018-05-09 15:48:37 +05305857 Intent intent = new Intent(NxpConstants.ACTION_TRANSACTION_DETECTED);
Suhas Sureshca6584b2018-04-27 17:17:22 +05305858 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
Suhas Suresh061c9b02018-05-15 17:45:06 +05305859 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Suhas Suresh9139dc22018-05-09 15:48:37 +05305860 intent.putExtra(NxpConstants.EXTRA_AID, aid);
5861 intent.putExtra(NxpConstants.EXTRA_DATA, data);
5862 intent.putExtra(NxpConstants.EXTRA_SE_NAME, reader);
Suhas Suresh061c9b02018-05-15 17:45:06 +05305863 StringBuilder aidString = new StringBuilder(aid.length);
5864 for (byte b : aid) {
5865 aidString.append(String.format("%02X", b));
5866 }
5867 String url = new String ("nfc://secure:0/" + reader + "/" + aidString.toString());
5868 intent.setData(Uri.parse(url));
Suhas Sureshca6584b2018-04-27 17:17:22 +05305869 for (int i = 0; i < nfcAccess.length; i++) {
5870 if (nfcAccess[i]) {
Suhas Suresh140f7ac2018-05-15 14:59:11 +05305871 intent.setPackage(mNfcEventInstalledPackages.get(i));
Suhas Sureshca6584b2018-04-27 17:17:22 +05305872 mContext.sendBroadcast(intent);
5873 }
5874 }
5875 } catch (RemoteException e) {
5876 Log.e(TAG, "Error in isNFCEventAllowed() " + e);
Suhas Suresh061c9b02018-05-15 17:45:06 +05305877 } catch (UnsupportedEncodingException e) {
5878 Log.e(TAG, "Incorrect format for Secure Element name" + e);
Suhas Sureshca6584b2018-04-27 17:17:22 +05305879 }
5880 }
5881
5882 /* Returns the list of packages that have access to NFC Events on any SE */
5883 private ArrayList<String> getSEAccessAllowedPackages() {
5884 if (mSEService == null || mNfcEventInstalledPackages.isEmpty()) {
5885 return null;
5886 }
5887 String[] readers = null;
5888 try {
5889 readers = mSEService.getReaders();
5890 } catch (RemoteException e) {
5891 Log.e(TAG, "Error in getReaders() " + e);
5892 return null;
5893 }
5894
5895 if (readers == null || readers.length == 0) {
5896 return null;
5897 }
5898 boolean[] nfcAccessFinal = null;
5899 String[] installedPackages = new String[mNfcEventInstalledPackages.size()];
5900 for (String reader : readers) {
5901 try {
5902 boolean[] accessList = mSEService.isNFCEventAllowed(reader, null,
5903 mNfcEventInstalledPackages.toArray(installedPackages));
5904 if (accessList == null) {
5905 continue;
5906 }
5907 if (nfcAccessFinal == null) {
5908 nfcAccessFinal = accessList;
5909 }
5910 for (int i = 0; i < accessList.length; i++) {
5911 if (accessList[i]) {
5912 nfcAccessFinal[i] = true;
5913 }
5914 }
5915 } catch (RemoteException e) {
5916 Log.e(TAG, "Error in isNFCEventAllowed() " + e);
5917 }
5918 }
5919 if (nfcAccessFinal == null) {
5920 return null;
5921 }
5922 ArrayList<String> packages = new ArrayList<String>();
5923 for (int i = 0; i < nfcAccessFinal.length; i++) {
5924 if (nfcAccessFinal[i]) {
Suhas Suresh140f7ac2018-05-15 14:59:11 +05305925 packages.add(mNfcEventInstalledPackages.get(i));
Suhas Sureshca6584b2018-04-27 17:17:22 +05305926 }
5927 }
5928 return packages;
5929 }
5930
nxpandroid64fd68c2015-09-23 16:45:15 +05305931 private void sendSeBroadcast(Intent intent) {
5932 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
5933 // Resume app switches so the receivers can start activites without delay
5934 mNfcDispatcher.resumeAppSwitches();
nxpandroida51b5bd2017-04-10 18:28:21 +05305935 Log.d(TAG, "NFCINTENT sendNfcEeAccessProtectedBroadcast");
nxpandroid64fd68c2015-09-23 16:45:15 +05305936 synchronized(this) {
Suhas Sureshca6584b2018-04-27 17:17:22 +05305937 ArrayList<String> SEPackages = getSEAccessAllowedPackages();
5938 if (SEPackages!= null && !SEPackages.isEmpty()) {
5939 for (String packageName : SEPackages) {
nxpandroid64fd68c2015-09-23 16:45:15 +05305940 intent.setPackage(packageName);
nxpandroida51b5bd2017-04-10 18:28:21 +05305941 Log.d(TAG, "NFCINTENT SENT TO PACKAGE" + packageName);
nxpandroid64fd68c2015-09-23 16:45:15 +05305942 mContext.sendBroadcast(intent);
5943 }
Suhas Sureshca6584b2018-04-27 17:17:22 +05305944 }
Suhas Suresh140f7ac2018-05-15 14:59:11 +05305945 PackageManager pm = mContext.getPackageManager();
5946 for (String packageName : mNfcEventInstalledPackages) {
5947 try {
5948 PackageInfo info = pm.getPackageInfo(packageName, 0);
5949 if (SEPackages != null && SEPackages.contains(packageName)) {
5950 continue;
5951 }
5952 if (info.applicationInfo != null &&
5953 ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 ||
5954 (info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0)) {
5955 intent.setPackage(packageName);
5956 mContext.sendBroadcast(intent);
5957 }
5958 } catch (Exception e) {
5959 Log.e(TAG, "Exception in getPackageInfo " + e);
nxpandroid64fd68c2015-09-23 16:45:15 +05305960 }
5961 }
5962 }
5963 }
5964
5965 private void sendMultiEvtBroadcast(Intent intent) {
5966
5967 ArrayList<String> packageList = mNxpNfcController.getEnabledMultiEvtsPackageList();
nxpandroida9a68ba2016-01-14 21:12:17 +05305968 ComponentName unicastComponent = null;
nxpandroid64fd68c2015-09-23 16:45:15 +05305969 if(packageList.size() == 0) {
5970 Log.d(TAG, "No packages to send broadcast.");
nxpandroida9a68ba2016-01-14 21:12:17 +05305971 unicastComponent = mNxpNfcController.getUnicastPackage();
5972 if(unicastComponent != null)
5973 {
5974 intent.setComponent(unicastComponent);
5975 try {
5976 //start gsma
5977 Log.d(TAG, "Starting activity uincast Pkg"+unicastComponent.flattenToString());
5978 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
5979 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
5980 if(mContext.getPackageManager().resolveActivity(intent, 0) != null)
5981 {
nxpandroid5d64ce92016-11-18 19:48:53 +05305982 mContext.startActivityAsUser(intent, UserHandle.CURRENT);
nxpandroida9a68ba2016-01-14 21:12:17 +05305983 } else {
5984 Log.d(TAG, "Intent not resolved");
5985 }
5986 } catch (Exception e) {
5987 if (DBG) Log.d(TAG, "Exception: " + e.getMessage());
5988 }
5989 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305990 return;
5991 }
nxpandroid64fd68c2015-09-23 16:45:15 +05305992 for(int i=0; i<packageList.size(); i++) {
5993 Log.d(TAG,"MultiEvt Enabled Application packageName: " + packageList.get(i));
5994 intent.setPackage(packageList.get(i));
nxpandroid5d64ce92016-11-18 19:48:53 +05305995 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT,
5996 NxpConstants.PERMISSIONS_TRANSACTION_EVENT);
nxpandroid64fd68c2015-09-23 16:45:15 +05305997 }
5998 }
5999
6000 private boolean llcpActivated(NfcDepEndpoint device) {
6001 Log.d(TAG, "LLCP Activation message");
6002
6003 if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) {
6004 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_TARGET");
6005 if (device.connect()) {
6006 /* Check LLCP compliance */
6007 if (mDeviceHost.doCheckLlcp()) {
6008 /* Activate LLCP Link */
6009 if (mDeviceHost.doActivateLlcp()) {
6010 if (DBG) Log.d(TAG, "Initiator Activate LLCP OK");
6011 synchronized (NfcService.this) {
6012 // Register P2P device
6013 mObjectMap.put(device.getHandle(), device);
6014 }
nxpandroid1153eb32015-11-06 18:46:58 +05306015 mP2pLinkManager.onLlcpActivated(device.getLlcpVersion());
nxpandroid64fd68c2015-09-23 16:45:15 +05306016 return true;
6017 } else {
6018 /* should not happen */
6019 Log.w(TAG, "Initiator LLCP activation failed. Disconnect.");
6020 device.disconnect();
6021 }
6022 } else {
6023 if (DBG) Log.d(TAG, "Remote Target does not support LLCP. Disconnect.");
6024 device.disconnect();
6025 }
6026 } else {
6027 if (DBG) Log.d(TAG, "Cannot connect remote Target. Polling loop restarted.");
6028 /*
6029 * The polling loop should have been restarted in failing
6030 * doConnect
6031 */
6032 }
6033 } else if (device.getMode() == NfcDepEndpoint.MODE_P2P_INITIATOR) {
6034 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_INITIATOR");
6035 /* Check LLCP compliancy */
6036 if (mDeviceHost.doCheckLlcp()) {
6037 /* Activate LLCP Link */
6038 if (mDeviceHost.doActivateLlcp()) {
6039 if (DBG) Log.d(TAG, "Target Activate LLCP OK");
6040 synchronized (NfcService.this) {
6041 // Register P2P device
6042 mObjectMap.put(device.getHandle(), device);
6043 }
nxpandroid1153eb32015-11-06 18:46:58 +05306044 mP2pLinkManager.onLlcpActivated(device.getLlcpVersion());
nxpandroid64fd68c2015-09-23 16:45:15 +05306045 return true;
6046 }
6047 } else {
6048 Log.w(TAG, "checkLlcp failed");
6049 }
6050 }
6051
6052 return false;
6053 }
6054
6055 private void dispatchTagEndpoint(TagEndpoint tagEndpoint, ReaderModeParams readerParams) {
6056 Tag tag = new Tag(tagEndpoint.getUid(), tagEndpoint.getTechList(),
6057 tagEndpoint.getTechExtras(), tagEndpoint.getHandle(), mNfcTagService);
6058 registerTagObject(tagEndpoint);
6059 if (readerParams != null) {
6060 try {
6061 if ((readerParams.flags & NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS) == 0) {
Suhas Suresh6e05ee02018-04-25 12:19:35 +05306062 mVibrator.vibrate(mVibrationEffect);
nxpandroid64fd68c2015-09-23 16:45:15 +05306063 playSound(SOUND_END);
6064 }
6065 if (readerParams.callback != null) {
6066 readerParams.callback.onTagDiscovered(tag);
6067 return;
6068 } else {
6069 // Follow normal dispatch below
6070 }
6071 } catch (RemoteException e) {
6072 Log.e(TAG, "Reader mode remote has died, falling back.", e);
6073 // Intentional fall-through
6074 } catch (Exception e) {
6075 // Catch any other exception
6076 Log.e(TAG, "App exception, not dispatching.", e);
6077 return;
6078 }
6079 }
6080 int dispatchResult = mNfcDispatcher.dispatchTag(tag);
6081 if (dispatchResult == NfcDispatcher.DISPATCH_FAIL) {
6082 unregisterObject(tagEndpoint.getHandle());
6083 playSound(SOUND_ERROR);
6084 } else if (dispatchResult == NfcDispatcher.DISPATCH_SUCCESS) {
Suhas Suresh6e05ee02018-04-25 12:19:35 +05306085 mVibrator.vibrate(mVibrationEffect);
nxpandroid64fd68c2015-09-23 16:45:15 +05306086 playSound(SOUND_END);
6087 }
6088 }
6089 }
6090
6091 private NfcServiceHandler mHandler = new NfcServiceHandler();
6092
6093 class ApplyRoutingTask extends AsyncTask<Integer, Void, Void> {
6094 @Override
6095 protected Void doInBackground(Integer... params) {
6096 synchronized (NfcService.this) {
6097 if (params == null || params.length != 1) {
6098 // force apply current routing
6099 Log.e(TAG, "applyRouting -1");
6100 applyRouting(true);
6101 return null;
6102 }
6103 mScreenState = params[0].intValue();
nxpandroid64fd68c2015-09-23 16:45:15 +05306104 mRoutingWakeLock.acquire();
6105 try {
6106 Log.e(TAG, "applyRouting -2");
6107 applyRouting(false);
6108 } finally {
6109 mRoutingWakeLock.release();
6110 }
6111 return null;
6112 }
6113 }
6114 }
6115
Pratap Reddy49abbe32018-03-27 16:51:59 +05306116 class EtsiStopConfigTask extends AsyncTask<Integer, Void, Void> {
nxpandroid64fd68c2015-09-23 16:45:15 +05306117 @Override
6118 protected Void doInBackground(Integer... params) {
Pratap Reddy49abbe32018-03-27 16:51:59 +05306119 synchronized (NfcService.this) {
6120 etsiStopConfig(params[0].intValue());
nxpandroid64fd68c2015-09-23 16:45:15 +05306121 return null;
Pratap Reddy49abbe32018-03-27 16:51:59 +05306122 }
6123 }
6124 }
6125
6126 class TagRemoveTaskTimer extends TimerTask {
6127 public void run()
6128 {
6129 Intent swpReaderTagRemoveIntent = new Intent();
6130 swpReaderTagRemoveIntent.setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_REMOVE_CARD);
6131 if (DBG) {
6132 Log.d(TAG, "SWP READER - Tag Remove");
6133 }
6134 mContext.sendBroadcast(swpReaderTagRemoveIntent);
nxpandroid64fd68c2015-09-23 16:45:15 +05306135 }
6136 }
6137
6138
6139 private final BroadcastReceiver x509CertificateReceiver = new BroadcastReceiver() {
6140 @Override
6141 public void onReceive(Context context, Intent intent) {
6142 boolean result = intent.getBooleanExtra(NxpConstants.EXTRA_RESULT, false);
6143 mNxpNfcController.setResultForCertificates(result);
6144 }
6145 };
6146
6147 private final BroadcastReceiver mEnableNfc = new BroadcastReceiver() {
6148 @Override
6149 public void onReceive(Context context, Intent intent) {
6150 String action = intent.getAction();
6151 Intent nfcDialogIntent = new Intent(mContext, EnableNfcDialogActivity.class);
6152 nfcDialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
6153 mContext.startActivityAsUser(nfcDialogIntent, UserHandle.CURRENT);
6154 }
6155 };
6156
Shashank vimal83779082018-02-06 18:10:31 +05306157 private final BroadcastReceiver mActivateSwpInterface = new BroadcastReceiver() {
6158 @Override
6159 public void onReceive(Context context, Intent intent) {
6160
6161 String action = intent.getAction();
6162
6163 if(NxpConstants.CAT_ACTIVATE_NOTIFY_ACTION.equals(action)){
6164
6165 Log.i(TAG, "Received ACTIVATE intent:" + action);
6166
6167 if(mSelectedSeId != ALL_SE_ID_TYPE){
6168 mDeviceHost.doSelectSecureElement(mSelectedSeId);
6169 Log.i(TAG, "Activated:" + mSelectedSeId);
6170 }
6171 else{
6172 int[] seList = mDeviceHost.doGetSecureElementList();
6173 Log.i(TAG, "Activating all SE:");
6174
6175 for(int i = 0; i < seList.length; i++){
6176 mDeviceHost.doActivateSecureElement(seList[i]);
6177 try{
6178 //Delay between two SE selection
6179 Thread.sleep(200);
6180 }catch(Exception e){
6181 e.printStackTrace();
6182 }
6183 }
6184 }
6185 }
6186 }
6187 };
6188
6189
nxpandroid64fd68c2015-09-23 16:45:15 +05306190 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
6191 @Override
6192 public void onReceive(Context context, Intent intent) {
6193 String action = intent.getAction();
nxpandroid6fd9cdb2017-07-12 18:25:41 +05306194 Log.e(TAG, "screen state "+action);
nxpandroid64fd68c2015-09-23 16:45:15 +05306195 if (action.equals(
6196 NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) {
6197 // Perform applyRouting() in AsyncTask to serialize blocking calls
6198 new ApplyRoutingTask().execute();
6199 } else if ((action.equals(Intent.ACTION_SCREEN_ON)
6200 || action.equals(Intent.ACTION_SCREEN_OFF)
6201 || action.equals(Intent.ACTION_USER_PRESENT)) &&
6202 mState == NfcAdapter.STATE_ON) {
6203 // Perform applyRouting() in AsyncTask to serialize blocking calls
nxpandroid6fd9cdb2017-07-12 18:25:41 +05306204 int screenState = mScreenStateHelper.checkScreenState();
nxpandroid64fd68c2015-09-23 16:45:15 +05306205 if (action.equals(Intent.ACTION_SCREEN_OFF)) {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05306206 if(mScreenState != ScreenStateHelper.SCREEN_STATE_OFF_LOCKED)
nxpandroid64fd68c2015-09-23 16:45:15 +05306207 {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05306208 Log.e(TAG, "screen state OFF required");
6209 screenState = mKeyguard.isKeyguardLocked() ?
6210 ScreenStateHelper.SCREEN_STATE_OFF_LOCKED :
6211 ScreenStateHelper.SCREEN_STATE_OFF_UNLOCKED;
nxpandroid64fd68c2015-09-23 16:45:15 +05306212 }
nxpandroid64fd68c2015-09-23 16:45:15 +05306213 } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
6214 screenState = mKeyguard.isKeyguardLocked() ?
6215 ScreenStateHelper.SCREEN_STATE_ON_LOCKED : ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED;
nxpandroid6fd9cdb2017-07-12 18:25:41 +05306216 Log.e(TAG, "screen state on");
6217 /*
nxpandroid64fd68c2015-09-23 16:45:15 +05306218 if(screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mScreenState == ScreenStateHelper.SCREEN_STATE_OFF) {
nxpandroid64fd68c2015-09-23 16:45:15 +05306219 } else if (screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mScreenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED) {
6220 return;
nxpandroid6fd9cdb2017-07-12 18:25:41 +05306221 }*/
nxpandroid64fd68c2015-09-23 16:45:15 +05306222 } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
6223 if (mScreenState != ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05306224 Log.e(TAG, "screen state user present");
nxpandroid64fd68c2015-09-23 16:45:15 +05306225 screenState = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED;
nxpandroid64fd68c2015-09-23 16:45:15 +05306226 } else {
6227 return;
6228 }
6229 }
Bhupendra Paware1c7ede2018-02-26 11:51:32 +05306230 /* This piece of code is duplicate as MSG_APPLY_SCREEN_STATE
6231 is already calling applyRouting api */
6232 /*if(nci_version != NCI_VERSION_2_0) {
nxpandroide66eb092017-07-12 21:36:08 +05306233 new ApplyRoutingTask().execute(Integer.valueOf(screenState));
Bhupendra Paware1c7ede2018-02-26 11:51:32 +05306234 }*/
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05306235
6236 if( mDeviceHost.getEtsiReaederState() == STATE_SE_RDR_MODE_STOPPED ||
6237 mDeviceHost.getEtsiReaederState() == STATE_SE_RDR_MODE_INVALID) {
6238 sendMessage(NfcService.MSG_APPLY_SCREEN_STATE, screenState);
6239 } else {
6240 Log.e(TAG, "mPOS in progress holding screen state "+screenState);
6241 mScreenState = screenState;
6242 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +05306243 Log.e(TAG, "screen state "+screenState);
6244 Log.e(TAG, "screen state mScreenState "+mScreenState);
nxpandroid64fd68c2015-09-23 16:45:15 +05306245 } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
nxpandroid6fd9cdb2017-07-12 18:25:41 +05306246 int screenState = mScreenStateHelper.checkScreenState();
nxpandroid64fd68c2015-09-23 16:45:15 +05306247 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
Suhas Sureshe2a2ff02018-04-27 12:21:19 +05306248 int beamSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6249 try {
6250 IPackageManager mIpm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
6251 beamSetting = mIpm.getComponentEnabledSetting(new ComponentName(
6252 BeamShareActivity.class.getPackageName$(),
6253 BeamShareActivity.class.getName()),
6254 userId);
6255 } catch(RemoteException e) {
6256 Log.e(TAG, "Error int getComponentEnabledSetting for BeamShareActivity");
6257 }
nxpandroid64fd68c2015-09-23 16:45:15 +05306258 synchronized (this) {
6259 mUserId = userId;
Suhas Sureshe2a2ff02018-04-27 12:21:19 +05306260 if (beamSetting == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
6261 mIsNdefPushEnabled = false;
6262 } else {
6263 mIsNdefPushEnabled = true;
6264 }
nxpandroid64fd68c2015-09-23 16:45:15 +05306265 }
6266 mP2pLinkManager.onUserSwitched(getUserId());
6267 if (mIsHceCapable) {
6268 mCardEmulationManager.onUserSwitched(getUserId());
6269 }
nxpandroide66eb092017-07-12 21:36:08 +05306270 screenState = mScreenStateHelper.checkScreenState();
nxpandroid64fd68c2015-09-23 16:45:15 +05306271 new ApplyRoutingTask().execute(Integer.valueOf(screenState));
nxpandroid64fd68c2015-09-23 16:45:15 +05306272 }
6273 }
6274 };
6275
6276 private final BroadcastReceiver mOwnerReceiver = new BroadcastReceiver() {
6277 @Override
6278 public void onReceive(Context context, Intent intent) {
6279 String action = intent.getAction();
6280 if (action.equals(Intent.ACTION_PACKAGE_REMOVED) ||
6281 action.equals(Intent.ACTION_PACKAGE_ADDED) ||
6282 action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE) ||
6283 action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) {
6284 updatePackageCache();
6285
nxpandroid5d64ce92016-11-18 19:48:53 +05306286 } else if(action.equals(Intent.ACTION_SHUTDOWN)) {
6287 mPowerShutDown = true;
6288 if (DBG) Log.d(TAG,"Device is shutting down.");
6289 mDeviceHost.doSetScreenOrPowerState(ScreenStateHelper.POWER_STATE_OFF);
Suhas Suresh9139dc22018-05-09 15:48:37 +05306290 if (isNfcEnabled()) {
6291 mDeviceHost.shutdown();
6292 }
nxpandroid64fd68c2015-09-23 16:45:15 +05306293 }
6294 }
6295 };
6296
6297 final BroadcastReceiver mAlaReceiver = new BroadcastReceiver() {
6298 @Override
6299 public void onReceive(Context context, Intent intent) {
6300 String action = intent.getAction();
6301 if (NfcAdapter.ACTION_ADAPTER_STATE_CHANGED.equals(intent.getAction())) {
6302 int state = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE,
6303 NfcAdapter.STATE_OFF);
6304 if (state == NfcAdapter.STATE_ON) {
6305 Log.e(TAG, "Loader service update start from NFC_ON Broadcast");
6306 NfcAlaService nas = new NfcAlaService();
nxpandroid5d3fdf82017-07-31 16:11:33 +05306307 int lsVersion = mNfcAla.doGetLSConfigVersion();
6308
6309 if(lsVersion >= LOADER_SERVICE_VERSION_LOW_LIMIT &&
6310 lsVersion <= LOADER_SERVICE_VERSION_HIGH_LIMIT)
nxpandroid64fd68c2015-09-23 16:45:15 +05306311 nas.updateLoaderService();
6312 }
6313 }
6314 }
6315 };
6316
6317 private final BroadcastReceiver mPolicyReceiver = new BroadcastReceiver() {
6318 @Override
6319 public void onReceive(Context context, Intent intent){
6320 String action = intent.getAction();
6321 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
6322 .equals(action)) {
6323 enforceBeamShareActivityPolicy(context,
Suhas Suresha18dee02018-04-27 15:28:04 +05306324 new UserHandle(getSendingUserId()));
nxpandroid64fd68c2015-09-23 16:45:15 +05306325 }
6326 }
6327 };
6328
Nikhil Chhabrafc8f3f62018-01-08 20:48:49 +05306329 private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
6330 @Override
6331 public void onVrStateChanged(boolean enabled) {
6332 synchronized (this) {
6333 mIsVrModeEnabled = enabled;
6334 }
6335 }
6336 };
6337
nxpandroid64fd68c2015-09-23 16:45:15 +05306338 /**
nxpandroid64fd68c2015-09-23 16:45:15 +05306339 * for debugging only - no i18n
6340 */
6341 static String stateToString(int state) {
6342 switch (state) {
6343 case NfcAdapter.STATE_OFF:
6344 return "off";
6345 case NfcAdapter.STATE_TURNING_ON:
6346 return "turning on";
6347 case NfcAdapter.STATE_ON:
6348 return "on";
6349 case NfcAdapter.STATE_TURNING_OFF:
6350 return "turning off";
6351 default:
6352 return "<error>";
6353 }
6354 }
6355
6356 void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
6357 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
6358 != PackageManager.PERMISSION_GRANTED) {
6359 pw.println("Permission Denial: can't dump nfc from from pid="
6360 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6361 + " without permission " + android.Manifest.permission.DUMP);
6362 return;
6363 }
6364
6365 synchronized (this) {
6366 pw.println("mState=" + stateToString(mState));
6367 pw.println("mIsZeroClickRequested=" + mIsNdefPushEnabled);
6368 pw.println("mScreenState=" + ScreenStateHelper.screenStateToString(mScreenState));
6369 pw.println("mNfcPollingEnabled=" + mNfcPollingEnabled);
6370 pw.println("mNfceeRouteEnabled=" + mNfceeRouteEnabled);
6371 pw.println("mOpenEe=" + mOpenEe);
nxpandroid64fd68c2015-09-23 16:45:15 +05306372 pw.println("mLockscreenPollMask=" + mLockscreenPollMask);
6373 pw.println(mCurrentDiscoveryParameters);
6374 mP2pLinkManager.dump(fd, pw, args);
6375 if (mIsHceCapable) {
6376 mCardEmulationManager.dump(fd, pw, args);
6377 }
nxpandroid64fd68c2015-09-23 16:45:15 +05306378 mNfcDispatcher.dump(fd, pw, args);
Nikhil Chhabra9645ab62018-01-09 18:44:05 +05306379 pw.flush();
Nikhil Chhabra1e1ac462018-01-10 12:53:43 +05306380 mDeviceHost.dump(fd);
nxpandroid64fd68c2015-09-23 16:45:15 +05306381
6382 }
6383 }
nxpandroid34627bd2016-05-27 15:52:30 +05306384 /**
6385 * Update the status of all the services which were populated to commit to routing table
6386 */
6387 public void updateStatusOfServices(boolean commitStatus) {
nxpandroidebf53fb2016-12-22 18:48:59 +05306388 if(commitStatus == true)
6389 {
6390 mAidCache.setPreviousPreferredPaymentService(null);
6391 }
nxpandroid34627bd2016-05-27 15:52:30 +05306392 mCardEmulationManager.updateStatusOfServices(commitStatus);
6393 }
nxpandroid64fd68c2015-09-23 16:45:15 +05306394}