diff options
Diffstat (limited to 'src/com')
56 files changed, 2056 insertions, 4649 deletions
diff --git a/src/com/android/nfc/BeamShareActivity.java b/src/com/android/nfc/BeamShareActivity.java index 446e499a..446e499a 100644..100755 --- a/src/com/android/nfc/BeamShareActivity.java +++ b/src/com/android/nfc/BeamShareActivity.java diff --git a/src/com/android/nfc/ConfirmConnectToWifiNetworkActivity.java b/src/com/android/nfc/ConfirmConnectToWifiNetworkActivity.java index 4734f04c..e81f0762 100644..100755 --- a/src/com/android/nfc/ConfirmConnectToWifiNetworkActivity.java +++ b/src/com/android/nfc/ConfirmConnectToWifiNetworkActivity.java @@ -2,6 +2,7 @@ package com.android.nfc; import android.app.Activity; import android.app.AlertDialog; +import android.app.AppOpsManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; @@ -11,6 +12,7 @@ import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.Handler; +import android.os.Process; import android.view.View; import android.widget.Toast; @@ -60,7 +62,9 @@ public class ConfirmConnectToWifiNetworkActivity extends Activity public void onClick(View v) { WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); - if (!wifiManager.isWifiEnabled()) { + if (!isChangeWifiStateGranted()) { + showFailToast(); + } else if (!wifiManager.isWifiEnabled()) { wifiManager.setWifiEnabled(true); mEnableWifiInProgress = true; @@ -81,6 +85,13 @@ public class ConfirmConnectToWifiNetworkActivity extends Activity mAlertDialog.dismiss(); } + private boolean isChangeWifiStateGranted() { + AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE); + int modeChangeWifiState = appOps.checkOpNoThrow(AppOpsManager.OP_CHANGE_WIFI_STATE, + Process.NFC_UID, getPackageName()); + return modeChangeWifiState == AppOpsManager.MODE_ALLOWED; + } + private void doConnect(WifiManager wifiManager) { mCurrentWifiConfiguration.hiddenSSID = true; int networkId = wifiManager.addNetwork(mCurrentWifiConfiguration); @@ -139,7 +150,6 @@ public class ConfirmConnectToWifiNetworkActivity extends Activity doConnect( (WifiManager) ConfirmConnectToWifiNetworkActivity.this .getSystemService(Context.WIFI_SERVICE)); - ConfirmConnectToWifiNetworkActivity.this.finish(); } } } diff --git a/src/com/android/nfc/DeviceHost.java b/src/com/android/nfc/DeviceHost.java index 1c5afa73..19985dd0 100755 --- a/src/com/android/nfc/DeviceHost.java +++ b/src/com/android/nfc/DeviceHost.java @@ -14,30 +14,29 @@ * limitations under the License. */ /****************************************************************************** - * - * The original Work has been changed by NXP Semiconductors. - * - * Copyright (C) 2015-2018 NXP Semiconductors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ +* +* The original Work has been changed by NXP. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +* Copyright 2018-2019 NXP +* +******************************************************************************/ package com.android.nfc; import android.annotation.Nullable; import android.nfc.NdefMessage; import android.os.Bundle; - import java.io.FileDescriptor; import java.io.IOException; @@ -46,27 +45,21 @@ public interface DeviceHost { public void onRemoteEndpointDiscovered(TagEndpoint tag); /** - * Notifies transaction */ - public void onCardEmulationDeselected(); - - /** - * Notifies connectivity event from the SE - */ - public void onConnectivityEvent(int evtSrc); public void onHostCardEmulationActivated(int technology); public void onHostCardEmulationData(int technology, byte[] data); public void onHostCardEmulationDeactivated(int technology); - public void onAidRoutingTableFull(); - public void onNotifyT3tConfigure(); - public void onNotifyReRoutingEntry(); + /** + * Notifies that the SE has been activated in listen mode + */ + public void onSeListenActivated(); /** - * Notifies about multiple card presented to - * emvco reader. + * Notifies that the SE has been deactivated */ - public void onEmvcoMultiCardDetectedEvent(); + public void onSeListenDeactivated(); + public void onSeInitialized(); /** * Notifies P2P Device detected, to activate LLCP link */ @@ -82,28 +75,6 @@ public interface DeviceHost { public void onRemoteFieldActivated(); public void onRemoteFieldDeactivated(); - - /*Restart disable watchdog timer*/ - public void onRestartWatchDog(int enable); - - /*Restart NFC:When Fw dwnld request was stored during SPI onGoing*/ - public void onFwDwnldReqRestartNfc(); - - /** - * Notifies that the SE has been activated in listen mode - */ - public void onSeListenActivated(); - - /** - * Notifies that the SE has been deactivated - */ - public void onSeListenDeactivated(); - - public void onSeApduReceived(byte[] apdu); - - public void onSeEmvCardRemoval(); - - public void onSeMifareAccess(byte[] block); /** * Notifies SWP Reader Events. */ @@ -119,8 +90,6 @@ public interface DeviceHost { public void onETSIReaderModeRestart(); - public void onUiccStatusEvent(int uiccStat); - public void onNfcTransactionEvent(byte[] aid, byte[] data, String seName); } @@ -245,9 +214,7 @@ public interface DeviceHost { * <p>This is called from a thread * that may block for long periods of time during the update process. */ - public void checkFirmware(); - - public boolean download(); + public boolean checkFirmware(); public boolean initialize(); @@ -257,54 +224,20 @@ public interface DeviceHost { public void enableDiscovery(NfcDiscoveryParameters params, boolean restart); - public int getNciVersion(); - - public void doSetScreenState(int screen_state_mask); - - public void doEnablep2p(boolean p2pFlag); - public void disableDiscovery(); - public int[] doGetSecureElementList(); - public int[] doGetActiveSecureElementList(); - - public void doSelectSecureElement(int seID); - - public void doActivateSecureElement(int seID); - - public void doSetSecureElementListenTechMask(int tech_mask); - public int doGetSecureElementTechList(); - - public int GetDefaultSE(); - - public byte[] getSecureElementUid(); - - public int setEmvCoPollProfile(boolean enable, int route); - - public void doDeselectSecureElement(int seID); - - public void doSetSEPowerOffState(int seID,boolean enable); - - public void setDefaultTechRoute(int seID, int tech_switchon, int tech_switchoff); - - public void setDefaultProtoRoute(int seID, int proto_switchon, int proto_switchoff); - - public void doSetProvisionMode(boolean provisionMode); - public boolean sendRawFrame(byte[] data); - public boolean routeAid(byte[] aid, int route, int powerState, int aidInfo); - - public boolean setDefaultRoute(int defaultRouteEntry, int defaultProtoRouteEntry, int defaultTechRouteEntry); + public boolean routeAid(byte[] aid, int route, int aidInfo, int powerState); public boolean unrouteAid(byte[] aid); - public boolean clearAidTable(); - public int getAidTableSize(); - public int getRemainingAidTableSize(); + public boolean setRoutingEntry(int type, int value, int route, int power); + + public boolean clearRoutingEntry(int type); public int getDefaultAidRoute(); @@ -312,15 +245,29 @@ public interface DeviceHost { public int getDefaultMifareCLTRoute(); + public int getDefaultFelicaCLTRoute(); + public int getDefaultAidPowerState(); public int getDefaultDesfirePowerState(); public int getDefaultMifareCLTPowerState(); - public boolean setRoutingEntry(int type, int value, int route, int power); + public int getDefaultFelicaCLTPowerState(); - public boolean clearRoutingEntry(int type); + public int getGsmaPwrState(); + + public boolean commitRouting(); + + public void setEmptyAidRoute(int defaultAidRoute); + + public void registerT3tIdentifier(byte[] t3tIdentifier); + + public void deregisterT3tIdentifier(byte[] t3tIdentifier); + + public void clearT3tIdentifiersCache(); + + public int getLfT3tMax(); public boolean routeApduPattern(int route, int powerState, byte[] apduData, byte[] apduMask); @@ -335,16 +282,10 @@ public interface DeviceHost { public boolean unrouteApduPattern(byte[] apduData); - public int doNfcSelfTest(int type); - public boolean doCheckLlcp(); - public boolean doCheckJcopDlAtBoot(); - public boolean doActivateLlcp(); - public void doSetScreenOrPowerState(int state); - public void resetTimeouts(); public boolean setTimeout(int technology, int timeout); @@ -363,31 +304,17 @@ public interface DeviceHost { boolean getExtendedLengthApdusSupported(); - byte[][] getWipeApdus(); - int getDefaultLlcpMiu(); int getDefaultLlcpRwSize(); - int getChipVer(); - - int setTransitConfig(String configs); - - int getNfcInitTimeout(); - - int JCOSDownload(); - - void doSetNfcMode(int nfcMode); - void dump(FileDescriptor fd); boolean enableScreenOffSuspend(); boolean disableScreenOffSuspend(); - boolean isVzwFeatureEnabled(); - - boolean isNfccBusy(); + public void doSetScreenState(int screen_state_mask); void setEtsiReaederState(int newState); @@ -409,34 +336,7 @@ public interface DeviceHost { boolean mposGetReaderMode(); - void updateScreenState(); - //boolean enableReaderMode(int technologies); - - //boolean disableScreenOffSuspend(); - - public void registerT3tIdentifier(byte[] t3tIdentifier); - - public void deregisterT3tIdentifier(byte[] t3tIdentifier); - - public void clearT3tIdentifiersCache(); - - public int getLfT3tMax(); - - void commitRouting(); - - //Factory Test --start - public void doPrbsOn(int prbs, int hw_prbs, int tech, int rate); - - public void doPrbsOff(); - - public int SWPSelfTest(int ch); - - public int getFWVersion(); - - public byte[] doGetRouting(); - - public void doSetEEPROM(byte[] val); - //Factory Test --end + public int getNciVersion(); public void enableDtaMode(); @@ -446,13 +346,20 @@ public interface DeviceHost { public void shutdown(); - public int doselectUicc(int uiccSlot); + public boolean setNfcSecure(boolean enable); - public int doGetSelectedUicc(); - - public int setPreferredSimSlot(int uiccSlot); +/* NXP extension are here */ + public void doChangeDiscoveryTech(int pollTech, int listenTech); + public int accessControlForCOSU (int mode); + public int getFWVersion(); public byte[] readerPassThruMode(byte status, byte modulationTyp); - public byte[] transceiveAppData(byte[] data); + boolean isNfccBusy(); + int setTransitConfig(String configs); + public int getRemainingAidTableSize(); + public int doselectUicc(int uiccSlot); + public int doGetSelectedUicc(); + public int setPreferredSimSlot(int uiccSlot); + } diff --git a/src/com/android/nfc/DtaServiceConnector.java b/src/com/android/nfc/DtaServiceConnector.java index a6620866..147084b7 100755 --- a/src/com/android/nfc/DtaServiceConnector.java +++ b/src/com/android/nfc/DtaServiceConnector.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2018 NXP Semiconductors + * Copyright (C) 2017 NXP Semiconductors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,13 +44,11 @@ public class DtaServiceConnector { } public void bindService() { - if (!isBound) { - Intent intent = new Intent(sMessageService); - Intent explicitIntent = createExplicitFromImplicitIntent(mContext, intent); - if (null != explicitIntent) { - mContext.bindService(explicitIntent, myConnection, Context.BIND_AUTO_CREATE); + if (!isBound) { + Intent intent = new Intent(sMessageService); + mContext.bindService(createExplicitFromImplicitIntent(mContext,intent), + myConnection,Context.BIND_AUTO_CREATE); } - } } private ServiceConnection myConnection = new ServiceConnection() { diff --git a/src/com/android/nfc/EnableNfcDialogActivity.java b/src/com/android/nfc/EnableNfcDialogActivity.java deleted file mode 100644 index f9d72426..00000000 --- a/src/com/android/nfc/EnableNfcDialogActivity.java +++ /dev/null @@ -1,68 +0,0 @@ -/* -* Copyright (C) 2015 NXP Semiconductors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package com.android.nfc; - -import android.content.Intent; -import android.nfc.NfcAdapter; -import android.os.Bundle; -import android.widget.Button; -import android.content.DialogInterface; -import com.android.internal.app.AlertActivity; -import com.android.internal.app.AlertController; -import com.nxp.nfc.NxpConstants; -import com.android.internal.R; - - -public class EnableNfcDialogActivity extends AlertActivity implements DialogInterface.OnClickListener { - static final String TAG ="EnableNfcDialogActivity"; - static final boolean DBG = false; - - Intent mLaunchIntent; - Button mBt1, mBt2; - NfcAdapter mNfcAdapter; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setTheme(R.style.Theme_DeviceDefault_Light_Dialog_Alert); - super.onCreate(savedInstanceState); - mNfcAdapter = NfcAdapter.getDefaultAdapter(this); - - AlertController.AlertParams ap = mAlertParams; - - ap.mMessage = getString(com.android.nfc.R.string.nfc_enabled_dialog); - ap.mNegativeButtonText = getString(com.android.nfc.R.string.cancel); - ap.mPositiveButtonText = getString(com.android.nfc.R.string.ok); - ap.mPositiveButtonListener = this; - ap.mNegativeButtonListener = this; - setupAlert(); - } - - @Override - public void onClick(DialogInterface dialog, int which) { - Intent enableNfc = new Intent(); - enableNfc.setAction(NxpConstants.ACTION_GSMA_ENABLE_SET_FLAG); - if(which == -1) { - mNfcAdapter.enable(); // POSITIVE - enableNfc.putExtra("ENABLE_STATE", true); - } else if(which == -2) { //Nagitive - enableNfc.putExtra("ENABLE_STATE", false); - } - sendBroadcast(enableNfc); - finish(); - } -} diff --git a/src/com/android/nfc/ForegroundUtils.java b/src/com/android/nfc/ForegroundUtils.java index e5c3491c..e5c3491c 100644..100755 --- a/src/com/android/nfc/ForegroundUtils.java +++ b/src/com/android/nfc/ForegroundUtils.java diff --git a/src/com/android/nfc/NfcApplication.java b/src/com/android/nfc/NfcApplication.java index 6210c2d6..6210c2d6 100644..100755 --- a/src/com/android/nfc/NfcApplication.java +++ b/src/com/android/nfc/NfcApplication.java diff --git a/src/com/android/nfc/NfcBackupAgent.java b/src/com/android/nfc/NfcBackupAgent.java index 98637dbf..98637dbf 100644..100755 --- a/src/com/android/nfc/NfcBackupAgent.java +++ b/src/com/android/nfc/NfcBackupAgent.java diff --git a/src/com/android/nfc/NfcBootCompletedReceiver.java b/src/com/android/nfc/NfcBootCompletedReceiver.java index 6827a91c..fef0ff5f 100644..100755 --- a/src/com/android/nfc/NfcBootCompletedReceiver.java +++ b/src/com/android/nfc/NfcBootCompletedReceiver.java @@ -40,4 +40,3 @@ public class NfcBootCompletedReceiver extends BroadcastReceiver { } } } - diff --git a/src/com/android/nfc/NfcDiscoveryParameters.java b/src/com/android/nfc/NfcDiscoveryParameters.java index 1149836d..1149836d 100644..100755 --- a/src/com/android/nfc/NfcDiscoveryParameters.java +++ b/src/com/android/nfc/NfcDiscoveryParameters.java diff --git a/src/com/android/nfc/NfcDispatcher.java b/src/com/android/nfc/NfcDispatcher.java index 068e1c4b..1d633f87 100755 --- a/src/com/android/nfc/NfcDispatcher.java +++ b/src/com/android/nfc/NfcDispatcher.java @@ -16,16 +16,16 @@ package com.android.nfc; -import android.Manifest; +import android.app.ActivityManager; import android.bluetooth.BluetoothAdapter; import android.os.UserManager; + import com.android.nfc.RegisteredComponentCache.ComponentInfo; import com.android.nfc.handover.HandoverDataParser; import com.android.nfc.handover.PeripheralHandoverService; import android.app.Activity; import android.app.ActivityManager; -import android.app.AlertDialog; import android.app.IActivityManager; import android.app.PendingIntent; import android.app.PendingIntent.CanceledException; @@ -33,7 +33,6 @@ import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; @@ -53,10 +52,6 @@ import android.os.Messenger; import android.os.RemoteException; import android.os.UserHandle; import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.WindowManager; -import android.widget.TextView; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -66,7 +61,6 @@ import java.util.Arrays; import java.util.concurrent.atomic.AtomicBoolean; import java.util.LinkedList; import java.util.List; -import java.util.Locale; /** * Dispatch of NFC events to start activities @@ -85,7 +79,6 @@ class NfcDispatcher { private final ContentResolver mContentResolver; private final HandoverDataParser mHandoverDataParser; private final String[] mProvisioningMimes; - private final String[] mLiveCaseMimes; private final ScreenStateHelper mScreenStateHelper; private final NfcUnlockManager mNfcUnlockManager; private final boolean mDeviceSupportsBluetooth; @@ -101,8 +94,7 @@ class NfcDispatcher { NfcDispatcher(Context context, HandoverDataParser handoverDataParser, - boolean provisionOnly, - boolean isLiveCaseEnabled) { + boolean provisionOnly) { mContext = context; mIActivityManager = ActivityManager.getService(); mTechListFilters = new RegisteredComponentCache(mContext, @@ -128,18 +120,6 @@ class NfcDispatcher { } mProvisioningMimes = provisionMimes; - String[] liveCaseMimes = null; - if (isLiveCaseEnabled) { - try { - // Get accepted mime-types - liveCaseMimes = context.getResources(). - getStringArray(R.array.live_case_mime_types); - } catch (NotFoundException e) { - liveCaseMimes = null; - } - } - mLiveCaseMimes = liveCaseMimes; - IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); mContext.registerReceiver(mBluetoothStatusReceiver, filter); } @@ -221,16 +201,6 @@ class NfcDispatcher { return intent; } - public boolean isWebIntent() { - if (ndefUri == null) return false; - if (ndefUri.normalizeScheme().getScheme() == null) return false; - return ndefUri != null && ndefUri.normalizeScheme().getScheme().startsWith("http"); - } - - public String getUri() { - return ndefUri.toString(); - } - /** * Launch the activity via a (single) NFC root task, so that it * creates a new task stack instead of interfering with any existing @@ -277,9 +247,9 @@ class NfcDispatcher { IntentFilter[] overrideFilters; String[][] overrideTechLists; String[] provisioningMimes; - String[] liveCaseMimes; - NdefMessage message = null; boolean provisioningOnly; + NdefMessage message = null; + Ndef ndef = Ndef.get(tag); synchronized (this) { overrideFilters = mOverrideFilters; @@ -287,34 +257,19 @@ class NfcDispatcher { overrideTechLists = mOverrideTechLists; provisioningOnly = mProvisioningOnly; provisioningMimes = mProvisioningMimes; - liveCaseMimes = mLiveCaseMimes; } boolean screenUnlocked = false; - boolean liveCaseDetected = false; - Ndef ndef = Ndef.get(tag); if (!provisioningOnly && mScreenStateHelper.checkScreenState() == ScreenStateHelper.SCREEN_STATE_ON_LOCKED) { screenUnlocked = handleNfcUnlock(tag); - - if (ndef != null) { - message = ndef.getCachedNdefMessage(); - if (message != null) { - String ndefMimeType = message.getRecords()[0].toMimeType(); - if (liveCaseMimes != null && - Arrays.asList(liveCaseMimes).contains(ndefMimeType)) { - liveCaseDetected = true; - } - } - } - - if (!screenUnlocked && !liveCaseDetected) + if (!screenUnlocked) return DISPATCH_FAIL; } if (ndef != null) { message = ndef.getCachedNdefMessage(); - }else { + } else { NfcBarcode nfcBarcode = NfcBarcode.get(tag); if (nfcBarcode != null && nfcBarcode.getType() == NfcBarcode.TYPE_KOVIO) { message = decodeNfcBarcodeUri(nfcBarcode); @@ -427,7 +382,7 @@ class NfcDispatcher { // All tags of NfcBarcode technology and Kovio type have lengths of a multiple of 16 bytes if (tagId.length >= 4 && (tagId[1] == URI_PREFIX_HTTP_WWW || tagId[1] == URI_PREFIX_HTTPS_WWW - || tagId[1] == URI_PREFIX_HTTP || tagId[1] == URI_PREFIX_HTTPS)) { + || tagId[1] == URI_PREFIX_HTTP || tagId[1] == URI_PREFIX_HTTPS)) { // Look for optional URI terminator (0xfe), used to indicate the end of a URI prior to // the end of the full NfcBarcode payload. No terminator means that the URI occupies the // entire length of the payload field. Exclude checking the CRC in the final two bytes @@ -569,13 +524,6 @@ class NfcDispatcher { // regular launch dispatch.intent.setPackage(null); - - if (dispatch.isWebIntent()) { - if (DBG) Log.i(TAG, "matched Web link - prompting user"); - showWebLinkConfirmation(dispatch); - return true; - } - if (dispatch.tryStartActivity()) { if (DBG) Log.i(TAG, "matched NDEF"); return true; @@ -683,6 +631,7 @@ class NfcDispatcher { return true; } + /** * Tells the ActivityManager to resume allowing app switches. * @@ -747,33 +696,6 @@ class NfcDispatcher { return enabled; } - void showWebLinkConfirmation(DispatchInfo dispatch) { - if (!mContext.getResources().getBoolean(R.bool.enable_nfc_url_open_dialog)) { - dispatch.tryStartActivity(); - return; - } - AlertDialog.Builder builder = new AlertDialog.Builder( - mContext.getApplicationContext(), - android.R.style.Theme_DeviceDefault_Light_Dialog_Alert); - builder.setTitle(R.string.title_confirm_url_open); - LayoutInflater inflater = LayoutInflater.from(mContext); - View view = inflater.inflate(R.layout.url_open_confirmation, null); - if (view != null) { - TextView url = view.findViewById(R.id.url_open_confirmation_link); - if (url != null) { - url.setText(dispatch.getUri()); - } - builder.setView(view); - } - builder.setNegativeButton(R.string.cancel, (dialog, which) -> {}); - builder.setPositiveButton(R.string.action_confirm_url_open, (dialog, which) -> { - dispatch.tryStartActivity(); - }); - AlertDialog dialog = builder.create(); - dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); - dialog.show(); - } - void dump(FileDescriptor fd, PrintWriter pw, String[] args) { synchronized (this) { pw.println("mOverrideIntent=" + mOverrideIntent); diff --git a/src/com/android/nfc/NfcPermissions.java b/src/com/android/nfc/NfcPermissions.java index 2972cae2..50adf23a 100644..100755 --- a/src/com/android/nfc/NfcPermissions.java +++ b/src/com/android/nfc/NfcPermissions.java @@ -9,7 +9,7 @@ public class NfcPermissions { /** * NFC ADMIN permission - only for system apps */ - static final String ADMIN_PERM = android.Manifest.permission.WRITE_SECURE_SETTINGS; + private static final String ADMIN_PERM = android.Manifest.permission.WRITE_SECURE_SETTINGS; private static final String ADMIN_PERM_ERROR = "WRITE_SECURE_SETTINGS permission required"; /** diff --git a/src/com/android/nfc/NfcRootActivity.java b/src/com/android/nfc/NfcRootActivity.java index 68687cb8..cc216f2e 100755 --- a/src/com/android/nfc/NfcRootActivity.java +++ b/src/com/android/nfc/NfcRootActivity.java @@ -17,6 +17,7 @@ package com.android.nfc; import android.app.Activity; +import android.app.ActivityManager; import android.content.ActivityNotFoundException; import android.content.Intent; import android.os.Bundle; diff --git a/src/com/android/nfc/NfcSccAccessControl.java b/src/com/android/nfc/NfcSccAccessControl.java deleted file mode 100644 index bbe46594..00000000 --- a/src/com/android/nfc/NfcSccAccessControl.java +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (C) 2015 NXP Semiconductors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package com.android.nfc; - -import java.io.File; -import java.io.FileDescriptor; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.HashMap; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlPullParserFactory; - -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.Signature; -import android.content.pm.PackageManager.NameNotFoundException; -import android.os.Environment; -import android.util.Log; - -public class NfcSccAccessControl { - static final String TAG = "NfcSccAccess"; - static final boolean DBG = true; - - /*NFC Smart Card Channel Access Control*/ - public static final String NFCSCC_ACCESS_PATH = "/etc/nfcscc_access.xml"; - - /** - * Map of signatures to valid packages names, as read from nfcscc_access.xml. - * An empty list of package names indicates that any package - * with this signature is allowed. - */ - final HashMap<Signature, String[]> mNfcsccAccess; // contents final after onCreate() - - /** - * Map from UID to NFCSCC access, used as a cache. - * Note: if a UID contains multiple packages they must all be - * signed with the same certificate so in effect UID == certificate - * used to sign the package. - */ - final HashMap<Integer, Boolean> mUidCache; // contents guarded by this - - final Context mContext; - final boolean mDebugPrintSignature; - - NfcSccAccessControl(Context context) { - mContext = context; - mNfcsccAccess = new HashMap<Signature, String[]>(); - mUidCache = new HashMap<Integer, Boolean>(); - mDebugPrintSignature = parseNfcsccAccess(); - } - - /** - * Check if the {uid, pkg} combination may use NFCEE. - * Also verify with package manager that this {uid, pkg} combination - * is valid if it is not cached. - */ - public boolean check(int uid, String pkg) { - Log.d(TAG, "check : " + pkg + " UID " + uid); - synchronized (this) { - - boolean access = false; - boolean packageFound = false; - // Ensure the claimed package is present in the calling UID - PackageManager pm = mContext.getPackageManager(); - String[] pkgs = pm.getPackagesForUid(uid); - for (String uidPkg : pkgs) { - if (uidPkg.equals(pkg)) { - packageFound = true; - - Boolean cached = mUidCache.get(uid); - if (cached != null) { - return cached; - } - - // Ensure the package has access permissions - if (checkPackageNfcsccAccess(pkg)) { - access = true; - } - break; - } - } - - //Special case to support NFC EE SERVICE. - //FIXME: Need to improve. - if(!packageFound) { - String[] pkgs1 = pm.getPackagesForUid(uid); - for (String uidPkg : pkgs1) { - if ("com.nxp.nfceeapi.service".compareTo(uidPkg) == 0) { - if (checkPackageNfcsccAccess(pkg)) { - access = true; - } - break; - } - } - } - Log.d(TAG, "Access for " + pkg + " UID " + uid + " IS " + access); - if(packageFound) - { - mUidCache.put(uid, access); - } - return access; - } - } - - /** - * Check if the given ApplicationInfo may use the NFCEE. - * Assumes ApplicationInfo came from package manager, - * so no need to confirm {uid, pkg} is valid. - */ - public boolean check(ApplicationInfo info) { - synchronized (this) { - Boolean access = mUidCache.get(info.uid); - if (access == null) { - access = checkPackageNfcsccAccess(info.packageName); - mUidCache.put(info.uid, access); - } - return access; - } - } - - public void invalidateCache() { - synchronized (this) { - mUidCache.clear(); - } - } - - /** - * Check with package manager if the pkg may use NFCEE. - * Does not use cache. - */ - boolean checkPackageNfcsccAccess(String pkg) { - PackageManager pm = mContext.getPackageManager(); - try { - PackageInfo info = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES); - if (info.signatures == null) { - return false; - } - - for (Signature s : info.signatures){ - if (s == null) { - continue; - } - String[] packages = mNfcsccAccess.get(s); - if (packages == null) { - continue; - } - if (packages.length == 0) { - // wildcard access - if (DBG) Log.d(TAG, "Granted NFCSCC access to " + pkg + " (wildcard)"); - return true; - } - for (String p : packages) { - if (pkg.equals(p)) { - // explicit package access - if (DBG) Log.d(TAG, "Granted access to " + pkg + " (explicit)"); - return true; - } - } - } - - if (mDebugPrintSignature) { - Log.w(TAG, "denied NFCSCC access for " + pkg + " with signature:"); - for (Signature s : info.signatures) { - if (s != null) { - Log.w(TAG, s.toCharsString()); - } - } - } - } catch (NameNotFoundException e) { - // ignore - } - return false; - } - - /** - * Parse NFCSCC_access.xml, populate mNFCSCCAccess - * Policy is to ignore unexpected XML elements and continue processing, - * except for obvious errors within a <signer> group since they might cause - * package names to by ignored and therefore wildcard access granted - * by mistake. Those errors invalidate the entire <signer> group. - */ - boolean parseNfcsccAccess() { - File file = new File(Environment.getRootDirectory(), NFCSCC_ACCESS_PATH); - FileReader reader = null; - boolean debug = false; - try { - reader = new FileReader(file); - XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); - XmlPullParser parser = factory.newPullParser(); - parser.setInput(reader); - - int event; - ArrayList<String> packages = new ArrayList<String>(); - Signature signature = null; - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); - while (true) { - event = parser.next(); - String tag = parser.getName(); - if (event == XmlPullParser.START_TAG && "signer".equals(tag)) { - signature = null; - packages.clear(); - for (int i = 0; i < parser.getAttributeCount(); i++) { - if ("android:signature".equals(parser.getAttributeName(i))) { - signature = new Signature(parser.getAttributeValue(i)); - break; - } - } - if (signature == null) { - Log.w(TAG, "signer tag is missing android:signature attribute, igorning"); - continue; - } - if (mNfcsccAccess.containsKey(signature)) { - Log.w(TAG, "duplicate signature, ignoring"); - signature = null; - continue; - } - } else if (event == XmlPullParser.END_TAG && "signer".equals(tag)) { - if (signature == null) { - Log.w(TAG, "mis-matched signer tag"); - continue; - } - mNfcsccAccess.put(signature, (String[])packages.toArray(new String[0])); - packages.clear(); - } else if (event == XmlPullParser.START_TAG && "package".equals(tag)) { - if (signature == null) { - Log.w(TAG, "ignoring unnested packge tag"); - continue; - } - String name = null; - for (int i = 0; i < parser.getAttributeCount(); i++) { - if ("android:name".equals(parser.getAttributeName(i))) { - name = parser.getAttributeValue(i); - break; - } - } - if (name == null) { - Log.w(TAG, "package missing android:name, ignoring signer group"); - signature = null; // invalidate signer - continue; - } - // check for duplicate package names - if (packages.contains(name)) { - Log.w(TAG, "duplicate package name in signer group, ignoring"); - continue; - } - packages.add(name); - } else if (event == XmlPullParser.START_TAG && "debug".equals(tag)) { - debug = true; - } else if (event == XmlPullParser.END_DOCUMENT) { - break; - } - } - } catch (XmlPullParserException e) { - Log.w(TAG, "failed to load NFCSCC access list", e); - mNfcsccAccess.clear(); // invalidate entire access list - } catch (FileNotFoundException e) { - Log.w(TAG, "could not find " + NFCSCC_ACCESS_PATH + ", no NFCSCC access allowed"); - } catch (IOException e) { - Log.e(TAG, "Failed to load NFCSCC access list", e); - mNfcsccAccess.clear(); // invalidate entire access list - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException e2) { } - } - } - Log.i(TAG, "read " + mNfcsccAccess.size() + " signature(s) for NFCSCC access"); - return debug; - } - - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("mNfcsccAccess="); - for (Signature s : mNfcsccAccess.keySet()) { - pw.printf("\t%s [", s.toCharsString()); - String[] ps = mNfcsccAccess.get(s); - for (String p : ps) { - pw.printf("%s, ", p); - } - pw.println("]"); - } - synchronized (this) { - pw.println("mNfcsccUidCache="); - for (Integer uid : mUidCache.keySet()) { - Boolean b = mUidCache.get(uid); - pw.printf("\t%d %s\n", uid, b); - } - } - } -} diff --git a/src/com/android/nfc/NfcSeAccessControl.java b/src/com/android/nfc/NfcSeAccessControl.java deleted file mode 100644 index c0d9c70e..00000000 --- a/src/com/android/nfc/NfcSeAccessControl.java +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (C) 2015 NXP Semiconductors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.nfc; - -import java.io.File; -import java.io.FileDescriptor; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.HashMap; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlPullParserFactory; - -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.Signature; -import android.content.pm.PackageManager.NameNotFoundException; -import android.os.Environment; -import android.util.Log; - -public class NfcSeAccessControl { - static final String TAG = "NfcSeAccess"; - static final boolean DBG = true; - - public static final String NFCSE_ACCESS_PATH = "/etc/nfcse_access.xml"; - - /** - * Map of signatures to valid packages names, as read from nfcse_access.xml. - * An empty list of package names indicates that any package - * with this signature is allowed. - */ - final HashMap<Signature, String[]> mNfcSeAccess; // contents final after onCreate() - - /** - * Map from UID to NFCSE access, used as a cache. - * Note: if a UID contains multiple packages they must all be - * signed with the same certificate so in effect UID == certificate - * used to sign the package. - */ - final HashMap<Integer, Boolean> mUidCache; // contents guarded by this - - final Context mContext; - final boolean mDebugPrintSignature; - - NfcSeAccessControl(Context context) { - mContext = context; - mNfcSeAccess = new HashMap<Signature, String[]>(); - mUidCache = new HashMap<Integer, Boolean>(); - mDebugPrintSignature = parseNfcSeAccess(); - } - - /** - * Check if the {uid, pkg} combination may use NFCSE. - * Also verify with package manager that this {uid, pkg} combination - * is valid if it is not cached. - */ - public boolean check(int uid, String pkg) { - Log.d(TAG, "check " + pkg + " UID " + uid); - synchronized (this) { - - boolean access = false; - boolean packageFound = false; - // Ensure the claimed package is present in the calling UID - PackageManager pm = mContext.getPackageManager(); - String[] pkgs = pm.getPackagesForUid(uid); - for (String uidPkg : pkgs) { - if (uidPkg.equals(pkg)) { - packageFound = true; - - Boolean cached = mUidCache.get(uid); - if (cached != null) { - return cached; - } - - // Ensure the package has access permissions - if (checkPackageNfcSeAccess(pkg)) { - access = true; - } - break; - } - } - - //Special case to support NFC EE SERVICE. - //FIXME: Need to improve. - if(!packageFound) { - String[] pkgs1 = pm.getPackagesForUid(uid); - for (String uidPkg : pkgs1) { - if ("com.nxp.nfceeapi.service".compareTo(uidPkg) == 0) { - if (checkPackageNfcSeAccess(pkg)) { - access = true; - } - break; - } - } - } - Log.d(TAG, "Access for " + pkg + " UID " + uid + " IS " + access); - if(packageFound) - { - mUidCache.put(uid, access); - } - return access; - } - } - - /** - * Check if the given ApplicationInfo may use the NFCSE. - * Assumes ApplicationInfo came from package manager, - * so no need to confirm {uid, pkg} is valid. - */ - public boolean check(ApplicationInfo info) { - synchronized (this) { - Boolean access = mUidCache.get(info.uid); - if (access == null) { - access = checkPackageNfcSeAccess(info.packageName); - mUidCache.put(info.uid, access); - } - return access; - } - } - - public void invalidateCache() { - synchronized (this) { - mUidCache.clear(); - } - } - - /** - * Check with package manager if the pkg may use NFCSE. - * Does not use cache. - */ - boolean checkPackageNfcSeAccess(String pkg) { - PackageManager pm = mContext.getPackageManager(); - try { - PackageInfo info = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES); - if (info.signatures == null) { - return false; - } - - for (Signature s : info.signatures){ - if (s == null) { - continue; - } - String[] packages = mNfcSeAccess.get(s); - if (packages == null) { - continue; - } - if (packages.length == 0) { - // wildcard access - if (DBG) Log.d(TAG, "Granted NFCSE access to " + pkg + " (wildcard)"); - return true; - } - for (String p : packages) { - if (pkg.equals(p)) { - // explicit package access - if (DBG) Log.d(TAG, "Granted access to " + pkg + " (explicit)"); - return true; - } - } - } - - if (mDebugPrintSignature) { - Log.w(TAG, "denied NFCSE access for " + pkg + " with signature:"); - for (Signature s : info.signatures) { - if (s != null) { - Log.w(TAG, s.toCharsString()); - } - } - } - } catch (NameNotFoundException e) { - // ignore - } - return false; - } - - /** - * Parse NFCSE_access.xml, populate mNFCSEAccess - * Policy is to ignore unexpected XML elements and continue processing, - * except for obvious errors within a <signer> group since they might cause - * package names to by ignored and therefore wildcard access granted - * by mistake. Those errors invalidate the entire <signer> group. - */ - boolean parseNfcSeAccess() { - File file = new File(Environment.getRootDirectory(), NFCSE_ACCESS_PATH); - FileReader reader = null; - boolean debug = false; - try { - reader = new FileReader(file); - XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); - XmlPullParser parser = factory.newPullParser(); - parser.setInput(reader); - - int event; - ArrayList<String> packages = new ArrayList<String>(); - Signature signature = null; - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); - while (true) { - event = parser.next(); - String tag = parser.getName(); - if (event == XmlPullParser.START_TAG && "signer".equals(tag)) { - signature = null; - packages.clear(); - for (int i = 0; i < parser.getAttributeCount(); i++) { - if ("android:signature".equals(parser.getAttributeName(i))) { - signature = new Signature(parser.getAttributeValue(i)); - break; - } - } - if (signature == null) { - Log.w(TAG, "signer tag is missing android:signature attribute, igorning"); - continue; - } - if (mNfcSeAccess.containsKey(signature)) { - Log.w(TAG, "duplicate signature, ignoring"); - signature = null; - continue; - } - } else if (event == XmlPullParser.END_TAG && "signer".equals(tag)) { - if (signature == null) { - Log.w(TAG, "mis-matched signer tag"); - continue; - } - mNfcSeAccess.put(signature, (String[])packages.toArray(new String[0])); - packages.clear(); - } else if (event == XmlPullParser.START_TAG && "package".equals(tag)) { - if (signature == null) { - Log.w(TAG, "ignoring unnested packge tag"); - continue; - } - String name = null; - for (int i = 0; i < parser.getAttributeCount(); i++) { - if ("android:name".equals(parser.getAttributeName(i))) { - name = parser.getAttributeValue(i); - break; - } - } - if (name == null) { - Log.w(TAG, "package missing android:name, ignoring signer group"); - signature = null; // invalidate signer - continue; - } - // check for duplicate package names - if (packages.contains(name)) { - Log.w(TAG, "duplicate package name in signer group, ignoring"); - continue; - } - packages.add(name); - } else if (event == XmlPullParser.START_TAG && "debug".equals(tag)) { - debug = true; - } else if (event == XmlPullParser.END_DOCUMENT) { - break; - } - } - } catch (XmlPullParserException e) { - Log.w(TAG, "failed to load NFCSE access list", e); - mNfcSeAccess.clear(); // invalidate entire access list - } catch (FileNotFoundException e) { - Log.w(TAG, "could not find " + NFCSE_ACCESS_PATH + ", no NFCSE access allowed"); - } catch (IOException e) { - Log.e(TAG, "Failed to load NFCSE access list", e); - mNfcSeAccess.clear(); // invalidate entire access list - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException e2) { } - } - } - Log.i(TAG, "read " + mNfcSeAccess.size() + " signature(s) for NFCSE access"); - return debug; - } - - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("mNfcSeAccess="); - for (Signature s : mNfcSeAccess.keySet()) { - pw.printf("\t%s [", s.toCharsString()); - String[] ps = mNfcSeAccess.get(s); - for (String p : ps) { - pw.printf("%s, ", p); - } - pw.println("]"); - } - synchronized (this) { - pw.println("mNfcSeUidCache="); - for (Integer uid : mUidCache.keySet()) { - Boolean b = mUidCache.get(uid); - pw.printf("\t%d %s\n", uid, b); - } - } - } -}
\ No newline at end of file diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java index be300d7b..2c4a74b8 100755 --- a/src/com/android/nfc/NfcService.java +++ b/src/com/android/nfc/NfcService.java @@ -1,4 +1,4 @@ - /* +/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,24 +14,24 @@ * limitations under the License. */ /****************************************************************************** - * - * The original Work has been changed by NXP Semiconductors. - * - * Copyright (C) 2015-2018 NXP Semiconductors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ +* +* The original Work has been changed by NXP. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +* Copyright 2018-2019 NXP +* +******************************************************************************/ package com.android.nfc; import android.app.ActivityManager; @@ -47,7 +47,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; - import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; @@ -64,6 +63,7 @@ import android.nfc.IAppCallback; import android.nfc.INfcAdapter; import android.nfc.INfcAdapterExtras; import android.nfc.INfcCardEmulation; +import android.nfc.INfcDta; import android.nfc.INfcFCardEmulation; import android.nfc.INfcTag; import android.nfc.INfcUnlockHandler; @@ -75,13 +75,12 @@ import android.nfc.TechListParcel; import android.nfc.TransceiveResult; import android.nfc.tech.Ndef; import android.nfc.tech.TagTechnology; -import android.nfc.INfcDta; import android.os.AsyncTask; import android.os.Binder; +import android.os.HwBinder; import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.os.HwBinder; import android.os.IBinder; import android.os.Message; import android.os.PowerManager; @@ -95,35 +94,26 @@ import android.os.UserManager; import android.os.VibrationEffect; import android.os.Vibrator; import android.provider.Settings; -import android.se.omapi.ISecureElementService; import android.service.vr.IVrManager; import android.service.vr.IVrStateCallbacks; +import android.text.TextUtils; import android.util.Log; import com.android.internal.logging.MetricsLogger; +import com.android.internal.util.ArrayUtils; import com.android.nfc.DeviceHost.DeviceHostListener; import com.android.nfc.DeviceHost.LlcpConnectionlessSocket; import com.android.nfc.DeviceHost.LlcpServerSocket; import com.android.nfc.DeviceHost.LlcpSocket; import com.android.nfc.DeviceHost.NfcDepEndpoint; import com.android.nfc.DeviceHost.TagEndpoint; - -import com.android.nfc.dhimpl.NativeNfcSecureElement; -import java.security.MessageDigest; - -import android.widget.Toast; - -import com.android.nfc.cardemulation.AidRoutingManager; import com.android.nfc.cardemulation.CardEmulationManager; -import com.android.nfc.cardemulation.RegisteredAidCache; import com.android.nfc.dhimpl.NativeNfcManager; import com.android.nfc.handover.HandoverDataParser; - +import com.android.nfc.dhimpl.NativeNfcSecureElement; import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; -import java.util.concurrent.atomic.AtomicInteger; import java.io.InputStream; import java.io.OutputStream; import java.io.FileInputStream; @@ -132,6 +122,9 @@ import java.io.File; import java.io.FileWriter; import java.io.BufferedReader; import java.io.FileReader; +import java.io.FileNotFoundException; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicInteger; import java.util.Arrays; import java.util.ArrayList; import java.util.HashMap; @@ -141,159 +134,103 @@ import java.util.NoSuchElementException; import java.util.TimerTask; import java.util.Timer; import java.io.IOException; -import java.io.FileNotFoundException; - +import android.widget.Toast; +import com.nxp.nfc.INxpNfcAdapter; +import com.nxp.nfc.INxpNfcAdapterExtras; +import java.util.HashSet; +import com.android.nfc.cardemulation.AidRoutingManager; +import com.android.nfc.cardemulation.RegisteredAidCache; +import com.nxp.nfc.NfcConstants; +import android.se.omapi.ISecureElementService; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; - -import android.util.Pair; -import java.util.HashSet; -import java.util.concurrent.ExecutionException; - -import com.nxp.nfc.INxpNfcAdapter; -import com.nxp.nfc.INfcVzw; -import com.nxp.nfc.NxpConstants; -import com.vzw.nfc.RouteEntry; -import com.gsma.nfc.internal.NxpNfcController; -import com.nxp.nfc.gsma.internal.INxpNfcController; -import com.nxp.nfc.NxpAidServiceInfo; +import java.lang.reflect.Constructor; +import com.nxp.nfc.NfcAidServiceInfo; public class NfcService implements DeviceHostListener { - private static final String ACTION_MASTER_CLEAR_NOTIFICATION = "android.intent.action.MASTER_CLEAR_NOTIFICATION"; - static final boolean DBG = true; static final String TAG = "NfcService"; public static final String SERVICE_NAME = "nfc"; - - /** Regular NFC permission */ - private static final String NFC_PERM = android.Manifest.permission.NFC; - private static final String NFC_PERM_ERROR = "NFC permission required"; - - public static final String PREF = "NfcServicePrefs"; public static final String NXP_PREF = "NfcServiceNxpPrefs"; - + public static final String PREF = "NfcServicePrefs"; + private static final String PREF_CUR_SELECTED_UICC_ID = "current_selected_uicc_id"; + private int SECURE_ELEMENT_UICC_SLOT_DEFAULT = 1; + static final int UICC_CONFIGURED = 0x00; + static final int UICC_NOT_CONFIGURED = 0x01; static final String PREF_NFC_ON = "nfc_on"; static final boolean NFC_ON_DEFAULT = true; static final String PREF_NDEF_PUSH_ON = "ndef_push_on"; static final boolean NDEF_PUSH_ON_DEFAULT = true; + static final String PREF_SECURE_NFC_ON = "secure_nfc_on"; + static final boolean SECURE_NFC_ON_DEFAULT = true; static final String PREF_FIRST_BEAM = "first_beam"; static final String PREF_FIRST_BOOT = "first_boot"; - private static final String PREF_SECURE_ELEMENT_ON = "secure_element_on"; - private boolean SECURE_ELEMENT_ON_DEFAULT = false; - private int SECURE_ELEMENT_ID_DEFAULT = 0; - private int SECURE_ELEMENT_UICC_SLOT_DEFAULT = 1; - private static final String PREF_DEFAULT_ROUTE_ID = "default_route_id"; - private static final String PREF_MIFARE_DESFIRE_PROTO_ROUTE_ID = "mifare_desfire_proto_route"; - private static final String PREF_SET_DEFAULT_ROUTE_ID ="set_default_route"; - private static final String PREF_MIFARE_CLT_ROUTE_ID= "mifare_clt_route"; - - private static final String[] path = {"/data/nfc/JcopOs_Update1.apdu", - "/data/nfc/JcopOs_Update2.apdu", - "/data/nfc/JcopOs_Update3.apdu"}; - - private static final String[] PREF_JCOP_MODTIME = {"jcop file1 modtime", - "jcop file2 modtime", - "jcop file3 modtime"}; - private static final long[] JCOP_MODTIME_DEFAULT = {-1,-1,-1}; - private static final long[] JCOP_MODTIME_TEMP = {-1,-1,-1}; - - private boolean ETSI_STOP_CONFIG = false; - private int ROUTE_ID_HOST = 0x00; - private int ROUTE_ID_SMX = 0x01; - private int ROUTE_ID_UICC = 0x02; - private int ROUTE_ID_UICC2 = 0x04; - - private int ROUTE_SWITCH_ON = 0x01; - private int ROUTE_SWITCH_OFF = 0x02; - private int ROUTE_BATT_OFF= 0x04; - - private int TECH_TYPE_A= 0x01; - private int TECH_TYPE_B= 0x02; - private int TECH_TYPE_F= 0x04; - - //TODO: Refer L_OSP_EXT [PN547C2] -// private int DEFAULT_ROUTE_ID_DEFAULT = AidRoutingManager.DEFAULT_ROUTE; - private int DEFAULT_ROUTE_ID_DEFAULT = 0x00; - static final boolean SE_BROADCASTS_WITH_HCE = true; - - private static final String PREF_SECURE_ELEMENT_ID = "secure_element_id"; - private static final String PREF_CUR_SELECTED_UICC_ID = "current_selected_uicc_id"; public static final int ROUTE_LOC_MASK=8; public static final int TECH_TYPE_MASK=11; - static final String TRON_NFC_CE = "nfc_ce"; static final String TRON_NFC_P2P = "nfc_p2p"; static final String TRON_NFC_TAG = "nfc_tag"; - + static final int TECH_TYPE_A= 0x01; static final int MSG_NDEF_TAG = 0; - static final int MSG_LLCP_LINK_ACTIVATION = 2; - static final int MSG_LLCP_LINK_DEACTIVATED = 3; - static final int MSG_TARGET_DESELECTED = 4; - static final int MSG_MOCK_NDEF = 7; - static final int MSG_SE_FIELD_ACTIVATED = 8; - static final int MSG_SE_FIELD_DEACTIVATED = 9; - static final int MSG_SE_APDU_RECEIVED = 10; - static final int MSG_SE_EMV_CARD_REMOVAL = 11; - static final int MSG_SE_MIFARE_ACCESS = 12; - static final int MSG_SE_LISTEN_ACTIVATED = 13; - static final int MSG_SE_LISTEN_DEACTIVATED = 14; - static final int MSG_LLCP_LINK_FIRST_PACKET = 15; - static final int MSG_ROUTE_AID = 16; - static final int MSG_UNROUTE_AID = 17; - static final int MSG_COMMIT_ROUTING = 18; - static final int MSG_INVOKE_BEAM = 19; - - static final int MSG_SWP_READER_REQUESTED = 20; - static final int MSG_SWP_READER_DEACTIVATED = 22; - static final int MSG_CLEAR_ROUTING = 23; - static final int MSG_SET_SCREEN_STATE = 25; - - - static final int MSG_RF_FIELD_ACTIVATED = 26; - static final int MSG_RF_FIELD_DEACTIVATED = 27; - static final int MSG_RESUME_POLLING = 28; - static final int MSG_SWP_READER_REQUESTED_FAIL =29 ; - static final int MSG_SWP_READER_TAG_PRESENT = 30; - static final int MSG_SWP_READER_TAG_REMOVE = 31; - static final int MSG_CONNECTIVITY_EVENT = 40; - static final int MSG_VZW_ROUTE_AID = 41; - static final int MSG_VZW_COMMIT_ROUTING = 42; - static final int MSG_ROUTE_NFCID2 = 43; - static final int MSG_UNROUTE_NFCID2 = 44; - static final int MSG_COMMITINF_FELICA_ROUTING = 45; - static final int MSG_COMMITED_FELICA_ROUTING = 46; - static final int MSG_EMVCO_MULTI_CARD_DETECTED_EVENT = 47; + private boolean ETSI_STOP_CONFIG = false; + static final int MSG_LLCP_LINK_ACTIVATION = 1; + static final int MSG_LLCP_LINK_DEACTIVATED = 2; + static final int MSG_MOCK_NDEF = 3; + static final int MSG_LLCP_LINK_FIRST_PACKET = 4; + static final int MSG_ROUTE_AID = 5; + static final int MSG_UNROUTE_AID = 6; + static final int MSG_COMMIT_ROUTING = 7; + static final int MSG_INVOKE_BEAM = 8; + static final int MSG_RF_FIELD_ACTIVATED = 9; + static final int MSG_RF_FIELD_DEACTIVATED = 10; + static final int MSG_RESUME_POLLING = 11; + static final int MSG_REGISTER_T3T_IDENTIFIER = 12; + static final int MSG_DEREGISTER_T3T_IDENTIFIER = 13; + static final int MSG_TAG_DEBOUNCE = 14; + static final int MSG_UPDATE_STATS = 15; + static final int MSG_APPLY_SCREEN_STATE = 16; + static final int MSG_TRANSACTION_EVENT = 17; + static final int MSG_CARD_EMULATION = 21; + static final int MSG_SWP_READER_REQUESTED = 18; + static final int MSG_SWP_READER_DEACTIVATED = 19; + static final int MSG_SWP_READER_REQUESTED_FAIL =20 ; static final int MSG_ETSI_START_CONFIG = 48; static final int MSG_ETSI_STOP_CONFIG = 49; static final int MSG_ETSI_SWP_TIMEOUT = 50; - static final int MSG_APPLY_SCREEN_STATE = 51; - static final int MSG_REGISTER_T3T_IDENTIFIER = 54; - static final int MSG_DEREGISTER_T3T_IDENTIFIER = 55; - static final int MSG_TAG_DEBOUNCE = 56; - static final int MSG_UPDATE_STATS = 57; static final int MSG_SWP_READER_RESTART = 58; - /*Restart Nfc disbale watchdog timer*/ - static final int MSG_RESTART_WATCHDOG = 60; - static final int MSG_ROUTE_APDU = 61; - static final int MSG_UNROUTE_APDU = 62; - static final int MSG_TRANSACTION_EVENT = 63; + static final int MSG_SE_INIT = 59; + static final int MSG_ROUTE_APDU = 60; + static final int MSG_UNROUTE_APDU = 61; + static final int MSG_CLEAR_ROUTING = 62; + static final int MSG_INIT_WIREDSE = 63; + static final int MSG_COMPUTE_ROUTING_PARAMS = 64; // Update stats every 4 hours static final long STATS_UPDATE_INTERVAL_MS = 4 * 60 * 60 * 1000; static final long MAX_POLLING_PAUSE_TIMEOUT = 40000; + static final int TASK_ENABLE = 1; static final int TASK_DISABLE = 2; static final int TASK_BOOT = 3; - static final int TASK_EE_WIPE = 4; - static final int TASK_RESTART = 0x1F; - static final int MSG_CHANGE_DEFAULT_ROUTE = 52; - static final int MSG_SE_DELIVER_INTENT = 53; - // Copied from com.android.nfc_extras to avoid library dependency - // Must keep in sync with com.android.nfc_extras - static final int ROUTE_OFF = 1; - static final int ROUTE_ON_WHEN_SCREEN_ON = 2; + // Listen Protocol + public static final int NFC_LISTEN_PROTO_ISO_DEP = 0x01; // This values is need to move from this to CardEmulationManager + public static final int NFC_LISTEN_PROTO_NFC_DEP = 0x02; // This values is need to move from this to CardEmulationManager + public static final int NFC_LISTEN_PROTO_T3T = 0x04; + + public static final int NFC_LISTEN_TECH_A = 0x01; // This values is need to move from this to CardEmulationManager + public static final int NFC_LISTEN_TECH_B = 0x02; // This values is need to move from this to CardEmulationManager + public static final int NFC_LISTEN_TECH_F = 0x04; // This values is need to move from this to CardEmulationManager + + + // Polling technology masks + static final int NFC_POLL_A = 0x01; + static final int NFC_POLL_B = 0x02; + static final int NFC_POLL_F = 0x04; + static final int NFC_POLL_V = 0x08; + static final int NFC_POLL_B_PRIME = 0x10; + static final int NFC_POLL_KOVIO = 0x20; // Return values from NfcEe.open() - these are 1:1 mapped // to the thrown EE_EXCEPTION_ exceptions in nfc-extras. @@ -304,13 +241,9 @@ public class NfcService implements DeviceHostListener { static final int EE_ERROR_EXT_FIELD = -5; static final int EE_ERROR_NFC_DISABLED = -6; - // Polling technology masks - static final int NFC_POLL_A = 0x01; - static final int NFC_POLL_B = 0x02; - static final int NFC_POLL_F = 0x04; - static final int NFC_POLL_V = 0x08; - static final int NFC_POLL_B_PRIME = 0x10; - static final int NFC_POLL_KOVIO = 0x20; + static final public int TECH_ENTRY = 1; + static final public int PROTOCOL_ENTRY = 2; + static final public int AID_ENTRY = 4; // it is dummy values; // minimum screen state that enables NFC polling static final int NFC_POLLING_MODE = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED; @@ -319,28 +252,25 @@ public class NfcService implements DeviceHostListener { // goes off. This time is chosen large, because firmware download // may be a part of initialization. static final int INIT_WATCHDOG_MS = 90000; - static final int INIT_WATCHDOG_LS_MS = 180000; + // Time to wait for routing to be applied before watchdog // goes off static final int ROUTING_WATCHDOG_MS = 10000; - // Amount of time to wait before closing the NFCEE connection - // in a disable/shutdown scenario. - static final int WAIT_FOR_NFCEE_OPERATIONS_MS = 5000; - // Polling interval for waiting on NFCEE operations - static final int WAIT_FOR_NFCEE_POLL_MS = 100; - // Default delay used for presence checks static final int DEFAULT_PRESENCE_CHECK_DELAY = 125; - //Delay used for presence checks of NFC_F non-Ndef - //Make secure communication done or tranceive next request response command - //to pause timer before presence check command is sent - static final int NFC_F_TRANSCEIVE_PRESENCE_CHECK_DELAY = 500; - // The amount of time we wait before manually launching // the Beam animation when called through the share menu. static final int INVOKE_BEAM_DELAY_MS = 1000; + + // RF field events as defined in NFC extras + public static final String ACTION_RF_FIELD_ON_DETECTED = + "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED"; + public static final String ACTION_RF_FIELD_OFF_DETECTED = + "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED"; + + public static boolean sIsShortRecordLayout = false; // Default delay used for presence checks in ETSI mode static final int ETSI_PRESENCE_CHECK_DELAY = 1000; // for use with playSound() @@ -351,6 +281,12 @@ public class NfcService implements DeviceHostListener { public static final int NCI_VERSION_2_0 = 0x20; public static final int NCI_VERSION_1_0 = 0x10; + + public static final String ACTION_LLCP_UP = + "com.android.nfc.action.LLCP_UP"; + + public static final String ACTION_LLCP_DOWN = + "com.android.nfc.action.LLCP_DOWN"; //ETSI Reader Events public static final int ETSI_READER_START_SUCCESS = 0; public static final int ETSI_READER_START_FAIL = 1; @@ -371,49 +307,12 @@ public class NfcService implements DeviceHostListener { public static final int TRANSIT_SETCONFIG_STAT_SUCCESS = 0x00; public static final int TRANSIT_SETCONFIG_STAT_FAILED = 0xFF; - public static final String ACTION_RF_FIELD_ON_DETECTED = - "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED"; - public static final String ACTION_RF_FIELD_OFF_DETECTED = - "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED"; - public static final String ACTION_AID_SELECTED = - "com.android.nfc_extras.action.AID_SELECTED"; - - public static final String ACTION_LLCP_UP = - "com.android.nfc.action.LLCP_UP"; - - public static final String ACTION_LLCP_DOWN = - "com.android.nfc.action.LLCP_DOWN"; - - public static final String ACTION_APDU_RECEIVED = - "com.android.nfc_extras.action.APDU_RECEIVED"; - public static final String EXTRA_APDU_BYTES = - "com.android.nfc_extras.extra.APDU_BYTES"; - - public static final String ACTION_EMV_CARD_REMOVAL = - "com.android.nfc_extras.action.EMV_CARD_REMOVAL"; - - public static final String ACTION_MIFARE_ACCESS_DETECTED = - "com.android.nfc_extras.action.MIFARE_ACCESS_DETECTED"; - public static final String EXTRA_MIFARE_BLOCK = - "com.android.nfc_extras.extra.MIFARE_BLOCK"; - - public static final String ACTION_SE_LISTEN_ACTIVATED = - "com.android.nfc_extras.action.SE_LISTEN_ACTIVATED"; - public static final String ACTION_SE_LISTEN_DEACTIVATED = - "com.android.nfc_extras.action.SE_LISTEN_DEACTIVATED"; - - public static final String ACTION_EMVCO_MULTIPLE_CARD_DETECTED = - "com.nxp.action.EMVCO_MULTIPLE_CARD_DETECTED"; - - public static final String ACTION_UICC_STATUS_RECEIVED = - "com.nxp.action.UICC_STATUS_RECEIVED"; - - public static final String ACTION_FLASH_SUCCESS = - "com.android.nfc_extras.action.ACTION_FLASH_SUCCESS"; + // Timeout to re-apply routing if a tag was present and we postponed it + private static final int APPLY_ROUTING_RETRY_TIMEOUT_MS = 5000; - public static final String EXTRA_UICC_STATUS = "com.nxp.extra.UICC_STATUS"; + // eSE handle + public static final int EE_HANDLE_0xF3 = 0x4C0; - private static final String PACKAGE_SMART_CARD_SERVICE = "org.simalliance.openmobileapi.service"; /** * SMART MX ID to be able to select it as the default Secure Element */ @@ -428,76 +327,42 @@ public class NfcService implements DeviceHostListener { * UICC2 ID to be able to select it as the default Secure Element */ public static final int UICC2_ID_TYPE = 4; - /** - * ID to be able to select all Secure Elements - */ - private static int ALL_SE_ID_TYPE = 7; - - public static final int PN547C2_ID = 1; - public static final int PN65T_ID = 2; - public static final int PN548C2_ID = 3; - public static final int PN66T_ID = 4; - public static final int PN551_ID = 5; - public static final int PN67T_ID = 6; - public static final int PN553_ID = 7; - public static final int PN80T_ID = 8; - - public static final int LS_RETRY_CNT = 3; - public static final int LOADER_SERVICE_VERSION_LOW_LIMIT = 0x21; - public static final int LOADER_SERVICE_VERSION_HIGH_LIMIT = 0x24; - - private int mSelectedSeId = 0; - private boolean mNfcSecureElementState; - private boolean mIsSmartCardServiceSupported = false; - // Timeout to re-apply routing if a tag was present and we postponed it - private static final int APPLY_ROUTING_RETRY_TIMEOUT_MS = 5000; - // these states are for making enable and disable nfc atomic - private int NXP_NFC_STATE_OFF = 0; - private int NXP_NFC_STATE_TURNING_ON = 1; - private int NXP_NFC_STATE_ON = 2; - private int NXP_NFC_STATE_TURNING_OFF = 3; + public boolean mIsRouteForced; private final UserManager mUserManager; + private static int nci_version = NCI_VERSION_1_0; // NFC Execution Environment // fields below are protected by this public NativeNfcSecureElement mSecureElement; - private OpenSecureElement mOpenEe; // null when EE closed + public boolean isWiredOpen = false; private final ReaderModeDeathRecipient mReaderModeDeathRecipient = new ReaderModeDeathRecipient(); private final NfcUnlockManager mNfcUnlockManager; - private int mEeRoutingState; // contactless interface routing - private int mLockscreenPollMask; - // cached version of installed packages requesting Android.permission.NFC_TRANSACTION_EVENTS - List<String> mNfcEventInstalledPackages = new ArrayList<String>(); private final BackupManager mBackupManager; + // cached version of installed packages requesting Android.permission.NFC_TRANSACTION_EVENTS + List<String> mNfcEventInstalledPackages = new ArrayList<String>(); // fields below are used in multiple threads and protected by synchronized(this) final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>(); - // mSePackages holds packages that accessed the SE, but only for the owner user, - // as SE access is not granted for non-owner users. HashSet<String> mSePackages = new HashSet<String>(); int mScreenState; - int mChipVer; - boolean mIsTaskBoot = false; boolean mInProvisionMode; // whether we're in setup wizard and enabled NFC provisioning boolean mIsNdefPushEnabled; - boolean mNfcPollingEnabled; // current Device Host state of NFC-C polling - boolean mHostRouteEnabled; // current Device Host state of host-based routing - boolean mReaderModeEnabled; // current Device Host state of reader mode - boolean mNfceeRouteEnabled; // current Device Host state of NFC-EE routing + boolean mIsSecureNfcEnabled; NfcDiscoveryParameters mCurrentDiscoveryParameters = NfcDiscoveryParameters.getNfcOffParameters(); + ReaderModeParams mReaderModeParams; + private int mUserId; boolean mPollingPaused; static final int INVALID_NATIVE_HANDLE = -1; - static final int SE_ACCESS_DENIED = -2; - byte[] mDebounceTagUid; + byte mDebounceTagUid[]; int mDebounceTagDebounceMs; int mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE; ITagRemovedCallback mDebounceTagRemovedCallback; @@ -509,170 +374,92 @@ public class NfcService implements DeviceHostListener { AtomicInteger mNumTagsDetected; AtomicInteger mNumP2pDetected; AtomicInteger mNumHceDetected; - + ToastHandler mToastHandler; // mState is protected by this, however it is only modified in onCreate() // and the default AsyncTask thread so it is read unprotected from that // thread int mState; // one of NfcAdapter.STATE_ON, STATE_TURNING_ON, etc - int mNxpNfcState = NXP_NFC_STATE_OFF; - - boolean mPowerShutDown = false; // State for power shut down state - // fields below are final after onCreate() Context mContext; private DeviceHost mDeviceHost; private SharedPreferences mPrefs; - private SharedPreferences mNxpPrefs; private SharedPreferences.Editor mPrefsEditor; - private SharedPreferences.Editor mNxpPrefsEditor; private PowerManager.WakeLock mRoutingWakeLock; private PowerManager.WakeLock mEeWakeLock; - + private SharedPreferences.Editor mNxpPrefsEditor; + private SharedPreferences mNxpPrefs; int mStartSound; int mEndSound; int mErrorSound; SoundPool mSoundPool; // playback synchronized on this P2pLinkManager mP2pLinkManager; TagService mNfcTagService; + boolean mIsSecureElementOpened = false; + boolean mSEClientAccessState = false; NfcAdapterService mNfcAdapter; - NfcAdapterExtrasService mExtrasService; -// CardEmulationService mCardEmulationService; + NfcDtaService mNfcDtaService; + NxpNfcAdapterExtrasService mNxpExtrasService; NxpNfcAdapterService mNxpNfcAdapter; boolean mIsDebugBuild; boolean mIsHceCapable; boolean mIsHceFCapable; - public boolean mIsRoutingTableDirty; - boolean mIsFelicaOnHostConfigured; - boolean mIsFelicaOnHostConfiguring; + boolean mIsBeamCapable; + boolean mIsSecureNfcCapable; - public boolean mIsRouteForced; - NfcSccAccessControl mNfcSccAccessControl; - NfcSeAccessControl mNfcSeAccessControl; - NfcDtaService mNfcDtaService; - NfcVzwService mVzwService; private NfcDispatcher mNfcDispatcher; private PowerManager mPowerManager; private KeyguardManager mKeyguard; - ToastHandler mToastHandler; private HandoverDataParser mHandoverDataParser; private ContentResolver mContentResolver; - private RegisteredAidCache mAidCache; private CardEmulationManager mCardEmulationManager; + private AidRoutingManager mAidRoutingManager; + private RegisteredAidCache mAidCache; private Vibrator mVibrator; private VibrationEffect mVibrationEffect; - private AidRoutingManager mAidRoutingManager; - private ISecureElementService mSEService; + private ScreenStateHelper mScreenStateHelper; private ForegroundUtils mForegroundUtils; - private boolean mClearNextTapDefault; - private NxpNfcController mNxpNfcController; private static NfcService sService; - public static boolean sIsDtaMode = false; - public static boolean sIsShortRecordLayout = false; - public static boolean sAidTableFull = false; - private WatchDogThread disableInternalwatchDog; + public static boolean sIsDtaMode = false; - //GSMA - private final Boolean defaultTransactionEventReceptionMode = Boolean.FALSE; - private static final Boolean multiReceptionMode = Boolean.TRUE; - private static final Boolean unicastReceptionMode = Boolean.FALSE; - boolean mIsSentUnicastReception = false; - - //WiredSe + private IVrManager vrManager; + boolean mIsVrModeEnabled; + private ISecureElementService mSEService; + /* WiredSe attributes */ Class mWiredSeClass; - Method mWiredSeInitMethod, mWiredSeDeInitMwthod; + Method mWiredSeInitMethod, mWiredSeDeInitMethod; Object mWiredSeObj; - public void enforceNfcSeAdminPerm(String pkg) { - if (pkg == null) { - throw new SecurityException("caller must pass a package name"); - } - mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); - if (!mNfcSeAccessControl.check(Binder.getCallingUid(), pkg)) { - throw new SecurityException(NfcSeAccessControl.NFCSE_ACCESS_PATH + - " denies NFCSe access to " + pkg); - } - if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) { - throw new SecurityException("only the owner is allowed to act as SCC admin"); - } - } - public void enforceNfceeAdminPerm(String pkg) { - if (pkg == null) { - throw new SecurityException("caller must pass a package name"); - } - NfcPermissions.enforceUserPermissions(mContext); - if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) { - throw new SecurityException("only the owner is allowed to call SE APIs"); - } - } - - - /* SCC Access Control */ - public void enforceNfcSccAdminPerm(String pkg) { - if (pkg == null) { - throw new SecurityException("caller must pass a package name"); - } - mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); - if (!mNfcSccAccessControl.check(Binder.getCallingUid(), pkg)) { - throw new SecurityException(NfcSccAccessControl.NFCSCC_ACCESS_PATH + - " denies NFCSCC access to " + pkg); - } - if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) { - throw new SecurityException("only the owner is allowed to act as SCC admin"); - } - } - - boolean mIsLiveCaseEnabled; // whether live cases are enabled - int mLiveCaseTechnology; // Technology mask of accepted NFC tags + Class mNfcExtraClass; + Object mNfcExtraObj; - private IVrManager vrManager; - boolean mIsVrModeEnabled; + private int ROUTE_ID_HOST = 0x00; + private int ROUTE_ID_SMX = 0x01; + private int ROUTE_ID_UICC = 0x02; + private int ROUTE_ID_UICC2 = 0x04; + private int DEFAULT_ROUTE_ID_DEFAULT = 0x00; public static NfcService getInstance() { return sService; } - @Override - public void onRemoteEndpointDiscovered(TagEndpoint tag) { - sendMessage(NfcService.MSG_NDEF_TAG, tag); - } - public int getRemainingAidTableSize() { return mDeviceHost.getRemainingAidTableSize(); } + public boolean getLastCommitRoutingStatus() { return mAidRoutingManager.getLastCommitRoutingStatus(); } - public int getChipVer() { - return mDeviceHost.getChipVer(); + public AidRoutingManager getAidRoutingCache() { + return mAidRoutingManager; } - /** - * Notifies Card emulation deselect - */ @Override - public void onCardEmulationDeselected() { - if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { - sendMessage(NfcService.MSG_TARGET_DESELECTED, null); - } - } - - /** - * Notifies connectivity - */ - @Override - public void onConnectivityEvent(int evtSrc) { - Log.d(TAG, "onConnectivityEvent : Source" + evtSrc); - sendMessage(NfcService.MSG_CONNECTIVITY_EVENT, evtSrc); - } - - @Override - public void onEmvcoMultiCardDetectedEvent() { - Log.d(TAG, "onEmvcoMultiCardDetectedEvent"); - sendMessage(NfcService.MSG_EMVCO_MULTI_CARD_DETECTED_EVENT,null); + public void onRemoteEndpointDiscovered(TagEndpoint tag) { + sendMessage(NfcService.MSG_NDEF_TAG, tag); } /** @@ -684,36 +471,19 @@ public class NfcService implements DeviceHostListener { mCardEmulationManager.onHostCardEmulationActivated(technology); } } - @Override - public void onAidRoutingTableFull() { - Log.d(TAG, "NxpNci: onAidRoutingTableFull: AID Routing Table is FULL!"); - /*if((ROUTE_ID_HOST != GetDefaultRouteLoc())&&(sAidTableFull == false)) - { - Log.d(TAG, "NxpNci: onAidRoutingTableFull: Making Default Route to HOST!"); - sAidTableFull = true; - mHandler.sendEmptyMessage(NfcService.MSG_CHANGE_DEFAULT_ROUTE); - }*/ + public void onSeListenActivated() { if (mIsHceCapable) { - mAidRoutingManager.onNfccRoutingTableCleared(); - mCardEmulationManager.onRoutingTableChanged(); + mCardEmulationManager.onHostCardEmulationActivated(TagTechnology.NFC_A); } } @Override - public void onNotifyT3tConfigure() { - if (mCardEmulationManager != null) { - mCardEmulationManager.onT3tConfigure(); - } - } - - @Override - public void onNotifyReRoutingEntry() { - if (mCardEmulationManager != null) { - mCardEmulationManager.onReRoutingEntry(); - } + public void onSeListenDeactivated() { + if( mIsHceCapable) { + mCardEmulationManager.onHostCardEmulationDeactivated(TagTechnology.NFC_A); + } } - @Override public void onHostCardEmulationData(int technology, byte[] data) { if (mCardEmulationManager != null) { @@ -735,6 +505,7 @@ public class NfcService implements DeviceHostListener { */ @Override public void onLlcpLinkActivated(NfcDepEndpoint device) { + if (!mIsBeamCapable) return; sendMessage(NfcService.MSG_LLCP_LINK_ACTIVATION, device); } @@ -743,6 +514,7 @@ public class NfcService implements DeviceHostListener { */ @Override public void onLlcpLinkDeactivated(NfcDepEndpoint device) { + if (!mIsBeamCapable) return; sendMessage(NfcService.MSG_LLCP_LINK_DEACTIVATED, device); } @@ -751,63 +523,24 @@ public class NfcService implements DeviceHostListener { */ @Override public void onLlcpFirstPacketReceived(NfcDepEndpoint device) { + if (!mIsBeamCapable) return; mNumP2pDetected.incrementAndGet(); sendMessage(NfcService.MSG_LLCP_LINK_FIRST_PACKET, device); } @Override public void onRemoteFieldActivated() { - if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { - sendMessage(NfcService.MSG_SE_FIELD_ACTIVATED, null); - } + sendMessage(NfcService.MSG_RF_FIELD_ACTIVATED, null); } @Override public void onRemoteFieldDeactivated() { - if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { - sendMessage(NfcService.MSG_SE_FIELD_DEACTIVATED, null); - } - } - - @Override - public void onSeListenActivated() { - if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { - sendMessage(NfcService.MSG_SE_LISTEN_ACTIVATED, null); - } - if (mIsHceCapable) { - mCardEmulationManager.onHostCardEmulationActivated(TagTechnology.NFC_A); - } - } - - @Override - public void onSeListenDeactivated() { - if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { - sendMessage(NfcService.MSG_SE_LISTEN_DEACTIVATED, null); - } - if( mIsHceCapable) { - mCardEmulationManager.onHostCardEmulationDeactivated(TagTechnology.NFC_A); - } - } - - @Override - public void onSeApduReceived(byte[] apdu) { - if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { - sendMessage(NfcService.MSG_SE_APDU_RECEIVED, apdu); - } + sendMessage(NfcService.MSG_RF_FIELD_DEACTIVATED, null); } @Override - public void onSeEmvCardRemoval() { - if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { - sendMessage(NfcService.MSG_SE_EMV_CARD_REMOVAL, null); - } - } - - @Override - public void onSeMifareAccess(byte[] block) { - if (!mIsHceCapable || SE_BROADCASTS_WITH_HCE) { - sendMessage(NfcService.MSG_SE_MIFARE_ACCESS, block); - } + public void onSeInitialized() { + sendMessage(NfcService.MSG_SE_INIT, null); } @Override @@ -824,6 +557,11 @@ public class NfcService implements DeviceHostListener { } @Override + public void onNfcTransactionEvent(byte[] aid, byte[] data, String seName) { + byte[][] dataObj = {aid, data, seName.getBytes()}; + sendMessage(NfcService.MSG_TRANSACTION_EVENT, dataObj); + } + @Override public void onETSIReaderRequestedFail(int FailCause) { sendMessage(NfcService.MSG_SWP_READER_REQUESTED_FAIL , FailCause); @@ -863,34 +601,6 @@ public class NfcService implements DeviceHostListener { public void onETSIReaderModeRestart() { sendMessage(NfcService.MSG_SWP_READER_RESTART, null); } - - @Override - public void onUiccStatusEvent(int uiccStat) - { - Log.i(TAG, "Broadcasting UICC Status : " + uiccStat); - Intent uiccStatusIntent = new Intent(); - uiccStatusIntent.setAction(ACTION_UICC_STATUS_RECEIVED); - uiccStatusIntent.putExtra(EXTRA_UICC_STATUS, uiccStat); - mContext.sendBroadcast(uiccStatusIntent); - } - - @Override - public void onRestartWatchDog(int enable) { - Log.d(TAG, "Restart Watchdog: WatchDog Thread ID is "+ disableInternalwatchDog.getId()); - sendMessage(NfcService.MSG_RESTART_WATCHDOG, enable); - } - @Override - public void onFwDwnldReqRestartNfc() { - Log.d(TAG, "Restart NFC:When Fw dwnld request was stored during SPI onGoing"); - new EnableDisableTask().execute(TASK_RESTART); - } - - @Override - public void onNfcTransactionEvent(byte[] aid, byte[] data, String seName) { - byte[][] dataObj = {aid, data, seName.getBytes()}; - sendMessage(NfcService.MSG_TRANSACTION_EVENT, dataObj); - } - final class ReaderModeParams { public int flags; public IAppCallback callback; @@ -903,9 +613,10 @@ public class NfcService implements DeviceHostListener { mNfcTagService = new TagService(); mNfcAdapter = new NfcAdapterService(); + mNxpNfcAdapter = new NxpNfcAdapterService(); - mExtrasService = new NfcAdapterExtrasService(); - // mCardEmulationService = new CardEmulationService(); + mNxpExtrasService = new NxpNfcAdapterExtrasService(); + Log.i(TAG, "Starting NFC service"); try { mWiredSeClass = Class.forName("com.android.nfc.WiredSeService"); @@ -915,15 +626,31 @@ public class NfcService implements DeviceHostListener { } catch (InstantiationException e) { Log.e(TAG, "WiredSeService object Instantiation failed"); } - - Log.i(TAG, "Starting NFC service"); - sService = this; mScreenStateHelper = new ScreenStateHelper(mContext); mContentResolver = mContext.getContentResolver(); mDeviceHost = new NativeNfcManager(mContext, this); + Object[] args = new Object[] {mDeviceHost, mContext}; + try { + mNfcExtraClass = Class.forName("com.android.nfc.NfcAdapterExtrasService"); + Constructor mNfcExtraConstr = mNfcExtraClass.getDeclaredConstructor(DeviceHost.class, Context.class); + mNfcExtraObj = mNfcExtraConstr.newInstance(args); + } catch (NoSuchMethodException e ) { + Log.e(TAG, "NfcAdapterExtrasService NoSuchMethodException"); + e.printStackTrace(); + } catch (InvocationTargetException e) { + Log.e(TAG, "NfcAdapterExtrasService InvocationTargetException"); + e.printStackTrace(); + } catch (ClassNotFoundException | IllegalAccessException e){ + Log.e(TAG, "NfcAdapterExtrasService Class not found"); + e.printStackTrace(); + } catch (InstantiationException e) { + Log.e(TAG, "NfcAdapterExtrasService object Instantiation failed"); + e.printStackTrace(); + } + mNfcUnlockManager = NfcUnlockManager.getInstance(); mHandoverDataParser = new HandoverDataParser(); @@ -934,31 +661,6 @@ public class NfcService implements DeviceHostListener { } catch (NotFoundException e) { } - try { - mIsLiveCaseEnabled = mContext.getResources().getBoolean(R.bool.enable_live_cases); - } catch (NotFoundException e) { - mIsLiveCaseEnabled = false; - } - - mLiveCaseTechnology = 0; - String[] liveCaseTechList; - try { - liveCaseTechList = mContext.getResources().getStringArray(R.array.live_case_tag_types); - for (int i=0; i < liveCaseTechList.length; i++) { - if (liveCaseTechList[i].equals("TypeA")) { - mLiveCaseTechnology |= NFC_POLL_A; - } else if (liveCaseTechList[i].equals("TypeB")) { - mLiveCaseTechnology |= NFC_POLL_B; - } else if (liveCaseTechList[i].equals("TypeF")) { - mLiveCaseTechnology |= NFC_POLL_F; - } else if (liveCaseTechList[i].equals("TypeV")) { - mLiveCaseTechnology |= NFC_POLL_V; - } - } - } catch (NotFoundException e) { - mLiveCaseTechnology = 0; - } - if (isNfcProvisioningEnabled) { mInProvisionMode = Settings.Secure.getInt(mContentResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0; @@ -966,42 +668,25 @@ public class NfcService implements DeviceHostListener { mInProvisionMode = false; } - if(mInProvisionMode) - { - /* if device is in provision mode, set this mode at lower layers */ - mDeviceHost.doSetProvisionMode(mInProvisionMode); - } - - mNfcDispatcher = new NfcDispatcher(mContext, mHandoverDataParser, mInProvisionMode, - mIsLiveCaseEnabled); - mP2pLinkManager = new P2pLinkManager(mContext, mHandoverDataParser, - mDeviceHost.getDefaultLlcpMiu(), mDeviceHost.getDefaultLlcpRwSize()); + mNfcDispatcher = new NfcDispatcher(mContext, mHandoverDataParser, mInProvisionMode); mSecureElement = new NativeNfcSecureElement(mContext); - mEeRoutingState = ROUTE_OFF; mToastHandler = new ToastHandler(mContext); - - mNfcSccAccessControl = new NfcSccAccessControl(mContext); - mNfcSeAccessControl = new NfcSeAccessControl(mContext); - mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE); mPrefsEditor = mPrefs.edit(); mNxpPrefs = mContext.getSharedPreferences(NXP_PREF, Context.MODE_PRIVATE); mNxpPrefsEditor = mNxpPrefs.edit(); mState = NfcAdapter.STATE_OFF; - mIsNdefPushEnabled = mPrefs.getBoolean(PREF_NDEF_PUSH_ON, NDEF_PUSH_ON_DEFAULT); - enforceBeamShareActivityPolicy(mContext, new UserHandle(mUserId)); mIsDebugBuild = "userdebug".equals(Build.TYPE) || "eng".equals(Build.TYPE); mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mRoutingWakeLock = mPowerManager.newWakeLock( - PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mRoutingWakeLock"); + PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mRoutingWakeLock"); mEeWakeLock = mPowerManager.newWakeLock( - PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mEeWakeLock"); - + PowerManager.PARTIAL_WAKE_LOCK, "NfcService:mEeWakeLock"); mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); @@ -1016,16 +701,12 @@ public class NfcService implements DeviceHostListener { mBackupManager = new BackupManager(mContext); // Intents for all users - IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION); - filter.addAction(Intent.ACTION_SCREEN_OFF); + IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_USER_PRESENT); filter.addAction(Intent.ACTION_USER_SWITCHED); mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null); - filter = new IntentFilter(Intent.ACTION_SHUTDOWN); - mContext.registerReceiver(mOwnerReceiver, filter); - IntentFilter ownerFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); ownerFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); ownerFilter.addAction(Intent.ACTION_SHUTDOWN); @@ -1037,51 +718,46 @@ public class NfcService implements DeviceHostListener { ownerFilter.addDataScheme("package"); mContext.registerReceiver(mOwnerReceiver, ownerFilter); - IntentFilter x509CertificateFilter = new IntentFilter(); - x509CertificateFilter.addAction(NxpConstants.ACTION_CHECK_X509_RESULT); - mContext.registerReceiverAsUser(x509CertificateReceiver, UserHandle.ALL, - x509CertificateFilter, NfcPermissions.ADMIN_PERM, null); - - IntentFilter activateStkFilter = new IntentFilter(); - activateStkFilter.addAction(NxpConstants.CAT_ACTIVATE_NOTIFY_ACTION); - mContext.registerReceiver(mActivateSwpInterface, activateStkFilter); - - IntentFilter enableNfc = new IntentFilter(); - enableNfc.addAction(NxpConstants.ACTION_GSMA_ENABLE_NFC); - mContext.registerReceiverAsUser(mEnableNfc, UserHandle.ALL, enableNfc, null, null); - - IntentFilter lsFilter = new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED); - //mContext.registerReceiver(mAlaReceiver, lsFilter); - IntentFilter policyFilter = new IntentFilter(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); mContext.registerReceiverAsUser(mPolicyReceiver, UserHandle.ALL, policyFilter, null, null); updatePackageCache(); PackageManager pm = mContext.getPackageManager(); + mIsBeamCapable = pm.hasSystemFeature(PackageManager.FEATURE_NFC_BEAM); + mIsNdefPushEnabled = + mPrefs.getBoolean(PREF_NDEF_PUSH_ON, NDEF_PUSH_ON_DEFAULT) && + mIsBeamCapable; + if (mIsBeamCapable) { + mP2pLinkManager = new P2pLinkManager( + mContext, mHandoverDataParser, mDeviceHost.getDefaultLlcpMiu(), + mDeviceHost.getDefaultLlcpRwSize()); + } + enforceBeamShareActivityPolicy(mContext, new UserHandle(mUserId)); + mIsHceCapable = pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION) || pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF); mIsHceFCapable = pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF); - if (mIsHceCapable) { mAidRoutingManager = new AidRoutingManager(); - mCardEmulationManager = new CardEmulationManager(mContext, mAidRoutingManager); + mCardEmulationManager = new CardEmulationManager(mContext); mAidCache = mCardEmulationManager.getRegisteredAidCache(); - //mCardEmulationManager = new CardEmulationManager(mContext); - Log.d("NfcService", "Before mIsHceCapable"); - mNxpNfcController = new NxpNfcController(mContext, mCardEmulationManager); } - mForegroundUtils = ForegroundUtils.getInstance(); + mIsSecureNfcCapable = mNfcAdapter.deviceSupportsNfcSecure(); + mIsSecureNfcEnabled = + // To be reverted once device support added for secure NFC. + //mPrefs.getBoolean(PREF_SECURE_NFC_ON, SECURE_NFC_ON_DEFAULT) && + //mIsSecureNfcCapable; + mPrefs.getBoolean(PREF_SECURE_NFC_ON, SECURE_NFC_ON_DEFAULT); + mDeviceHost.setNfcSecure(mIsSecureNfcEnabled); + // Make sure this is only called when object construction is complete. ServiceManager.addService(SERVICE_NAME, mNfcAdapter); - - ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); - - new EnableDisableTask().execute(TASK_BOOT); // do blocking boot tasks + new EnableDisableTask().execute(TASK_BOOT); // do blocking boot tasks mHandler.sendEmptyMessageDelayed(MSG_UPDATE_STATS, STATS_UPDATE_INTERVAL_MS); @@ -1097,8 +773,6 @@ public class NfcService implements DeviceHostListener { } mSEService = ISecureElementService.Stub.asInterface(ServiceManager.getService( Context.SECURE_ELEMENT_SERVICE)); - /*SoundPool clean up before NFC state updated*/ - initSoundPool(); } private boolean isSEServiceAvailable() { @@ -1110,7 +784,7 @@ public class NfcService implements DeviceHostListener { } void initSoundPool() { - synchronized(this) { + synchronized (this) { if (mSoundPool == null) { mSoundPool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0); mStartSound = mSoundPool.load(mContext, R.raw.start, 1); @@ -1142,70 +816,35 @@ public class NfcService implements DeviceHostListener { } } - int doOpenSecureElementConnection(int seId) { + int doOpenSecureElementConnection() { mEeWakeLock.acquire(); try { - return mSecureElement.doOpenSecureElementConnection(seId); + return mSecureElement.doOpenSecureElementConnection(); } finally { mEeWakeLock.release(); } } - byte[] doTransceive(int handle, byte[] cmd) { + void doDisconnect(int handle) { mEeWakeLock.acquire(); try { - return doTransceiveNoLock(handle, cmd); + mSecureElement.doDisconnect(handle); } finally { mEeWakeLock.release(); } } - byte[] doTransceiveNoLock(int handle, byte[] cmd) { - return mSecureElement.doTransceive(handle, cmd); - } - - void doDisconnect(int handle) { - mEeWakeLock.acquire(); + byte[] doTransceive(int handle, byte[] cmd) { + mEeWakeLock.acquire(); try { - mSecureElement.doDisconnect(handle); + return doTransceiveNoLock(handle, cmd); } finally { mEeWakeLock.release(); } } - boolean doReset(int handle) { - mEeWakeLock.acquire(); - try { - return mSecureElement.doReset(handle); - } finally { - mEeWakeLock.release(); - } - } - - public static byte[] CreateSHA(String pkg, int alaVer){ - String localTAG = "Utils:CreateSHA"; - StringBuffer sb = new StringBuffer(); - try { - MessageDigest md; - if(alaVer == 1) - md = MessageDigest.getInstance("SHA-256"); - else - md = MessageDigest.getInstance("SHA-1"); - - md.update(pkg.getBytes()); - - byte[] byteData = md.digest(); - Log.i(localTAG, "byteData len : " + byteData.length); - /* - for (int i = 0; i < byteData.length; i++) { - sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1)); - } - // Log.i(TAG, "sb.toString()" + sb.toString());*/ - return byteData; - } catch (Exception e) { - e.printStackTrace(); - } - return null; + byte[] doTransceiveNoLock(int handle, byte[] cmd) { + return mSecureElement.doTransceive(handle, cmd); } /** @@ -1264,7 +903,8 @@ public class NfcService implements DeviceHostListener { disableInternal(); break; case TASK_BOOT: - if (mPrefs.getBoolean(PREF_FIRST_BOOT, true)) { + boolean initialized; + if (mPrefs.getBoolean(PREF_FIRST_BOOT, true)) { Log.i(TAG, "First Boot"); mPrefsEditor.putBoolean(PREF_FIRST_BOOT, false); mPrefsEditor.apply(); @@ -1273,18 +913,15 @@ public class NfcService implements DeviceHostListener { Log.d(TAG, "checking on firmware download"); if (mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT)) { Log.d(TAG, "NFC is on. Doing normal stuff"); - mIsTaskBoot = true; - enableInternal(); - mIsTaskBoot = false; + initialized = enableInternal(); } else { Log.d(TAG, "NFC is off. Checking firmware version"); - mDeviceHost.checkFirmware(); + initialized = mDeviceHost.checkFirmware(); + } + if (initialized) { + SystemProperties.set("nfc.initialized", "true"); } - SystemProperties.set("nfc.initialized", "true"); break; - case TASK_RESTART: - restartInternal(); - } // Restore default AsyncTask priority @@ -1292,187 +929,6 @@ public class NfcService implements DeviceHostListener { return null; } - @Override - protected void onPostExecute(Void result) { - - if(mState == NfcAdapter.STATE_ON){ - IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION); - filter.addAction(Intent.ACTION_SCREEN_OFF); - filter.addAction(Intent.ACTION_SCREEN_ON); - filter.addAction(Intent.ACTION_USER_PRESENT); - filter.addAction(Intent.ACTION_USER_SWITCHED); - mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null); - }else if (mState == NfcAdapter.STATE_OFF){ - mContext.unregisterReceiver(mReceiver); - IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION); - filter.addAction(Intent.ACTION_USER_SWITCHED); - mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null); - } - - - } - - /** - * Check the default Secure Element configuration. - */ - void checkSecureElementConfuration() { - - /* Get SE List */ - int[] seList = mDeviceHost.doGetSecureElementList(); - int uiccSlot = 0; - uiccSlot = mPrefs.getInt(PREF_CUR_SELECTED_UICC_ID, SECURE_ELEMENT_UICC_SLOT_DEFAULT); - int status = mDeviceHost.setPreferredSimSlot(uiccSlot); - /* Check Secure Element setting */ - int seNum=mDeviceHost.GetDefaultSE(); - if(seNum != 0) - { - SECURE_ELEMENT_ON_DEFAULT=true; - SECURE_ELEMENT_ID_DEFAULT=seNum; - } else { - if (seList != null) { - for (int i = 0; i < seList.length; i++) { - mDeviceHost.doDeselectSecureElement(seList[i]); - } - } - } - - mNfcSecureElementState = - mNxpPrefs.getBoolean(PREF_SECURE_ELEMENT_ON, SECURE_ELEMENT_ON_DEFAULT); - - if (mNfcSecureElementState) { - int secureElementId = - mNxpPrefs.getInt(PREF_SECURE_ELEMENT_ID, SECURE_ELEMENT_ID_DEFAULT); - - if (seList != null) { - if (secureElementId != ALL_SE_ID_TYPE/* SECURE_ELEMENT_ALL */) { - mDeviceHost.doDeselectSecureElement(UICC_ID_TYPE); - mDeviceHost.doDeselectSecureElement(UICC2_ID_TYPE); - mDeviceHost.doDeselectSecureElement(SMART_MX_ID_TYPE); - - for (int i = 0; i < seList.length; i++) { - - if (seList[i] == secureElementId) { - if (secureElementId == SMART_MX_ID_TYPE) { // SECURE_ELEMENT_SMX_ID - if (seList.length > 1) { - if (DBG) { - Log.d(TAG, "Deselect UICC"); - } - } - Log.d(TAG, "Select SMX"); - mDeviceHost.doSelectSecureElement(secureElementId); - mSelectedSeId = secureElementId; - break; - } else if (secureElementId == UICC_ID_TYPE/* SECURE_ELEMENT_UICC_ID */) { - if (seList.length > 1) { - if (DBG) { - Log.d(TAG, "Deselect SMX"); - } - } - Log.d(TAG, "Select UICC"); - mDeviceHost.doSelectSecureElement(secureElementId); - mSelectedSeId = secureElementId; - break; - }else if (secureElementId == UICC2_ID_TYPE/* SECURE_ELEMENT_UICC_ID */) { - if (seList.length > 1) { - if (DBG) { - Log.d(TAG, "Deselect SMX"); - } - } - Log.d(TAG, "Select UICC2"); - mDeviceHost.doSelectSecureElement(secureElementId); - mSelectedSeId = secureElementId; - break; - } else if (secureElementId == SECURE_ELEMENT_ID_DEFAULT) { - if (seList.length > 1) { - if (DBG) { - Log.d(TAG, "UICC deselected by default"); - } - } - } - } - } - } else { - if (DBG) { - Log.d(TAG, "Select ALL_SE"); - } - - if (seList.length > 1) { - - for (int i = 0; i < seList.length; i++) { - mDeviceHost.doSelectSecureElement(seList[i]); - try{ - //Delay b/w two SE selection. - Thread.sleep(200); - } catch(Exception e) { - e.printStackTrace(); - } - } - mSelectedSeId = secureElementId; - } - } - } - } else { - if (seList != null && seList.length > 0) { - if (DBG) { - Log.d(TAG, "UICC/eSE deselected by default"); - } - mDeviceHost.doDeselectSecureElement(UICC_ID_TYPE); - mDeviceHost.doDeselectSecureElement(UICC2_ID_TYPE); - mDeviceHost.doDeselectSecureElement(SMART_MX_ID_TYPE); - } - } - } - - boolean getJcopOsFileInfo() { - File jcopOsFile; - Log.i(TAG, "getJcopOsFileInfo"); - - for (int num = 0; num < 3; num++) { - try{ - jcopOsFile = new File(path[num]); - }catch(NullPointerException npe) { - Log.e(TAG,"path to jcop os file was null"); - return false; - } - long modtime = jcopOsFile.lastModified(); - SharedPreferences prefs = mContext.getSharedPreferences(PREF,Context.MODE_PRIVATE); - long prev_modtime = prefs.getLong(PREF_JCOP_MODTIME[num], JCOP_MODTIME_DEFAULT[num]); - Log.d(TAG,"prev_modtime:" + prev_modtime); - Log.d(TAG,"new_modtime:" + modtime); - if(prev_modtime == modtime){ - return false; - } - JCOP_MODTIME_TEMP[num] = modtime; - } - return true; - } - - /* jcop os Download at boot time */ - void jcopOsDownload() { - int status = ErrorCodes.SUCCESS; - boolean jcopStatus; - Log.i(TAG, "Jcop Download starts"); - - SharedPreferences prefs = mContext.getSharedPreferences(PREF,Context.MODE_PRIVATE); - jcopStatus = getJcopOsFileInfo(); - - if( jcopStatus == true) { - Log.i(TAG, "Starting getChipName"); - int Ver = mDeviceHost.getChipVer(); - if(Ver == PN80T_ID || Ver == PN67T_ID || Ver == PN66T_ID || Ver == PN65T_ID) { - status = mDeviceHost.JCOSDownload(); - } - if(status != ErrorCodes.SUCCESS) { - Log.i(TAG, "Jcop Download failed"); - } - else { - Log.i(TAG, "Jcop Download success"); - prefs.edit().putLong(PREF_JCOP_MODTIME[0],JCOP_MODTIME_TEMP[0]).apply(); - prefs.edit().putLong(PREF_JCOP_MODTIME[1],JCOP_MODTIME_TEMP[1]).apply(); - prefs.edit().putLong(PREF_JCOP_MODTIME[2],JCOP_MODTIME_TEMP[2]).apply(); - } - } - } /** * Enable NFC adapter functions. * Does not toggle preferences. @@ -1483,13 +939,8 @@ public class NfcService implements DeviceHostListener { } Log.i(TAG, "Enabling NFC"); updateState(NfcAdapter.STATE_TURNING_ON); - int timeout = mDeviceHost.getNfcInitTimeout(); - if (timeout < INIT_WATCHDOG_MS) - { - timeout = INIT_WATCHDOG_MS; - } - Log.i(TAG, "Enabling NFC timeout" +timeout); - WatchDogThread watchDog = new WatchDogThread("enableInternal", timeout); + + WatchDogThread watchDog = new WatchDogThread("enableInternal", INIT_WATCHDOG_MS); watchDog.start(); try { mRoutingWakeLock.acquire(); @@ -1497,7 +948,6 @@ public class NfcService implements DeviceHostListener { if (!mDeviceHost.initialize()) { Log.w(TAG, "Error enabling NFC"); updateState(NfcAdapter.STATE_OFF); - watchDog.cancel(); return false; } } finally { @@ -1506,42 +956,28 @@ public class NfcService implements DeviceHostListener { } finally { watchDog.cancel(); } - mChipVer = mDeviceHost.getChipVer(); - if(mChipVer < PN553_ID) { - ALL_SE_ID_TYPE &= ~UICC2_ID_TYPE; - } - checkSecureElementConfuration(); - - mIsRouteForced = true; + int uiccSlot = 0; + uiccSlot = mPrefs.getInt(PREF_CUR_SELECTED_UICC_ID, SECURE_ELEMENT_UICC_SLOT_DEFAULT); + mDeviceHost.setPreferredSimSlot(uiccSlot); if (mIsHceCapable) { // Generate the initial card emulation routing table - sAidTableFull = false; mCardEmulationManager.onNfcEnabled(); + computeRoutingParameters(); } - mIsRouteForced = false; + nci_version = getNciVersion(); + Log.d(TAG, "NCI_Version: " + nci_version); synchronized (NfcService.this) { mObjectMap.clear(); - mP2pLinkManager.enableDisable(mIsNdefPushEnabled, true); + if (mIsBeamCapable) { + mP2pLinkManager.enableDisable(mIsNdefPushEnabled, true); + } + updateState(NfcAdapter.STATE_ON); } - synchronized (NfcService.this) { - updateState(NfcAdapter.STATE_ON); - try { - mWiredSeInitMethod = mWiredSeClass.getDeclaredMethod("wiredSeInitialize"); - mWiredSeInitMethod.invoke(mWiredSeObj); - } catch (NoSuchElementException | NoSuchMethodException e) { - Log.i(TAG, "No such Method WiredSeInitialize"); - } catch (RuntimeException | IllegalAccessException | InvocationTargetException e) { - Log.e(TAG, "Error in invoking wiredSeInitialize invocation"); - } catch (Exception e) { - Log.e(TAG, "caught Exception during wiredSeInitialize"); - e.printStackTrace(); - } - } - /* Start polling loop */ - Log.e(TAG, "applyRouting -3"); + initSoundPool(); + mScreenState = mScreenStateHelper.checkScreenState(); int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ? (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState; @@ -1549,21 +985,13 @@ public class NfcService implements DeviceHostListener { if(mNfcUnlockManager.isLockscreenPollingEnabled()) applyRouting(false); - mDeviceHost.doSetScreenOrPowerState(screen_state_mask); - mIsRoutingTableDirty = true; - if((mScreenState < NFC_POLLING_MODE) && mIsTaskBoot) - { - /*During device boot if screen state is other ON_UNLOCKED, - *first send discovery command with poll and linsten enabled - *for DC/DC pass through mode activation. - *Then send normal discovery according to screen state*/ - applyRouting(true); - mIsTaskBoot = false; - } + mDeviceHost.doSetScreenState(screen_state_mask); + + /* Start polling loop */ applyRouting(true); - synchronized (NfcService.this) { - mNxpNfcState = NXP_NFC_STATE_ON; - } + commitRouting(); + /* WiredSe Init after ESE is discovered and initialised */ + initWiredSe(); return true; } @@ -1579,8 +1007,8 @@ public class NfcService implements DeviceHostListener { updateState(NfcAdapter.STATE_TURNING_OFF); try{ - mWiredSeDeInitMwthod = mWiredSeClass.getDeclaredMethod("wiredSeDeInitialize"); - mWiredSeDeInitMwthod.invoke(mWiredSeObj); + mWiredSeDeInitMethod = mWiredSeClass.getDeclaredMethod("wiredSeDeInitialize"); + mWiredSeDeInitMethod.invoke(mWiredSeObj); } catch (NoSuchElementException | NoSuchMethodException e) { Log.i(TAG, "No such Method WiredSeInitialize"); } catch (RuntimeException | IllegalAccessException | InvocationTargetException e) { @@ -1589,48 +1017,20 @@ public class NfcService implements DeviceHostListener { Log.e(TAG, "caught Exception during wiredSeInitialize"); e.printStackTrace(); } - - /*SoundPool clean up before NFC state updated - releaseSoundPool();*/ - /* Sometimes mDeviceHost.deinitialize() hangs, use a watch-dog. * Implemented with a new thread (instead of a Handler or AsyncTask), * because the UI Thread and AsyncTask thread-pools can also get hung * when the NFC controller stops responding */ - disableInternalwatchDog = new WatchDogThread("disableInternal", ROUTING_WATCHDOG_MS); - disableInternalwatchDog.start(); + WatchDogThread watchDog = new WatchDogThread("disableInternal", ROUTING_WATCHDOG_MS); + Log.d(TAG, "New Watchdog: WatchDog Thread ID is "+ watchDog.getId()); + watchDog.start(); if (mIsHceCapable) { mCardEmulationManager.onNfcDisabled(); } - mP2pLinkManager.enableDisable(false, false); - - /* The NFC-EE may still be opened by another process, - * and a transceive() could still be in progress on - * another Binder thread. - * Give it a while to finish existing operations - * before we close it. - */ - Long startTime = SystemClock.elapsedRealtime(); - do { - synchronized (NfcService.this) { - if (mOpenEe == null) - break; - } - try { - Thread.sleep(WAIT_FOR_NFCEE_POLL_MS); - } catch (InterruptedException e) { - // Ignore - } - } while (SystemClock.elapsedRealtime() - startTime < WAIT_FOR_NFCEE_OPERATIONS_MS); - - synchronized (NfcService.this) { - if (mOpenEe != null) { - try { - _nfcEeClose(-1, mOpenEe.binder); - } catch (IOException e) { } - } + if (mIsBeamCapable) { + mP2pLinkManager.enableDisable(false, false); } // Stop watchdog if tag present @@ -1641,46 +1041,17 @@ public class NfcService implements DeviceHostListener { mNfcDispatcher.setForegroundDispatch(null, null, null); + boolean result = mDeviceHost.deinitialize(); if (DBG) Log.d(TAG, "mDeviceHost.deinitialize() = " + result); - - disableInternalwatchDog.cancel(); + isWiredOpen = false; + watchDog.cancel(); synchronized (NfcService.this) { mCurrentDiscoveryParameters = NfcDiscoveryParameters.getNfcOffParameters(); updateState(NfcAdapter.STATE_OFF); - mNxpNfcState = NXP_NFC_STATE_OFF; } - return result; - } - - boolean restartInternal() - { - boolean result; - result = disableInternal(); - if (DBG) Log.d(TAG, "disableInternal status = " + result); - while(true) - { - if(mState == NfcAdapter.STATE_OFF) - { - if (DBG) Log.d(TAG, "disableInternal is success = " + result); - break; - } - } - result = enableInternal(); - if (DBG) Log.d(TAG, "enableInternal status = " + result); - while(true) - { - if(mState == NfcAdapter.STATE_ON) - { - if (DBG) Log.d(TAG, "enableInternal is success = " + result); - break; - } - } - Intent flashIntent = new Intent(); - flashIntent.setAction(ACTION_FLASH_SUCCESS); - if (DBG) Log.d(TAG, "Broadcasting " + ACTION_FLASH_SUCCESS); - mContext.sendBroadcast(flashIntent); + releaseSoundPool(); return result; } @@ -1750,8 +1121,8 @@ public class NfcService implements DeviceHostListener { } } boolean isActiveForUser = - (!um.hasUserRestriction(UserManager.DISALLOW_OUTGOING_BEAM, uh)) && - isGlobalEnabled; + (!um.hasUserRestriction(UserManager.DISALLOW_OUTGOING_BEAM, uh)) && + isGlobalEnabled && mIsBeamCapable; if (DBG) { Log.d(TAG, "Enforcing a policy change on user: " + uh.toString() + ", isActiveForUser = " + isActiveForUser); @@ -1764,7 +1135,7 @@ public class NfcService implements DeviceHostListener { PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP, - uh.getIdentifier()); + uh.getIdentifier()); } catch (RemoteException e) { Log.w(TAG, "Unable to change Beam status for user " + uh); } @@ -1774,18 +1145,6 @@ public class NfcService implements DeviceHostListener { @Override public boolean enable() throws RemoteException { NfcPermissions.enforceAdminPermissions(mContext); - if (mNxpNfcState != NXP_NFC_STATE_OFF) { - return true; - } else { - // do nothing - } - - synchronized (NfcService.this) { - mNxpNfcState = NXP_NFC_STATE_TURNING_ON; - } - - int val = mDeviceHost.GetDefaultSE(); - Log.i(TAG, "getDefaultSE " + val); saveNfcOnSetting(true); @@ -1796,44 +1155,15 @@ public class NfcService implements DeviceHostListener { @Override public boolean disable(boolean saveState) throws RemoteException { - NfcPermissions.enforceAdminPermissions(mContext); - if (mNxpNfcState != NXP_NFC_STATE_ON) { - return true; - } else { - // do nothing - } + NfcPermissions.enforceAdminPermissions(mContext); - synchronized (NfcService.this) { - mNxpNfcState = NXP_NFC_STATE_TURNING_OFF; - } - - Log.d(TAG,"Disabling Nfc."); - - //Check if this a device shutdown or Nfc only Nfc disable. - if(!mPowerShutDown) - { - int[] seList = mDeviceHost.doGetSecureElementList(); - Log.i(TAG, "Disabling NFC Disabling ESE/UICC"); - //Since only Nfc is getting disabled so disable CE from EE. - mDeviceHost.doSetScreenOrPowerState(ScreenStateHelper.POWER_STATE_ON); - if (seList != null) { - for (int i = 0; i < seList.length; i++) { - mDeviceHost.doDeselectSecureElement(seList[i]); - } - } - } else { - Log.i(TAG, "Power off : Disabling NFC Disabling ESE/UICC"); - mPowerShutDown = false; - mCardEmulationManager.onPreferredForegroundServiceChanged(null); - } - - if (saveState) { - saveNfcOnSetting(false); - } + if (saveState) { + saveNfcOnSetting(false); + } - new EnableDisableTask().execute(TASK_DISABLE); + new EnableDisableTask().execute(TASK_DISABLE); - return true; + return true; } @Override @@ -1879,7 +1209,7 @@ public class NfcService implements DeviceHostListener { public boolean enableNdefPush() throws RemoteException { NfcPermissions.enforceAdminPermissions(mContext); synchronized (NfcService.this) { - if (mIsNdefPushEnabled) { + if (mIsNdefPushEnabled || !mIsBeamCapable) { return true; } Log.i(TAG, "enabling NDEF Push"); @@ -1888,7 +1218,6 @@ public class NfcService implements DeviceHostListener { mIsNdefPushEnabled = true; enforceBeamShareActivityPolicy(mContext, new UserHandle(mUserId)); if (isNfcEnabled()) { - mDeviceHost.doEnablep2p(mIsNdefPushEnabled); mP2pLinkManager.enableDisable(true, true); } mBackupManager.dataChanged(); @@ -1896,11 +1225,36 @@ public class NfcService implements DeviceHostListener { return true; } + @Override + public boolean isNfcSecureEnabled() throws RemoteException { + synchronized (NfcService.this) { + return mIsSecureNfcEnabled; + } + } + + @Override + public boolean setNfcSecure(boolean enable) { + NfcPermissions.enforceAdminPermissions(mContext); + synchronized (NfcService.this) { + Log.i(TAG, "setting Secure NFC " + enable); + mPrefsEditor.putBoolean(PREF_SECURE_NFC_ON, enable); + mPrefsEditor.apply(); + mIsSecureNfcEnabled = enable; + mBackupManager.dataChanged(); + mDeviceHost.setNfcSecure(enable); + computeAndSetRoutingParameters(); + } + if (mIsHceCapable) { + mCardEmulationManager.onSecureNfcToggled(); + } + return true; + } + @Override public boolean disableNdefPush() throws RemoteException { NfcPermissions.enforceAdminPermissions(mContext); synchronized (NfcService.this) { - if (!mIsNdefPushEnabled) { + if (!mIsNdefPushEnabled || !mIsBeamCapable) { return true; } Log.i(TAG, "disabling NDEF Push"); @@ -1952,14 +1306,16 @@ public class NfcService implements DeviceHostListener { mNfcDispatcher.setForegroundDispatch(intent, filters, techLists); } + @Override public void setAppCallback(IAppCallback callback) { NfcPermissions.enforceUserPermissions(mContext); // don't allow Beam for managed profiles, or devices with a device owner or policy owner UserInfo userInfo = mUserManager.getUserInfo(UserHandle.getCallingUserId()); - if(!mUserManager.hasUserRestriction( - UserManager.DISALLOW_OUTGOING_BEAM, userInfo.getUserHandle())) { + if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_OUTGOING_BEAM, + userInfo.getUserHandle()) && + mIsBeamCapable) { mP2pLinkManager.setNdefCallback(callback, Binder.getCallingUid()); } else if (DBG) { Log.d(TAG, "Disabling default Beam behavior"); @@ -1967,27 +1323,6 @@ public class NfcService implements DeviceHostListener { } @Override - public INfcAdapterExtras getNfcAdapterExtrasInterface(String pkg) { - - if (pkg.equals(PACKAGE_SMART_CARD_SERVICE)){ - Log.d(TAG, "wildcard for SmartcardService"); - return mExtrasService; - } - - NfcService.this.enforceNfceeAdminPerm(pkg); - return mExtrasService; - } - - @Override - public INfcDta getNfcDtaInterface(String pkg) throws RemoteException { - NfcPermissions.enforceAdminPermissions(mContext); - if (mNfcDtaService == null) { - mNfcDtaService = new NfcDtaService(); - } - return mNfcDtaService; - } - - @Override public boolean ignore(int nativeHandle, int debounceMs, ITagRemovedCallback callback) throws RemoteException { NfcPermissions.enforceUserPermissions(mContext); @@ -2023,13 +1358,16 @@ public class NfcService implements DeviceHostListener { } } - @Override + @Override public void verifyNfcPermission() { NfcPermissions.enforceUserPermissions(mContext); } @Override public void invokeBeam() { + if (!mIsBeamCapable) { + return; + } NfcPermissions.enforceUserPermissions(mContext); if (mForegroundUtils.isInForeground(Binder.getCallingUid())) { @@ -2087,8 +1425,7 @@ public class NfcService implements DeviceHostListener { } else { return null; } - } - + } @Override public int getState() throws RemoteException { @@ -2152,11 +1489,23 @@ public class NfcService implements DeviceHostListener { Log.e(TAG, "Reader mode Binder was never registered."); } } - Log.e(TAG, "applyRouting -4"); applyRouting(false); } } + @Override + public INfcAdapterExtras getNfcAdapterExtrasInterface(String pkg) throws RemoteException { + return (INfcAdapterExtras) mNfcExtraObj; + } + + @Override + public INfcDta getNfcDtaInterface(String pkg) throws RemoteException { + NfcPermissions.enforceAdminPermissions(mContext); + if (mNfcDtaService == null) { + mNfcDtaService = new NfcDtaService(); + } + return mNfcDtaService; + } @Override public void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, int[] techList) { @@ -2178,6 +1527,19 @@ public class NfcService implements DeviceHostListener { applyRouting(false); } + + @Override + public boolean deviceSupportsNfcSecure() { + /*String skuList[] = mContext.getResources().getStringArray( + R.array.config_skuSupportsSecureNfc); + String sku = SystemProperties.get("ro.boot.hardware.sku"); + if (TextUtils.isEmpty(sku) || !ArrayUtils.contains(skuList, sku)) { + return false; + } + return true;*/ + return false; //TODO - Needto revert this changes once stabilised. + } + private int computeLockscreenPollMask(int[] techList) { Map<Integer, Integer> techCodeToMask = new HashMap<Integer, Integer>(); @@ -2187,8 +1549,6 @@ public class NfcService implements DeviceHostListener { techCodeToMask.put(TagTechnology.NFC_V, NfcService.NFC_POLL_V); techCodeToMask.put(TagTechnology.NFC_F, NfcService.NFC_POLL_F); techCodeToMask.put(TagTechnology.NFC_BARCODE, NfcService.NFC_POLL_KOVIO); - techCodeToMask.put(TagTechnology.MIFARE_CLASSIC, NfcService.NFC_POLL_A); - techCodeToMask.put(TagTechnology.MIFARE_ULTRALIGHT, NfcService.NFC_POLL_A); int mask = 0; @@ -2196,15 +1556,10 @@ public class NfcService implements DeviceHostListener { if (techCodeToMask.containsKey(techList[i])) { mask |= techCodeToMask.get(techList[i]).intValue(); } - int screenState = mScreenStateHelper.checkScreenState(); - if (screenState != mScreenState) { - new ApplyRoutingTask().execute(Integer.valueOf(screenState)); - } } return mask; } - /** * An interface for nxp extensions */ @@ -2216,29 +1571,68 @@ public class NfcService implements DeviceHostListener { return null; } } - } + final class NxpNfcAdapterService extends INxpNfcAdapter.Stub { - //GSMA Changes @Override - public INxpNfcController getNxpNfcControllerInterface() { - return mNxpNfcController.getNxpNfcControllerInterface(); + public INxpNfcAdapterExtras getNxpNfcAdapterExtrasInterface() throws RemoteException { + return mNxpExtrasService; } - @Override - public INfcVzw getNfcVzwInterface() { - NfcPermissions.enforceAdminPermissions(mContext); - //begin - if(mVzwService == null){ - mVzwService = new NfcVzwService(); - } - //end - return mVzwService; - } + public void MifareDesfireRouteSet(int routeLoc, boolean fullPower, boolean lowPower, + boolean noPower) throws RemoteException { + if (routeLoc == UICC2_ID_TYPE) { + throw new RemoteException("UICC2 is not supported"); + } + int protoRouteEntry = 0; + /*UICC2 ID-4(fromApp) mapped to 3 (JNI)*/ + protoRouteEntry = ((routeLoc & 0x07) == 0x04) ? (0x03 << ROUTE_LOC_MASK) : /*UICC2*/ + ((routeLoc & 0x07) == 0x02) ? (0x02 << ROUTE_LOC_MASK) : /*UICC1*/ + ((routeLoc & 0x07) == 0x01) ? (0x01 << ROUTE_LOC_MASK) : /*eSE*/ + 0x00; + protoRouteEntry |= + ((fullPower ? (mDeviceHost.getDefaultDesfirePowerState() & 0x1F) | 0x01 : 0) + | (lowPower ? 0x01 << 1 : 0) | (noPower ? 0x01 << 2 : 0)); + if (routeLoc == 0x00) { + /* + bit pos 1 = Power Off + bit pos 2 = Battery Off + bit pos 4 = Screen Off + Set these bits to 0 because in case routeLoc = HOST it can not work on POWER_OFF, + BATTERY_OFF and SCREEN_OFF*/ + protoRouteEntry &= 0xE9; + } + + Log.i(TAG, "MifareDesfireRouteSet : " + protoRouteEntry); + mNxpPrefsEditor = mNxpPrefs.edit(); + mNxpPrefsEditor.putInt("PREF_MIFARE_DESFIRE_PROTO_ROUTE_ID", protoRouteEntry); + mNxpPrefsEditor.commit(); + Log.i(TAG, "MifareDesfireRouteSet function in"); + commitRouting(); + } @Override - public int setEmvCoPollProfile(boolean enable, int route) throws RemoteException { - return mDeviceHost.setEmvCoPollProfile(enable, route); + public void MifareCLTRouteSet(int routeLoc, boolean fullPower, boolean lowPower, + boolean noPower) throws RemoteException { + if (routeLoc == UICC2_ID_TYPE) { + throw new RemoteException("UICC2 is not supported"); + } + + int techRouteEntry = 0; + techRouteEntry = ((routeLoc & 0x07) == 0x04) ? (0x03 << ROUTE_LOC_MASK) : /*UICC2*/ + ((routeLoc & 0x07) == 0x02) ? (0x02 << ROUTE_LOC_MASK) : /*UICC1*/ + ((routeLoc & 0x07) == 0x01) ? (0x01 << ROUTE_LOC_MASK) : /*eSE*/ + 0x00; + techRouteEntry |= + ((fullPower ? (mDeviceHost.getDefaultMifareCLTPowerState() & 0x1F) | 0x01 : 0) + | (lowPower ? 0x01 << 1 : 0) | (noPower ? 0x01 << 2 : 0)); + techRouteEntry |= (TECH_TYPE_A << TECH_TYPE_MASK); + + Log.i(TAG, "MifareCLTRouteSet : " + techRouteEntry); + mNxpPrefsEditor = mNxpPrefs.edit(); + mNxpPrefsEditor.putInt("PREF_MIFARE_CLT_ROUTE_ID", techRouteEntry); + mNxpPrefsEditor.commit(); + commitRouting(); } @Override @@ -2246,53 +1640,114 @@ public class NfcService implements DeviceHostListener { int[] list = null; if (isNfcEnabled()) { list = mDeviceHost.doGetActiveSecureElementList(); - - for (int i = 0; i < list.length; i++) { - Log.d(TAG, "Active element = " + list[i]); - } + } + for (int i = 0; i < list.length; i++) { + Log.d(TAG, "Active element = " + list[i]); } return list; } @Override - public void MifareDesfireRouteSet(int routeLoc, boolean fullPower, boolean lowPower, boolean noPower) - throws RemoteException - { - if((mChipVer < PN553_ID) && (routeLoc == UICC2_ID_TYPE)) { - throw new RemoteException("UICC2 is not supported"); + public int mPOSSetReaderMode (String pkg, boolean on) { + // Check if NFC is enabled + if (!isNfcEnabled()) { + return NfcConstants.MPOS_STATUS_REJECTED; } - int protoRouteEntry = 0; - /*UICC2 ID-4(fromApp) mapped to 3 (JNI)*/ - protoRouteEntry=((routeLoc & 0x07) == 0x04) ? (0x03 << ROUTE_LOC_MASK) : /*UICC2*/ - ((routeLoc & 0x07) == 0x02) ? (0x02 << ROUTE_LOC_MASK) : /*UICC1*/ - ((routeLoc & 0x07) == 0x01) ? (0x01 << ROUTE_LOC_MASK) : /*eSE*/ - 0x00; - protoRouteEntry |= ((fullPower ? (mDeviceHost.getDefaultDesfirePowerState() & 0x3F) | 0x01 : 0) | (lowPower ? 0x01 << 1 :0 ) | (noPower ? 0x01 << 2 :0)); - if(routeLoc == 0x00) - { - /* - bit pos 1 = Power Off - bit pos 2 = Battery Off - bit pos 3 = Screen Off and Unlocked - bit pos 5 = Screen Off and locked - Set these bits to 0 because in case routeLoc = HOST it can not work on POWER_OFF, BATTERY_OFF and SCREEN_OFF*/ - protoRouteEntry &= (getNciVersion() == NCI_VERSION_2_0) ? 0x11 : 0xE9; - } - - Log.i(TAG,"MifareDesfireRouteSet : " + protoRouteEntry); - mNxpPrefsEditor = mNxpPrefs.edit(); - mNxpPrefsEditor.putInt("PREF_MIFARE_DESFIRE_PROTO_ROUTE_ID", protoRouteEntry); - mNxpPrefsEditor.commit(); - Log.i(TAG,"MifareDesfireRouteSet function in"); - commitRouting(); + synchronized(NfcService.this) { + int status = mDeviceHost.mposSetReaderMode(on); + if(!on) { + if(nci_version != NCI_VERSION_2_0) { + applyRouting(true); + } else if(mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED + || mNfcUnlockManager.isLockscreenPollingEnabled()) { + applyRouting(false); + } + } + return status; + } + } + + @Override + public boolean mPOSGetReaderMode (String pkg) { + // Check if NFC is enabled + if (!isNfcEnabled()) { + return false; + } + + boolean status = false; + synchronized(NfcService.this) { + status = mDeviceHost.mposGetReaderMode(); + } + return status; + } + @Override + public void changeDiscoveryTech(IBinder binder, int pollTech, int listenTech) + throws RemoteException { + + synchronized (NfcService.this) { + if (!(mState == NfcAdapter.STATE_ON)) { + if (DBG) Log.d(TAG, "changeDiscoveryTech. NFC is not enabled"); + return; + } + + if (DBG) Log.d(TAG, "changeDiscoveryTech. pollTech : 0x" + Integer.toHexString(pollTech) + ", listenTech : 0x" + Integer.toHexString(listenTech)); + + //In case both parameters are set to 0xFF, which means that original poll, listen techs are applied. + if (pollTech == 0xFF && listenTech == 0xFF) { + //Recover to previous state. + try { + if (!mIsNdefPushEnabled) { + if (DBG) Log.d(TAG, "changeDiscoveryTech. Android Beam was temporarily enabled, so disable this."); + mP2pLinkManager.enableDisable(false, true); + } + mDeviceHost.doChangeDiscoveryTech(pollTech, listenTech); + } catch(NoSuchElementException e) { + Log.e(TAG, "Change Tech Binder was never registered."); + } + } else { + //Change discovery tech. + if (!mIsNdefPushEnabled) { + if (DBG) Log.d(TAG, "changeDiscoveryTech. Android Beam is disabled, so enable this temporarily."); + mP2pLinkManager.enableDisable(true, true); + } + mDeviceHost.doChangeDiscoveryTech(pollTech, listenTech); + } + + if (DBG) Log.d(TAG, "applyRouting #15"); + applyRouting(true); + } + } + + @Override + public void stopPoll(String pkg, int mode) { + // Check if NFC is enabled + if (!isNfcEnabled()) { + return; + } + + synchronized(NfcService.this) { + mDeviceHost.stopPoll(mode); + } + } + + @Override + public void startPoll(String pkg) { + // Check if NFC is enabled + if (!isNfcEnabled()) { + return; + } + + synchronized(NfcService.this) { + mDeviceHost.startPoll(); + } } @Override public void DefaultRouteSet(int routeLoc, boolean fullPower, boolean lowPower, boolean noPower) throws RemoteException { - if((mChipVer < PN553_ID) && (routeLoc == UICC2_ID_TYPE)) { + if(routeLoc == UICC2_ID_TYPE) { throw new RemoteException("UICC2 is not supported"); } if (mIsHceCapable) { @@ -2301,18 +1756,19 @@ public class NfcService implements DeviceHostListener { ((routeLoc & 0x07) == 0x02) ? (0x02 << ROUTE_LOC_MASK) : /*UICC1*/ ((routeLoc & 0x07) == 0x01) ? (0x01 << ROUTE_LOC_MASK) : /*eSE*/ 0x00; - protoRouteEntry |= ((fullPower ? (mDeviceHost.getDefaultAidPowerState() & 0x3F) | 0x01 : 0) | (lowPower ? 0x01 << 1 :0 ) | (noPower ? 0x01 << 2 :0)); + protoRouteEntry |= + ((fullPower ? (mDeviceHost.getDefaultAidPowerState() & 0x1F) | 0x01 : 0) + | (lowPower ? 0x01 << 1 : 0) | (noPower ? 0x01 << 2 : 0)); if(routeLoc == 0x00) { /* bit pos 1 = Power Off bit pos 2 = Battery Off - bit pos 3 = Screen Off and Unlocked - bit pos 5 = Screen Off and locked - Set these bits to 0 because in case routeLoc = HOST it can not work on POWER_OFF, BATTERY_OFF and SCREEN_OFF*/ - - protoRouteEntry &= (getNciVersion() == NCI_VERSION_2_0) ? 0x11 : 0xE9; + bit pos 4 = Screen Off + Set these bits to 0 because in case routeLoc = HOST it can not work on + POWER_OFF, BATTERY_OFF and SCREEN_OFF*/ + protoRouteEntry &= 0xE9; } Log.i(TAG,"DefaultRouteSet : " + protoRouteEntry); if(GetDefaultRouteLoc() != routeLoc) @@ -2334,29 +1790,6 @@ public class NfcService implements DeviceHostListener { } @Override - public void MifareCLTRouteSet(int routeLoc, boolean fullPower, boolean lowPower, boolean noPower) - throws RemoteException - { - if((mChipVer < PN553_ID) && (routeLoc == UICC2_ID_TYPE)) { - throw new RemoteException("UICC2 is not supported"); - } - - int techRouteEntry=0; - techRouteEntry=((routeLoc & 0x07) == 0x04) ? (0x03 << ROUTE_LOC_MASK) : /*UICC2*/ - ((routeLoc & 0x07) == 0x02) ? (0x02 << ROUTE_LOC_MASK) : /*UICC1*/ - ((routeLoc & 0x07) == 0x01) ? (0x01 << ROUTE_LOC_MASK) : /*eSE*/ - 0x00; - techRouteEntry |= ((fullPower ? (mDeviceHost.getDefaultMifareCLTPowerState() & 0x1F) | 0x01 : 0) | (lowPower ? 0x01 << 1 :0 ) | (noPower ? 0x01 << 2 :0)); - techRouteEntry |= (TECH_TYPE_A << TECH_TYPE_MASK); - - Log.i(TAG,"MifareCLTRouteSet : " + techRouteEntry); - mNxpPrefsEditor = mNxpPrefs.edit(); - mNxpPrefsEditor.putInt("PREF_MIFARE_CLT_ROUTE_ID", techRouteEntry); - mNxpPrefsEditor.commit(); - commitRouting(); - } - - @Override public byte[] getFWVersion() { byte[] buf = new byte[3]; @@ -2369,6 +1802,20 @@ public class NfcService implements DeviceHostListener { return buf; } + private void WaitForAdapterChange(int state) { + while (true) { + if(mState == state) { + break; + } + try { + Thread.sleep(100); + } catch (Exception e) { + e.printStackTrace(); + } + } + return; + } + @Override public byte[] readerPassThruMode(byte status, byte modulationTyp) throws RemoteException { @@ -2384,30 +1831,6 @@ public class NfcService implements DeviceHostListener { Log.i(TAG, "Transceive requested on reader pass through mode"); return mDeviceHost.transceiveAppData(data); } - - @Override - public List<NxpAidServiceInfo> getServicesAidInfo(int userId, String category){ - return mCardEmulationManager.getServicesAidInfo(userId, category); - } - - @Override - public int updateServiceState(int userId , Map serviceState) { - return mCardEmulationManager.updateServiceState(userId ,serviceState); - } - - @Override - public int getMaxAidRoutingTableSize() throws RemoteException { - NfcPermissions.enforceUserPermissions(mContext); - return getAidRoutingTableSize(); - } - - - @Override - public int getCommittedAidRoutingTableSize() throws RemoteException { - NfcPermissions.enforceUserPermissions(mContext); - return (getAidRoutingTableSize() - getRemainingAidTableSize()); - } - @Override public int setConfig(String configs , String pkg) { Log.e(TAG, "Setting configs for Transit" ); @@ -2458,102 +1881,6 @@ public class NfcService implements DeviceHostListener { return TRANSIT_SETCONFIG_STAT_SUCCESS; } - private void WaitForAdapterChange(int state) { - while (true) { - if(mState == state) { - break; - } - try { - Thread.sleep(100); - } catch (Exception e) { - e.printStackTrace(); - } - } - return; - } - - @Override - public int mPOSSetReaderMode (String pkg, boolean on) { - NfcService.this.enforceNfceeAdminPerm(pkg); - // Check if NFC is enabled - if (!isNfcEnabled()) { - return NxpConstants.MPOS_STATUS_REJECTED; - } - - synchronized(NfcService.this) { - int status = mDeviceHost.mposSetReaderMode(on); - if(!on) { - if(nci_version != NCI_VERSION_2_0) { - applyRouting(true); - } else if(mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED - || mNfcUnlockManager.isLockscreenPollingEnabled()) { - applyRouting(false); - } - } - return status; - } - } - - @Override - public boolean mPOSGetReaderMode (String pkg) { - NfcService.this.enforceNfceeAdminPerm(pkg); - // Check if NFC is enabled - if (!isNfcEnabled()) { - return false; - } - - boolean status = false; - synchronized(NfcService.this) { - status = mDeviceHost.mposGetReaderMode(); - } - return status; - } - - @Override - public void stopPoll(String pkg, int mode) { - NfcService.this.enforceNfceeAdminPerm(pkg); - // Check if NFC is enabled - if (!isNfcEnabled()) { - return; - } - - synchronized(NfcService.this) { - mDeviceHost.stopPoll(mode); - } - } - - @Override - public void startPoll(String pkg) { - NfcService.this.enforceNfceeAdminPerm(pkg); - // Check if NFC is enabled - if (!isNfcEnabled()) { - return; - } - - synchronized(NfcService.this) { - mDeviceHost.startPoll(); - } - } - - @Override - public int nfcSelfTest(String pkg, int type) { - int status = 0xFF; - NfcService.this.enforceNfceeAdminPerm(pkg); - - synchronized(NfcService.this) { - status = mDeviceHost.doNfcSelfTest(type); - } - return status; - } - - @Override - public int getSelectedUicc() throws RemoteException { - if (!isNfcEnabled()) { - throw new RemoteException("NFC is not enabled"); - } - return mDeviceHost.doGetSelectedUicc(); - } - @Override public int selectUicc(int uiccSlot) throws RemoteException { synchronized(NfcService.this) { @@ -2565,7 +1892,7 @@ public class NfcService implements DeviceHostListener { /*In case of UICC connected and Enabled or Removed , *Reconfigure the routing table based on current UICC parameters **/ - if((status == 0x00)||(status == 0x01)) + if((status == UICC_CONFIGURED)||(status == UICC_NOT_CONFIGURED)) { mPrefsEditor.putInt(PREF_CUR_SELECTED_UICC_ID, uiccSlot); mPrefsEditor.apply(); @@ -2573,13 +1900,16 @@ public class NfcService implements DeviceHostListener { { Log.i(TAG, "Update routing table"); mAidRoutingManager.onNfccRoutingTableCleared(); - mIsRoutingTableDirty = true; + mDeviceHost.clearRoutingEntry(AID_ENTRY); + mDeviceHost.clearRoutingEntry(TECH_ENTRY); + mDeviceHost.clearRoutingEntry(PROTOCOL_ENTRY); mCardEmulationManager.onNfcEnabled(); + computeRoutingParameters(); + commitRouting(); } else { Log.i(TAG, "Update only Mifare and Desfire route"); - mIsRoutingTableDirty = true; applyRouting(false); } } @@ -2587,7 +1917,36 @@ public class NfcService implements DeviceHostListener { } } - } + @Override + public List<NfcAidServiceInfo> getServicesAidInfo(int userId, String category){ + return mCardEmulationManager.getServicesAidInfo(userId, category); + } + + @Override + public int updateServiceState(int userId , Map serviceState) { + return mCardEmulationManager.updateServiceState(userId ,serviceState); + } + + @Override + public int getMaxAidRoutingTableSize() throws RemoteException { + NfcPermissions.enforceUserPermissions(mContext); + return getAidRoutingTableSize(); + } + + @Override + public int getCommittedAidRoutingTableSize() throws RemoteException { + NfcPermissions.enforceUserPermissions(mContext); + return (getAidRoutingTableSize() - getRemainingAidTableSize()); + } + + @Override + public int getSelectedUicc() throws RemoteException { + if (!isNfcEnabled()) { + throw new RemoteException("NFC is not enabled"); + } + return mDeviceHost.doGetSelectedUicc(); + } +} final class ReaderModeDeathRecipient implements IBinder.DeathRecipient { @Override @@ -2595,7 +1954,6 @@ public class NfcService implements DeviceHostListener { synchronized (NfcService.this) { if (mReaderModeParams != null) { mReaderModeParams = null; - Log.e(TAG, "applyRouting -5"); applyRouting(false); } } @@ -2951,7 +2309,7 @@ public class NfcService implements DeviceHostListener { int rwSize,int testCaseId) throws RemoteException { NfcPermissions.enforceAdminPermissions(mContext); - if(serviceName.equals(null)) + if (serviceName.equals(null) || !mIsBeamCapable) return false; mP2pLinkManager.enableExtDtaSnepServer(serviceName, serviceSap, miu, rwSize,testCaseId); @@ -2959,6 +2317,8 @@ public class NfcService implements DeviceHostListener { } public void disableServer() throws RemoteException { + if (!mIsBeamCapable) + return; NfcPermissions.enforceAdminPermissions(mContext); mP2pLinkManager.disableExtDtaSnepServer(); } @@ -2967,7 +2327,7 @@ public class NfcService implements DeviceHostListener { int testCaseId) throws RemoteException { NfcPermissions.enforceAdminPermissions(mContext); - if(testCaseId == 0) + if (testCaseId == 0 || !mIsBeamCapable) return false; if (testCaseId>20){ @@ -2982,8 +2342,10 @@ public class NfcService implements DeviceHostListener { } public void disableClient() throws RemoteException { - NfcPermissions.enforceAdminPermissions(mContext); - mP2pLinkManager.disableDtaSnepClient(); + if (!mIsBeamCapable) + return; + NfcPermissions.enforceAdminPermissions(mContext); + mP2pLinkManager.disableDtaSnepClient(); } public boolean registerMessageService(String msgServiceName) @@ -2994,305 +2356,84 @@ public class NfcService implements DeviceHostListener { DtaServiceConnector.setMessageService(msgServiceName); return true; - } - }; - - final class NfcVzwService extends INfcVzw.Stub { - @Override - public void setScreenOffCondition(boolean enable) throws RemoteException { - - Message msg = mHandler.obtainMessage(); - msg.what=MSG_SET_SCREEN_STATE; - msg.arg1= (enable)?1:0; - mHandler.sendMessage(msg); - - } - - @Override - public boolean setVzwAidList(RouteEntry[] entries) - throws RemoteException { - Log.i(TAG, "setVzwAidList enter"); - Log.i(TAG, "setVzwAidList entries length =" + entries.length); - if (mIsHceCapable) { - mAidRoutingManager.ClearVzwCache(); - for (int i = 0; i < entries.length; i++) { - RouteEntry routeEntry = entries[i]; - mAidRoutingManager.UpdateVzwCache(routeEntry.getAid(), - routeEntry.getLocation(), routeEntry.getPowerState(), - routeEntry.isAllowed()); - - Log.i(TAG, - "AID" + routeEntry.getAid() + "Location " - + routeEntry.getLocation() + "powerstate " - + routeEntry.getPowerState()); - } - mAidRoutingManager.onNfccRoutingTableCleared(); - mCardEmulationManager.onRoutingTableChanged(); - return true; - } else { - return false; - } } }; - void _nfcEeClose(int callingPid, IBinder binder) throws IOException { - // Blocks until a pending open() or transceive() times out. - //TODO: This is incorrect behavior - the close should interrupt pending - // operations. However this is not supported by current hardware. - - synchronized (NfcService.this) { - if (!isNfcEnabledOrShuttingDown()) { - throw new IOException("NFC adapter is disabled"); - } - if (mOpenEe == null) { - throw new IOException("NFC EE closed"); - } - if (callingPid != -1 && callingPid != mOpenEe.pid) { - throw new SecurityException("Wrong PID"); - } - if (mOpenEe.binder != binder) { - throw new SecurityException("Wrong binder handle"); - } - - binder.unlinkToDeath(mOpenEe, 0); - mDeviceHost.resetTimeouts(); - doDisconnect(mOpenEe.handle); - mOpenEe = null; - } + final class NxpNfcAdapterExtrasService extends INxpNfcAdapterExtras.Stub { + private Bundle writeNoException() { + Bundle p = new Bundle(); + p.putInt("e", 0); + return p; } - boolean _nfcEeReset() throws IOException { - synchronized (NfcService.this) { - if (!isNfcEnabledOrShuttingDown()) { - throw new IOException("NFC adapter is disabled"); - } - if (mOpenEe == null) { - throw new IOException("NFC EE closed"); - } - return mSecureElement.doReset(mOpenEe.handle); - } + private Bundle writeEeException(int exceptionType, String message) { + Bundle p = new Bundle(); + p.putInt("e", exceptionType); + p.putString("m", message); + return p; + } + /* + * Enable or disable eSE COS patch dedicated mode + * @param mode 1:dedicated mode 0:normal mode + * @return 0:success 1:SWP is already in use -1:error + */ + @Override + public int accessControlForCOSU (int mode) + { + return mDeviceHost.accessControlForCOSU(mode); } - final class NfcAdapterExtrasService extends INfcAdapterExtras.Stub { - ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); - private Bundle writeNoException() { - Bundle p = new Bundle(); - p.putInt("e", 0); - return p; - } - - private Bundle writeEeException(int exceptionType, String message) { - Bundle p = new Bundle(); - p.putInt("e", exceptionType); - p.putString("m", message); - return p; - } - - @Override - public Bundle open(String pkg, IBinder b) throws RemoteException { - NfcService.this.enforceNfceeAdminPerm(pkg); - - Bundle result; - if (activityManager.isLowRamDevice()) { - result = writeEeException(SE_ACCESS_DENIED, "SE open access denied."); - } else { - int handle = _open(b); - if (handle < 0) { - result = writeEeException(handle, "NFCEE open exception."); - } else { - result = writeNoException(); - } - } - return result; - } - - /** - * Opens a connection to the secure element. - * - * @return A handle with a value >= 0 in case of success, or a - * negative value in case of failure. - */ - private int _open(IBinder b) { - synchronized(NfcService.this) { - if (!isNfcEnabled()) { - return EE_ERROR_NFC_DISABLED; - } - if (mInProvisionMode) { - // Deny access to the NFCEE as long as the device is being setup - return EE_ERROR_IO; - } - /*Concurrent access for DWP transactions to be allowed even when P2P is already ongoing */ - /* - if (mP2pLinkManager.isLlcpActive()) { - // Don't allow PN544-based devices to open the SE while the LLCP - // link is still up or in a debounce state. This avoids race - // conditions in the NXP stack around P2P/SMX switching. - return EE_ERROR_EXT_FIELD; - }*/ - if (mOpenEe != null) { - Log.i(TAG, "SE is Busy. returning.."); - return EE_ERROR_ALREADY_OPEN; - } - boolean restorePolling = false; - if (mNfcPollingEnabled) { - // Disable polling for tags/P2P when connecting to the SMX - // on PN544-based devices. Whenever nfceeClose is called, - // the polling configuration will be restored. - mDeviceHost.disableDiscovery(); - mNfcPollingEnabled = false; - restorePolling = true; - } - - int handle = doOpenSecureElementConnection(0xF3); - if (handle < 0) { - - if (restorePolling) { - mDeviceHost.enableDiscovery(mCurrentDiscoveryParameters, true); - mNfcPollingEnabled = true; - } - return handle; - } - mOpenEe = new OpenSecureElement(getCallingPid(), handle, b); - try { - b.linkToDeath(mOpenEe, 0); - } catch (RemoteException e) { - mOpenEe.binderDied(); - } - - // Add the calling package to the list of packages that have accessed - // the secure element. - for (String packageName : mContext.getPackageManager().getPackagesForUid(getCallingUid())) { - mSePackages.add(packageName); - } - - return handle; - } - } - - @Override - public Bundle close(String pkg, IBinder binder) throws RemoteException { - NfcService.this.enforceNfceeAdminPerm(pkg); - - Bundle result; - - if (activityManager.isLowRamDevice()) { - result = writeEeException(SE_ACCESS_DENIED, "SE close access denied."); - } else { - try { - _nfcEeClose(getCallingPid(), binder); - result = writeNoException(); - } catch (IOException e) { - result = writeEeException(EE_ERROR_IO, e.getMessage()); - } - } - return result; - } - - @Override - public Bundle transceive(String pkg, byte[] in) throws RemoteException { - NfcService.this.enforceNfceeAdminPerm(pkg); - - Bundle result; - - if (activityManager.isLowRamDevice()) { - result = writeEeException(SE_ACCESS_DENIED, "SE transceive access denied."); - } else { - byte[] out; - try { - out = _transceive(in); - result = writeNoException(); - result.putByteArray("out", out); - } catch (IOException e) { - result = writeEeException(EE_ERROR_IO, e.getMessage()); - } - } - return result; - } - - private byte[] _transceive(byte[] data) throws IOException { - synchronized(NfcService.this) { - if (!isNfcEnabled()) { - throw new IOException("NFC is not enabled"); - } - if (mOpenEe == null) { - throw new IOException("NFC EE is not open"); - } - if (getCallingPid() != mOpenEe.pid) { - throw new SecurityException("Wrong PID"); - } - } - - return doTransceive(mOpenEe.handle, data); - } - - @Override - public int getCardEmulationRoute(String pkg) throws RemoteException { - NfcService.this.enforceNfceeAdminPerm(pkg); - return mEeRoutingState; + @Override + public boolean reset(String pkg) throws RemoteException { + Bundle result; + boolean stat = false; + try { + stat = _nfcEeReset(); + result = writeNoException(); + } catch (IOException e) { + result = writeEeException(EE_ERROR_IO, e.getMessage()); } + Log.d(TAG,"reset" + stat); + return stat; + } - @Override - public void setCardEmulationRoute(String pkg, int route) throws RemoteException { - NfcService.this.enforceNfceeAdminPerm(pkg); - mEeRoutingState = route; - ApplyRoutingTask applyRoutingTask = new ApplyRoutingTask(); - applyRoutingTask.execute(); - try { - // Block until route is set - applyRoutingTask.get(); - } catch (ExecutionException e) { - Log.e(TAG, "failed to set card emulation mode"); - } catch (InterruptedException e) { - Log.e(TAG, "failed to set card emulation mode"); + boolean _nfcEeReset() throws IOException { + synchronized (NfcService.this) { + if (!isNfcEnabledOrShuttingDown()) { + throw new IOException("NFC adapter is disabled"); } + return mSecureElement.doReset(EE_HANDLE_0xF3); } + } - @Override - public void authenticate(String pkg, byte[] token) throws RemoteException { - NfcService.this.enforceNfceeAdminPerm(pkg); - } + @Override + public Bundle getAtr(String pkg) throws RemoteException { - @Override - public String getDriverName(String pkg) throws RemoteException { - NfcService.this.enforceNfceeAdminPerm(pkg); - return mDeviceHost.getName(); + Bundle result; + byte[] out; + try { + out = _getAtr(); + result = writeNoException(); + result.putByteArray("out", out); + } catch (IOException e) { + result = writeEeException(EE_ERROR_IO, e.getMessage()); } - + Log.d(TAG,"getAtr result " + result); + return result; } - /** resources kept while secure element is open */ - private class OpenSecureElement implements IBinder.DeathRecipient { - public int pid; // pid that opened SE - // binder handle used for DeathReceipient. Must keep - // a reference to this, otherwise it can get GC'd and - // the binder stub code might create a different BinderProxy - // for the same remote IBinder, causing mismatched - // link()/unlink() - public IBinder binder; - public int handle; // low-level handle - public OpenSecureElement(int pid, int handle, IBinder binder) { - this.pid = pid; - this.handle = handle; - this.binder = binder; - } - @Override - public void binderDied() { - synchronized (NfcService.this) { - Log.i(TAG, "Tracked app " + pid + " died"); - pid = -1; - try { - _nfcEeClose(-1, binder); - } catch (IOException e) { /* already closed */ } + private byte[] _getAtr() throws IOException { + synchronized(NfcService.this) { + if (!isNfcEnabled()) { + throw new IOException("NFC is not enabled"); } } - @Override - public String toString() { - return new StringBuilder('@').append(Integer.toHexString(hashCode())).append("[pid=") - .append(pid).append(" handle=").append(handle).append("]").toString(); - } + return mSecureElement.doGetAtr(EE_HANDLE_0xF3); } +} + boolean isNfcEnabledOrShuttingDown() { synchronized (this) { return (mState == NfcAdapter.STATE_ON || mState == NfcAdapter.STATE_TURNING_OFF); @@ -3341,56 +2482,6 @@ public class NfcService implements DeviceHostListener { } } - /* For Toast from background process*/ - - public class ToastHandler - { - // General attributes - private Context mContext; - private Handler mHandler; - - public ToastHandler(Context _context) - { - this.mContext = _context; - this.mHandler = new Handler(); - } - - /** - * Runs the <code>Runnable</code> in a separate <code>Thread</code>. - * - * @param _runnable - * The <code>Runnable</code> containing the <code>Toast</code> - */ - private void runRunnable(final Runnable _runnable) - { - Thread thread = new Thread() - { - public void run() - { - mHandler.post(_runnable); - } - }; - - thread.start(); - thread.interrupt(); - thread = null; - } - - public void showToast(final CharSequence _text, final int _duration) - { - final Runnable runnable = new Runnable() - { - @Override - public void run() - { - Toast.makeText(mContext, _text, _duration).show(); - } - }; - - runRunnable(runnable); - } - } - static byte[] hexStringToBytes(String s) { if (s == null || s.length() == 0) return null; int len = s.length(); @@ -3406,29 +2497,15 @@ public class NfcService implements DeviceHostListener { return data; } - static String toHexString(byte[] buffer, int offset, int length) { - final char[] hexChars = "0123456789abcdef".toCharArray(); - char[] chars = new char[2 * length]; - for (int j = offset; j < offset + length; ++j) { - chars[2 * (j-offset)] = hexChars[(buffer[j] & 0xF0) >>> 4]; - chars[2 * (j-offset) + 1] = hexChars[buffer[j] & 0x0F]; - } - return new String(chars); - } - /** * Read mScreenState and apply NFC-C polling and NFC-EE routing */ void applyRouting(boolean force) { - Log.d(TAG, "applyRouting - enter force = " + force + " mScreenState = " + mScreenState); - + Log.d(TAG, "applyRouting enter"); + if (!isNfcEnabledOrShuttingDown()) { + return; + } synchronized (this) { - //Since Reader mode during wired mode is supported - //enableDiscovery or disableDiscovery is allowed - if (!isNfcEnabledOrShuttingDown()) { - // PN544 cannot be reconfigured while EE is open - return; - } WatchDogThread watchDog = new WatchDogThread("applyRouting", ROUTING_WATCHDOG_MS); if (mInProvisionMode) { mInProvisionMode = Settings.Secure.getInt(mContentResolver, @@ -3437,8 +2514,6 @@ public class NfcService implements DeviceHostListener { // Notify dispatcher it's fine to dispatch to any package now // and allow handover transfers. mNfcDispatcher.disableProvisioningMode(); - /* if provision mode is disabled, then send this info to lower layers as well */ - mDeviceHost.doSetProvisionMode(mInProvisionMode); } } // Special case: if we're transitioning to unlocked state while @@ -3474,9 +2549,8 @@ public class NfcService implements DeviceHostListener { private NfcDiscoveryParameters computeDiscoveryParameters(int screenState) { // Recompute discovery parameters based on screen state NfcDiscoveryParameters.Builder paramsBuilder = NfcDiscoveryParameters.newBuilder(); - // Polling - if ((screenState >= NFC_POLLING_MODE)||mIsTaskBoot) { + if (screenState >= NFC_POLLING_MODE) { // Check if reader-mode is enabled if (mReaderModeParams != null) { int techMask = 0; @@ -3495,48 +2569,64 @@ public class NfcService implements DeviceHostListener { paramsBuilder.setEnableReaderMode(true); } else { paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT); - paramsBuilder.setEnableP2p(true); + paramsBuilder.setEnableP2p(mIsBeamCapable); } - } - if ((screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mInProvisionMode) && - !mNfcUnlockManager.isLockscreenPollingEnabled()) { - if (mReaderModeParams != null) + } else if (screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mInProvisionMode) { paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT); // enable P2P for MFM/EDU/Corp provisioning - paramsBuilder.setEnableP2p(true); - } else if ((screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED) && - (mIsLiveCaseEnabled || mNfcUnlockManager.isLockscreenPollingEnabled())) { + paramsBuilder.setEnableP2p(mIsBeamCapable); + } else if (screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && + mNfcUnlockManager.isLockscreenPollingEnabled()) { int techMask = 0; - // enable polling for Live Case technologies - if (mIsLiveCaseEnabled) - techMask |= mLiveCaseTechnology; if (mNfcUnlockManager.isLockscreenPollingEnabled()) - { techMask |= mNfcUnlockManager.getLockscreenPollMask(); - } paramsBuilder.setTechMask(techMask); paramsBuilder.setEnableLowPowerDiscovery(false); paramsBuilder.setEnableP2p(false); } - if (mIsHceCapable && mReaderModeParams == null) { + if (mIsHceCapable && mScreenState >= ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mReaderModeParams == null) { // Host routing is always enabled at lock screen or later, provided we aren't in reader mode - paramsBuilder.setEnableHostRouting(true); - } - - //To make routing table update. - if(mIsRoutingTableDirty) { - mIsRoutingTableDirty = false; - int protoRoute = mNxpPrefs.getInt("PREF_MIFARE_DESFIRE_PROTO_ROUTE_ID", GetDefaultMifareDesfireRouteEntry()); - int defaultRoute=mNxpPrefs.getInt("PREF_SET_DEFAULT_ROUTE_ID", GetDefaultRouteEntry()); - int techRoute=mNxpPrefs.getInt("PREF_MIFARE_CLT_ROUTE_ID", GetDefaultMifateCLTRouteEntry()); - if (DBG) Log.d(TAG, "Set default Route Entry"); - setDefaultRoute(defaultRoute, protoRoute, techRoute); + paramsBuilder.setEnableHostRouting(true); } return paramsBuilder.build(); } + private void computeAndSetRoutingParameters() + { + int protoRoute = mNxpPrefs.getInt("PREF_MIFARE_DESFIRE_PROTO_ROUTE_ID", GetDefaultMifareDesfireRouteEntry()); + int defaultRoute=mNxpPrefs.getInt("PREF_SET_DEFAULT_ROUTE_ID", GetDefaultRouteEntry()); + int techRoute=mNxpPrefs.getInt("PREF_MIFARE_CLT_ROUTE_ID", GetDefaultMifateCLTRouteEntry()); + int techfRoute=mNxpPrefs.getInt("PREF_FELICA_CLT_ROUTE_ID", GetDefaultFelicaCLTRouteEntry()); + int TechSeId,TechFSeId; + int TechRoute = 0x00; + if (DBG) Log.d(TAG, "Set Routing Entry"); + /* Routing for Protocol */ + mDeviceHost.setRoutingEntry(PROTOCOL_ENTRY, NFC_LISTEN_PROTO_ISO_DEP, ((protoRoute >> ROUTE_LOC_MASK) & 0x07), protoRoute & 0x3F); + mDeviceHost.setRoutingEntry(PROTOCOL_ENTRY, NFC_LISTEN_PROTO_NFC_DEP, 0x00, 0x01); + + /* Routing for Technology */ + TechSeId = (techRoute >> ROUTE_LOC_MASK); + TechFSeId = (techfRoute >> ROUTE_LOC_MASK); + /* Technology types are masked internally depending on the capability of SE */ + if(TechSeId == TechFSeId) + { + TechRoute = 0x07; + mDeviceHost.setRoutingEntry(TECH_ENTRY,TechRoute, TechSeId, techRoute & 0x3F); + } + else { + TechRoute = 0x03; + mDeviceHost.setRoutingEntry(TECH_ENTRY,TechRoute, TechSeId, techRoute & 0x3F); + TechRoute = 0x04; + Log.d(TAG, "Set Routing Entry" + TechRoute + "" + TechFSeId + "" + techfRoute); + mDeviceHost.setRoutingEntry(TECH_ENTRY,TechRoute, TechFSeId, techfRoute & 0x3F); + } + } + public void computeRoutingParameters() { + Log.d(TAG, "computeRoutingParameters >>>"); + mHandler.sendEmptyMessage(MSG_COMPUTE_ROUTING_PARAMS); + } private boolean isTagPresent() { for (Object object : mObjectMap.values()) { if (object instanceof TagEndpoint) { @@ -3656,26 +2746,41 @@ public class NfcService implements DeviceHostListener { public void notifyRoutingTableFull() { mToastHandler.showToast("Last installed NFC Service is not enabled due to limited resources. To enable this service, " + - "please disable other servives in Settings Menu", 20); - - if(!mNxpNfcController.isGsmaCommitOffhostService()) { - ComponentName prevPaymentComponent = mAidCache.getPreviousPreferredPaymentService(); - - mNxpPrefsEditor = mNxpPrefs.edit(); - mNxpPrefsEditor.putInt("PREF_SET_AID_ROUTING_TABLE_FULL",0x01); - mNxpPrefsEditor.commit(); - //broadcast Aid Routing Table Full intent to the user - Intent aidTableFull = new Intent(); - aidTableFull.putExtra(NxpConstants.EXTRA_GSMA_PREV_PAYMENT_COMPONENT,prevPaymentComponent); - aidTableFull.setAction(NxpConstants.ACTION_ROUTING_TABLE_FULL); - if (DBG) { - Log.d(TAG, "notify aid routing table full to the user"); - } - mContext.sendBroadcastAsUser(aidTableFull, UserHandle.CURRENT); - mAidCache.setPreviousPreferredPaymentService(null); + "please disable other servives in Settings Menu", 20); + Log.d(TAG, "notify aid routing table full to the user here"); + + ComponentName prevPaymentComponent = mAidCache.getPreviousPreferredPaymentService(); + mNxpPrefsEditor = mNxpPrefs.edit(); + mNxpPrefsEditor.putInt("PREF_SET_AID_ROUTING_TABLE_FULL",0x01); + mNxpPrefsEditor.commit(); + //broadcast Aid Routing Table Full intent to the user + Intent aidTableFull = new Intent(); + aidTableFull.setAction(NfcConstants.ACTION_ROUTING_TABLE_FULL); + if (DBG) { + Log.d(TAG, "notify aid routing table full to the user"); } + mContext.sendBroadcastAsUser(aidTableFull, UserHandle.CURRENT); + mAidCache.setPreviousPreferredPaymentService(null); + } + + public void routeAids(String aid, int route, int aidInfo, int power) { + Message msg = mHandler.obtainMessage(); + msg.what = MSG_ROUTE_AID; + msg.arg1 = route; + msg.obj = aid; + msg.arg2 = aidInfo; + Bundle aidbundle = new Bundle(); + aidbundle.putInt("power",power); + msg.setData(aidbundle); + mHandler.sendMessage(msg); + } + public int getAidRoutingTableSize () + { + //return 18; + return mDeviceHost.getAidTableSize(); } + /** * set default Aid route entry in case application does not configure this route entry */ @@ -3685,17 +2790,6 @@ public class NfcService implements DeviceHostListener { Log.d(TAG, "writing to preferences setDefaultAidRouteLoc :" + routeLoc); int defaultAidRoute = ((mDeviceHost.getDefaultAidPowerState() & 0x3F) | (routeLoc << ROUTE_LOC_MASK)); - if(routeLoc == 0x00) - { - /* - bit pos 1 = Power Off - bit pos 2 = Battery Off - bit pos 3 = Screen Off and Unlocked - bit pos 5 = Screen Off and locked - Set these bits to 0 because in case routeLoc = HOST it can not work on POWER_OFF, BATTERY_OFF and SCREEN_OFF*/ - - defaultAidRoute &= (getNciVersion() == NCI_VERSION_2_0) ? 0x11 : 0xE9; - } mNxpPrefsEditor.putInt("PREF_SET_DEFAULT_ROUTE_ID", defaultAidRoute); mNxpPrefsEditor.commit(); @@ -3703,25 +2797,6 @@ public class NfcService implements DeviceHostListener { Log.d(TAG, "reading preferences from user :" + defaultRoute); } - public int getAidRoutingTableSize () - { - int aidTableSize = 0x00; - aidTableSize = mDeviceHost.getAidTableSize(); - return aidTableSize; - } - - public void routeAids(String aid, int route, int powerState, int aidInfo) { - Message msg = mHandler.obtainMessage(); - msg.what = MSG_ROUTE_AID; - msg.arg1 = route; - msg.arg2 = powerState; - Bundle aidbundle = new Bundle(); - aidbundle.putInt("aidinfo",aidInfo); - msg.setData(aidbundle); - msg.obj = aid; - mHandler.sendMessage(msg); - } - public void unrouteAids(String aid) { sendMessage(MSG_UNROUTE_AID, aid); } @@ -3739,15 +2814,18 @@ public class NfcService implements DeviceHostListener { } public void unrouteApduPattern(String apdu) { - //sendMessage(MSG_UNROUTE_APDU, apdu); - mDeviceHost.unrouteApduPattern(hexStringToBytes(apdu)); + Message msg = mHandler.obtainMessage(); + msg.what = MSG_UNROUTE_APDU; + msg.obj = apdu; + mHandler.sendMessage(msg); } public int getNciVersion() { return mDeviceHost.getNciVersion(); } + private byte[] getT3tIdentifierBytes(String systemCode, String nfcId2, String t3tPmm) { - ByteBuffer buffer = ByteBuffer.allocate(2 + 8 + 8); + ByteBuffer buffer = ByteBuffer.allocate(2 + 8 + 8); /* systemcode + nfcid2 + t3tpmm */ buffer.put(hexStringToBytes(systemCode)); buffer.put(hexStringToBytes(nfcId2)); buffer.put(hexStringToBytes(t3tPmm)); @@ -3782,11 +2860,12 @@ public class NfcService implements DeviceHostListener { } public void commitRouting() { - if (mNxpNfcState != NXP_NFC_STATE_ON) { - Log.d(TAG, "Nfc is not completely initialized. Returning.."); - return; - } - mHandler.sendEmptyMessage(MSG_COMMIT_ROUTING); + Log.d(TAG, "commitRouting >>>"); + mHandler.sendEmptyMessage(MSG_COMMIT_ROUTING); + } + public void initWiredSe() { + Log.d(TAG, "Init wired Se"); + mHandler.sendEmptyMessage(MSG_INIT_WIREDSE); } /** * get default Aid route entry in case application does not configure this route entry @@ -3797,7 +2876,6 @@ public class NfcService implements DeviceHostListener { Log.d(TAG, "GetDefaultRouteLoc :" + defaultRouteLoc); return defaultRouteLoc ; } - /** * get default MifareDesfireRoute route entry in case application does not configure this route entry */ @@ -3810,10 +2888,9 @@ public class NfcService implements DeviceHostListener { /* bit pos 1 = Power Off bit pos 2 = Battery Off - bit pos 3 = Screen Off and Unlocked - bit pos 5 = Screen Off and locked + bit pos 4 = Screen Off Set these bits to 0 because in case routeLoc = HOST it can not work on POWER_OFF, BATTERY_OFF and SCREEN_OFF*/ - defaultMifareDesfireRoute &= (getNciVersion() == NCI_VERSION_2_0) ? 0x11 : 0xE9; + defaultMifareDesfireRoute &= 0xF9; } if (DBG) Log.d(TAG, "defaultMifareDesfireRoute : " + defaultMifareDesfireRoute); return defaultMifareDesfireRoute; @@ -3831,10 +2908,9 @@ public class NfcService implements DeviceHostListener { /* bit pos 1 = Power Off bit pos 2 = Battery Off - bit pos 3 = Screen Off and Unlocked - bit pos 5 = Screen Off and locked + bit pos 4 = Screen Off Set these bits to 0 because in case routeLoc = HOST it can not work on POWER_OFF, BATTERY_OFF and SCREEN_OFF*/ - defaultAidRoute &= (getNciVersion() == NCI_VERSION_2_0) ? 0x11 : 0xE9; + defaultAidRoute &= 0xF9; } if (DBG) Log.d(TAG, "defaultAidRoute : " + defaultAidRoute); return defaultAidRoute; @@ -3846,28 +2922,24 @@ public class NfcService implements DeviceHostListener { public int GetDefaultMifateCLTRouteEntry() { int routeLoc = mDeviceHost.getDefaultMifareCLTRoute(); - int defaultMifateCLTRoute = ((mDeviceHost.getDefaultMifareCLTPowerState() & 0x3F) | (routeLoc << ROUTE_LOC_MASK) | (TECH_TYPE_A << TECH_TYPE_MASK)); - + int defaultMifateCLTRoute = ((mDeviceHost.getDefaultMifareCLTPowerState() & 0x3F) | (mDeviceHost.getDefaultMifareCLTRoute() << ROUTE_LOC_MASK)) ; if (DBG) Log.d(TAG, "defaultMifateCLTRoute : " + defaultMifateCLTRoute); return defaultMifateCLTRoute; } - - public boolean setDefaultRoute(int defaultRouteEntry, int defaultProtoRouteEntry, int defaultTechRouteEntry) { - boolean ret = mDeviceHost.setDefaultRoute(defaultRouteEntry, defaultProtoRouteEntry, defaultTechRouteEntry); - return ret; - } - - public int getDefaultRoute() { - return mNxpPrefs.getInt(PREF_DEFAULT_ROUTE_ID, DEFAULT_ROUTE_ID_DEFAULT); - } - - - public void commitingFelicaRouting() { - mHandler.sendEmptyMessage(MSG_COMMITINF_FELICA_ROUTING); + /** + * get default FelicaCLT route entry in case application does not configure this route entry + */ + public int GetDefaultFelicaCLTRouteEntry() + { + int routeLoc = mDeviceHost.getDefaultFelicaCLTRoute(); + int defaultFelicaCLTRoute = ((mDeviceHost.getDefaultFelicaCLTPowerState() & 0x3F) | (mDeviceHost.getDefaultFelicaCLTRoute() << ROUTE_LOC_MASK)) ; + if (DBG) Log.d(TAG, "defaultFelicaCLTRoute : " + defaultFelicaCLTRoute); + return defaultFelicaCLTRoute; } - public void commitedFelicaRouting() { - mHandler.sendEmptyMessage(MSG_COMMITED_FELICA_ROUTING); + public int getGsmaPwrState() + { + return mDeviceHost.getGsmaPwrState(); } public int getAidRoutingTableStatus() { @@ -3875,27 +2947,15 @@ public class NfcService implements DeviceHostListener { aidTableStatus = mNxpPrefs.getInt("PREF_SET_AID_ROUTING_TABLE_FULL",0x00); return aidTableStatus; } - - public void clearRouting() { - mHandler.sendEmptyMessage(MSG_CLEAR_ROUTING); - } - - public boolean isVzwFeatureEnabled(){ - return mDeviceHost.isVzwFeatureEnabled(); - } - public boolean sendData(byte[] data) { return mDeviceHost.sendRawFrame(data); } - public int getDefaultSecureElement() { - int[] seList = mDeviceHost.doGetSecureElementList(); - if ( seList == null || seList.length != 1) { - //use default value - return -1; - } else { - return seList[0]; - } + void sendMessage(int what, Object obj) { + Message msg = mHandler.obtainMessage(); + msg.what = what; + msg.obj = obj; + mHandler.sendMessage(msg); } public void updateLastScreenState() @@ -3903,7 +2963,7 @@ public class NfcService implements DeviceHostListener { Log.d(TAG, "updateLastScreenState"); int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ? (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState; - mDeviceHost.doSetScreenOrPowerState(screen_state_mask); + mDeviceHost.doSetScreenState(screen_state_mask); } public void etsiStartConfig(int eeHandle) { @@ -3925,7 +2985,7 @@ public class NfcService implements DeviceHostListener { mDeviceHost.setEtsiReaederState(STATE_SE_RDR_MODE_STARTED); //broadcast SWP_READER_ACTIVATED evt Intent swpReaderRequestedIntent = new Intent(); - swpReaderRequestedIntent.setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_START_SUCCESS); + swpReaderRequestedIntent.setAction(NfcConstants.ACTION_NFC_MPOS_READER_MODE_START_SUCCESS); if (DBG) { Log.d(TAG, "SWP READER - Requested"); } @@ -3953,7 +3013,7 @@ public class NfcService implements DeviceHostListener { mTimer.schedule(tagRemoveTask, ETSI_PRESENCE_CHECK_DELAY, ETSI_PRESENCE_CHECK_DELAY); Log.d(TAG, "etsiStopConfig : disableDiscovery"); - mDeviceHost.stopPoll(NxpConstants.ULTRA_LOW_POWER); + mDeviceHost.stopPoll(NfcConstants.ULTRA_LOW_POWER); mTimer.cancel(); if(mDeviceHost.getEtsiReaederState() == STATE_SE_RDR_MODE_STOPPED) @@ -3968,16 +3028,11 @@ public class NfcService implements DeviceHostListener { Log.d(TAG, "etsiStopConfig : notifyEEReaderEvent"); mDeviceHost.notifyEEReaderEvent(ETSI_READER_STOP); - Log.d(TAG, "etsiStopConfig : enable discovery"); - NfcDiscoveryParameters params = computeDiscoveryParameters(mScreenState); - boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery(); - mDeviceHost.enableDiscovery(params, shouldRestart); - Intent swpReaderDeActivatedIntent = new Intent(); //broadcast SWP_READER_DEACTIVATED evt swpReaderDeActivatedIntent - .setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_STOP_SUCCESS); + .setAction(NfcConstants.ACTION_NFC_MPOS_READER_MODE_STOP_SUCCESS); if (DBG) { Log.d(TAG, "SWP READER - DeActivated"); } @@ -3991,34 +3046,27 @@ public class NfcService implements DeviceHostListener { Log.d(TAG, "etsiStopConfig Exit"); } - - void sendMessage(int what, Object obj) { - Message msg = mHandler.obtainMessage(); - msg.what = what; - msg.obj = obj; - mHandler.sendMessage(msg); - } - final class NfcServiceHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_ROUTE_AID: { - int route = msg.arg1; - int power = msg.arg2; - int aidInfo = 0x00; + int route = msg.arg1; + int aidInfo = msg.arg2; + int power = 0x00; Bundle dataBundle = msg.getData(); if (dataBundle != null) - aidInfo = dataBundle.getInt("aidinfo"); - String aid = (String) msg.obj; - String cuttedAid = aid; - if(aid.endsWith("*")||aid.endsWith("#")) { - cuttedAid = aid.substring(0, aid.length() - 1); - } - mDeviceHost.routeAid(hexStringToBytes(cuttedAid), route, power, aidInfo); + power = dataBundle.getInt("power"); + String aid = (String) msg.obj; + mDeviceHost.routeAid(hexStringToBytes(aid), route, aidInfo,power); // Restart polling config break; } + case MSG_UNROUTE_AID: { + String aid = (String) msg.obj; + mDeviceHost.unrouteAid(hexStringToBytes(aid)); + break; + } case MSG_REGISTER_T3T_IDENTIFIER: { Log.d(TAG, "message to register LF_T3T_IDENTIFIER"); mDeviceHost.disableDiscovery(); @@ -4047,62 +3095,28 @@ public class NfcService implements DeviceHostListener { mP2pLinkManager.onManualBeamInvoke((BeamShareData)msg.obj); break; } - - case MSG_UNROUTE_AID: { - String aid = (String) msg.obj; - mDeviceHost.unrouteAid(hexStringToBytes(aid)); - break; - } - - case MSG_COMMITINF_FELICA_ROUTING: { - Log.e(TAG, "applyRouting -10"); - mIsFelicaOnHostConfiguring = true; - applyRouting(true); - break; - } - - case MSG_COMMITED_FELICA_ROUTING: { - Log.e(TAG, "applyRouting -11"); - mIsFelicaOnHostConfigured = true; - applyRouting(true); - break; - } - case MSG_COMMIT_ROUTING: { - Log.e(TAG, "applyRouting -9"); - boolean commit = false; - boolean enForced = false; + boolean commit = false; + Log.d(TAG, "commitRouting >>>"); synchronized (NfcService.this) { + int defaultRoute=mNxpPrefs.getInt("PREF_SET_DEFAULT_ROUTE_ID", GetDefaultRouteEntry()); + mDeviceHost.setEmptyAidRoute(defaultRoute >> ROUTE_LOC_MASK); if (mCurrentDiscoveryParameters.shouldEnableDiscovery()) { commit = true; - }else if(mAidRoutingManager.isRoutingTableUpdated()){ - commit = true; - enForced = true; - Log.d(TAG, "Routing table is updated thus needs to be committed."); - } - else { + } else { Log.d(TAG, "Not committing routing because discovery is disabled."); } } if (commit) { - mIsRoutingTableDirty = true; - applyRouting(enForced); + mDeviceHost.commitRouting(); } - - - break; - } - case MSG_CLEAR_ROUTING: { - mDeviceHost.clearAidTable(); break; } - case MSG_CHANGE_DEFAULT_ROUTE: - Log.d(TAG, "Handler: Change default route"); - try{ - mNxpNfcAdapter.DefaultRouteSet(ROUTE_ID_HOST, true, false, false); - } catch(RemoteException re) { - Log.d(TAG, "NxpNci: onAidRoutingTableFull: Exception to change default route to host!"); + case MSG_COMPUTE_ROUTING_PARAMS: + Log.d(TAG, "computeRoutingParameters >>>"); + synchronized (NfcService.this) { + computeAndSetRoutingParameters(); } break; @@ -4127,62 +3141,6 @@ public class NfcService implements DeviceHostListener { break; } - case MSG_SE_DELIVER_INTENT: { - Log.d(TAG, "SE DELIVER INTENT"); - Intent seIntent = (Intent) msg.obj; - - String action = seIntent.getAction(); - if (action.equals("com.gsma.services.nfc.action.TRANSACTION_EVENT")) { - byte[] byteAid = seIntent.getByteArrayExtra("com.android.nfc_extras.extra.AID"); - byte[] data = seIntent.getByteArrayExtra("com.android.nfc_extras.extra.DATA"); - String seName = seIntent.getStringExtra("com.android.nfc_extras.extra.SECURE_ELEMENT_NAME"); - StringBuffer strAid = new StringBuffer(); - Intent gsmaIntent = new Intent(); - gsmaIntent.setAction("com.gsma.services.nfc.action.TRANSACTION_EVENT"); - if (byteAid != null) { - for (int i = 0; i < byteAid.length; i++) { - String hex = Integer.toHexString(0xFF & byteAid[i]); - if (hex.length() == 1) - strAid.append('0'); - strAid.append(hex); - } - gsmaIntent.putExtra("com.gsma.services.nfc.extra.AID", byteAid); - } - if (data != null) - gsmaIntent.putExtra("com.gsma.services.nfc.extra.DATA", data); - - //"nfc://secure:0/<seName>/<strAid>" - String url = new String ("nfc://secure:0/" + seName + "/" + strAid); - gsmaIntent.setData(Uri.parse(url)); - gsmaIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - gsmaIntent.setPackage(seIntent.getPackage()); - - Boolean receptionMode = mNxpNfcController.mMultiReceptionMap.get(seName); - if (receptionMode == null) - receptionMode = defaultTransactionEventReceptionMode; - - if (receptionMode == multiReceptionMode) { - // if multicast reception for GSMA - mContext.sendBroadcast(gsmaIntent); - } else { - // if unicast reception for GSMA - try { - if (mIsSentUnicastReception == false) { - //start gsma - gsmaIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mContext.startActivity(gsmaIntent); - mIsSentUnicastReception = true; - } - } catch (Exception e) { - if (DBG) Log.d(TAG, "Exception: " + e.getMessage()); - } - } - } else { - mContext.sendBroadcast(seIntent); - } - break; - } - case MSG_NDEF_TAG: if (DBG) Log.d(TAG, "Tag detected, notifying applications"); mPowerManager.userActivity(SystemClock.uptimeMillis(), @@ -4197,16 +3155,13 @@ public class NfcService implements DeviceHostListener { debounceTagMs = mDebounceTagDebounceMs; debounceTagRemovedCallback = mDebounceTagRemovedCallback; } - ReaderModeParams readerParams = null; int presenceCheckDelay = DEFAULT_PRESENCE_CHECK_DELAY; DeviceHost.TagDisconnectedCallback callback = new DeviceHost.TagDisconnectedCallback() { @Override public void onTagDisconnected(long handle) { - if(nci_version != NCI_VERSION_2_0) { - applyRouting(false); - } + applyRouting(false); } }; synchronized (NfcService.this) { @@ -4272,81 +3227,6 @@ public class NfcService implements DeviceHostListener { tag.startPresenceChecking(presenceCheckDelay, callback); dispatchTagEndpoint(tag, readerParams); break; - - case MSG_CONNECTIVITY_EVENT: - if (DBG) { - Log.d(TAG, "SE EVENT CONNECTIVITY"); - } - Integer evtSrcInfo = (Integer) msg.obj; - Log.d(TAG, "Event source " + evtSrcInfo); - String evtSrc = ""; - if(evtSrcInfo == UICC_ID_TYPE) { - evtSrc = NxpConstants.UICC_ID; - } else if(evtSrcInfo == UICC2_ID_TYPE) { - evtSrc = NxpConstants.UICC2_ID; - } else if(evtSrcInfo == SMART_MX_ID_TYPE) { - evtSrc = NxpConstants.SMART_MX_ID; - } - - Intent eventConnectivityIntent = new Intent(); - eventConnectivityIntent.setAction(NxpConstants.ACTION_CONNECTIVITY_EVENT_DETECTED); - eventConnectivityIntent.putExtra(NxpConstants.EXTRA_SOURCE, evtSrc); - if (DBG) { - Log.d(TAG, "Broadcasting Intent"); - } - mContext.sendBroadcast(eventConnectivityIntent, NfcPermissions.NFC_PERMISSION); - break; - - case MSG_EMVCO_MULTI_CARD_DETECTED_EVENT: - if (DBG) { - Log.d(TAG, "EMVCO MULTI CARD DETECTED EVENT"); - } - - Intent eventEmvcoMultiCardIntent = new Intent(); - eventEmvcoMultiCardIntent.setAction(ACTION_EMVCO_MULTIPLE_CARD_DETECTED); - if (DBG) { - Log.d(TAG, "Broadcasting Intent"); - } - mContext.sendBroadcast(eventEmvcoMultiCardIntent, NFC_PERM); - break; - - case MSG_SE_EMV_CARD_REMOVAL: - if (DBG) Log.d(TAG, "Card Removal message"); - /* Send broadcast */ - Intent cardRemovalIntent = new Intent(); - cardRemovalIntent.setAction(ACTION_EMV_CARD_REMOVAL); - if (DBG) Log.d(TAG, "Broadcasting " + ACTION_EMV_CARD_REMOVAL); - sendSeBroadcast(cardRemovalIntent); - break; - - case MSG_SE_APDU_RECEIVED: - if (DBG) Log.d(TAG, "APDU Received message"); - byte[] apduBytes = (byte[]) msg.obj; - /* Send broadcast */ - Intent apduReceivedIntent = new Intent(); - apduReceivedIntent.setAction(ACTION_APDU_RECEIVED); - if (apduBytes != null && apduBytes.length > 0) { - apduReceivedIntent.putExtra(EXTRA_APDU_BYTES, apduBytes); - } - if (DBG) Log.d(TAG, "Broadcasting " + ACTION_APDU_RECEIVED); - sendSeBroadcast(apduReceivedIntent); - break; - - case MSG_SE_MIFARE_ACCESS: - if (DBG) Log.d(TAG, "MIFARE access message"); - /* Send broadcast */ - byte[] mifareCmd = (byte[]) msg.obj; - Intent mifareAccessIntent = new Intent(); - mifareAccessIntent.setAction(ACTION_MIFARE_ACCESS_DETECTED); - if (mifareCmd != null && mifareCmd.length > 1) { - int mifareBlock = mifareCmd[1] & 0xff; - if (DBG) Log.d(TAG, "Mifare Block=" + mifareBlock); - mifareAccessIntent.putExtra(EXTRA_MIFARE_BLOCK, mifareBlock); - } - if (DBG) Log.d(TAG, "Broadcasting " + ACTION_MIFARE_ACCESS_DETECTED); - sendSeBroadcast(mifareAccessIntent); - break; - case MSG_LLCP_LINK_ACTIVATION: mPowerManager.userActivity(SystemClock.uptimeMillis(), PowerManager.USER_ACTIVITY_EVENT_OTHER, 0); @@ -4387,77 +3267,72 @@ public class NfcService implements DeviceHostListener { case MSG_LLCP_LINK_FIRST_PACKET: mP2pLinkManager.onLlcpFirstPacketReceived(); break; - case MSG_TARGET_DESELECTED: - /* Broadcast Intent Target Deselected */ - if (DBG) Log.d(TAG, "Target Deselected"); - Intent intent = new Intent(); - intent.setAction(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION); - if (DBG) Log.d(TAG, "Broadcasting Intent"); - mContext.sendOrderedBroadcast(intent, NfcPermissions.NFC_PERMISSION); + case MSG_RF_FIELD_ACTIVATED: + Intent fieldOnIntent = new Intent(ACTION_RF_FIELD_ON_DETECTED); + sendNfcEeAccessProtectedBroadcast(fieldOnIntent); break; - - case MSG_SE_FIELD_ACTIVATED: { - if (DBG) Log.d(TAG, "SE FIELD ACTIVATED"); - Intent eventFieldOnIntent = new Intent(); - eventFieldOnIntent.setAction(ACTION_RF_FIELD_ON_DETECTED); - sendSeBroadcast(eventFieldOnIntent); + case MSG_RF_FIELD_DEACTIVATED: + Intent fieldOffIntent = new Intent(ACTION_RF_FIELD_OFF_DETECTED); + sendNfcEeAccessProtectedBroadcast(fieldOffIntent); break; - } case MSG_RESUME_POLLING: mNfcAdapter.resumePolling(); break; - - case MSG_SE_FIELD_DEACTIVATED: { - if (DBG) Log.d(TAG, "SE FIELD DEACTIVATED"); - Intent eventFieldOffIntent = new Intent(); - eventFieldOffIntent.setAction(ACTION_RF_FIELD_OFF_DETECTED); - sendSeBroadcast(eventFieldOffIntent); - break; - } - - case MSG_SE_LISTEN_ACTIVATED: { - if (DBG) Log.d(TAG, "SE LISTEN MODE ACTIVATED"); - Intent listenModeActivated = new Intent(); - listenModeActivated.setAction(ACTION_SE_LISTEN_ACTIVATED); - sendSeBroadcast(listenModeActivated); + case MSG_TAG_DEBOUNCE: + // Didn't see the tag again, tag is gone + ITagRemovedCallback tagRemovedCallback; + synchronized (NfcService.this) { + mDebounceTagUid = null; + tagRemovedCallback = mDebounceTagRemovedCallback; + mDebounceTagRemovedCallback = null; + mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE; + } + if (tagRemovedCallback != null) { + try { + tagRemovedCallback.onTagRemoved(); + } catch (RemoteException e) { + // Ignore + } + } break; - } - - case MSG_SE_LISTEN_DEACTIVATED: { - if (DBG) Log.d(TAG, "SE LISTEN MODE DEACTIVATED"); - Intent listenModeDeactivated = new Intent(); - listenModeDeactivated.setAction(ACTION_SE_LISTEN_DEACTIVATED); - sendSeBroadcast(listenModeDeactivated); + case MSG_UPDATE_STATS: + if (mNumTagsDetected.get() > 0) { + MetricsLogger.count(mContext, TRON_NFC_TAG, mNumTagsDetected.get()); + mNumTagsDetected.set(0); + } + if (mNumHceDetected.get() > 0) { + MetricsLogger.count(mContext, TRON_NFC_CE, mNumHceDetected.get()); + mNumHceDetected.set(0); + } + if (mNumP2pDetected.get() > 0) { + MetricsLogger.count(mContext, TRON_NFC_P2P, mNumP2pDetected.get()); + mNumP2pDetected.set(0); + } + removeMessages(MSG_UPDATE_STATS); + sendEmptyMessageDelayed(MSG_UPDATE_STATS, STATS_UPDATE_INTERVAL_MS); break; - } - case MSG_SWP_READER_REQUESTED: + case MSG_APPLY_SCREEN_STATE: + mScreenState = (Integer)msg.obj; + Log.d(TAG, "MSG_APPLY_SCREEN_STATE " + mScreenState); - /* Send broadcast ordered */ - Intent swpReaderRequestedIntent = new Intent(); - ArrayList<Integer> techList = (ArrayList<Integer>) msg.obj; - Integer[] techs = techList.toArray(new Integer[techList.size()]); - swpReaderRequestedIntent - .setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_START_SUCCESS); - if (DBG) { - Log.d(TAG, "SWP READER - Requested"); + // If NFC is turning off, we shouldn't need any changes here + synchronized (NfcService.this) { + if (mState == NfcAdapter.STATE_TURNING_OFF) + return; } - mContext.sendBroadcast(swpReaderRequestedIntent); - break; - case MSG_SWP_READER_REQUESTED_FAIL: + if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) { + applyRouting(false); + } + int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ? + (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState; - /* Send broadcast ordered */ - Intent swpReaderRequestedFailIntent = new Intent(); + if (mNfcUnlockManager.isLockscreenPollingEnabled()) + applyRouting(false); - swpReaderRequestedFailIntent - .setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_START_FAIL); - if (DBG) { - Log.d(TAG, "SWP READER - Requested Fail"); - } - mContext.sendBroadcast(swpReaderRequestedFailIntent); + mDeviceHost.doSetScreenState(screen_state_mask); break; - case MSG_ETSI_START_CONFIG: { Log.d(TAG, "NfcServiceHandler - MSG_ETSI_START_CONFIG"); @@ -4491,7 +3366,7 @@ public class NfcService implements DeviceHostListener { Intent swpReaderTimeoutIntent = new Intent(); swpReaderTimeoutIntent - .setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_TIMEOUT); + .setAction(NfcConstants.ACTION_NFC_MPOS_READER_MODE_TIMEOUT); if (DBG) { Log.d(TAG, "SWP READER - Timeout"); } @@ -4506,79 +3381,35 @@ public class NfcService implements DeviceHostListener { Intent swpReaderRestartIntent = new Intent(); swpReaderRestartIntent - .setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_RESTART); + .setAction(NfcConstants.ACTION_NFC_MPOS_READER_MODE_RESTART); if (DBG) { Log.d(TAG, "SWP READER - RESTART"); } mContext.sendBroadcast(swpReaderRestartIntent); break; + case MSG_TRANSACTION_EVENT: + if (mCardEmulationManager != null) { + mCardEmulationManager.onOffHostAidSelected(); + } + byte[][] data = (byte[][]) msg.obj; + sendOffHostTransactionEvent(data[0], data[1], data[2]); + break; + case MSG_SE_INIT: + Log.e(TAG, "msg se init"); - case MSG_APPLY_SCREEN_STATE: - - mScreenState = (int)msg.obj; - - // If NFC is turning off, we shouldn't need any changes here - synchronized (NfcService.this) { - if (mState == NfcAdapter.STATE_TURNING_OFF) - return; + try { + if (mIsHceCapable) { + // Generate the initial card emulation routing table + computeRoutingParameters(); } - int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ? - (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState; - mDeviceHost.doSetScreenOrPowerState(screen_state_mask); + /* TODO Call WiredSe HAL to notify */ - if(nci_version != NCI_VERSION_2_0) { - applyRouting(false); - } else if(mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED - || mNfcUnlockManager.isLockscreenPollingEnabled()) { - applyRouting(false); - } - break; - case MSG_TAG_DEBOUNCE: - // Didn't see the tag again, tag is gone - ITagRemovedCallback tagRemovedCallback; - synchronized (NfcService.this) { - mDebounceTagUid = null; - tagRemovedCallback = mDebounceTagRemovedCallback; - mDebounceTagRemovedCallback = null; - mDebounceTagNativeHandle = INVALID_NATIVE_HANDLE; - } - if (tagRemovedCallback != null) { - try { - tagRemovedCallback.onTagRemoved(); - } catch (RemoteException e) { - // Ignore - } - } - break; - case MSG_RESTART_WATCHDOG: - int enable = msg.arg1; - disableInternalwatchDog.cancel(); - try{ - disableInternalwatchDog.join(); - } catch (java.lang.InterruptedException e) { - } - disableInternalwatchDog = new WatchDogThread("disableInternal", ROUTING_WATCHDOG_MS); - Log.d(TAG, "New Watchdog: WatchDog Thread ID is "+ disableInternalwatchDog.getId()); - disableInternalwatchDog.start(); - break; - case MSG_UPDATE_STATS: - if (mNumTagsDetected.get() > 0) { - MetricsLogger.count(mContext, TRON_NFC_TAG, mNumTagsDetected.get()); - mNumTagsDetected.set(0); - } - if (mNumHceDetected.get() > 0) { - MetricsLogger.count(mContext, TRON_NFC_CE, mNumHceDetected.get()); - mNumHceDetected.set(0); - } - if (mNumP2pDetected.get() > 0) { - MetricsLogger.count(mContext, TRON_NFC_P2P, mNumP2pDetected.get()); - mNumP2pDetected.set(0); + } catch (Exception e) { + Log.e(TAG, "mSecureElementclientCallback.onStateChange"); } - removeMessages(MSG_UPDATE_STATS); - sendEmptyMessageDelayed(MSG_UPDATE_STATS, STATS_UPDATE_INTERVAL_MS); - break; + break; case MSG_ROUTE_APDU:{ int route = msg.arg1; int power = msg.arg2; @@ -4599,13 +3430,20 @@ public class NfcService implements DeviceHostListener { mDeviceHost.unrouteApduPattern(hexStringToBytes(apdu)); break; } - case MSG_TRANSACTION_EVENT: - if (mCardEmulationManager != null) { - mCardEmulationManager.onOffHostAidSelected(); - } - byte[][] data = (byte[][]) msg.obj; - sendOffHostTransactionEvent(data[0], data[1], data[2]); + case MSG_INIT_WIREDSE: { + try { + mWiredSeInitMethod = mWiredSeClass.getDeclaredMethod("wiredSeInitialize"); + mWiredSeInitMethod.invoke(mWiredSeObj); + } catch (NoSuchElementException | NoSuchMethodException e) { + Log.i(TAG, "No such Method WiredSeInitialize"); + } catch (RuntimeException | IllegalAccessException | InvocationTargetException e) { + Log.e(TAG, "Error in invoking wiredSeInitialize invocation"); + } catch (Exception e) { + Log.e(TAG, "caught Exception during wiredSeInitialize"); + e.printStackTrace(); + } break; + } default: Log.e(TAG, "Unknown message received"); break; @@ -4613,10 +3451,10 @@ public class NfcService implements DeviceHostListener { } private void sendOffHostTransactionEvent(byte[] aid, byte[] data, byte[] readerByteArray) { - if (!isSEServiceAvailable() || mNfcEventInstalledPackages.isEmpty()) { return; } + try { String reader = new String(readerByteArray, "UTF-8"); String[] installedPackages = new String[mNfcEventInstalledPackages.size()]; @@ -4700,17 +3538,17 @@ public class NfcService implements DeviceHostListener { return packages; } - private void sendSeBroadcast(Intent intent) { + private void sendNfcEeAccessProtectedBroadcast(Intent intent) { intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); // Resume app switches so the receivers can start activites without delay mNfcDispatcher.resumeAppSwitches(); - Log.d(TAG, "NFCINTENT sendNfcEeAccessProtectedBroadcast"); - synchronized(this) { + ArrayList<String> matchingPackages = new ArrayList<String>(); + ArrayList<String> preferredPackages = new ArrayList<String>(); + synchronized (this) { ArrayList<String> SEPackages = getSEAccessAllowedPackages(); if (SEPackages!= null && !SEPackages.isEmpty()) { for (String packageName : SEPackages) { intent.setPackage(packageName); - Log.d(TAG, "NFCINTENT SENT TO PACKAGE" + packageName); mContext.sendBroadcast(intent); } } @@ -4734,48 +3572,13 @@ public class NfcService implements DeviceHostListener { } } - private void sendMultiEvtBroadcast(Intent intent) { - - ArrayList<String> packageList = mNxpNfcController.getEnabledMultiEvtsPackageList(); - ComponentName unicastComponent = null; - if(packageList.size() == 0) { - Log.d(TAG, "No packages to send broadcast."); - unicastComponent = mNxpNfcController.getUnicastPackage(); - if(unicastComponent != null) - { - intent.setComponent(unicastComponent); - try { - //start gsma - Log.d(TAG, "Starting activity uincast Pkg"+unicastComponent.flattenToString()); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - if(mContext.getPackageManager().resolveActivity(intent, 0) != null) - { - mContext.startActivityAsUser(intent, UserHandle.CURRENT); - } else { - Log.d(TAG, "Intent not resolved"); - } - } catch (Exception e) { - if (DBG) Log.d(TAG, "Exception: " + e.getMessage()); - } - } - return; - } - for(int i=0; i<packageList.size(); i++) { - Log.d(TAG,"MultiEvt Enabled Application packageName: " + packageList.get(i)); - intent.setPackage(packageList.get(i)); - mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT, - NxpConstants.PERMISSIONS_TRANSACTION_EVENT); - } - } - private boolean llcpActivated(NfcDepEndpoint device) { Log.d(TAG, "LLCP Activation message"); if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) { if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_TARGET"); if (device.connect()) { - /* Check LLCP compliance */ + /* Check LLCP compliancy */ if (mDeviceHost.doCheckLlcp()) { /* Activate LLCP Link */ if (mDeviceHost.doActivateLlcp()) { @@ -4850,7 +3653,7 @@ public class NfcService implements DeviceHostListener { } } int dispatchResult = mNfcDispatcher.dispatchTag(tag); - if (dispatchResult == NfcDispatcher.DISPATCH_FAIL) { + if (dispatchResult == NfcDispatcher.DISPATCH_FAIL && !mInProvisionMode) { unregisterObject(tagEndpoint.getHandle()); playSound(SOUND_ERROR); } else if (dispatchResult == NfcDispatcher.DISPATCH_SUCCESS) { @@ -4860,6 +3663,56 @@ public class NfcService implements DeviceHostListener { } } + /* For Toast from background process*/ + + public class ToastHandler + { + // General attributes + private Context mContext; + private Handler mHandler; + + public ToastHandler(Context _context) + { + this.mContext = _context; + this.mHandler = new Handler(); + } + + /** + * Runs the <code>Runnable</code> in a separate <code>Thread</code>. + * + * @param _runnable + * The <code>Runnable</code> containing the <code>Toast</code> + */ + private void runRunnable(final Runnable _runnable) + { + Thread thread = new Thread() + { + public void run() + { + mHandler.post(_runnable); + } + }; + + thread.start(); + thread.interrupt(); + thread = null; + } + + public void showToast(final CharSequence _text, final int _duration) + { + final Runnable runnable = new Runnable() + { + @Override + public void run() + { + Toast.makeText(mContext, _text, _duration).show(); + } + }; + + runRunnable(runnable); + } + } + private NfcServiceHandler mHandler = new NfcServiceHandler(); class ApplyRoutingTask extends AsyncTask<Integer, Void, Void> { @@ -4868,14 +3721,13 @@ public class NfcService implements DeviceHostListener { synchronized (NfcService.this) { if (params == null || params.length != 1) { // force apply current routing - Log.e(TAG, "applyRouting -1"); applyRouting(true); return null; } mScreenState = params[0].intValue(); + mRoutingWakeLock.acquire(); try { - Log.e(TAG, "applyRouting -2"); applyRouting(false); } finally { mRoutingWakeLock.release(); @@ -4885,166 +3737,88 @@ public class NfcService implements DeviceHostListener { } } - class EtsiStopConfigTask extends AsyncTask<Integer, Void, Void> { - @Override - protected Void doInBackground(Integer... params) { - synchronized (NfcService.this) { - etsiStopConfig(params[0].intValue()); - return null; - } - } - } - class TagRemoveTaskTimer extends TimerTask { public void run() { Intent swpReaderTagRemoveIntent = new Intent(); - swpReaderTagRemoveIntent.setAction(NxpConstants.ACTION_NFC_MPOS_READER_MODE_REMOVE_CARD); + swpReaderTagRemoveIntent.setAction(NfcConstants.ACTION_NFC_MPOS_READER_MODE_REMOVE_CARD); if (DBG) { Log.d(TAG, "SWP READER - Tag Remove"); } mContext.sendBroadcast(swpReaderTagRemoveIntent); } } - - - private final BroadcastReceiver x509CertificateReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - boolean result = intent.getBooleanExtra(NxpConstants.EXTRA_RESULT, false); - mNxpNfcController.setResultForCertificates(result); - } - }; - - private final BroadcastReceiver mEnableNfc = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - Intent nfcDialogIntent = new Intent(mContext, EnableNfcDialogActivity.class); - nfcDialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - mContext.startActivityAsUser(nfcDialogIntent, UserHandle.CURRENT); - } - }; - - private final BroadcastReceiver mActivateSwpInterface = new BroadcastReceiver() { + class EtsiStopConfigTask extends AsyncTask<Integer, Void, Void> { @Override - public void onReceive(Context context, Intent intent) { - - String action = intent.getAction(); - - if(NxpConstants.CAT_ACTIVATE_NOTIFY_ACTION.equals(action)){ - - Log.i(TAG, "Received ACTIVATE intent:" + action); - - if(mSelectedSeId != ALL_SE_ID_TYPE){ - mDeviceHost.doSelectSecureElement(mSelectedSeId); - Log.i(TAG, "Activated:" + mSelectedSeId); - } - else{ - int[] seList = mDeviceHost.doGetSecureElementList(); - Log.i(TAG, "Activating all SE:"); - - for(int i = 0; i < seList.length; i++){ - mDeviceHost.doActivateSecureElement(seList[i]); - try{ - //Delay between two SE selection - Thread.sleep(200); - }catch(Exception e){ - e.printStackTrace(); - } - } - } + protected Void doInBackground(Integer... params) { + synchronized (NfcService.this) { + etsiStopConfig(params[0].intValue()); + return null; } } - }; - - + } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); - Log.e(TAG, "screen state "+action); - if (action.equals( - NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) { - // Perform applyRouting() in AsyncTask to serialize blocking calls - new ApplyRoutingTask().execute(); - } else if ((action.equals(Intent.ACTION_SCREEN_ON) + if (action.equals(Intent.ACTION_SCREEN_ON) || action.equals(Intent.ACTION_SCREEN_OFF) - || action.equals(Intent.ACTION_USER_PRESENT)) && - mState == NfcAdapter.STATE_ON) { + || action.equals(Intent.ACTION_USER_PRESENT)) { // Perform applyRouting() in AsyncTask to serialize blocking calls int screenState = mScreenStateHelper.checkScreenState(); if (action.equals(Intent.ACTION_SCREEN_OFF)) { - if(mScreenState != ScreenStateHelper.SCREEN_STATE_OFF_LOCKED) - { - Log.e(TAG, "screen state OFF required"); + if (mScreenState != ScreenStateHelper.SCREEN_STATE_OFF_LOCKED) { screenState = mKeyguard.isKeyguardLocked() ? - ScreenStateHelper.SCREEN_STATE_OFF_LOCKED : - ScreenStateHelper.SCREEN_STATE_OFF_UNLOCKED; - } + ScreenStateHelper.SCREEN_STATE_OFF_LOCKED : ScreenStateHelper.SCREEN_STATE_OFF_UNLOCKED; + } } else if (action.equals(Intent.ACTION_SCREEN_ON)) { - screenState = mKeyguard.isKeyguardLocked() ? - ScreenStateHelper.SCREEN_STATE_ON_LOCKED : ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED; - Log.e(TAG, "screen state on"); - /* - if(screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mScreenState == ScreenStateHelper.SCREEN_STATE_OFF) { - } else if (screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mScreenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED) { - return; - }*/ + screenState = mKeyguard.isKeyguardLocked() + ? ScreenStateHelper.SCREEN_STATE_ON_LOCKED + : ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED; } else if (action.equals(Intent.ACTION_USER_PRESENT)) { - if (mScreenState != ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) { - Log.e(TAG, "screen state user present"); - screenState = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED; - } else { - return; - } + screenState = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED; } - /* This piece of code is duplicate as MSG_APPLY_SCREEN_STATE - is already calling applyRouting api */ - /*if(nci_version != NCI_VERSION_2_0) { + if (nci_version != NCI_VERSION_2_0) { new ApplyRoutingTask().execute(Integer.valueOf(screenState)); - }*/ - - if( mDeviceHost.getEtsiReaederState() == STATE_SE_RDR_MODE_STOPPED || - mDeviceHost.getEtsiReaederState() == STATE_SE_RDR_MODE_INVALID) { - sendMessage(NfcService.MSG_APPLY_SCREEN_STATE, screenState); - } else { - Log.e(TAG, "mPOS in progress holding screen state "+screenState); - mScreenState = screenState; } - Log.e(TAG, "screen state "+screenState); - Log.e(TAG, "screen state mScreenState "+mScreenState); + sendMessage(NfcService.MSG_APPLY_SCREEN_STATE, screenState); } else if (action.equals(Intent.ACTION_USER_SWITCHED)) { - int screenState = mScreenStateHelper.checkScreenState(); int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); - int beamSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; - try { - IPackageManager mIpm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); - beamSetting = mIpm.getComponentEnabledSetting(new ComponentName( - BeamShareActivity.class.getPackageName$(), - BeamShareActivity.class.getName()), - userId); - } catch(RemoteException e) { - Log.e(TAG, "Error int getComponentEnabledSetting for BeamShareActivity"); - } - synchronized (this) { - mUserId = userId; - if (beamSetting == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) { - mIsNdefPushEnabled = false; - } else { - mIsNdefPushEnabled = true; + if (mIsBeamCapable) { + int beamSetting = + PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; + try { + IPackageManager mIpm = IPackageManager.Stub.asInterface( + ServiceManager.getService("package")); + beamSetting = mIpm.getComponentEnabledSetting(new ComponentName( + BeamShareActivity.class.getPackageName$(), + BeamShareActivity.class.getName()), + userId); + } catch(RemoteException e) { + Log.e(TAG, "Error int getComponentEnabledSetting for BeamShareActivity"); + } + synchronized (this) { + mUserId = userId; + if (beamSetting == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) { + mIsNdefPushEnabled = false; + } else { + mIsNdefPushEnabled = true; + } } + mP2pLinkManager.onUserSwitched(getUserId()); } - mP2pLinkManager.onUserSwitched(getUserId()); if (mIsHceCapable) { mCardEmulationManager.onUserSwitched(getUserId()); } - screenState = mScreenStateHelper.checkScreenState(); - new ApplyRoutingTask().execute(Integer.valueOf(screenState)); + int screenState = mScreenStateHelper.checkScreenState(); + if (screenState != mScreenState) { + new ApplyRoutingTask().execute(Integer.valueOf(screenState)); + } } } }; + private final BroadcastReceiver mOwnerReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -5054,11 +3828,8 @@ public class NfcService implements DeviceHostListener { action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE) || action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) { updatePackageCache(); - - } else if(action.equals(Intent.ACTION_SHUTDOWN)) { - mPowerShutDown = true; - if (DBG) Log.d(TAG,"Device is shutting down."); - mDeviceHost.doSetScreenOrPowerState(ScreenStateHelper.POWER_STATE_OFF); + } else if (action.equals(Intent.ACTION_SHUTDOWN)) { + if (DBG) Log.d(TAG, "Device is shutting down."); if (isNfcEnabled()) { mDeviceHost.shutdown(); } @@ -5071,9 +3842,10 @@ public class NfcService implements DeviceHostListener { public void onReceive(Context context, Intent intent){ String action = intent.getAction(); if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED - .equals(action)) { - enforceBeamShareActivityPolicy(context, - new UserHandle(getSendingUserId())); + .equals(action) && + mIsBeamCapable) { + enforceBeamShareActivityPolicy( + context, new UserHandle(getSendingUserId())); } } }; @@ -5118,22 +3890,18 @@ public class NfcService implements DeviceHostListener { pw.println("mState=" + stateToString(mState)); pw.println("mIsZeroClickRequested=" + mIsNdefPushEnabled); pw.println("mScreenState=" + ScreenStateHelper.screenStateToString(mScreenState)); - pw.println("mNfcPollingEnabled=" + mNfcPollingEnabled); - pw.println("mNfceeRouteEnabled=" + mNfceeRouteEnabled); - pw.println("mOpenEe=" + mOpenEe); - pw.println("mLockscreenPollMask=" + mLockscreenPollMask); pw.println(mCurrentDiscoveryParameters); - mP2pLinkManager.dump(fd, pw, args); + if (mIsBeamCapable) + mP2pLinkManager.dump(fd, pw, args); if (mIsHceCapable) { mCardEmulationManager.dump(fd, pw, args); } mNfcDispatcher.dump(fd, pw, args); pw.flush(); mDeviceHost.dump(fd); - } } - /** + /** * Update the status of all the services which were populated to commit to routing table */ public void updateStatusOfServices(boolean commitStatus) { diff --git a/src/com/android/nfc/NfcUnlockManager.java b/src/com/android/nfc/NfcUnlockManager.java index 8d2b249a..8d2b249a 100644..100755 --- a/src/com/android/nfc/NfcUnlockManager.java +++ b/src/com/android/nfc/NfcUnlockManager.java diff --git a/src/com/android/nfc/NfcWifiProtectedSetup.java b/src/com/android/nfc/NfcWifiProtectedSetup.java index 7e206bce..af4dd6f6 100644..100755 --- a/src/com/android/nfc/NfcWifiProtectedSetup.java +++ b/src/com/android/nfc/NfcWifiProtectedSetup.java @@ -25,8 +25,11 @@ import android.nfc.NdefRecord; import android.nfc.tech.Ndef; import android.os.UserHandle; import android.os.UserManager; +import android.util.Log; + import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; +import java.util.Arrays; import java.util.BitSet; public final class NfcWifiProtectedSetup { @@ -51,6 +54,7 @@ public final class NfcWifiProtectedSetup { private static final short AUTH_TYPE_WPA_EAP = 0x0008; private static final short AUTH_TYPE_WPA2_EAP = 0x0010; private static final short AUTH_TYPE_WPA2_PSK = 0x0020; + private static final short AUTH_TYPE_WPA_AND_WPA2_PSK = 0x0022; private static final int MAX_NETWORK_KEY_SIZE_BYTES = 64; @@ -135,7 +139,7 @@ public final class NfcWifiProtectedSetup { byte[] networkKey = new byte[fieldSize]; payload.get(networkKey); if (fieldSize > 0) { - result.preSharedKey = "\"" + new String(networkKey) + "\""; + result.preSharedKey = getPskValidFormat(new String(networkKey)); } break; case AUTH_TYPE_FIELD_ID: @@ -170,7 +174,8 @@ public final class NfcWifiProtectedSetup { } private static void populateAllowedKeyManagement(BitSet allowedKeyManagement, short authType) { - if (authType == AUTH_TYPE_WPA_PSK || authType == AUTH_TYPE_WPA2_PSK) { + if (authType == AUTH_TYPE_WPA_PSK || authType == AUTH_TYPE_WPA2_PSK + || authType == AUTH_TYPE_WPA_AND_WPA2_PSK) { allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); } else if (authType == AUTH_TYPE_WPA_EAP || authType == AUTH_TYPE_WPA2_EAP) { allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP); @@ -178,4 +183,15 @@ public final class NfcWifiProtectedSetup { allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); } } + + private static String getPskValidFormat(String data) { + if (!data.matches("[0-9A-Fa-f]{64}")) { // if not HEX string + data = convertToQuotedString(data); + } + return data; + } + + private static String convertToQuotedString(String str) { + return '"' + str + '"'; + } } diff --git a/src/com/android/nfc/P2pEventManager.java b/src/com/android/nfc/P2pEventManager.java index d1c4ef0c..1f84947c 100644..100755 --- a/src/com/android/nfc/P2pEventManager.java +++ b/src/com/android/nfc/P2pEventManager.java @@ -17,6 +17,7 @@ package com.android.nfc; import com.android.nfc.beam.SendUi; + import android.app.NotificationManager; import android.content.Context; import android.content.res.Configuration; diff --git a/src/com/android/nfc/P2pLinkManager.java b/src/com/android/nfc/P2pLinkManager.java index ba6b29a5..3dd601b2 100755 --- a/src/com/android/nfc/P2pLinkManager.java +++ b/src/com/android/nfc/P2pLinkManager.java @@ -13,29 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/****************************************************************************** - * - * The original Work has been changed by NXP Semiconductors. - * - * Copyright (C) 2015-2018 NXP Semiconductors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ + package com.android.nfc; +import android.content.Intent; import android.content.pm.UserInfo; + import com.android.nfc.beam.BeamManager; +import com.android.nfc.beam.BeamSendService; +import com.android.nfc.beam.BeamTransferRecord; + import android.os.UserManager; import com.android.nfc.sneptest.ExtDtaSnepServer; import com.android.nfc.sneptest.DtaSnepClient; @@ -49,7 +36,6 @@ import com.android.nfc.snep.SnepClient; import com.android.nfc.snep.SnepMessage; import com.android.nfc.snep.SnepServer; - import android.content.Context; import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; @@ -67,12 +53,13 @@ import android.os.Message; import android.os.SystemClock; import android.os.UserHandle; import android.util.Log; - import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.List; +import java.io.UnsupportedEncodingException; /** * Interface to listen for P2P events. @@ -97,7 +84,6 @@ interface P2pEventListener { * Indicates a P2P device is in range. * <p>onP2pInRange() and onP2pOutOfRange() will always be called * alternately. - * <p>All other callbacks will only occur while a P2P device is in range. */ public void onP2pInRange(); @@ -134,8 +120,8 @@ interface P2pEventListener { /** * Called to indicate the device is busy with another handover transfer */ - public void onP2pHandoverBusy(); + /** * Called to indicate a receive was successful. */ @@ -321,14 +307,15 @@ class P2pLinkManager implements Handler.Callback, P2pEventListener.Callback { if (mEchoServer != null) { mHandler.sendEmptyMessage(MSG_STOP_ECHOSERVER); } - if(mExtDtaSnepServerRunning) + if (mExtDtaSnepServerRunning) disableExtDtaSnepServer(); } mIsSendEnabled = sendEnable; mIsReceiveEnabled = receiveEnable; } } - /** + + /** * To Enable DTA SNEP Server for NFC Forum testing */ public void enableExtDtaSnepServer(String serviceName, int serviceSap, int miu, int rwSize,int testCaseId) { @@ -430,6 +417,7 @@ class P2pLinkManager implements Handler.Callback, P2pEventListener.Callback { } else if (shareData.ndefMessage != null) { mMessageToSend = shareData.ndefMessage; } + mUserHandle = shareData.userHandle; } if (mMessageToSend != null || @@ -446,7 +434,6 @@ class P2pLinkManager implements Handler.Callback, P2pEventListener.Callback { */ public void onLlcpActivated(byte peerLlcpVersion) { Log.i(TAG, "LLCP activated"); - synchronized (P2pLinkManager.this) { if (mEchoServer != null) { mEchoServer.onLlcpActivated(); @@ -456,7 +443,7 @@ class P2pLinkManager implements Handler.Callback, P2pEventListener.Callback { switch (mLinkState) { case LINK_STATE_DOWN: if (DBG) Log.d(TAG, "onP2pInRange()"); - // Start taking a screenshot + // Start taking a screenshot mEventListener.onP2pInRange(); mLinkState = LINK_STATE_UP; // If we had a pending send (manual Beam invoke), @@ -731,7 +718,7 @@ class P2pLinkManager implements Handler.Callback, P2pEventListener.Callback { mEventListener.onP2pResumeSend(); sendNdefMessage(); } else { - // Either nothing to send or canceled/complete, ignore + // Either nothing to send or canceled/complete, ignore } } } @@ -881,6 +868,7 @@ class P2pLinkManager implements Handler.Callback, P2pEventListener.Callback { mHandoverDataParser.getOutgoingHandoverData(response), uris, userHandle)) { return HANDOVER_BUSY; } + return HANDOVER_SUCCESS; } diff --git a/src/com/android/nfc/ScreenStateHelper.java b/src/com/android/nfc/ScreenStateHelper.java index 4552c686..92ba1687 100644..100755 --- a/src/com/android/nfc/ScreenStateHelper.java +++ b/src/com/android/nfc/ScreenStateHelper.java @@ -9,7 +9,7 @@ import android.os.PowerManager; */ class ScreenStateHelper { - static final int SCREEN_STATE_UNKNOWN = 0; + static final int SCREEN_STATE_UNKNOWN = 0x00; static final int SCREEN_STATE_OFF_UNLOCKED = 0x01; static final int SCREEN_STATE_OFF_LOCKED = 0x02; static final int SCREEN_STATE_ON_LOCKED = 0x04; @@ -19,8 +19,6 @@ class ScreenStateHelper { static final int SCREEN_POLLING_TAG_MASK = 0x10; static final int SCREEN_POLLING_P2P_MASK = 0x20; static final int SCREEN_POLLING_READER_MASK = 0x40; - static final int POWER_STATE_ON = 0x09; - static final int POWER_STATE_OFF = 0x0A; private final PowerManager mPowerManager; private final KeyguardManager mKeyguardManager; diff --git a/src/com/android/nfc/WiredSeService.java b/src/com/android/nfc/WiredSeService.java deleted file mode 100644 index 4446da55..00000000 --- a/src/com/android/nfc/WiredSeService.java +++ /dev/null @@ -1,185 +0,0 @@ -/* -* Copyright (C) 2018 NXP Semiconductors -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package com.android.nfc; - -import java.util.ArrayList; -import android.util.Log; -import android.os.Handler; -import android.os.HwBinder; -import android.os.Looper; -import android.os.Message; -import android.os.RemoteException; -import java.io.IOException; -import java.util.NoSuchElementException; - -import vendor.nxp.nxpwiredse.V1_0.INxpWiredSe; -import vendor.nxp.nxpwiredse.V1_0.INxpWiredSeHalCallback; - - - -public class WiredSeService { - - static final String TAG = "WiredSeService"; - - private static WiredSeService sService ; - - private static final int EVENT_GET_HAL = 1; - private static final int MAX_GET_HAL_RETRY = 5; - private static final int GET_SERVICE_DELAY_MILLIS = 200; - private static int sNfcWiredSeHandle = 0; - private static int sWiredSeGetHalRetry = 0; - INxpWiredSe mWiredSEHal = null; - - - public static WiredSeService getInstance() { - if (sService == null) { - sService = new WiredSeService(); - } - return sService; - } - - private HwBinder.DeathRecipient mWiredSeDeathRecipient = new WiredSeDeathRecipient(); - - private - INxpWiredSeHalCallback.Stub mWiredSeCallback = new INxpWiredSeHalCallback.Stub() { - private - ArrayList<Byte> byteArrayToArrayList(byte[] array) { - ArrayList<Byte> list = new ArrayList<Byte>(); - if (array == null) { - return list; - } - for (Byte b : array) { - list.add(b); - } - return list; - } - - private - byte[] arrayListToByteArray(ArrayList<Byte> list) { - Byte[] byteArray = list.toArray(new Byte[list.size()]); - int i = 0; - byte[] result = new byte[list.size()]; - for (Byte b : byteArray) { - result[i++] = b.byteValue(); - } - return result; - } - - @Override public int openWiredSe() { - Log.d(TAG, "WiredSe: openWiredSe"); - sNfcWiredSeHandle = NfcService.getInstance().doOpenSecureElementConnection(0xF3); - if (sNfcWiredSeHandle <= 0) { - Log.e(TAG, "WiredSe: open secure element failed."); - sNfcWiredSeHandle = 0; - } else { - Log.d(TAG, "WiredSe: open secure element success."); - } - return sNfcWiredSeHandle; - } - - @Override public ArrayList<Byte> transmit(ArrayList<Byte> data, int wiredSeHandle) { - Log.d(TAG, "WiredSe: transmit"); - if (wiredSeHandle <= 0) { - Log.d(TAG, "WiredSe: Secure Element handle NULL"); - return null; - } else { - byte[] resp = NfcService.getInstance().doTransceive(wiredSeHandle, arrayListToByteArray(data)); - if (resp != null) { - Log.d(TAG, "WiredSe: response is received"); - } - return byteArrayToArrayList(resp); - } - } - - @Override public ArrayList<Byte> getAtr(int wiredSeHandle) - throws android.os.RemoteException { - Log.d(TAG, "WiredSe: getAtr"); - synchronized(WiredSeService.this) { - return byteArrayToArrayList(NfcService.getInstance().mSecureElement.doGetAtr(wiredSeHandle)); - } - } - - @Override public int closeWiredSe(int wiredSeHandle) { - Log.d(TAG, "WiredSe: closeWiredSe"); - NfcService.getInstance().doDisconnect(wiredSeHandle); - sNfcWiredSeHandle = 0; - return 0; - } - }; - - public void wiredSeInitialize() throws NoSuchElementException, RemoteException { - Log.e(TAG, "wiredSeInitialize Enter"); - if (mWiredSEHal == null) { - mWiredSEHal = INxpWiredSe.getService(); - } - if (mWiredSEHal == null) { - throw new NoSuchElementException("No HAL is provided for WiredSe"); - } - mWiredSEHal.setWiredSeCallback(mWiredSeCallback); - mWiredSEHal.linkToDeath(mWiredSeDeathRecipient, 0); - } - - public void wiredSeDeInitialize() throws NoSuchElementException, RemoteException { - Log.e(TAG, "wiredSeDeInitialize Enter"); - mWiredSEHal.setWiredSeCallback(null); - } - - class WiredSeDeathRecipient implements HwBinder.DeathRecipient { - @Override - public void serviceDied(long cookie) { - try{ - Log.d(TAG, "WiredSe: serviceDied !!"); - if(sNfcWiredSeHandle > 0) { - mWiredSeCallback.closeWiredSe(sNfcWiredSeHandle); - sNfcWiredSeHandle = 0; - } - mWiredSEHal.unlinkToDeath(mWiredSeDeathRecipient); - mWiredSEHal = null; - mWiredSeHandler.sendMessageDelayed(mWiredSeHandler.obtainMessage(EVENT_GET_HAL, 0), - GET_SERVICE_DELAY_MILLIS); - }catch(Exception e) { - e.printStackTrace(); - } - } - } - - private Handler mWiredSeHandler = new Handler(Looper.getMainLooper()) { - @Override - public void handleMessage(Message message) { - switch (message.what) { - case EVENT_GET_HAL: - try { - if(sWiredSeGetHalRetry > MAX_GET_HAL_RETRY) { - Log.e(TAG, "WiredSe GET_HAL retry failed"); - sWiredSeGetHalRetry = 0; - break; - } - wiredSeInitialize(); - sWiredSeGetHalRetry = 0; - } catch (Exception e) { - Log.e(TAG, " could not get the service. trying again"); - sWiredSeGetHalRetry++; - sendMessageDelayed(obtainMessage(EVENT_GET_HAL, 0), - GET_SERVICE_DELAY_MILLIS); - } - break; - default: - break; - } - } - }; -} diff --git a/src/com/android/nfc/beam/BeamManager.java b/src/com/android/nfc/beam/BeamManager.java index 03346634..03346634 100644..100755 --- a/src/com/android/nfc/beam/BeamManager.java +++ b/src/com/android/nfc/beam/BeamManager.java diff --git a/src/com/android/nfc/beam/BeamReceiveService.java b/src/com/android/nfc/beam/BeamReceiveService.java index 4370c13e..9d24dd05 100755 --- a/src/com/android/nfc/beam/BeamReceiveService.java +++ b/src/com/android/nfc/beam/BeamReceiveService.java @@ -88,7 +88,6 @@ public class BeamReceiveService extends Service implements BeamTransferManager.C @Override public void onDestroy() { super.onDestroy(); - if (mBeamStatusReceiver != null) { unregisterReceiver(mBeamStatusReceiver); } diff --git a/src/com/android/nfc/beam/BeamSendService.java b/src/com/android/nfc/beam/BeamSendService.java index 6c013ea3..6c013ea3 100644..100755 --- a/src/com/android/nfc/beam/BeamSendService.java +++ b/src/com/android/nfc/beam/BeamSendService.java diff --git a/src/com/android/nfc/beam/BeamStatusReceiver.java b/src/com/android/nfc/beam/BeamStatusReceiver.java index 23e1ce80..23e1ce80 100644..100755 --- a/src/com/android/nfc/beam/BeamStatusReceiver.java +++ b/src/com/android/nfc/beam/BeamStatusReceiver.java diff --git a/src/com/android/nfc/beam/BeamTransferManager.java b/src/com/android/nfc/beam/BeamTransferManager.java index be20aadd..be20aadd 100644..100755 --- a/src/com/android/nfc/beam/BeamTransferManager.java +++ b/src/com/android/nfc/beam/BeamTransferManager.java diff --git a/src/com/android/nfc/beam/BeamTransferRecord.java b/src/com/android/nfc/beam/BeamTransferRecord.java index d8f86689..d8f86689 100644..100755 --- a/src/com/android/nfc/beam/BeamTransferRecord.java +++ b/src/com/android/nfc/beam/BeamTransferRecord.java diff --git a/src/com/android/nfc/beam/BluetoothOppHandover.java b/src/com/android/nfc/beam/BluetoothOppHandover.java index 292d93c0..292d93c0 100644..100755 --- a/src/com/android/nfc/beam/BluetoothOppHandover.java +++ b/src/com/android/nfc/beam/BluetoothOppHandover.java diff --git a/src/com/android/nfc/beam/FireflyRenderer.java b/src/com/android/nfc/beam/FireflyRenderer.java index d87a5d97..d87a5d97 100644..100755 --- a/src/com/android/nfc/beam/FireflyRenderer.java +++ b/src/com/android/nfc/beam/FireflyRenderer.java diff --git a/src/com/android/nfc/beam/MimeTypeUtil.java b/src/com/android/nfc/beam/MimeTypeUtil.java index 283a24ce..283a24ce 100644..100755 --- a/src/com/android/nfc/beam/MimeTypeUtil.java +++ b/src/com/android/nfc/beam/MimeTypeUtil.java diff --git a/src/com/android/nfc/beam/SendUi.java b/src/com/android/nfc/beam/SendUi.java index e11aef84..64dab180 100644..100755 --- a/src/com/android/nfc/beam/SendUi.java +++ b/src/com/android/nfc/beam/SendUi.java @@ -13,26 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/****************************************************************************** -* -* The original Work has been changed by NXP. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -* Copyright 2018 NXP -* NOT A CONTRIBUTION -* -******************************************************************************/ + package com.android.nfc.beam; import com.android.nfc.R; @@ -486,8 +467,7 @@ public class SendUi implements Animator.AnimatorListener, View.OnTouchListener, // We didn't build up any animation state yet, but // did store the bitmap. Clear out the bitmap, reset // state and bail. - mScreenshotView.setImageBitmap(null); - recycleBitmap(); + mScreenshotBitmap = null; mState = STATE_IDLE; return; default: @@ -553,9 +533,9 @@ public class SendUi implements Animator.AnimatorListener, View.OnTouchListener, mScaleUpAnimator.cancel(); mAlphaUpAnimator.cancel(); mAlphaDownAnimator.cancel(); - mScreenshotView.setImageBitmap(null); mWindowManager.removeView(mDecor); mStatusBarManager.disable(StatusBarManager.DISABLE_NONE); + mScreenshotBitmap = null; mContext.unregisterReceiver(mReceiver); if (mToastString != null) { Toast toast = Toast.makeText(mContext, mToastString, Toast.LENGTH_LONG); @@ -563,19 +543,6 @@ public class SendUi implements Animator.AnimatorListener, View.OnTouchListener, toast.show(); } mToastString = null; - recycleBitmap(); - } - /* - * Recycles Bitmap of ScreenShot - */ - private void recycleBitmap(){ - try{ - if(mScreenshotBitmap!=null && !mScreenshotBitmap.isRecycled()){ - mScreenshotBitmap.recycle(); - } - }catch(Exception e){ - Log.e(TAG, "Error while recycle bitmap", e); - } } /** diff --git a/src/com/android/nfc/cardemulation/AidElement.java b/src/com/android/nfc/cardemulation/AidElement.java deleted file mode 100644 index ee481d40..00000000 --- a/src/com/android/nfc/cardemulation/AidElement.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2015 NXP Semiconductors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.nfc.cardemulation; - -import android.util.Log; - -import java.util.Collections; -import java.util.Hashtable; -import java.util.List; -import java.util.Iterator; - -public class AidElement implements Comparable { - - static final int ROUTE_WIEGHT_FOREGROUND = 4; - static final int ROUTE_WIEGHT_PAYMENT = 2; - static final int ROUTE_WIEGHT_OTHER = 1; - - private String mAid; - private int mWeight; - private int mRouteLocation; - private int mPowerState; - private int mAidInfo; - public AidElement(String aid, int weight, int route, int power, int aidInfo) { - mAid = aid; - mWeight = weight; - mRouteLocation = route; - mPowerState = power; - mAidInfo = aidInfo; - } - - public int getWeight() { - return mWeight; - } - - public void setRouteLocation(int routeLocation) { - mRouteLocation = routeLocation; - } - - public void setAid(String aid) { - mAid = aid; - } - - public int getAidInfo() { - return mAidInfo; - } - public void setPowerState(int powerState) { - mPowerState = powerState; - } - - public String getAid() { - return mAid; - } - - public int getRouteLocation() { - return mRouteLocation; - } - - public int getPowerState() { - return mPowerState; - } - - @Override - public int compareTo(Object o) { - - AidElement elem = (AidElement)o; - - if (mWeight > elem.getWeight()) { - return -1; - } - else if (mWeight < elem.getWeight()) { - return 1; - } - return elem.getAid().length() - mAid.length(); - } - - @Override - public String toString() { - return "aid: " + mAid + ", location: " + mRouteLocation - + ", power: " + mPowerState + ",weight: " + mWeight; - } -} diff --git a/src/com/android/nfc/cardemulation/AidRoutingManager.java b/src/com/android/nfc/cardemulation/AidRoutingManager.java index d27e254b..1e5cfe2d 100644..100755 --- a/src/com/android/nfc/cardemulation/AidRoutingManager.java +++ b/src/com/android/nfc/cardemulation/AidRoutingManager.java @@ -13,40 +13,39 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /****************************************************************************** - * - * The original Work has been changed by NXP Semiconductors. - * - * Copyright (C) 2015-2018 NXP Semiconductors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ +* +* The original Work has been changed by NXP. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +* Copyright 2018-2019 NXP +* +******************************************************************************/ package com.android.nfc.cardemulation; -import android.app.ActivityManager; -import android.app.ActivityManager.RunningTaskInfo; -import android.app.ActivityThread; -import android.content.Context; import android.util.Log; import android.util.SparseArray; - +import android.content.Context; +import android.app.ActivityThread; +import android.app.ActivityManager; +import android.app.ActivityManager.RunningTaskInfo; import com.android.nfc.NfcService; - +import android.util.SparseArray; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Collections; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; @@ -54,12 +53,16 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.List; import java.util.ArrayList; +import java.util.Hashtable; +import android.os.SystemProperties; public class AidRoutingManager { + static final String TAG = "AidRoutingManager"; static final boolean DBG = - ("1" == (System.getProperty("persist.nfc.ce_debug")) ? true : false); + ((SystemProperties.get("persist.nfc.ce_debug").equals("1")) ? true : false); static final int ROUTE_HOST = 0x00; @@ -71,30 +74,22 @@ public class AidRoutingManager { static final int AID_MATCHING_PREFIX_ONLY = 0x02; // Every routing table entry can be matched either exact or prefix or subset only static final int AID_MATCHING_EXACT_OR_SUBSET_OR_PREFIX = 0x03; - //Behavior as per Android-L, supporting prefix match and full - //match for both OnHost and OffHost apps. - static final int AID_MATCHING_L = 0x01; - //Behavior as per Android-KitKat by NXP, supporting prefix match for - //OffHost and prefix and full both for OnHost apps. - static final int AID_MATCHING_K = 0x02; - // This is the default IsoDep protocol route; it means - // that for any AID that needs to be routed to this - // destination, we won't need to add a rule to the routing - // table, because this destination is already the default route. - // - // For Nexus devices, the default route is always 0x00. + + int mDefaultIsoDepRoute; + //Let mDefaultRoute as default aid route int mDefaultRoute; - boolean mRoutingTableChanged; - // For Nexus devices, just a static route to the eSE - // OEMs/Carriers could manually map off-host AIDs - // to the correct eSE/UICC based on state they keep. - int mDefaultOffHostRoute; + + int mMaxAidRoutingTableSize; + int mDefaultAidRoute; + final byte[] mOffHostRouteUicc; + final byte[] mOffHostRouteEse; + // Used for backward compatibility in case application doesn't specify the + // SE + final int mDefaultOffHostRoute; // How the NFC controller can match AIDs in the routing table; // see AID_MATCHING constants - int mAidMatchingSupport; - int mAidMatchingPlatform; - //Changed from final to private int to update RoutingtableSize later in configureRouting. + final int mAidMatchingSupport; private int mAidRoutingTableSize; // Maximum AID routing table size final Object mLock = new Object(); @@ -111,30 +106,41 @@ public class AidRoutingManager { // Easy look-up what the route is for a certain AID HashMap<String, Integer> mRouteForAid = new HashMap<String, Integer>(); - // Easy look-up what the power state is for a certain AID - HashMap<String, Integer> mPowerForAid = new HashMap<String, Integer>(); - - private native int doGetDefaultRouteDestination(); private native int doGetDefaultOffHostRouteDestination(); + private native byte[] doGetOffHostUiccDestination(); + private native byte[] doGetOffHostEseDestination(); private native int doGetAidMatchingMode(); - private native int doGetAidMatchingPlatform(); - - final VzwRoutingCache mVzwRoutingCache; - + private native int doGetDefaultIsoDepRouteDestination(); final ActivityManager mActivityManager; + final class AidEntry { + boolean isOnHost; + String offHostSE; + int aidInfo; + int powerstate; + int route; + } public AidRoutingManager() { mDefaultRoute = doGetDefaultRouteDestination(); - mRoutingTableChanged = false; - if (DBG) Log.d(TAG, "mDefaultRoute=0x" + Integer.toHexString(mDefaultRoute)); + if (DBG) + Log.d(TAG, "mDefaultRoute=0x" + Integer.toHexString(mDefaultRoute)); mDefaultOffHostRoute = doGetDefaultOffHostRouteDestination(); - if (DBG) Log.d(TAG, "mDefaultOffHostRoute=0x" + Integer.toHexString(mDefaultOffHostRoute)); + if (DBG) + Log.d(TAG, "mDefaultOffHostRoute=0x" + Integer.toHexString(mDefaultOffHostRoute)); + mOffHostRouteUicc = doGetOffHostUiccDestination(); + if (DBG) + Log.d(TAG, "mOffHostRouteUicc=" + Arrays.toString(mOffHostRouteUicc)); + mOffHostRouteEse = doGetOffHostEseDestination(); + if (DBG) + Log.d(TAG, "mOffHostRouteEse=" + Arrays.toString(mOffHostRouteEse)); mAidMatchingSupport = doGetAidMatchingMode(); if (DBG) Log.d(TAG, "mAidMatchingSupport=0x" + Integer.toHexString(mAidMatchingSupport)); - mAidMatchingPlatform = doGetAidMatchingPlatform(); - if (DBG) Log.d(TAG, "mAidMatchingPlatform=0x" + Integer.toHexString(mAidMatchingPlatform)); - mVzwRoutingCache = new VzwRoutingCache(); + mDefaultAidRoute = NfcService.getInstance().GetDefaultRouteEntry() >> 0x08; + if (DBG) + Log.d(TAG, "mDefaultAidRoute=0x" + Integer.toHexString(mDefaultAidRoute)); + mDefaultIsoDepRoute = doGetDefaultIsoDepRouteDestination(); + if (DBG) Log.d(TAG, "mDefaultIsoDepRoute=0x" + Integer.toHexString(mDefaultIsoDepRoute)); mLastCommitStatus = true; Context context = (Context) ActivityThread.currentApplication(); @@ -151,11 +157,24 @@ public class AidRoutingManager { return mAidMatchingSupport == AID_MATCHING_EXACT_OR_SUBSET_OR_PREFIX; } - public boolean isRoutingTableUpdated() { - return mRoutingTableChanged; + public int calculateAidRouteSize(HashMap<String, AidEntry> routeCache) { + // TAG + ROUTE + LENGTH_BYTE + POWER + int AID_HDR_LENGTH = 0x04; + int routeTableSize = 0x00; + for(Map.Entry<String, AidEntry> aidEntry : routeCache.entrySet()) { + String aid = aidEntry.getKey(); + // removing prefix length + if(aid.endsWith("*")) { + routeTableSize += ((aid.length() - 0x01) / 0x02) + AID_HDR_LENGTH; + } else { + routeTableSize += (aid.length() / 0x02)+ AID_HDR_LENGTH; + } + } + if (DBG) Log.d(TAG, "calculateAidRouteSize: " + routeTableSize); + return routeTableSize; } - void clearNfcRoutingTableLocked() { - /* + + private void clearNfcRoutingTableLocked() { for (Map.Entry<String, Integer> aidEntry : mRouteForAid.entrySet()) { String aid = aidEntry.getKey(); if (aid.endsWith("*")) { @@ -186,19 +205,19 @@ public class AidRoutingManager { } else { if (DBG) Log.d(TAG, "Unrouting exact AID " + aid); } + NfcService.getInstance().unrouteAids(aid); } - */ - NfcService.getInstance().clearRouting(); - mRouteForAid.clear(); - mPowerForAid.clear(); - mAidRoutingTable.clear(); + if (NfcService.getInstance().getNciVersion() != NfcService.getInstance().NCI_VERSION_1_0) { + // unRoute EmptyAid + NfcService.getInstance().unrouteAids(""); + } } public boolean configureApduPatternRouting(List<ApduPatternResolveInfo> apduPatternList) { + NfcService.getInstance().unrouteApduPattern("FFFFFFFFFFFFFFEF"); if(apduPatternList.size() == 0x00 || apduPatternList == null) return false; - NfcService.getInstance().unrouteApduPattern("FFFFFFFFFFFFFFEF"); for(ApduPatternResolveInfo apduPatternInfo : apduPatternList) { NfcService.getInstance().routeApduPattern(apduPatternInfo.referenceData,apduPatternInfo.mask, apduPatternInfo.route,apduPatternInfo.powerState); @@ -206,86 +225,101 @@ public class AidRoutingManager { return true; } - public void refreshConfigParameters() { - mDefaultRoute = doGetDefaultRouteDestination(); - if (DBG) - Log.d(TAG, "mDefaultRoute=0x" + Integer.toHexString(mDefaultRoute)); - mDefaultOffHostRoute = doGetDefaultOffHostRouteDestination(); - if (DBG) - Log.d(TAG, "mDefaultOffHostRoute=0x" + Integer.toHexString(mDefaultOffHostRoute)); - mAidMatchingSupport = doGetAidMatchingMode(); - if (DBG) - Log.d(TAG, "mAidMatchingSupport=0x" + Integer.toHexString(mAidMatchingSupport)); - mAidMatchingPlatform = doGetAidMatchingPlatform(); + private int getRouteForSecureElement(String se) { + if (se == null || se.length() <= 3) { + return 0; + } + try { + if (se.startsWith("eSE") && mOffHostRouteEse != null) { + int index = Integer.parseInt(se.substring(3)); + if (mOffHostRouteEse.length >= index && index > 0) { + return mOffHostRouteEse[index - 1] & 0xFF; + } + } else if (se.startsWith("SIM") && mOffHostRouteUicc != null) { + int index = Integer.parseInt(se.substring(3)); + if (mOffHostRouteUicc.length >= index && index > 0) { + return mOffHostRouteUicc[index - 1] & 0xFF; + } + } + } catch (NumberFormatException e) { + } + return 0; } - public boolean configureRouting(HashMap<String, AidElement> aidMap) { - mRoutingTableChanged = false; - //To handle Dynamic change in config files. - refreshConfigParameters(); - mDefaultRoute = NfcService.getInstance().GetDefaultRouteLoc(); + public boolean configureRouting(HashMap<String, AidEntry> aidMap, boolean force) { boolean aidRouteResolved = false; - if (DBG) Log.d(TAG, "mAidMatchingPlatform=0x" + Integer.toHexString(mAidMatchingPlatform)); - mAidRoutingTableSize = NfcService.getInstance().getAidRoutingTableSize(); - if (DBG) Log.d(TAG, "mDefaultRoute=0x" + Integer.toHexString(mDefaultRoute)); - Hashtable<String, AidElement> routeCache = new Hashtable<String, AidElement>(50); + HashMap<String, AidEntry> aidRoutingTableCache = new HashMap<String, AidEntry>(aidMap.size()); + ArrayList<Integer> seList = new ArrayList<Integer>(); SparseArray<Set<String>> aidRoutingTable = new SparseArray<Set<String>>(aidMap.size()); HashMap<String, Integer> routeForAid = new HashMap<String, Integer>(aidMap.size()); - HashMap<String, Integer> powerForAid = new HashMap<String, Integer>(aidMap.size()); HashMap<String, Integer> infoForAid = new HashMap<String, Integer>(aidMap.size()); + HashMap<String, Integer> powerForAid = new HashMap<String, Integer>(aidMap.size()); + mDefaultRoute = NfcService.getInstance().GetDefaultRouteLoc(); + mAidRoutingTableSize = NfcService.getInstance().getAidRoutingTableSize(); + mDefaultAidRoute = NfcService.getInstance().GetDefaultRouteEntry() >> 0x08; + Log.e(TAG, "Size of routing table"+mAidRoutingTableSize); + seList.add(mDefaultAidRoute); // Then, populate internal data structures first - DefaultAidRouteResolveCache defaultRouteCache = new DefaultAidRouteResolveCache(); - - for (Map.Entry<String, AidElement> aidEntry : aidMap.entrySet()) { - AidElement elem = aidEntry.getValue(); - int route = elem.getRouteLocation(); - int power = elem.getPowerState(); - int aidType = elem.getAidInfo(); - if (route == -1 ) { - route = mDefaultOffHostRoute; - elem.setRouteLocation(route); + for (Map.Entry<String, AidEntry> aidEntry : aidMap.entrySet()) { + int route = ROUTE_HOST; + if (!aidEntry.getValue().isOnHost) { + String offHostSE = aidEntry.getValue().offHostSE; + if (offHostSE == null) { + route = mDefaultOffHostRoute; + } else { + route = getRouteForSecureElement(offHostSE); + if (route == 0) { + Log.e(TAG, "Invalid Off host Aid Entry " + offHostSE); + continue; + } + } } + if (!seList.contains(route)) + seList.add(route); + aidEntry.getValue().route = route; + int aidType = aidEntry.getValue().aidInfo; + int power = aidEntry.getValue().powerstate; String aid = aidEntry.getKey(); Set<String> entries = aidRoutingTable.get(route, new HashSet<String>()); entries.add(aid); aidRoutingTable.put(route, entries); routeForAid.put(aid, route); - powerForAid.put(aid, power); infoForAid.put(aid, aidType); + powerForAid.put(aid, power); if (DBG) Log.d(TAG, "#######Routing AID " + aid + " to route " + Integer.toString(route) + " with power "+ power); } + if (!seList.contains(ROUTE_HOST)) + seList.add(ROUTE_HOST); synchronized (mLock) { - if (routeForAid.equals(mRouteForAid)) { - if (DBG) Log.d(TAG, "Routing table unchanged"); + if (routeForAid.equals(mRouteForAid) && !force) { + if (DBG) Log.d(TAG, "Routing table unchanged, but commit the routing"); if(mLastCommitStatus == false){ NfcService.getInstance().updateStatusOfServices(false); - NfcService.getInstance().notifyRoutingTableFull(); } else {/*If last commit status was success, And a new service is added whose AID's are already resolved by previously installed services, service state of newly installed app needs to be updated*/ NfcService.getInstance().updateStatusOfServices(true); } - if (isProcessingTapAgain() || NfcService.getInstance().mIsRoutingTableDirty) { - if (DBG) Log.d(TAG, "Routing table unchanged, but commit the routing"); - NfcService.getInstance().commitRouting(); - } else { - if (DBG) Log.d(TAG, "Routing table unchanged, not updating"); - } return false; } // Otherwise, update internal structures and commit new routing clearNfcRoutingTableLocked(); mRouteForAid = routeForAid; - mPowerForAid = powerForAid; mAidRoutingTable = aidRoutingTable; - for(int routeIndex=0; routeIndex < 0x03; routeIndex++) { - routeCache.clear(); - if (mAidMatchingSupport == AID_MATCHING_PREFIX_ONLY || - mAidMatchingPlatform == AID_MATCHING_K) { + mMaxAidRoutingTableSize = NfcService.getInstance().getAidRoutingTableSize(); + if (DBG) Log.d(TAG, "mMaxAidRoutingTableSize: " + mMaxAidRoutingTableSize); + + for(int index=0; index < seList.size(); index++) { + mDefaultRoute = seList.get(index); + if(index != 0) + if (DBG) Log.d(TAG, "AidRoutingTable is full, try to switch mDefaultRoute to 0x" + Integer.toHexString(mDefaultRoute)); + + aidRoutingTableCache.clear(); + if (mAidMatchingSupport == AID_MATCHING_PREFIX_ONLY) { /* If a non-default route registers an exact AID which is shorter * than this exact AID, this will create a problem with controllers * that treat every AID in the routing table as a prefix. @@ -310,18 +344,17 @@ public class AidRoutingManager { int route = aidEntry.getValue(); if (defaultRouteAid.startsWith(aid) && route != mDefaultRoute) { if (DBG) Log.d(TAG, "Adding AID " + defaultRouteAid + " for default " + - "route, because a conflicting shorter AID will be added" + - "to the routing table"); - AidElement elem = aidMap.get(defaultRouteAid); - elem.setRouteLocation(mDefaultRoute); - routeCache.put(defaultRouteAid, elem); - //NfcService.getInstance().routeAids(defaultRouteAid, mDefaultRoute, mPowerForAid.get(defaultRouteAid),infoForAid.get(defaultRouteAid)); + "route, because a conflicting shorter AID will be " + + "added to the routing table"); + aidRoutingTableCache.put(defaultRouteAid, aidMap.get(defaultRouteAid)); } } } } } - + // Add AID entries for + // 1. all non-default routes + // 2. default route but only payment AID // Add AID entries for all non-default routes for (int i = 0; i < mAidRoutingTable.size(); i++) { int route = mAidRoutingTable.keyAt(i); @@ -335,19 +368,12 @@ public class AidRoutingManager { if (DBG) Log.d(TAG, "Routing prefix AID " + aid + " to route " + Integer.toString(route)); // Cut off '*' since controller anyway treats all AIDs as a prefix - AidElement elem = aidMap.get(aid); - elem.setAid(aid.substring(0,aid.length() - 1)); - routeCache.put(aid, elem); - //NfcService.getInstance().routeAids(aid.substring(0, - //aid.length() - 1), route, mPowerForAid.get(aid),infoForAid.get(aid)); - } else if (mAidMatchingSupport == AID_MATCHING_EXACT_OR_PREFIX - || mAidMatchingSupport == AID_MATCHING_EXACT_OR_SUBSET_OR_PREFIX) { - Log.d(TAG, "Routing AID in AID_MATCHING_EXACT_OR_PREFIX"); + aidRoutingTableCache.put(aid.substring(0,aid.length() - 1), aidMap.get(aid)); + } else if (mAidMatchingSupport == AID_MATCHING_EXACT_OR_PREFIX || + mAidMatchingSupport == AID_MATCHING_EXACT_OR_SUBSET_OR_PREFIX) { if (DBG) Log.d(TAG, "Routing prefix AID " + aid + " to route " + Integer.toString(route)); - AidElement elem = aidMap.get(aid); - routeCache.put(aid, elem); - //NfcService.getInstance().routeAids(aid, route, (mPowerForAid.get(aid)),infoForAid.get(aid)); + aidRoutingTableCache.put(aid.substring(0,aid.length() - 1), aidMap.get(aid)); } } else if (aid.endsWith("#")) { if (mAidMatchingSupport == AID_MATCHING_EXACT_ONLY) { @@ -360,87 +386,72 @@ public class AidRoutingManager { } else if (mAidMatchingSupport == AID_MATCHING_EXACT_OR_SUBSET_OR_PREFIX) { if (DBG) Log.d(TAG, "Routing subset AID " + aid + " to route " + Integer.toString(route)); - AidElement elem = aidMap.get(aid); - routeCache.put(aid, elem); - //NfcService.getInstance().routeAids(aid, route, (mPowerForAid.get(aid)),infoForAid.get(aid)); + aidRoutingTableCache.put(aid.substring(0,aid.length() - 1), aidMap.get(aid)); } } else { if (DBG) Log.d(TAG, "Routing exact AID " + aid + " to route " + Integer.toString(route)); - AidElement elem = aidMap.get(aid); - routeCache.put(aid, elem); - //NfcService.getInstance().routeAids(aid, route, mPowerForAid.get(aid),infoForAid.get(aid)); + aidRoutingTableCache.put(aid, aidMap.get(aid)); } + } } } - } - - if((routeIndex == 0x00) && (defaultRouteCache.calculateAidRouteSize(routeCache) <= mAidRoutingTableSize)) { - // maximum aid table size is less than AID route table size - aidRouteResolved = true; - break; - } else { - defaultRouteCache.updateDefaultAidRouteCache(routeCache , mDefaultRoute); - mDefaultRoute = defaultRouteCache.getNextRouteLoc(); - if(mDefaultRoute == 0xFF) - { - break; + if(mDefaultRoute != mDefaultIsoDepRoute) { + if(NfcService.getInstance().getNciVersion() != NfcService.getInstance().NCI_VERSION_1_0) { + String emptyAid = ""; + AidEntry entry = new AidEntry(); + entry.route = mDefaultRoute; + if(mDefaultRoute==ROUTE_HOST) { + entry.isOnHost = true; + } else{ + entry.isOnHost = false; + } + entry.aidInfo = RegisteredAidCache.AID_ROUTE_QUAL_PREFIX; + aidRoutingTableCache.put(emptyAid, entry); + if (DBG) Log.d(TAG, "Add emptyAid into AidRoutingTable"); + } } - } - - } - } - if(aidRouteResolved == false) { - if(mAidRoutingTable.size() == 0x00) { + if( calculateAidRouteSize(aidRoutingTableCache) <= mMaxAidRoutingTableSize) { aidRouteResolved = true; - //update the cache , no applications present. - } - else if(defaultRouteCache.resolveDefaultAidRoute() == true) { - aidRouteResolved = true; - routeCache = defaultRouteCache.getResolvedAidRouteCache(); - //update preferences if different - NfcService.getInstance().setDefaultAidRouteLoc(defaultRouteCache.getResolvedAidRoute()); - } else { - NfcService.getInstance().notifyRoutingTableFull(); + break; + } } + if(aidRouteResolved == true) { + commit(aidRoutingTableCache); + NfcService.getInstance().updateStatusOfServices(true); + mLastCommitStatus = true; + } else { + Log.e(TAG, "RoutingTable unchanged because it's full, not updating"); + NfcService.getInstance().notifyRoutingTableFull(); + NfcService.getInstance().updateStatusOfServices(false); + mLastCommitStatus = false; + } } - // And finally commit the routing and update the status of commit for each service - if(aidRouteResolved == true) { - mRoutingTableChanged = true; - commit(routeCache); - NfcService.getInstance().updateStatusOfServices(true); - mLastCommitStatus = true; - } - else{ - NfcService.getInstance().updateStatusOfServices(false); - mLastCommitStatus = false; - } -// NfcService.getInstance().commitRouting(); - + NfcService.getInstance().commitRouting(); return true; } - private void commit(Hashtable<String, AidElement> routeCache ) { - - if(routeCache != null) { - List<AidElement> list = Collections.list(routeCache.elements()); - Collections.sort(list); - Iterator<AidElement> it = list.iterator(); - NfcService.getInstance().clearRouting(); - while(it.hasNext()){ - AidElement element =it.next(); - if (DBG) Log.d (TAG, element.toString()); - NfcService.getInstance().routeAids( - element.getAid(), - element.getRouteLocation(), - element.getPowerState(), - element.getAidInfo()); - } + private void commit(HashMap<String, AidEntry> routeCache ) { + if(routeCache == null) + { + return; + } + for (Map.Entry<String, AidEntry> aidEntry : routeCache.entrySet()) { + if(aidEntry.getKey().isEmpty()) + continue; + AidEntry element = aidEntry.getValue(); + if (DBG) Log.d (TAG, element.toString()); + NfcService.getInstance().routeAids( + aidEntry.getKey(), + element.route, + element.aidInfo, + element.powerstate); } - // And finally commit the routing - NfcService.getInstance().commitRouting(); + AidEntry emptyAidEntry = routeCache.get(""); + if (emptyAidEntry != null) + NfcService.getInstance().routeAids( + "", emptyAidEntry.route, emptyAidEntry.aidInfo, emptyAidEntry.powerstate); } - /** * This notifies that the AID routing table in the controller * has been cleared (usually due to NFC being turned off). @@ -454,35 +465,20 @@ public class AidRoutingManager { } } - public boolean UpdateVzwCache(byte[] aid,int route,int power,boolean isAllowed){ - mVzwRoutingCache.addAid(aid,route,power,isAllowed); - return true; - } - - public VzwRoutingCache GetVzwCache(){ - return mVzwRoutingCache; - } - - public void ClearVzwCache() { - mVzwRoutingCache.clear(); - } - - public int getAidMatchMode() { - return mAidMatchingSupport; - } - public boolean getLastCommitRoutingStatus() { return mLastCommitStatus; } - public int getAidMatchingPlatform() { - return mAidMatchingPlatform; + final class ApduPatternResolveInfo { + public String mask; + public String referenceData; + public int route; + public int powerState; } public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("Routing table:"); - pw.println(" Default route: " + - (NfcService.getInstance().GetDefaultRouteLoc() == 0x00 ? "host" : "secure element")); + pw.println(" Default route: " + ((mDefaultRoute == 0x00) ? "host" : "secure element")); synchronized (mLock) { for (int i = 0; i < mAidRoutingTable.size(); i++) { Set<String> aids = mAidRoutingTable.valueAt(i); @@ -494,130 +490,6 @@ public class AidRoutingManager { } } - final class ApduPatternResolveInfo { - public String mask; - public String referenceData; - public int route; - public int powerState; - } - - final class DefaultAidRouteResolveCache { - static final int AID_HDR_LENGTH = 0x04; // TAG + ROUTE + LENGTH_BYTE + POWER - static final int MAX_AID_ENTRIES = 50; - //AidCacheTable contains the current aid routing table for particular route. - //The index is the route ID. - private SparseArray<Hashtable<String, AidElement>> aidCacheTable; - private HashMap <Integer , Integer> aidCacheSize; - //HashMap containing aid routing size . - //The index is route ID. - private Hashtable<String, AidElement> resolvedAidCache;//HashTable containing resolved default aid routeCache - private int mCurrDefaultAidRoute; // current default route in preferences - private int mResolvedAidRoute; //resolved aid route location - private boolean mAidRouteResolvedStatus; // boolean value - private ArrayList<Integer> aidRoutes;//non-default route location - - DefaultAidRouteResolveCache () { - aidCacheTable = new SparseArray<Hashtable<String, AidElement>>(0x03); - resolvedAidCache = new Hashtable<String, AidElement>(); - aidCacheSize= new HashMap <Integer , Integer>(0x03); - aidRoutes = new ArrayList<Integer>(); - mCurrDefaultAidRoute = NfcService.getInstance().GetDefaultRouteLoc(); - mAidRouteResolvedStatus = false; - } - - private Hashtable<String, AidElement> extractResolvedCache() - { - if(mAidRouteResolvedStatus == false) { - return null; - } - for(int i=0;i< aidCacheTable.size() ;i++) { - int route = aidCacheTable.keyAt(i); - if(route == mResolvedAidRoute) { - return aidCacheTable.get(route); - } - } - return null; - } - - - public int calculateAidRouteSize(Hashtable<String, AidElement> routeCache) { - int routeTableSize = 0x00; - int routeAidCount = 0x00; - for(Map.Entry<String, AidElement> aidEntry : routeCache.entrySet()) { - String aid = aidEntry.getKey(); - if(aid.endsWith("*")) { - routeTableSize += ((aid.length() - 0x01) / 0x02) + AID_HDR_LENGTH; // removing prefix length - } else { - routeTableSize += (aid.length() / 0x02)+ AID_HDR_LENGTH; - } - routeAidCount++; - } - Log.d(TAG, "calculateAidRouteSize final Routing table size" +routeTableSize); - if(routeTableSize <= mAidRoutingTableSize && routeAidCount > MAX_AID_ENTRIES) { - routeTableSize = mAidRoutingTableSize + 0x01; - } - return routeTableSize; - } - - public int updateDefaultAidRouteCache(Hashtable<String, AidElement> routeCache , int route) { - int routesize = 0x00; - Hashtable<String, AidElement> tempRouteCache = new Hashtable<String, AidElement>(0x50); - tempRouteCache.putAll(routeCache); - routesize = calculateAidRouteSize(tempRouteCache); - aidCacheTable.put(route, tempRouteCache); - aidCacheSize.put(route, routesize); - Log.d(TAG, "updateDefaultAidRouteCache Routing table size" +routesize); - return routesize; - } - - public boolean resolveDefaultAidRoute () { - - int minRoute = 0xFF; - int minAidRouteSize = mAidRoutingTableSize; - int tempRoute = 0x00; - int tempCacheSize = 0x00; - Hashtable<String, AidElement> aidRouteCache = new Hashtable<String, AidElement>(); - Set<Integer> keys = aidCacheSize.keySet(); - for (Integer key : keys) { - tempRoute = key; - tempCacheSize = aidCacheSize.get(key); - if (tempCacheSize <= minAidRouteSize) { - minAidRouteSize = tempCacheSize; - minRoute = tempRoute; - } - } - if(minRoute != 0xFF) { - mAidRouteResolvedStatus = true; - mResolvedAidRoute = minRoute; - Log.d(TAG, "min route found "+mResolvedAidRoute); - } - - return mAidRouteResolvedStatus; - } - - public int getResolvedAidRoute () { - return mResolvedAidRoute; - } - - public Hashtable<String, AidElement> getResolvedAidRouteCache() { - - return extractResolvedCache(); - } - - public int getNextRouteLoc() { - - for (int i = 0; i < 0x03; i++) { - if((i != mCurrDefaultAidRoute) && (!aidRoutes.contains(i))) - { - aidRoutes.add(i); - return i; - } - } - return 0xFF; - } - - } - // Returns true if AppChooserActivity is foreground to restart RF discovery so that // TapAgainDialog is dismissed when an external reader detects the device. private boolean isProcessingTapAgain() { diff --git a/src/com/android/nfc/cardemulation/AppChooserActivity.java b/src/com/android/nfc/cardemulation/AppChooserActivity.java index 5ed96c0d..5ed96c0d 100644..100755 --- a/src/com/android/nfc/cardemulation/AppChooserActivity.java +++ b/src/com/android/nfc/cardemulation/AppChooserActivity.java diff --git a/src/com/android/nfc/cardemulation/CardEmulationManager.java b/src/com/android/nfc/cardemulation/CardEmulationManager.java index 59f42c8c..50c970df 100755 --- a/src/com/android/nfc/cardemulation/CardEmulationManager.java +++ b/src/com/android/nfc/cardemulation/CardEmulationManager.java @@ -14,31 +14,29 @@ * limitations under the License. */ /****************************************************************************** - * - * The original Work has been changed by NXP Semiconductors. - * - * Copyright (C) 2015-2018 NXP Semiconductors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ +* +* The original Work has been changed by NXP. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +* Copyright 2018-2019 NXP +* +******************************************************************************/ package com.android.nfc.cardemulation; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.List; -import java.util.Map; -import java.util.HashMap; import java.util.ArrayList; import android.app.ActivityManager; import android.content.ComponentName; @@ -47,10 +45,9 @@ import android.content.Intent; import android.nfc.INfcCardEmulation; import android.nfc.INfcFCardEmulation; import android.nfc.cardemulation.AidGroup; -import android.nfc.cardemulation.NxpAidGroup; +import android.nfc.cardemulation.NfcAidGroup; import android.nfc.cardemulation.ApduServiceInfo; -import android.nfc.cardemulation.NxpApduServiceInfo; -import com.nxp.nfc.NxpAidServiceInfo; +import android.nfc.cardemulation.NfcApduServiceInfo; import android.nfc.cardemulation.NfcFServiceInfo; import android.nfc.cardemulation.CardEmulation; import android.nfc.cardemulation.NfcFCardEmulation; @@ -61,12 +58,15 @@ import android.os.PowerManager; import android.os.SystemClock; import android.provider.Settings; import android.util.Log; +import java.util.Map; +import java.util.HashMap; import com.android.nfc.NfcPermissions; import com.android.nfc.NfcService; import com.android.nfc.cardemulation.RegisteredServicesCache; -import com.gsma.nfc.internal.RegisteredNxpServicesCache; import com.android.nfc.cardemulation.RegisteredNfcFServicesCache; +import com.nxp.nfc.NfcAidServiceInfo; +import android.os.SystemProperties; /** * CardEmulationManager is the central entity @@ -87,7 +87,7 @@ public class CardEmulationManager implements RegisteredServicesCache.Callback, RegisteredNfcFServicesCache.Callback, PreferredServices.Callback, EnabledNfcFServices.Callback { static final String TAG = "CardEmulationManager"; - static final boolean DBG = ("1" == (System.getProperty("persist.nfc.ce_debug")) ? true : false); + static final boolean DBG = ((SystemProperties.get("persist.nfc.ce_debug").equals("1")) ? true : false); static final int NFC_HCE_APDU = 0x01; static final int NFC_HCE_NFCF = 0x04; @@ -101,47 +101,39 @@ public class CardEmulationManager implements RegisteredServicesCache.Callback, final EnabledNfcFServices mEnabledNfcFServices; final Context mContext; final CardEmulationInterface mCardEmulationInterface; - final RegisteredNxpServicesCache mRegisteredNxpServicesCache; final NfcFCardEmulationInterface mNfcFCardEmulationInterface; final PowerManager mPowerManager; - public CardEmulationManager(Context context, AidRoutingManager aidRoutingManager) { + public CardEmulationManager(Context context) { mContext = context; mCardEmulationInterface = new CardEmulationInterface(); mNfcFCardEmulationInterface = new NfcFCardEmulationInterface(); - mAidCache = new RegisteredAidCache(context, aidRoutingManager); + mAidCache = new RegisteredAidCache(context); mT3tIdentifiersCache = new RegisteredT3tIdentifiersCache(context); - mServiceCache = new RegisteredServicesCache(context, this); - mNfcFServicesCache = new RegisteredNfcFServicesCache(context, this); mHostEmulationManager = new HostEmulationManager(context, mAidCache); mHostNfcFEmulationManager = new HostNfcFEmulationManager(context, mT3tIdentifiersCache); + mServiceCache = new RegisteredServicesCache(context, this); + mNfcFServicesCache = new RegisteredNfcFServicesCache(context, this); mPreferredServices = new PreferredServices(context, mServiceCache, mAidCache, this); - mRegisteredNxpServicesCache = new RegisteredNxpServicesCache(context, mServiceCache); mEnabledNfcFServices = new EnabledNfcFServices( context, mNfcFServicesCache, mT3tIdentifiersCache, this); - - mServiceCache.initialize(mRegisteredNxpServicesCache); + mServiceCache.initialize(); mNfcFServicesCache.initialize(); mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); } - public RegisteredNxpServicesCache getRegisteredNxpServicesCache() { - return mRegisteredNxpServicesCache; + public INfcCardEmulation getNfcCardEmulationInterface() { + return mCardEmulationInterface; } public INfcFCardEmulation getNfcFCardEmulationInterface() { return mNfcFCardEmulationInterface; } - - // To get Object of RegisteredAidCache to get the Default Offhost service. + // To get Object of RegisteredAidCache to get the Default Offhost service. public RegisteredAidCache getRegisteredAidCache() { return mAidCache; } - public INfcCardEmulation getNfcCardEmulationInterface() { - return mCardEmulationInterface; - } - public void onHostCardEmulationActivated(int technology) { if (mPowerManager != null) { mPowerManager.userActivity(SystemClock.uptimeMillis(), PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0); @@ -183,38 +175,26 @@ public class CardEmulationManager implements RegisteredServicesCache.Callback, } public void onUserSwitched(int userId) { - //For HCE + // for HCE mServiceCache.invalidateCache(userId); mPreferredServices.onUserSwitched(userId); - //For HCE-F + // for HCE-F mHostNfcFEmulationManager.onUserSwitched(); mT3tIdentifiersCache.onUserSwitched(); mEnabledNfcFServices.onUserSwitched(userId); mNfcFServicesCache.onUserSwitched(); mNfcFServicesCache.invalidateCache(userId); - - } - - public void onT3tConfigure() - { - mT3tIdentifiersCache.clearT3tidentifiercache(); - mT3tIdentifiersCache.generateForegroundT3tIdentifiersCacheLocked(); - } - - public void onReRoutingEntry() - { - Log.e(TAG, "onReRoutingEntry: notify service."); - mAidCache.clearRoutingTable(); - mAidCache.generateAidCacheLocked(); } public void onNfcEnabled() { + // for HCE mAidCache.onNfcEnabled(); // for HCE-F mT3tIdentifiersCache.onNfcEnabled(); } public void onNfcDisabled() { + // for HCE mAidCache.onNfcDisabled(); // for HCE-F mHostNfcFEmulationManager.onNfcDisabled(); @@ -223,11 +203,16 @@ public class CardEmulationManager implements RegisteredServicesCache.Callback, mEnabledNfcFServices.onNfcDisabled(); } + public void onSecureNfcToggled() { + mAidCache.onSecureNfcToggled(); + mT3tIdentifiersCache.onSecureNfcToggled(); + } + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { mServiceCache.dump(fd, pw, args); mNfcFServicesCache.dump(fd, pw ,args); - mEnabledNfcFServices.dump(fd, pw, args); mPreferredServices.dump(fd, pw, args); + mEnabledNfcFServices.dump(fd, pw, args); mAidCache.dump(fd, pw, args); mT3tIdentifiersCache.dump(fd, pw, args); mHostEmulationManager.dump(fd, pw, args); @@ -235,7 +220,7 @@ public class CardEmulationManager implements RegisteredServicesCache.Callback, } @Override - public void onServicesUpdated(int userId, List<NxpApduServiceInfo> services) { + public void onServicesUpdated(int userId, List<NfcApduServiceInfo> services) { // Verify defaults are still sane verifyDefaults(userId, services); // Update the AID cache @@ -252,7 +237,7 @@ public class CardEmulationManager implements RegisteredServicesCache.Callback, mEnabledNfcFServices.onServicesUpdated(); } - void verifyDefaults(int userId, List<NxpApduServiceInfo> services) { + void verifyDefaults(int userId, List<NfcApduServiceInfo> services) { ComponentName defaultPaymentService = getDefaultServiceForCategory(userId, CardEmulation.CATEGORY_PAYMENT, false); if (DBG) Log.d(TAG, "Current default: " + defaultPaymentService); @@ -261,8 +246,8 @@ public class CardEmulationManager implements RegisteredServicesCache.Callback, // in that case, automatically set that app as default. int numPaymentServices = 0; ComponentName lastFoundPaymentService = null; - for (NxpApduServiceInfo service : services) { - if ((service.hasCategory(CardEmulation.CATEGORY_PAYMENT))&&(!service.getAids().isEmpty())) { + for (NfcApduServiceInfo service : services) { + if (service.hasCategory(CardEmulation.CATEGORY_PAYMENT)) { numPaymentServices++; lastFoundPaymentService = service.getComponent(); } @@ -304,20 +289,6 @@ public class CardEmulationManager implements RegisteredServicesCache.Callback, } } - boolean isNfcFServiceInstalled(int userId, ComponentName service) { - boolean serviceFound = mNfcFServicesCache.hasService(userId, service); - if (!serviceFound) { - // If we don't know about this service yet, it may have just been enabled - // using PackageManager.setComponentEnabledSetting(). The PackageManager - // broadcasts are delayed by 10 seconds in that scenario, which causes - // calls to our APIs referencing that service to fail. - // Hence, update the cache in case we don't know about the service. - if (DBG) Log.d(TAG, "Didn't find passed in service, invalidating cache."); - mNfcFServicesCache.invalidateCache(userId); - } - return mNfcFServicesCache.hasService(userId, service); - } - boolean setDefaultServiceForCategoryChecked(int userId, ComponentName service, String category) { if (!CardEmulation.CATEGORY_PAYMENT.equals(category)) { @@ -351,8 +322,21 @@ public class CardEmulationManager implements RegisteredServicesCache.Callback, return mServiceCache.hasService(userId, service); } + boolean isNfcFServiceInstalled(int userId, ComponentName service) { + boolean serviceFound = mNfcFServicesCache.hasService(userId, service); + if (!serviceFound) { + // If we don't know about this service yet, it may have just been enabled + // using PackageManager.setComponentEnabledSetting(). The PackageManager + // broadcasts are delayed by 10 seconds in that scenario, which causes + // calls to our APIs referencing that service to fail. + // Hence, update the cache in case we don't know about the service. + if (DBG) Log.d(TAG, "Didn't find passed in service, invalidating cache."); + mNfcFServicesCache.invalidateCache(userId); + } + return mNfcFServicesCache.hasService(userId, service); + } - /** + /** * Returns whether a service in this package is preferred, * either because it's the default payment app or it's running * in the foreground. @@ -361,12 +345,9 @@ public class CardEmulationManager implements RegisteredServicesCache.Callback, return mPreferredServices.packageHasPreferredService(packageName); } - /** - * This class implements the application-facing APIs - * and are called from binder. All calls must be - * permission-checked. - * + * This class implements the application-facing APIs and are called + * from binder. All calls must be permission-checked. */ final class CardEmulationInterface extends INfcCardEmulation.Stub { @Override @@ -424,7 +405,28 @@ public class CardEmulationManager implements RegisteredServicesCache.Callback, return false; } return mServiceCache.registerAidGroupForService(userId, Binder.getCallingUid(), service, - new NxpAidGroup(aidGroup)); + new NfcAidGroup(aidGroup)); + } + + @Override + public boolean setOffHostForService(int userId, ComponentName service, String offHostSE) { + NfcPermissions.validateUserId(userId); + NfcPermissions.enforceUserPermissions(mContext); + if (!isServiceRegistered(userId, service)) { + return false; + } + return mServiceCache.setOffHostSecureElement(userId, Binder.getCallingUid(), service, + offHostSE); + } + + @Override + public boolean unsetOffHostForService(int userId, ComponentName service) { + NfcPermissions.validateUserId(userId); + NfcPermissions.enforceUserPermissions(mContext); + if (!isServiceRegistered(userId, service)) { + return false; + } + return mServiceCache.unsetOffHostSecureElement(userId, Binder.getCallingUid(), service); } @Override @@ -456,11 +458,10 @@ public class CardEmulationManager implements RegisteredServicesCache.Callback, throws RemoteException { NfcPermissions.validateUserId(userId); NfcPermissions.enforceAdminPermissions(mContext); - List<NxpApduServiceInfo> nxpApduServices = mServiceCache.getServicesForCategory(userId, category); - + List<NfcApduServiceInfo> nfcApduServices = mServiceCache.getServicesForCategory(userId, category); ArrayList<ApduServiceInfo> apduServices = new ArrayList<ApduServiceInfo>(); - for(NxpApduServiceInfo nxpApdu : nxpApduServices) { - ApduServiceInfo apduService = nxpApdu.createApduServiceInfo(); + for(NfcApduServiceInfo nfcApdu : nfcApduServices) { + ApduServiceInfo apduService = nfcApdu.createApduServiceInfo(); apduServices.add(apduService); } if(DBG) Log.d(TAG, "getServices() size: " + apduServices.size()); @@ -484,8 +485,8 @@ public class CardEmulationManager implements RegisteredServicesCache.Callback, NfcPermissions.enforceUserPermissions(mContext); return mPreferredServices.unregisteredPreferredForegroundService( Binder.getCallingUid()); - } + @Override public boolean supportsAidPrefixRegistration() throws RemoteException { return mAidCache.supportsAidPrefixRegistration(); @@ -604,32 +605,22 @@ public class CardEmulationManager implements RegisteredServicesCache.Callback, mHostEmulationManager.onPreferredForegroundServiceChanged(service); } - @Override - public void onEnabledForegroundNfcFServiceChanged(ComponentName service) { - mT3tIdentifiersCache.onEnabledForegroundNfcFServiceChanged(service); - mHostNfcFEmulationManager.onEnabledForegroundNfcFServiceChanged(service); - } - - public void setScreenState(int state) { - mHostEmulationManager.setScreenState(state); - } - public void onRoutingTableChanged() { mAidCache.onRoutingTableChanged(); } - public List<NxpAidServiceInfo> getServicesAidInfo(int userId, String category) { + public List<NfcAidServiceInfo> getServicesAidInfo(int userId, String category) { if(category == CardEmulation.CATEGORY_PAYMENT) { return null; } - List<NxpApduServiceInfo> nonPaymentServices = new ArrayList<NxpApduServiceInfo>(); - List<NxpAidServiceInfo> nxpAidServiceInfoList = new ArrayList<NxpAidServiceInfo>(); + List<NfcApduServiceInfo> nonPaymentServices = new ArrayList<NfcApduServiceInfo>(); + List<NfcAidServiceInfo> nfcAidServiceInfoList = new ArrayList<NfcAidServiceInfo>(); Integer serviceAidCacheSize = 0x00; String serviceComponent = null; NfcPermissions.validateUserId(userId); NfcPermissions.enforceUserPermissions(mContext); nonPaymentServices = mServiceCache.getServicesForCategory(userId, CardEmulation.CATEGORY_OTHER); - for(NxpApduServiceInfo serviceinfo : nonPaymentServices) { + for(NfcApduServiceInfo serviceinfo : nonPaymentServices) { serviceAidCacheSize = 0x00; serviceComponent = null; if(serviceinfo != null) { @@ -641,30 +632,33 @@ public class CardEmulationManager implements RegisteredServicesCache.Callback, } } serviceComponent = serviceinfo.getComponent().flattenToString(); - NxpAidServiceInfo aidServiceInfo = new NxpAidServiceInfo(serviceComponent, serviceAidCacheSize, + NfcAidServiceInfo aidServiceInfo = new NfcAidServiceInfo(serviceComponent, serviceAidCacheSize, serviceinfo.isServiceEnabled(CardEmulation.CATEGORY_OTHER), serviceinfo.getDescription(),serviceinfo.getOtherAidGroupDescription()); - nxpAidServiceInfoList.add(aidServiceInfo); + nfcAidServiceInfoList.add(aidServiceInfo); } } - return nxpAidServiceInfoList; + return nfcAidServiceInfoList; } - public List<NxpApduServiceInfo> getAllServices() { - int userId = ActivityManager.getCurrentUser(); - return mServiceCache.getServices(userId); - } - - public int updateServiceState(int userId , - Map<String , Boolean> serviceState) { + public int updateServiceState(int userId , Map<String , Boolean> serviceState) { NfcPermissions.validateUserId(userId); NfcPermissions.enforceUserPermissions(mContext); return mServiceCache.updateServiceState(userId ,Binder.getCallingUid() ,serviceState); } - public void updateStatusOfServices(boolean commitStatus) { + @Override + public void onEnabledForegroundNfcFServiceChanged(ComponentName service) { + mT3tIdentifiersCache.onEnabledForegroundNfcFServiceChanged(service); + mHostNfcFEmulationManager.onEnabledForegroundNfcFServiceChanged(service); + } + public List<NfcApduServiceInfo> getAllServices() { + int userId = ActivityManager.getCurrentUser(); + return mServiceCache.getServices(userId); + } + public void updateStatusOfServices(boolean commitStatus) { mServiceCache.updateStatusOfServices(commitStatus); } } diff --git a/src/com/android/nfc/cardemulation/EnabledNfcFServices.java b/src/com/android/nfc/cardemulation/EnabledNfcFServices.java index 7a5178a6..c9126f06 100644..100755 --- a/src/com/android/nfc/cardemulation/EnabledNfcFServices.java +++ b/src/com/android/nfc/cardemulation/EnabledNfcFServices.java @@ -27,10 +27,11 @@ import android.nfc.cardemulation.NfcFServiceInfo; import android.os.Handler; import android.os.Looper; import android.util.Log; +import android.os.SystemProperties; public class EnabledNfcFServices implements com.android.nfc.ForegroundUtils.Callback { static final String TAG = "EnabledNfcFCardEmulationServices"; - static final boolean DBG = ("1" == (System.getProperty("persist.nfc.ce_debug")) ? true : false); + static final boolean DBG = ((SystemProperties.get("persist.nfc.ce_debug").equals("1")) ? true : false); final Context mContext; final RegisteredNfcFServicesCache mNfcFServiceCache; diff --git a/src/com/android/nfc/cardemulation/HostEmulationManager.java b/src/com/android/nfc/cardemulation/HostEmulationManager.java index 1875a05e..84952e04 100644..100755 --- a/src/com/android/nfc/cardemulation/HostEmulationManager.java +++ b/src/com/android/nfc/cardemulation/HostEmulationManager.java @@ -14,24 +14,24 @@ * limitations under the License. */ /****************************************************************************** - * - * The original Work has been changed by NXP Semiconductors. - * - * Copyright (C) 2015 NXP Semiconductors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ +* +* The original Work has been changed by NXP. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +* Copyright 2018 NXP +* +******************************************************************************/ package com.android.nfc.cardemulation; import android.app.ActivityManager; @@ -40,7 +40,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; -import android.nfc.cardemulation.NxpApduServiceInfo; +import android.nfc.cardemulation.NfcApduServiceInfo; import android.nfc.cardemulation.CardEmulation; import android.nfc.cardemulation.HostApduService; import android.os.Bundle; @@ -58,11 +58,11 @@ import com.android.nfc.cardemulation.RegisteredAidCache.AidResolveInfo; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; - +import android.os.SystemProperties; public class HostEmulationManager { static final String TAG = "HostEmulationManager"; - static final boolean DBG = ("1" == (System.getProperty("persist.nfc.ce_debug")) ? true : false); + static final boolean DBG = ((SystemProperties.get("persist.nfc.ce_debug").equals("1")) ? true : false); static final int STATE_IDLE = 0; static final int STATE_W4_SELECT = 1; @@ -70,30 +70,14 @@ public class HostEmulationManager { static final int STATE_W4_DEACTIVATE = 3; static final int STATE_XFER = 4; - static final int SCREEN_STATE_OFF = 1; - static final int SCREEN_STATE_ON_LOCKED = 2; - static final int SCREEN_STATE_ON_UNLOCKED = 3; - /** Minimum AID lenth as per ISO7816 */ static final int MINIMUM_AID_LENGTH = 5; - static final int NFCID2_LENGTH = 8; /** Length of Select APDU header including length byte */ static final int SELECT_APDU_HDR_LENGTH = 5; - static final int T3T_CMD_HDR_LENGTH = 1; static final byte INSTR_SELECT = (byte)0xA4; - /** NFC Forum / Felica commands */ - static final byte T3T_MSG_OPC_CHECK_CMD = 0x06; - static final byte T3T_MSG_OPC_UPDATE_CMD = 0x08; - - /** Felica commands (not specified in NFC-Forum Type 3 tag specifications) */ - static final byte T3T_MSG_OPC_POLL_CMD = 0x00; - static final byte T3T_MSG_OPC_REQ_SERVICE_CMD = 0x02; - static final byte T3T_MSG_OPC_REQ_RESPONSE_CMD = 0x04; - static final byte T3T_MSG_OPC_REQ_SYSTEMCODE_CMD = 0x0C; - static final String ANDROID_HCE_AID = "A000000476416E64726F6964484345"; static final byte[] ANDROID_HCE_RESPONSE = {0x14, (byte)0x81, 0x00, 0x00, (byte)0x90, 0x00}; @@ -102,7 +86,6 @@ public class HostEmulationManager { final Context mContext; final RegisteredAidCache mAidCache; - final Messenger mMessenger = new Messenger (new MessageHandler()); final KeyguardManager mKeyguard; final Object mLock; @@ -131,19 +114,14 @@ public class HostEmulationManager { ComponentName mActiveServiceName; String mLastSelectedAid; - String mLastSelectedNfcid2; - int mState; byte[] mSelectApdu; - int mScreenState; - public HostEmulationManager(Context context, RegisteredAidCache aidCache) { mContext = context; mLock = new Object(); mAidCache = aidCache; mState = STATE_IDLE; - mScreenState = SCREEN_STATE_ON_UNLOCKED; mKeyguard = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE); } @@ -167,10 +145,6 @@ public class HostEmulationManager { } } - public void setScreenState(int state) { - mScreenState = state; - } - public void onHostEmulationActivated() { Log.d(TAG, "notifyHostEmulationActivated"); synchronized (mLock) { @@ -187,13 +161,8 @@ public class HostEmulationManager { } public void onHostEmulationData(byte[] data) { - Log.d(TAG, "notifyHostEmulationData"+data.length); - // Handle and route the NFCID2 based routing here. - String nfcid2 = null; + Log.d(TAG, "notifyHostEmulationData"); String selectAid = findSelectAid(data); - if(selectAid == null && data.length !=5) { - nfcid2 = findSelectNfcid2(data); - } ComponentName resolvedService = null; synchronized (mLock) { if (mState == STATE_IDLE) { @@ -203,10 +172,6 @@ public class HostEmulationManager { Log.e(TAG, "Dropping APDU in STATE_W4_DECTIVATE"); return; } - if (mScreenState == SCREEN_STATE_OFF) { - NfcService.getInstance().sendData(AID_NOT_FOUND); - return; - } if (selectAid != null) { if (selectAid.equals(ANDROID_HCE_AID)) { NfcService.getInstance().sendData(ANDROID_HCE_RESPONSE); @@ -222,7 +187,7 @@ public class HostEmulationManager { if (resolveInfo.defaultService != null) { // Resolve to default // Check if resolvedService requires unlock - NxpApduServiceInfo defaultServiceInfo = resolveInfo.defaultService; + NfcApduServiceInfo defaultServiceInfo = resolveInfo.defaultService; if (defaultServiceInfo.requiresUnlock() && mKeyguard.isKeyguardLocked() && mKeyguard.isKeyguardSecure()) { // Just ignore all future APDUs until next tap @@ -240,7 +205,7 @@ public class HostEmulationManager { } resolvedService = defaultServiceInfo.getComponent(); } else if (mActiveServiceName != null) { - for (NxpApduServiceInfo serviceInfo : resolveInfo.services) { + for (NfcApduServiceInfo serviceInfo : resolveInfo.services) { if (mActiveServiceName.equals(serviceInfo.getComponent())) { resolvedService = mActiveServiceName; break; @@ -252,16 +217,11 @@ public class HostEmulationManager { // Ask the user to confirm. // Just ignore all future APDUs until we resolve to only one mState = STATE_W4_DEACTIVATE; - try{ - launchResolver((ArrayList<NxpApduServiceInfo>)resolveInfo.services, null, - resolveInfo.category); - }catch(Exception e){ - e.printStackTrace(); - } + launchResolver((ArrayList<NfcApduServiceInfo>)resolveInfo.services, null, + resolveInfo.category); return; } } - switch (mState) { case STATE_W4_SELECT: if (selectAid != null) { @@ -277,19 +237,6 @@ public class HostEmulationManager { mSelectApdu = data; mState = STATE_W4_SERVICE; } - } else if(nfcid2 != null) { - Messenger existingService = bindServiceIfNeededLocked(resolvedService); - if (existingService != null) { - Log.d(TAG, "Binding to existing service"); - mState = STATE_XFER; - sendDataToServiceLocked(existingService, data); - } else { - // Waiting for service to be bound - Log.d(TAG, "Waiting for new service."); - // Queue SELECT APDU to be used - mSelectApdu = data; - mState = STATE_W4_SERVICE; - } } else { Log.d(TAG, "Dropping non-select APDU in STATE_W4_SELECT"); NfcService.getInstance().sendData(UNKNOWN_ERROR); @@ -309,18 +256,7 @@ public class HostEmulationManager { mSelectApdu = data; mState = STATE_W4_SERVICE; } - } else if(nfcid2 != null) { - Messenger existingService = bindServiceIfNeededLocked(resolvedService); - if (existingService != null) { - sendDataToServiceLocked(existingService, data); - mState = STATE_XFER; - } else { - // Waiting for service to be bound - mSelectApdu = data; - mState = STATE_W4_SERVICE; - } - } - else if (mActiveService != null) { + } else if (mActiveService != null) { // Regular APDU data sendDataToServiceLocked(mActiveService, data); } else { @@ -358,7 +294,7 @@ public class HostEmulationManager { mActiveServiceName = null; unbindServiceIfNeededLocked(); mState = STATE_W4_SELECT; -//TODO: Check the impact on NfcService onSEDeactivated + //close the TapAgainDialog Intent intent = new Intent(TapAgainDialog.ACTION_CLOSE); intent.setPackage("com.android.nfc"); @@ -454,7 +390,7 @@ public class HostEmulationManager { } } - void launchTapAgain(NxpApduServiceInfo service, String category) { + void launchTapAgain(NfcApduServiceInfo service, String category) { Intent dialogIntent = new Intent(mContext, TapAgainDialog.class); dialogIntent.putExtra(TapAgainDialog.EXTRA_CATEGORY, category); dialogIntent.putExtra(TapAgainDialog.EXTRA_APDU_SERVICE, service); @@ -462,7 +398,7 @@ public class HostEmulationManager { mContext.startActivityAsUser(dialogIntent, UserHandle.CURRENT); } - void launchResolver(ArrayList<NxpApduServiceInfo> services, ComponentName failedComponent, + void launchResolver(ArrayList<NfcApduServiceInfo> services, ComponentName failedComponent, String category) { Intent intent = new Intent(mContext, AppChooserActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); @@ -498,33 +434,6 @@ public class HostEmulationManager { return null; } -//FelicaOnHost - String findSelectNfcid2(byte[] data) { - - /* - if (data == null || data.length < T3T_CMD_HDR_LENGTH + NFCID2_LENGTH) { - if (DBG) Log.d(TAG, "Data size too small for NFCID2"); - return null; - }*/ - int payloadLength = data[0]; - int FelicaCmdOpcodeByte0 = data[1]; - int FelicaCmdOpcodeLength=1; - if(data.length != data[0] || - (!isValidT3TOpcode(data[1])) ) { - return null; - } - if(FelicaCmdOpcodeByte0 >= 0xC0 && FelicaCmdOpcodeByte0 <= 0xDF) - FelicaCmdOpcodeLength =2; - - if (DBG) Log.d(TAG, "payloadLength = " + payloadLength); - if (DBG) Log.d(TAG, "FelicaCmdOpcodeLength = " + FelicaCmdOpcodeLength ); - if (DBG) Log.d(TAG, "FelicaCmdOpcodeByte0 = " + FelicaCmdOpcodeByte0 ); - //if (data.length < T3T_CMD_HDR_LENGTH + payloadLength) { - //return null; - //} - return bytesToString(data, FelicaCmdOpcodeLength + 1 , NFCID2_LENGTH); - } - private ServiceConnection mPaymentConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { @@ -615,7 +524,7 @@ public class HostEmulationManager { AidResolveInfo resolveInfo = mAidCache.resolveAid(mLastSelectedAid); boolean isPayment = false; if (resolveInfo.services.size() > 0) { - launchResolver((ArrayList<NxpApduServiceInfo>)resolveInfo.services, + launchResolver((ArrayList<NfcApduServiceInfo>)resolveInfo.services, mActiveServiceName, resolveInfo.category); } } @@ -644,21 +553,4 @@ public class HostEmulationManager { pw.println(" other: " + mServiceName); } } - - private boolean isValidT3TOpcode (byte opcode) { - boolean result = false; - if ( (opcode == T3T_MSG_OPC_CHECK_CMD) - ||(opcode == T3T_MSG_OPC_UPDATE_CMD) - ||(opcode == T3T_MSG_OPC_POLL_CMD) - ||(opcode == T3T_MSG_OPC_REQ_SERVICE_CMD) - ||(opcode == T3T_MSG_OPC_REQ_RESPONSE_CMD) - ||(opcode == T3T_MSG_OPC_REQ_SYSTEMCODE_CMD) - ||( opcode >= 0xC0 && opcode <= 0xDF) - ) - { - result = true; - } - - return result; - } } diff --git a/src/com/android/nfc/cardemulation/HostNfcFEmulationManager.java b/src/com/android/nfc/cardemulation/HostNfcFEmulationManager.java index a83588f3..9e08c1b4 100644..100755 --- a/src/com/android/nfc/cardemulation/HostNfcFEmulationManager.java +++ b/src/com/android/nfc/cardemulation/HostNfcFEmulationManager.java @@ -13,6 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/****************************************************************************** +* +* The original Work has been changed by NXP. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +* Copyright 2018 NXP +* +******************************************************************************/ package com.android.nfc.cardemulation; @@ -35,10 +54,11 @@ import com.android.nfc.NfcService; import java.io.FileDescriptor; import java.io.PrintWriter; +import android.os.SystemProperties; public class HostNfcFEmulationManager { static final String TAG = "HostNfcFEmulationManager"; - static final boolean DBG = ("1" == (System.getProperty("persist.nfc.ce_debug")) ? true : false); + static final boolean DBG = ((SystemProperties.get("persist.nfc.ce_debug").equals("1")) ? true : false); static final int STATE_IDLE = 0; static final int STATE_W4_SERVICE = 1; @@ -143,8 +163,7 @@ public class HostNfcFEmulationManager { break; } } - - } + } public void onHostEmulationDeactivated() { if (DBG) Log.d(TAG, "notifyHostEmulationDeactivated"); @@ -284,7 +303,6 @@ public class HostNfcFEmulationManager { mServiceName = null; } } - }; class MessageHandler extends Handler { @@ -305,19 +323,18 @@ public class HostNfcFEmulationManager { return; } byte[] data = dataBundle.getByteArray("data"); + /* this piece of code is commented to allow the application to send an empty + data packet */ /*if (data == null) { Log.e(TAG, "Data is null"); return; } - */ - if (data == null || data.length == 0) { - Log.e(TAG, "Empty response packet"); - sendEmptyData(); + if (data.length == 0) { + Log.e(TAG, "Invalid response packet"); return; - } + }*/ if (data != null && (data.length != (data[0] & 0xff))) { Log.e(TAG, "Invalid response packet"); - sendEmptyData(); return; } int state; @@ -335,12 +352,6 @@ public class HostNfcFEmulationManager { } } - static void sendEmptyData() { - byte[] data = new byte[0]; /* to send NCI empty message */ - Log.d(TAG, "sending empty data"); - NfcService.getInstance().sendData(data); - } - static String bytesToString(byte[] bytes, int offset, int length) { final char[] hexChars = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; char[] chars = new char[length * 2]; diff --git a/src/com/android/nfc/cardemulation/PreferredServices.java b/src/com/android/nfc/cardemulation/PreferredServices.java index 01fe2294..01fe2294 100644..100755 --- a/src/com/android/nfc/cardemulation/PreferredServices.java +++ b/src/com/android/nfc/cardemulation/PreferredServices.java diff --git a/src/com/android/nfc/cardemulation/RegisteredAidCache.java b/src/com/android/nfc/cardemulation/RegisteredAidCache.java index 7b382afb..cad2a33e 100755 --- a/src/com/android/nfc/cardemulation/RegisteredAidCache.java +++ b/src/com/android/nfc/cardemulation/RegisteredAidCache.java @@ -1,4 +1,4 @@ - /* +/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,35 +14,32 @@ * limitations under the License. */ /****************************************************************************** - * - * The original Work has been changed by NXP Semiconductors. - * - * Copyright (C) 2015-2018 NXP Semiconductors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - +* +* The original Work has been changed by NXP. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +* Copyright 2018-2019 NXP +* +******************************************************************************/ package com.android.nfc.cardemulation; import android.app.ActivityManager; import android.content.ComponentName; import android.content.Context; -import com.android.nfc.NfcService; -import android.nfc.cardemulation.NxpApduServiceInfo; +import android.nfc.cardemulation.NfcApduServiceInfo; import android.nfc.cardemulation.CardEmulation; import android.util.Log; -import com.nxp.nfc.NxpConstants; import com.google.android.collect.Maps; import java.util.Collections; @@ -57,15 +54,17 @@ import java.util.Map; import java.util.NavigableMap; import java.util.PriorityQueue; import java.util.TreeMap; -import android.nfc.cardemulation.NxpAidGroup; +import android.nfc.cardemulation.NfcAidGroup; +import com.android.nfc.NfcService; +import com.nxp.nfc.NfcConstants; +import android.os.SystemProperties; public class RegisteredAidCache { static final String TAG = "RegisteredAidCache"; - static final boolean DBG = ("1" == (System.getProperty("persist.nfc.ce_debug")) ? true : false); + static final boolean DBG = ((SystemProperties.get("persist.nfc.ce_debug").equals("1")) ? true : false); static final int AID_ROUTE_QUAL_SUBSET = 0x20; static final int AID_ROUTE_QUAL_PREFIX = 0x10; - // mAidServices maps AIDs to services that have registered them. // It's a TreeMap in order to be able to quickly select subsets // of AIDs that conflict with each other. @@ -79,9 +78,6 @@ public class RegisteredAidCache { // It is only valid for the current user. final TreeMap<String, AidResolveInfo> mAidCache = new TreeMap<String, AidResolveInfo>(); final TreeMap<String, ServiceApduInfo> mapduPatternList= new TreeMap<String, ServiceApduInfo>(); - // The power state for Host AIDs - int mHostAIDPowerState; - //FIXME: directly use the declaration in ApduServerInfo in framework static final int POWER_STATE_SWITCH_ON = 1; static final int POWER_STATE_SWITCH_OFF = 2; @@ -92,7 +88,7 @@ public class RegisteredAidCache { static final int SCREEN_STATE_OFF_LOCKED = 0x20; // Represents a single AID registration of a service final class ServiceAidInfo { - NxpApduServiceInfo service; + NfcApduServiceInfo service; String aid; String category; @@ -129,14 +125,14 @@ public class RegisteredAidCache { } final class ServiceApduInfo { - NxpApduServiceInfo service; - NxpAidGroup.ApduPattern apdu; + NfcApduServiceInfo service; + NfcAidGroup.ApduPattern apdu; } // Represents a list of services, an optional default and a category that // an AID was resolved to. final class AidResolveInfo { - List<NxpApduServiceInfo> services = new ArrayList<NxpApduServiceInfo>(); - NxpApduServiceInfo defaultService = null; + List<NfcApduServiceInfo> services = new ArrayList<NfcApduServiceInfo>(); + NfcApduServiceInfo defaultService = null; String category = null; boolean mustRoute = true; // Whether this AID should be routed at all ReslovedPrefixConflictAid prefixInfo = null; @@ -159,16 +155,15 @@ public class RegisteredAidCache { final Object mLock = new Object(); ComponentName mPreferredPaymentService; - ComponentName mPreviousPreferredPaymentService; ComponentName mPreferredForegroundService; - + ComponentName mPreviousPreferredPaymentService; boolean mNfcEnabled = false; boolean mSupportsPrefixes = false; boolean mSupportsSubset = false; - public RegisteredAidCache(Context context, AidRoutingManager aidRoutingManager) { + public RegisteredAidCache(Context context) { mContext = context; - mRoutingManager = aidRoutingManager; + mRoutingManager = NfcService.getInstance().getAidRoutingCache(); mPreferredPaymentService = null; mPreferredForegroundService = null; mSupportsPrefixes = mRoutingManager.supportsAidPrefixRouting(); @@ -179,7 +174,6 @@ public class RegisteredAidCache { if (mSupportsSubset) { if (DBG) Log.d(TAG, "Controller supports AID subset routing"); } - mHostAIDPowerState = POWER_STATE_SWITCH_ON | SCREEN_STATE_ON_LOCKED; } public AidResolveInfo resolveAid(String aid) { @@ -207,9 +201,10 @@ public class RegisteredAidCache { for (Map.Entry<String, AidResolveInfo> entry : matchingAids.entrySet()) { boolean isPrefix = isPrefix(entry.getKey()); boolean isSubset = isSubset(entry.getKey()); - String entryAid = (isPrefix || isSubset)? entry.getKey().substring(0, + String entryAid = (isPrefix || isSubset) ? entry.getKey().substring(0, entry.getKey().length() - 1):entry.getKey(); // Cut off '*' if prefix - if (entryAid.equalsIgnoreCase(aid) || (isPrefix && aid.startsWith(entryAid)) || (isSubset && entryAid.startsWith(aid)) ) { + if (entryAid.equalsIgnoreCase(aid) || (isPrefix && aid.startsWith(entryAid)) + || (isSubset && entryAid.startsWith(aid))) { if (DBG) Log.d(TAG, "resolveAid: AID " + entry.getKey() + " matches."); AidResolveInfo entryResolveInfo = entry.getValue(); if (entryResolveInfo.defaultService != null) { @@ -221,7 +216,7 @@ public class RegisteredAidCache { resolveInfo.defaultService = entryResolveInfo.defaultService; resolveInfo.category = entryResolveInfo.category; } - for (NxpApduServiceInfo serviceInfo : entryResolveInfo.services) { + for (NfcApduServiceInfo serviceInfo : entryResolveInfo.services) { if (!resolveInfo.services.contains(serviceInfo)) { resolveInfo.services.add(serviceInfo); } @@ -235,7 +230,9 @@ public class RegisteredAidCache { return resolveInfo; } } - + public void setPreviousPreferredPaymentService(ComponentName mPrevPaymentService) { + mPreviousPreferredPaymentService = mPrevPaymentService; + } public ComponentName getPreferredPaymentService(){ return mPreferredPaymentService; } @@ -286,8 +283,8 @@ public class RegisteredAidCache { AidResolveInfo resolveInfo = new AidResolveInfo(); resolveInfo.category = CardEmulation.CATEGORY_OTHER; - NxpApduServiceInfo matchedForeground = null; - NxpApduServiceInfo matchedPayment = null; + NfcApduServiceInfo matchedForeground = null; + NfcApduServiceInfo matchedPayment = null; for (ServiceAidInfo serviceAidInfo : conflictingServices) { boolean serviceClaimsPaymentAid = CardEmulation.CATEGORY_PAYMENT.equals(serviceAidInfo.category); @@ -384,7 +381,7 @@ public class RegisteredAidCache { //If the AID is subsetAID check for prefix in same service. if(isSubset(aidServices.get(0).aid)) { resolveinfo.prefixInfo = findPrefixConflictForSubsetAid(aidServices.get(0).aid , - new ArrayList<NxpApduServiceInfo>(){{add(resolveinfo.defaultService);}},true); + new ArrayList<NfcApduServiceInfo>(){{add(resolveinfo.defaultService);}},true); } return resolveinfo; } else if (aidDefaultInfo.paymentDefault != null) { @@ -403,7 +400,7 @@ public class RegisteredAidCache { //If the AID is subsetAID check for prefix in same service. if(isSubset(aidServices.get(0).aid)) { resolveinfo.prefixInfo = findPrefixConflictForSubsetAid(aidServices.get(0).aid , - new ArrayList<NxpApduServiceInfo>(){{add(resolveinfo.defaultService);}},true); + new ArrayList<NfcApduServiceInfo>(){{add(resolveinfo.defaultService);}},true); } return resolveinfo; } @@ -418,25 +415,27 @@ public class RegisteredAidCache { // make single service default if no children are present if (DBG) Log.d(TAG, "No service has preference, adding all."); resolveinfo = resolveAidConflictLocked(aidServices, conflictingServices.isEmpty()); - //If the AID is subsetAID check for conflicting prefix in all conflciting services and root services. - if(isSubset(aidServices.get(0).aid)) - { - ArrayList <NxpApduServiceInfo> apduServiceList = new ArrayList <NxpApduServiceInfo>(); + //If the AID is subsetAID check for conflicting prefix in all + //conflciting services and root services. + if (isSubset(aidServices.get(0).aid)) { + ArrayList <NfcApduServiceInfo> apduServiceList = new ArrayList <NfcApduServiceInfo>(); for(ServiceAidInfo serviceInfo : conflictingServices) apduServiceList.add(serviceInfo.service); for(ServiceAidInfo serviceInfo : aidServices) apduServiceList.add(serviceInfo.service); - resolveinfo.prefixInfo = findPrefixConflictForSubsetAid(aidServices.get(0).aid , apduServiceList,false); + resolveinfo.prefixInfo = + findPrefixConflictForSubsetAid(aidServices.get(0).aid ,apduServiceList,false); } return resolveinfo; } } } - void generateServiceMapLocked(List<NxpApduServiceInfo> services) { + void generateServiceMapLocked(List<NfcApduServiceInfo> services) { // Easiest is to just build the entire tree again mAidServices.clear(); - for (NxpApduServiceInfo service : services) { + mapduPatternList.clear(); + for (NfcApduServiceInfo service : services) { if (DBG) Log.d(TAG, "generateServiceMap component: " + service.getComponent()); List<String> prefixAids = service.getPrefixAids(); List<String> subSetAids = service.getSubsetAids(); @@ -488,21 +487,14 @@ public class RegisteredAidCache { serviceAidInfo.aid = aid.toUpperCase(); serviceAidInfo.service = service; serviceAidInfo.category = service.getCategoryForAid(aid); - if ((serviceAidInfo.category != null && serviceAidInfo.category.equals(CardEmulation.CATEGORY_OTHER)) && - ((service.getServiceState(CardEmulation.CATEGORY_OTHER) == NxpConstants.SERVICE_STATE_DISABLED) || - (service.getServiceState(CardEmulation.CATEGORY_OTHER) == NxpConstants.SERVICE_STATE_DISABLING))){ + if( (serviceAidInfo.category.equals(CardEmulation.CATEGORY_OTHER)) && + ((service.getServiceState(CardEmulation.CATEGORY_OTHER) == NfcConstants.SERVICE_STATE_DISABLED) || + (service.getServiceState(CardEmulation.CATEGORY_OTHER) == NfcConstants.SERVICE_STATE_DISABLING))){ /*Do not include the services which are already disabled Or services which are disabled by user recently * for the current commit to routing table*/ Log.e(TAG, "ignoring other category aid because service category is disabled"); continue; } - //NXP specific, Adding prefix (*) to all off host aid for prefix match. - if (mRoutingManager.getAidMatchingPlatform() == AidRoutingManager.AID_MATCHING_K - && !service.isOnHost() && !aid.endsWith("*")) { - aid = aid + "*"; - } - serviceAidInfo.aid = aid.toUpperCase(); - if (mAidServices.containsKey(serviceAidInfo.aid)) { final ArrayList<ServiceAidInfo> serviceAidInfos = mAidServices.get(serviceAidInfo.aid); @@ -514,11 +506,11 @@ public class RegisteredAidCache { mAidServices.put(serviceAidInfo.aid, serviceAidInfos); } } - for(NxpAidGroup group : service.getNxpAidGroups()) { - ArrayList<NxpAidGroup.ApduPattern> apduPattern = group.getApduPatternList(); + for(NfcAidGroup group : service.getNfcAidGroups()) { + ArrayList<NfcAidGroup.ApduPattern> apduPattern = group.getApduPatternList(); if(apduPattern == null || apduPattern.size() == 0x00) continue; - for(NxpAidGroup.ApduPattern apdu : apduPattern) { + for(NfcAidGroup.ApduPattern apdu : apduPattern) { ServiceApduInfo serviceApduInfo = new ServiceApduInfo(); serviceApduInfo.apdu = apdu; serviceApduInfo.service = service; @@ -556,7 +548,7 @@ public class RegisteredAidCache { } ReslovedPrefixConflictAid findPrefixConflictForSubsetAid(String subsetAid , - ArrayList<NxpApduServiceInfo> prefixServices, boolean priorityRootAid){ + ArrayList<NfcApduServiceInfo> prefixServices, boolean priorityRootAid){ ArrayList<String> prefixAids = new ArrayList<String>(); String minPrefix = null; //This functions checks whether there is a prefix AID matching to subset AID @@ -564,15 +556,16 @@ public class RegisteredAidCache { //1.Finds the prefix matching AID in the services sent. //2.Find the smallest prefix among matching prefix and add it only if it is not same as susbet AID. //3..If the subset AID and prefix AID are same add only one AID with both prefix , subset bits set. - String plainSubsetAid = subsetAid.substring(0, subsetAid.length() - 1); // Cut off "@" - for(NxpApduServiceInfo service : prefixServices) - { - for(String prefixAid : service.getPrefixAids()) - { - String plainPrefix= prefixAid.substring(0, prefixAid.length() - 1); // Cut off "@" - if(plainSubsetAid.startsWith(plainPrefix)) { - if(priorityRootAid) { - if(CardEmulation.CATEGORY_PAYMENT.equals(service.getCategoryForAid(prefixAid)) || (service.getComponent().equals(mPreferredForegroundService))) + // Cut off "#" + String plainSubsetAid = subsetAid.substring(0, subsetAid.length() - 1); + for (NfcApduServiceInfo service : prefixServices) { + for (String prefixAid : service.getPrefixAids()) { + // Cut off "#" + String plainPrefix= prefixAid.substring(0, prefixAid.length() - 1); + if( plainSubsetAid.startsWith(plainPrefix)) { + if (priorityRootAid) { + if (CardEmulation.CATEGORY_PAYMENT.equals(service.getCategoryForAid(prefixAid)) || + (service.getComponent().equals(mPreferredForegroundService))) prefixAids.add(prefixAid); } else { prefixAids.add(prefixAid); @@ -580,11 +573,12 @@ public class RegisteredAidCache { } } } - if(prefixAids.size() > 0) + if (prefixAids.size() > 0) minPrefix = Collections.min(prefixAids); ReslovedPrefixConflictAid resolvedPrefix = new ReslovedPrefixConflictAid(); resolvedPrefix.prefixAid = minPrefix; - if((minPrefix != null ) && plainSubsetAid.equalsIgnoreCase(minPrefix.substring(0, minPrefix.length() - 1))) + if ((minPrefix != null ) && + plainSubsetAid.equalsIgnoreCase(minPrefix.substring(0, minPrefix.length() - 1))) resolvedPrefix.matchingSubset = true; return resolvedPrefix; } @@ -612,8 +606,10 @@ public class RegisteredAidCache { AidConflicts findConflictsForSubsetAidLocked(String subsetAid) { AidConflicts subsetConflicts = new AidConflicts(); - String lastPlainAid = subsetAid.substring(0, subsetAid.length() - 1); // Cut off "@" - String plainSubsetAid = subsetAid.substring(0, subsetAid.length() - 1); // Cut off "@" + // Cut off "@" + String lastPlainAid = subsetAid.substring(0, subsetAid.length() - 1); + // Cut off "@" + String plainSubsetAid = subsetAid.substring(0, subsetAid.length() - 1); String firstAid = subsetAid.substring(0, 10); if (DBG) Log.d(TAG, "Finding AIDs in range [" + firstAid + " - " + lastPlainAid + "]"); @@ -622,9 +618,9 @@ public class RegisteredAidCache { mAidServices.entrySet()) { String aid = entry.getKey(); String plainAid = aid; - if(isSubset(aid) || isPrefix(aid)) + if (isSubset(aid) || isPrefix(aid)) plainAid = aid.substring(0, aid.length() - 1); - if(plainSubsetAid.startsWith(plainAid)) + if (plainSubsetAid.startsWith(plainAid)) subsetConflicts.conflictMap.put(entry.getKey(),entry.getValue()); } for (Map.Entry<String, ArrayList<ServiceAidInfo>> entry : @@ -683,9 +679,10 @@ public class RegisteredAidCache { // This prefix is the default; therefore, AIDs of all conflicting children // will no longer be evaluated. resolvedAids.addAll(prefixConflicts.aids); - for(String aid : resolveInfo.defaultService.getSubsetAids()) { - if(prefixConflicts.aids.contains(aid)) { - if((CardEmulation.CATEGORY_PAYMENT.equals(resolveInfo.defaultService.getCategoryForAid(aid))) || (resolveInfo.defaultService.getComponent().equals(mPreferredForegroundService))) { + for (String aid : resolveInfo.defaultService.getSubsetAids()) { + if (prefixConflicts.aids.contains(aid)) { + if ((CardEmulation.CATEGORY_PAYMENT.equals(resolveInfo.defaultService.getCategoryForAid(aid))) || + (resolveInfo.defaultService.getComponent().equals(mPreferredForegroundService))) { AidResolveInfo childResolveInfo = resolveAidConflictLocked(mAidServices.get(aid), false); aidCache.put(aid,childResolveInfo); Log.d(TAG, "AID " + aid+ " shared with prefix; " + @@ -743,14 +740,14 @@ public class RegisteredAidCache { } PriorityQueue<String> reversedQueue = new PriorityQueue<String>(1, Collections.reverseOrder()); reversedQueue.addAll(aidCache.keySet()); - while(!reversedQueue.isEmpty()) { + while (!reversedQueue.isEmpty()) { final ArrayList<String> resolvedAids = new ArrayList<String>(); String aidToResolve = reversedQueue.peek(); if (isPrefix(aidToResolve)) { String matchingSubset = aidToResolve.substring(0,aidToResolve.length()-1 ) + "#"; if (DBG) Log.d(TAG, "matching subset"+matchingSubset); - if(reversedQueue.contains(matchingSubset)) + if (reversedQueue.contains(matchingSubset)) aidToResolve = aidToResolve.substring(0,aidToResolve.length()-1) + "#"; } if (isSubset(aidToResolve)) { @@ -769,9 +766,11 @@ public class RegisteredAidCache { if (resolveInfo.defaultService != null) { // This subset is the default; therefore, AIDs of all conflicting children // will no longer be evaluated.Check for any prefix matching in the same service - if(resolveInfo.prefixInfo != null && resolveInfo.prefixInfo.prefixAid != null && !resolveInfo.prefixInfo.matchingSubset) { + if (resolveInfo.prefixInfo != null && resolveInfo.prefixInfo.prefixAid != null && + !resolveInfo.prefixInfo.matchingSubset) { if (DBG) - Log.d(TAG, "AID default " + resolveInfo.prefixInfo.prefixAid + " prefix AID shared with dsubset root; " + + Log.d(TAG, "AID default " + resolveInfo.prefixInfo.prefixAid + + " prefix AID shared with dsubset root; " + " adding prefix aid"); AidResolveInfo childResolveInfo = resolveAidConflictLocked( mAidServices.get(resolveInfo.prefixInfo.prefixAid), false); @@ -802,12 +801,15 @@ public class RegisteredAidCache { foundChildService |= !childResolveInfo.services.isEmpty(); } } - if(resolveInfo.prefixInfo != null && resolveInfo.prefixInfo.prefixAid != null && !resolveInfo.prefixInfo.matchingSubset) { + if(resolveInfo.prefixInfo != null && + resolveInfo.prefixInfo.prefixAid != null && + !resolveInfo.prefixInfo.matchingSubset) { AidResolveInfo childResolveInfo = resolveAidConflictLocked( mAidServices.get(resolveInfo.prefixInfo.prefixAid), false); mAidCache.put(resolveInfo.prefixInfo.prefixAid, childResolveInfo); if (DBG) - Log.d(TAG, "AID " + resolveInfo.prefixInfo.prefixAid + " prefix AID shared with subset root; " + + Log.d(TAG, "AID " + resolveInfo.prefixInfo.prefixAid + + " prefix AID shared with subset root; " + " adding prefix aid"); } // Special case: if in the end we didn't add any children services, @@ -820,8 +822,8 @@ public class RegisteredAidCache { // the children separately in next passes. } } else { - // Exact AID and no other conflicting AID registrations present - // This is true because reversedQueue is lexicographically ordered in revrese, and + // Exact AID and no other conflicting AID registrations present. This is + // true because reversedQueue is lexicographically ordered in revrese, and // so by necessity all other AIDs are different than this AID or shorter. if (DBG) Log.d(TAG, "Exact or Prefix AID."+aidToResolve); mAidCache.put(aidToResolve, aidCache.get(aidToResolve)); @@ -834,130 +836,147 @@ public class RegisteredAidCache { resolvedAids.clear(); } - updateRoutingLocked(); + updateRoutingLocked(false); } - void updateRoutingLocked() { + void updateRoutingLocked(boolean force) { if (!mNfcEnabled) { if (DBG) Log.d(TAG, "Not updating routing table because NFC is off."); return; } - final HashMap<String, AidElement> routingEntries = Maps.newHashMap(); + final HashMap<String, AidRoutingManager.AidEntry> routingEntries = Maps.newHashMap(); + int mGsmaPwrState = NfcService.getInstance().getGsmaPwrState(); // For each AID, find interested services for (Map.Entry<String, AidResolveInfo> aidEntry: mAidCache.entrySet()) { String aid = aidEntry.getKey(); - int aidInfo = 0x00; AidResolveInfo resolveInfo = aidEntry.getValue(); if (!resolveInfo.mustRoute) { if (DBG) Log.d(TAG, "Not routing AID " + aid + " on request."); continue; } - if(aid.endsWith("#")) { - aidInfo |= AID_ROUTE_QUAL_SUBSET; + AidRoutingManager.AidEntry aidType = mRoutingManager.new AidEntry(); + if (aid.endsWith("#")) { + aidType.aidInfo |= AID_ROUTE_QUAL_SUBSET; } - if(aid.endsWith("*") || (resolveInfo.prefixInfo != null && resolveInfo.prefixInfo.matchingSubset)) { - aidInfo |= AID_ROUTE_QUAL_PREFIX; + if(aid.endsWith("*") || (resolveInfo.prefixInfo != null && + resolveInfo.prefixInfo.matchingSubset)) { + aidType.aidInfo |= AID_ROUTE_QUAL_PREFIX; } if (resolveInfo.services.size() == 0) { // No interested services } else if (resolveInfo.defaultService != null) { - // There is a default service set, route to where that service resides - + // There is a default service set, route to where that service resides // either on the host (HCE) or on an SE. - NxpApduServiceInfo.ESeInfo seInfo = resolveInfo.defaultService.getSEInfo(); - boolean isDefaultPayment = resolveInfo.defaultService.getComponent().equals(mPreferredPaymentService); - boolean isForeground = resolveInfo.defaultService.getComponent().equals(mPreferredForegroundService); - boolean isOnHost = resolveInfo.defaultService.isOnHost(); - boolean isPaymentAid = resolveInfo.category.equals(CardEmulation.CATEGORY_PAYMENT); - int route; - int vzwPowerstate =0 ; - - /*get power state from the app : - N|L |F */ - int powerstate = seInfo.getPowerState() & POWER_STATE_ALL; - if(powerstate == 0) - { - powerstate |= POWER_STATE_SWITCH_ON; - if (!isOnHost) { - powerstate |= POWER_STATE_SWITCH_OFF; - } + NfcApduServiceInfo.ESeInfo seInfo = resolveInfo.defaultService.getSEInfo(); + aidType.isOnHost = resolveInfo.defaultService.isOnHost(); + if (!aidType.isOnHost) { + aidType.offHostSE = + resolveInfo.defaultService.getOffHostSecureElement(); } - int weight = AidElement.ROUTE_WIEGHT_OTHER; - - /*If non default off host payment AID ,set screen state*/ - if (!isOnHost) { - if (DBG) Log.d(TAG," set screen off enable for " + aid); - powerstate |= SCREEN_STATE_OFF_UNLOCKED | SCREEN_STATE_OFF_LOCKED; - } - Log.d(TAG," AID power state before adding screen state" + powerstate); - powerstate |= 0x10; - Log.d(TAG," AID power state after" + powerstate); - if (!isOnHost && NfcService.getInstance().isVzwFeatureEnabled()) { - String plainAid = ""; - if(aid.endsWith("*")) + int powerstate = seInfo.getPowerState() & POWER_STATE_ALL; + int screenstate= 0; + if(powerstate == 0x00) { + powerstate = POWER_STATE_SWITCH_ON; + if(mGsmaPwrState > 0) { - plainAid = aid.substring(0, aid.length()-1); - } else { - plainAid = aid; - } - if (mRoutingManager.GetVzwCache().isAidPresent(plainAid)) { - if (mRoutingManager.GetVzwCache().IsAidAllowed(plainAid)){ - /*if vzw AID reset the previous screen state */ - powerstate &= ~(SCREEN_STATE_OFF_UNLOCKED|SCREEN_STATE_OFF_LOCKED); - /*get the vzw power and screen state :- SCREEN | L |F */ - vzwPowerstate = mRoutingManager.GetVzwCache().getPowerState(plainAid); - /*merge power state with vzw power state */ - powerstate &= vzwPowerstate; - /*merge the power state with vzw screen state*/ - powerstate |= (vzwPowerstate & (SCREEN_STATE_OFF_UNLOCKED | SCREEN_STATE_OFF_LOCKED)); - Log.d(TAG," vzw aid" + aid); - Log.d(TAG," vzw merged power state" + powerstate); + if(aidType.isOnHost) + { + powerstate = (mGsmaPwrState & 0x39); + } else + { + powerstate = mGsmaPwrState; } + Log.d(TAG," Setting GSMA power state"+ aid + powerstate); } } - route = isOnHost ? 0 : seInfo.getSeId(); - Log.d(TAG," AID power state" + powerstate); - if (isForeground) { - weight += AidElement.ROUTE_WIEGHT_FOREGROUND; - } - if (isDefaultPayment && isPaymentAid) { - weight += AidElement.ROUTE_WIEGHT_PAYMENT; + + boolean isOnHost = resolveInfo.defaultService.isOnHost(); + if ((powerstate & POWER_STATE_SWITCH_ON) == POWER_STATE_SWITCH_ON ) + { + screenstate |= SCREEN_STATE_ON_LOCKED; + if (!isOnHost) { + if (DBG) Log.d(TAG," set screen off enable for " + aid); + screenstate |= SCREEN_STATE_OFF_UNLOCKED | SCREEN_STATE_OFF_LOCKED; + } + if(mGsmaPwrState == 0x00) + powerstate |= screenstate; } - AidElement aidElem = new AidElement(aid, weight, route, powerstate,aidInfo); - routingEntries.put(aid, aidElem); + + int route = isOnHost ? 0 : seInfo.getSeId(); + Log.d(TAG," AID power state"+ aid + powerstate +"route"+route); + aidType.route = route; + aidType.powerstate = powerstate; + routingEntries.put(aid, aidType); } else if (resolveInfo.services.size() == 1) { // Only one service, but not the default, must route to host // to ask the user to choose one. - AidElement aidElem = new AidElement(aid, AidElement.ROUTE_WIEGHT_OTHER, 0, mHostAIDPowerState,aidInfo); - routingEntries.put(aid, aidElem); + aidType.isOnHost = true; + aidType.powerstate = POWER_STATE_SWITCH_ON | SCREEN_STATE_ON_LOCKED; + Log.d(TAG," AID power state 2"+ aid +" "+aidType.powerstate); + if(mGsmaPwrState > 0) + { + aidType.powerstate = (mGsmaPwrState & 0x39); + Log.d(TAG," Setting GSMA power state"+ aid + " " +aidType.powerstate); + } + routingEntries.put(aid, aidType); } else if (resolveInfo.services.size() > 1) { - // Multiple services, need to route to host to ask - AidElement aidElem = new AidElement(aid, AidElement.ROUTE_WIEGHT_OTHER, 0, mHostAIDPowerState,aidInfo); - routingEntries.put(aid, aidElem); + // Multiple services if all the services are routing to same + // offhost then the service should be routed to off host. + boolean onHost = false; + String offHostSE = null; + for (NfcApduServiceInfo service : resolveInfo.services) { + // In case there is at least one service which routes to host + // Route it to host for user to select which service to use + onHost |= service.isOnHost(); + if (!onHost) { + if (offHostSE == null) { + offHostSE = service.getOffHostSecureElement(); + } else if (!offHostSE.equals( + service.getOffHostSecureElement())) { + // There are registerations to different SEs, route this + // to host and have user choose a service for this AID + offHostSE = null; + onHost = true; + break; + } + } + } + aidType.isOnHost = onHost; + aidType.offHostSE = onHost ? null : offHostSE; + aidType.powerstate = POWER_STATE_SWITCH_ON | SCREEN_STATE_ON_LOCKED; + if(mGsmaPwrState > 0) + { + aidType.powerstate = (mGsmaPwrState & 0x39); + Log.d(TAG," Setting GSMA power state"+ aid + " " +aidType.powerstate); + } + Log.d(TAG," AID power state 3"+ aid + aidType.powerstate); + routingEntries.put(aid, aidType); } } - if(mapduPatternList.size() > 0) { - addApduPatternEntries(); - } - mRoutingManager.configureRouting(routingEntries); + addApduPatternEntries(); + mRoutingManager.configureRouting(routingEntries, force); } public void addApduPatternEntries() { List<AidRoutingManager.ApduPatternResolveInfo> apduPatternRouting = new ArrayList<AidRoutingManager.ApduPatternResolveInfo>(); for(Map.Entry<String , ServiceApduInfo> entry : mapduPatternList.entrySet()) { AidRoutingManager.ApduPatternResolveInfo apduEntry = mRoutingManager.new ApduPatternResolveInfo(); - NxpApduServiceInfo service = entry.getValue().service; - NxpApduServiceInfo.ESeInfo seInfo = service.getSEInfo(); + NfcApduServiceInfo service = entry.getValue().service; + NfcApduServiceInfo.ESeInfo seInfo = service.getSEInfo(); apduEntry.referenceData = entry.getValue().apdu.getreferenceData(); apduEntry.mask = entry.getValue().apdu.getMask(); apduEntry.route = seInfo.getSeId(); apduEntry.powerState = seInfo.getPowerState() & POWER_STATE_ALL; + apduEntry.powerState |= SCREEN_STATE_ON_LOCKED | SCREEN_STATE_OFF_UNLOCKED | SCREEN_STATE_OFF_LOCKED; + apduPatternRouting.add(apduEntry); } mRoutingManager.configureApduPatternRouting(apduPatternRouting); } - public void onServicesUpdated(int userId, List<NxpApduServiceInfo> services) { + public void onServicesUpdated(int userId, List<NfcApduServiceInfo> services) { if (DBG) Log.d(TAG, "onServicesUpdated"); synchronized (mLock) { if (ActivityManager.getCurrentUser() == userId) { @@ -973,20 +992,14 @@ public class RegisteredAidCache { public void onPreferredPaymentServiceChanged(ComponentName service) { if (DBG) Log.d(TAG, "Preferred payment service changed."); synchronized (mLock) { - mPreviousPreferredPaymentService = mPreferredPaymentService; mPreferredPaymentService = service; + mPreviousPreferredPaymentService = mPreferredPaymentService; generateAidCacheLocked(); } } - - public ComponentName getPreviousPreferredPaymentService() { + public ComponentName getPreviousPreferredPaymentService() { return mPreviousPreferredPaymentService; } - - public void setPreviousPreferredPaymentService(ComponentName mPrevPaymentService) { - mPreviousPreferredPaymentService = mPrevPaymentService; - } - public void onPreferredForegroundServiceChanged(ComponentName service) { if (DBG) Log.d(TAG, "Preferred foreground service changed."); synchronized (mLock) { @@ -996,11 +1009,13 @@ public class RegisteredAidCache { } public void onRoutingTableChanged() { - if (DBG) Log.d(TAG, "onRoutingTableChanged"); - synchronized (mLock) { - generateAidCacheLocked(); - } + if (DBG) + Log.d(TAG, "onRoutingTableChanged"); + synchronized (mLock) { + generateAidCacheLocked(); + } } + public void onNfcDisabled() { synchronized (mLock) { mNfcEnabled = false; @@ -1011,24 +1026,25 @@ public class RegisteredAidCache { public void onNfcEnabled() { synchronized (mLock) { mNfcEnabled = true; - updateRoutingLocked(); + updateRoutingLocked(false); } } - public void clearRoutingTable() - { - mRoutingManager.clearNfcRoutingTableLocked(); + public void onSecureNfcToggled() { + synchronized (mLock) { + updateRoutingLocked(true); + } } String dumpEntry(Map.Entry<String, AidResolveInfo> entry) { StringBuilder sb = new StringBuilder(); String category = entry.getValue().category; - NxpApduServiceInfo defaultServiceInfo = entry.getValue().defaultService; + NfcApduServiceInfo defaultServiceInfo = entry.getValue().defaultService; sb.append(" \"" + entry.getKey() + "\" (category: " + category + ")\n"); ComponentName defaultComponent = defaultServiceInfo != null ? defaultServiceInfo.getComponent() : null; - for (NxpApduServiceInfo serviceInfo : entry.getValue().services) { + for (NfcApduServiceInfo serviceInfo : entry.getValue().services) { sb.append(" "); if (serviceInfo.getComponent().equals(defaultComponent)) { sb.append("*DEFAULT* "); diff --git a/src/com/android/nfc/cardemulation/RegisteredNfcFServicesCache.java b/src/com/android/nfc/cardemulation/RegisteredNfcFServicesCache.java index e68407a9..05d3678a 100644..100755 --- a/src/com/android/nfc/cardemulation/RegisteredNfcFServicesCache.java +++ b/src/com/android/nfc/cardemulation/RegisteredNfcFServicesCache.java @@ -56,11 +56,12 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; +import android.os.SystemProperties; public class RegisteredNfcFServicesCache { static final String XML_INDENT_OUTPUT_FEATURE = "http://xmlpull.org/v1/doc/features.html#indent-output"; static final String TAG = "RegisteredNfcFServicesCache"; - static final boolean DBG = ("1" == (System.getProperty("persist.nfc.ce_debug")) ? true : false); + static final boolean DBG = ((SystemProperties.get("persist.nfc.ce_debug").equals("1")) ? true : false); final Context mContext; final AtomicReference<BroadcastReceiver> mReceiver; diff --git a/src/com/android/nfc/cardemulation/RegisteredServicesCache.java b/src/com/android/nfc/cardemulation/RegisteredServicesCache.java index b826fccd..42ff79c7 100644..100755 --- a/src/com/android/nfc/cardemulation/RegisteredServicesCache.java +++ b/src/com/android/nfc/cardemulation/RegisteredServicesCache.java @@ -13,7 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +/****************************************************************************** +* +* The original Work has been changed by NXP. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +* Copyright 2018-2019 NXP +* +******************************************************************************/ package com.android.nfc.cardemulation; import org.xmlpull.v1.XmlPullParser; @@ -31,8 +49,8 @@ import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.net.Uri; -import android.nfc.cardemulation.NxpAidGroup; -import android.nfc.cardemulation.NxpApduServiceInfo; +import android.nfc.cardemulation.NfcAidGroup; +import android.nfc.cardemulation.NfcApduServiceInfo; import android.nfc.cardemulation.AidGroup; import android.nfc.cardemulation.CardEmulation; import android.nfc.cardemulation.HostApduService; @@ -42,7 +60,7 @@ import android.util.AtomicFile; import android.util.Log; import android.util.SparseArray; import android.util.Xml; -import com.nxp.nfc.NxpConstants; +import com.nxp.nfc.NfcConstants; import com.android.internal.util.FastXmlSerializer; import com.google.android.collect.Maps; @@ -60,8 +78,8 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; -import com.gsma.nfc.internal.RegisteredNxpServicesCache; import com.android.nfc.NfcService; +import android.os.SystemProperties; /** * This class is inspired by android.content.pm.RegisteredServicesCache @@ -74,7 +92,7 @@ public class RegisteredServicesCache { static final String XML_INDENT_OUTPUT_FEATURE = "http://xmlpull.org/v1/doc/features.html#indent-output"; static final String TAG = "RegisteredServicesCache"; static final boolean DEBUG = - ("1" == (System.getProperty("persist.nfc.ce_debug")) ? true : false); + ((SystemProperties.get("persist.nfc.ce_debug").equals("1")) ? true : false); static final String SERVICE_STATE_FILE_VERSION="1.0"; final Context mContext; @@ -86,27 +104,21 @@ public class RegisteredServicesCache { // mUserServices holds the card emulation services that are running for each user final SparseArray<UserServices> mUserServices = new SparseArray<UserServices>(); final Callback mCallback; - final AtomicFile mDynamicAidsFile; + final AtomicFile mDynamicSettingsFile; final AtomicFile mServiceStateFile; - //public ArrayList<NxpApduServiceInfo> mAllServices = new ArrayList<NxpApduServiceInfo>(); - final HashMap<ComponentName, NxpApduServiceInfo> mAllServices = Maps.newHashMap(); - /*Installed service will be used to load all the registered services available in the device - *key : UID corresponding to the service - owner of the service - *value : Hashmap of service component and corresponding state - * */ + final HashMap<ComponentName, NfcApduServiceInfo> mAllServices = Maps.newHashMap(); HashMap<String, HashMap<ComponentName, Integer>> installedServices = new HashMap<>(); - private RegisteredNxpServicesCache mRegisteredNxpServicesCache; - public interface Callback { - void onServicesUpdated(int userId, final List<NxpApduServiceInfo> services); + void onServicesUpdated(int userId, final List<NfcApduServiceInfo> services); }; - static class DynamicAids { + static class DynamicSettings { public final int uid; - public final HashMap<String, NxpAidGroup> aidGroups = Maps.newHashMap(); + public final HashMap<String, NfcAidGroup> aidGroups = Maps.newHashMap(); + public String offHostSE; - DynamicAids(int uid) { + DynamicSettings(int uid) { this.uid = uid; } }; @@ -115,10 +127,10 @@ public class RegisteredServicesCache { /** * All services that have registered */ - final HashMap<ComponentName, NxpApduServiceInfo> services = + final HashMap<ComponentName, NfcApduServiceInfo> services = Maps.newHashMap(); // Re-built at run-time - final HashMap<ComponentName, DynamicAids> dynamicAids = - Maps.newHashMap(); // In memory cache of dynamic AID store + final HashMap<ComponentName, DynamicSettings> dynamicSettings = + Maps.newHashMap(); // In memory cache of dynamic Setting store }; private UserServices findOrCreateUserLocked(int userId) { @@ -146,8 +158,6 @@ public class RegisteredServicesCache { if(Intent.ACTION_PACKAGE_REMOVED.equals(action)) { Uri uri = intent.getData(); String pkg = uri != null ? uri.getSchemeSpecificPart() : null; - mRegisteredNxpServicesCache.onPackageRemoved(pkg); //GSMA changes - mRegisteredNxpServicesCache.writeDynamicApduService(); } boolean replaced = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false) && (Intent.ACTION_PACKAGE_ADDED.equals(action) || @@ -155,10 +165,11 @@ public class RegisteredServicesCache { if (!replaced) { invalidateCache(UserHandle.getUserId(uid)); } else { - if (DEBUG) Log.d(TAG, "Ignoring package intent due to package being replaced."); + // Cache will automatically be updated on user switch + if (DEBUG) Log.d(TAG, " Not removing service here " + replaced); } } else { - // Cache will automatically be updated on user switch + if (DEBUG) Log.d(TAG, "Ignoring package intent due to package being replaced."); } } } @@ -182,27 +193,18 @@ public class RegisteredServicesCache { mContext.registerReceiverAsUser(mReceiver.get(), UserHandle.ALL, sdFilter, null, null); File dataDir = mContext.getFilesDir(); - mDynamicAidsFile = new AtomicFile(new File(dataDir, "dynamic_aids.xml")); + mDynamicSettingsFile = new AtomicFile(new File(dataDir, "dynamic_aids.xml")); mServiceStateFile = new AtomicFile(new File(dataDir, "service_state.xml")); } - void initialize(RegisteredNxpServicesCache registeredNxpServicesCache) { - mRegisteredNxpServicesCache = registeredNxpServicesCache; - synchronized (mLock) { - readDynamicAidsLocked(); - mRegisteredNxpServicesCache.readDynamicApduService(); - } - invalidateCache(ActivityManager.getCurrentUser()); - } - - void dump(ArrayList<NxpApduServiceInfo> services) { - for (NxpApduServiceInfo service : services) { + void dump(ArrayList<NfcApduServiceInfo> services) { + for (NfcApduServiceInfo service : services) { if (DEBUG) Log.d(TAG, service.toString()); } } - boolean containsServiceLocked(ArrayList<NxpApduServiceInfo> services, ComponentName serviceName) { - for (NxpApduServiceInfo service : services) { + boolean containsServiceLocked(ArrayList<NfcApduServiceInfo> services, ComponentName serviceName) { + for (NfcApduServiceInfo service : services) { if (service.getComponent().equals(serviceName)) return true; } return false; @@ -212,15 +214,15 @@ public class RegisteredServicesCache { return getService(userId, service) != null; } - public NxpApduServiceInfo getService(int userId, ComponentName service) { + public NfcApduServiceInfo getService(int userId, ComponentName service) { synchronized (mLock) { UserServices userServices = findOrCreateUserLocked(userId); return userServices.services.get(service); } } - public List<NxpApduServiceInfo> getServices(int userId) { - final ArrayList<NxpApduServiceInfo> services = new ArrayList<NxpApduServiceInfo>(); + public List<NfcApduServiceInfo> getServices(int userId) { + final ArrayList<NfcApduServiceInfo> services = new ArrayList<NfcApduServiceInfo>(); synchronized (mLock) { UserServices userServices = findOrCreateUserLocked(userId); services.addAll(userServices.services.values()); @@ -228,11 +230,11 @@ public class RegisteredServicesCache { return services; } - public List<NxpApduServiceInfo> getServicesForCategory(int userId, String category) { - final ArrayList<NxpApduServiceInfo> services = new ArrayList<NxpApduServiceInfo>(); + public List<NfcApduServiceInfo> getServicesForCategory(int userId, String category) { + final ArrayList<NfcApduServiceInfo> services = new ArrayList<NfcApduServiceInfo>(); synchronized (mLock) { UserServices userServices = findOrCreateUserLocked(userId); - for (NxpApduServiceInfo service : userServices.services.values()) { + for (NfcApduServiceInfo service : userServices.services.values()) { if (service.hasCategory(category) && (service.getAidCacheSizeForCategory(category) > 0)) services.add(service); } @@ -240,7 +242,7 @@ public class RegisteredServicesCache { return services; } - ArrayList<NxpApduServiceInfo> getInstalledServices(int userId) { + ArrayList<NfcApduServiceInfo> getInstalledServices(int userId) { PackageManager pm; try { pm = mContext.createPackageContextAsUser("android", 0, @@ -250,7 +252,7 @@ public class RegisteredServicesCache { return null; } mAllServices.clear(); - ArrayList<NxpApduServiceInfo> validServices = new ArrayList<NxpApduServiceInfo>(); + ArrayList<NfcApduServiceInfo> validServices = new ArrayList<NfcApduServiceInfo>(); List<ResolveInfo> resolvedServices = new ArrayList<>(pm.queryIntentServicesAsUser( new Intent(HostApduService.SERVICE_INTERFACE), @@ -281,7 +283,7 @@ public class RegisteredServicesCache { android.Manifest.permission.BIND_NFC_SERVICE); continue; } - NxpApduServiceInfo service = new NxpApduServiceInfo(pm, resolvedService, onHost); + NfcApduServiceInfo service = new NfcApduServiceInfo(pm, resolvedService, onHost); if (service != null) { validServices.add(service); if(!onHost) @@ -293,25 +295,19 @@ public class RegisteredServicesCache { Log.w(TAG, "Unable to load component info " + resolvedService.toString(), e); } } - AddGsmaServices(validServices); return validServices; } - public ArrayList<NxpApduServiceInfo> getAllServices() { - return new ArrayList<NxpApduServiceInfo>(mAllServices.values());//mAllServices; + public ArrayList<NfcApduServiceInfo> getAllServices() { + return new ArrayList<NfcApduServiceInfo>(mAllServices.values());//mAllServices; } - public HashMap<ComponentName, NxpApduServiceInfo> getAllStaticHashServices() { + public HashMap<ComponentName, NfcApduServiceInfo> getAllStaticHashServices() { return mAllServices; } -//Adding the GSMA Services to the Service List - private void AddGsmaServices(ArrayList<NxpApduServiceInfo> validServices){ - validServices.addAll(mRegisteredNxpServicesCache.getApduservicesList()); - } - public void invalidateCache(int userId) { - final ArrayList<NxpApduServiceInfo> validServices = getInstalledServices(userId); + final ArrayList<NfcApduServiceInfo> validServices = getInstalledServices(userId); if (validServices == null) { return; } @@ -319,47 +315,50 @@ public class RegisteredServicesCache { UserServices userServices = findOrCreateUserLocked(userId); // Find removed services - Iterator<Map.Entry<ComponentName, NxpApduServiceInfo>> it = + Iterator<Map.Entry<ComponentName, NfcApduServiceInfo>> it = userServices.services.entrySet().iterator(); while (it.hasNext()) { - Map.Entry<ComponentName, NxpApduServiceInfo> entry = - (Map.Entry<ComponentName, NxpApduServiceInfo>) it.next(); + Map.Entry<ComponentName, NfcApduServiceInfo> entry = + (Map.Entry<ComponentName, NfcApduServiceInfo>) it.next(); if (!containsServiceLocked(validServices, entry.getKey())) { Log.d(TAG, "Service removed: " + entry.getKey()); it.remove(); } } - for (NxpApduServiceInfo service : validServices) { + for (NfcApduServiceInfo service : validServices) { if (DEBUG) Log.d(TAG, "Adding service: " + service.getComponent() + " AIDs: " + service.getAids()); userServices.services.put(service.getComponent(), service); } - // Apply dynamic AID mappings + // Apply dynamic Setting mappings ArrayList<ComponentName> toBeRemoved = new ArrayList<ComponentName>(); - for (Map.Entry<ComponentName, DynamicAids> entry : - userServices.dynamicAids.entrySet()) { + for (Map.Entry<ComponentName, DynamicSettings> entry : + userServices.dynamicSettings.entrySet()) { // Verify component / uid match ComponentName component = entry.getKey(); - DynamicAids dynamicAids = entry.getValue(); - NxpApduServiceInfo serviceInfo = userServices.services.get(component); - if (serviceInfo == null || (serviceInfo.getUid() != dynamicAids.uid)) { + DynamicSettings dynamicSettings = entry.getValue(); + NfcApduServiceInfo serviceInfo = userServices.services.get(component); + if (serviceInfo == null || (serviceInfo.getUid() != dynamicSettings.uid)) { toBeRemoved.add(component); continue; } else { - for (NxpAidGroup group : dynamicAids.aidGroups.values()) { - serviceInfo.setOrReplaceDynamicNxpAidGroup(group); + for (NfcAidGroup group : dynamicSettings.aidGroups.values()) { + serviceInfo.setOrReplaceDynamicNfcAidGroup(group); + } + if (dynamicSettings.offHostSE != null) { + serviceInfo.setOffHostSecureElement(dynamicSettings.offHostSE); } } } if (toBeRemoved.size() > 0) { for (ComponentName component : toBeRemoved) { - Log.d(TAG, "Removing dynamic AIDs registered by " + component); - userServices.dynamicAids.remove(component); + Log.d(TAG, "Removing dynamic Settings registered by " + component); + userServices.dynamicSettings.remove(component); } // Persist to filesystem - writeDynamicAidsLocked(); + writeDynamicSettingsLocked(); } updateServiceStateFromFile(userId); Log.e(TAG,"1"+Thread.currentThread().getStackTrace()[2].getMethodName()+":WriteServiceStateToFile"); @@ -370,14 +369,14 @@ public class RegisteredServicesCache { dump(validServices); } - private void readDynamicAidsLocked() { + private void readDynamicSettingsLocked() { FileInputStream fis = null; try { - if (!mDynamicAidsFile.getBaseFile().exists()) { + if (!mDynamicSettingsFile.getBaseFile().exists()) { Log.d(TAG, "Dynamic AIDs file does not exist."); return; } - fis = mDynamicAidsFile.openRead(); + fis = mDynamicSettingsFile.openRead(); XmlPullParser parser = Xml.newPullParser(); parser.setInput(fis, null); int eventType = parser.getEventType(); @@ -390,19 +389,22 @@ public class RegisteredServicesCache { boolean inService = false; ComponentName currentComponent = null; int currentUid = -1; - ArrayList<NxpAidGroup> currentGroups = new ArrayList<NxpAidGroup>(); + String currentOffHostSE = null; + ArrayList<NfcAidGroup> currentGroups = new ArrayList<NfcAidGroup>(); while (eventType != XmlPullParser.END_DOCUMENT) { tagName = parser.getName(); if (eventType == XmlPullParser.START_TAG) { if ("service".equals(tagName) && parser.getDepth() == 2) { String compString = parser.getAttributeValue(null, "component"); String uidString = parser.getAttributeValue(null, "uid"); + String offHostString = parser.getAttributeValue(null, "offHostSE"); if (compString == null || uidString == null) { Log.e(TAG, "Invalid service attributes"); } else { try { currentUid = Integer.parseInt(uidString); currentComponent = ComponentName.unflattenFromString(compString); + currentOffHostSE = offHostString; inService = true; } catch (NumberFormatException e) { Log.e(TAG, "Could not parse service uid"); @@ -410,7 +412,7 @@ public class RegisteredServicesCache { } } if ("aid-group".equals(tagName) && parser.getDepth() == 3 && inService) { - NxpAidGroup group = NxpAidGroup.createFromXml(parser); + NfcAidGroup group = NfcAidGroup.createFromXml(parser); if (group != null) { currentGroups.add(group); } else { @@ -421,27 +423,29 @@ public class RegisteredServicesCache { if ("service".equals(tagName)) { // See if we have a valid service if (currentComponent != null && currentUid >= 0 && - currentGroups.size() > 0) { + (currentGroups.size() > 0 || currentOffHostSE != null)) { final int userId = UserHandle.getUserId(currentUid); - DynamicAids dynAids = new DynamicAids(currentUid); - for (NxpAidGroup group : currentGroups) { - dynAids.aidGroups.put(group.getCategory(), group); + DynamicSettings dynSettings = new DynamicSettings(currentUid); + for (NfcAidGroup group : currentGroups) { + dynSettings.aidGroups.put(group.getCategory(), group); } + dynSettings.offHostSE = currentOffHostSE; UserServices services = findOrCreateUserLocked(userId); - services.dynamicAids.put(currentComponent, dynAids); + services.dynamicSettings.put(currentComponent, dynSettings); } currentUid = -1; currentComponent = null; currentGroups.clear(); inService = false; + currentOffHostSE = null; } } eventType = parser.next(); }; } } catch (Exception e) { - Log.e(TAG, "Could not parse dynamic AIDs file, trashing."); - mDynamicAidsFile.delete(); + Log.e(TAG, "Could not parse dynamic Settings file, trashing."); + mDynamicSettingsFile.delete(); } finally { if (fis != null) { try { @@ -452,10 +456,10 @@ public class RegisteredServicesCache { } } - private boolean writeDynamicAidsLocked() { + private boolean writeDynamicSettingsLocked() { FileOutputStream fos = null; try { - fos = mDynamicAidsFile.startWrite(); + fos = mDynamicSettingsFile.startWrite(); XmlSerializer out = new FastXmlSerializer(); out.setOutput(fos, "utf-8"); out.startDocument(null, true); @@ -463,11 +467,14 @@ public class RegisteredServicesCache { out.startTag(null, "services"); for (int i = 0; i < mUserServices.size(); i++) { final UserServices user = mUserServices.valueAt(i); - for (Map.Entry<ComponentName, DynamicAids> service : user.dynamicAids.entrySet()) { + for (Map.Entry<ComponentName, DynamicSettings> service : user.dynamicSettings.entrySet()) { out.startTag(null, "service"); out.attribute(null, "component", service.getKey().flattenToString()); out.attribute(null, "uid", Integer.toString(service.getValue().uid)); - for (NxpAidGroup group : service.getValue().aidGroups.values()) { + if(service.getValue().offHostSE != null) { + out.attribute(null, "offHostSE", service.getValue().offHostSE); + } + for (NfcAidGroup group : service.getValue().aidGroups.values()) { group.writeAsXml(out); } out.endTag(null, "service"); @@ -475,12 +482,12 @@ public class RegisteredServicesCache { } out.endTag(null, "services"); out.endDocument(); - mDynamicAidsFile.finishWrite(fos); + mDynamicSettingsFile.finishWrite(fos); return true; } catch (Exception e) { - Log.e(TAG, "Error writing dynamic AIDs", e); + Log.e(TAG, "Error writing dynamic Settings", e); if (fos != null) { - mDynamicAidsFile.failWrite(fos); + mDynamicSettingsFile.failWrite(fos); } return false; } @@ -505,8 +512,8 @@ public class RegisteredServicesCache { int eventType = parser.getEventType(); int currUid = -1; ComponentName currComponent = null; - HashMap<ComponentName ,NxpApduServiceInfo> nxpOffHostServiceMap = mRegisteredNxpServicesCache.getApduservicesMaps(); - int state = NxpConstants.SERVICE_STATE_ENABLED; + //HashMap<ComponentName ,NfcApduServiceInfo> nfcOffHostServiceMap = mRegisteredNfcServicesCache.getApduservicesMaps(); + int state = NfcConstants.SERVICE_STATE_ENABLED; while (eventType != XmlPullParser.START_TAG && eventType != XmlPullParser.END_DOCUMENT) { @@ -551,12 +558,12 @@ public class RegisteredServicesCache { if(fileVersion.equals("null")){ if(stateString.equalsIgnoreCase("false")) - state = NxpConstants.SERVICE_STATE_DISABLED; + state = NfcConstants.SERVICE_STATE_DISABLED; else - state = NxpConstants.SERVICE_STATE_ENABLED; + state = NfcConstants.SERVICE_STATE_ENABLED; }else if(fileVersion.equals("1.0")){ state = Integer.parseInt(stateString); - if(state<NxpConstants.SERVICE_STATE_DISABLED || state > NxpConstants.SERVICE_STATE_DISABLING) + if(state<NfcConstants.SERVICE_STATE_DISABLED || state > NfcConstants.SERVICE_STATE_DISABLING) Log.e(TAG, "Invalid Service state"); } /*Load all the servies info into local memory from xml file and @@ -587,19 +594,15 @@ public class RegisteredServicesCache { final int userId = UserHandle.getUserId(currUid); UserServices serviceCache = findOrCreateUserLocked(userId); - NxpApduServiceInfo serviceInfo = serviceCache.services.get(currComponent); - - if(serviceInfo == null) { - // CHECK for GSMA related services also. - serviceInfo = nxpOffHostServiceMap.get(currComponent); - if(serviceInfo == null) { - Log.e(TAG, "could not find the required serviceInfo"); - } else serviceInfo.setServiceState(CardEmulation.CATEGORY_OTHER ,state); - } else serviceInfo.setServiceState(CardEmulation.CATEGORY_OTHER ,state); + NfcApduServiceInfo serviceInfo = serviceCache.services.get(currComponent); + + if(serviceInfo != null) { + serviceInfo.setServiceState(CardEmulation.CATEGORY_OTHER ,state); + } } currUid = -1; currComponent = null; - state = NxpConstants.SERVICE_STATE_ENABLED; + state = NfcConstants.SERVICE_STATE_ENABLED; } eventType = parser.next(); @@ -620,7 +623,7 @@ public class RegisteredServicesCache { private boolean writeServiceStateToFile(int currUserId) { FileOutputStream fos = null; - ArrayList<NxpApduServiceInfo> nxpOffHostServiceCache = mRegisteredNxpServicesCache.getApduservicesList(); + //ArrayList<NfcApduServiceInfo> nfcOffHostServiceCache = mRegisteredNfcServicesCache.getApduservicesList(); /*if(NfcService.getInstance().getAidRoutingTableStatus() == 0x00) { Log.e(TAG, " Aid Routing Table still availble , No need to disable services"); return false; @@ -629,7 +632,7 @@ public class RegisteredServicesCache { if(currUserId != ActivityManager.getCurrentUser()) { return false; } - int state = NxpConstants.SERVICE_STATE_ENABLED; + int state = NfcConstants.SERVICE_STATE_ENABLED; try { fos = mServiceStateFile.startWrite(); XmlSerializer out = new FastXmlSerializer(); @@ -642,7 +645,7 @@ public class RegisteredServicesCache { out.startTag(null ,"services"); for(int userId = 0; userId < mUserServices.size(); userId++) { final UserServices userServices = mUserServices.valueAt(userId); - for (NxpApduServiceInfo serviceInfo : userServices.services.values()) { + for (NfcApduServiceInfo serviceInfo : userServices.services.values()) { if(!serviceInfo.hasCategory(CardEmulation.CATEGORY_OTHER)) { continue; } @@ -671,35 +674,6 @@ public class RegisteredServicesCache { out.endTag(null, "service"); } } - dump(nxpOffHostServiceCache); - //ADD GSMA services Cache - for(NxpApduServiceInfo serviceInfo : nxpOffHostServiceCache) { - out.startTag(null ,"service"); - out.attribute(null, "component", serviceInfo.getComponent().flattenToString()); - Log.d(TAG,"component name"+ serviceInfo.getComponent().flattenToString()); - out.attribute(null, "uid", Integer.toString(serviceInfo.getUid())); - Log.d(TAG,"uid name"+ Integer.toString(serviceInfo.getUid())); - - boolean isServiceInstalled = false; - if(installedServices.containsKey(Integer.toString(serviceInfo.getUid()))){ - HashMap<ComponentName, Integer> componentStates = installedServices.get(Integer.toString(serviceInfo.getUid())); - if (componentStates.containsKey(serviceInfo.getComponent())) { - state = componentStates.get(serviceInfo.getComponent()); - componentStates.remove(serviceInfo.getComponent()); - if(componentStates.isEmpty()) - { - installedServices.remove(Integer.toString(serviceInfo.getUid())); - } - isServiceInstalled = true; - } - } - if (!isServiceInstalled) { - state = serviceInfo.getServiceState(CardEmulation.CATEGORY_OTHER); - } - out.attribute(null, "serviceState", Integer.toString(state)); - Log.d(TAG,"service State:"+ Integer.toString(state)); - out.endTag(null, "service"); - } out.endTag(null ,"services"); out.endDocument(); mServiceStateFile.finishWrite(fos); @@ -716,8 +690,8 @@ public class RegisteredServicesCache { public int updateServiceState(int userId , int uid, Map<String , Boolean> serviceState) { - boolean isWriteSuccess = false; - HashMap<ComponentName ,NxpApduServiceInfo> nxpOffHostServiceMap = mRegisteredNxpServicesCache.getApduservicesMaps(); + boolean success = false; + //HashMap<ComponentName ,NfcApduServiceInfo> nfcOffHostServiceMap = mRegisteredNfcServicesCache.getApduservicesMaps(); if(NfcService.getInstance().getAidRoutingTableStatus() == 0x00) { Log.e(TAG, " Aid Routing Table still availble , No need to disable services"); return 0xFF; @@ -729,36 +703,117 @@ public class RegisteredServicesCache { Map.Entry<String , Boolean> entry = (Map.Entry<String , Boolean>) it.next(); ComponentName componentName = ComponentName.unflattenFromString(entry.getKey()); - NxpApduServiceInfo serviceInfo = getService(userId, componentName); - Log.d(TAG, "updateServiceState " + entry.getKey()); - Log.d(TAG, "updateServiceState " + entry.getValue()); + NfcApduServiceInfo serviceInfo = getService(userId, componentName); + Log.e(TAG, "updateServiceState " + entry.getKey()); + Log.e(TAG, "updateServiceState " + entry.getValue()); if (serviceInfo != null) { serviceInfo.enableService(CardEmulation.CATEGORY_OTHER, entry.getValue()); - } else if ((serviceInfo = nxpOffHostServiceMap.get(componentName)) != null) { - // CHECK for GSMA cache - serviceInfo.enableService(CardEmulation.CATEGORY_OTHER, entry.getValue()); } else { Log.e(TAG, "Could not find service " + componentName); return 0xFF; } } Log.e(TAG,"2"+Thread.currentThread().getStackTrace()[2].getMethodName()+":WriteServiceStateToFile"); - isWriteSuccess = writeServiceStateToFile(userId); + success = writeServiceStateToFile(userId); } invalidateCache(ActivityManager.getCurrentUser()); - boolean isCommitSuccessful = NfcService.getInstance().getLastCommitRoutingStatus(); - Log.d(TAG, "WriteState:" + isWriteSuccess + "LastCommitStatus:" + isCommitSuccessful); - return ((isWriteSuccess && isCommitSuccessful)?0x00:0xFF); + return (success?0x00:0xFF); + } + + public boolean setOffHostSecureElement(int userId, int uid, ComponentName componentName, + String offHostSE) { + ArrayList<NfcApduServiceInfo> newServices = null; + synchronized (mLock) { + UserServices services = findOrCreateUserLocked(userId); + // Check if we can find this service + NfcApduServiceInfo serviceInfo = getService(userId, componentName); + if (serviceInfo == null) { + Log.e(TAG, "Service " + componentName + " does not exist."); + return false; + } + if (serviceInfo.getUid() != uid) { + // This is probably a good indication something is wrong here. + // Either newer service installed with different uid (but then + // we should have known about it), or somebody calling us from + // a different uid. + Log.e(TAG, "UID mismatch."); + return false; + } + if (offHostSE == null || serviceInfo.isOnHost()) { + Log.e(TAG, "OffHostSE mismatch with Service type"); + return false; + } + + DynamicSettings dynSettings = services.dynamicSettings.get(componentName); + if (dynSettings == null) { + dynSettings = new DynamicSettings(uid); + } + dynSettings.offHostSE = offHostSE; + boolean success = writeDynamicSettingsLocked(); + if (!success) { + Log.e(TAG, "Failed to persist AID group."); + dynSettings.offHostSE = null; + return false; + } + + serviceInfo.setOffHostSecureElement(offHostSE); + newServices = new ArrayList<NfcApduServiceInfo>(services.services.values()); + } + // Make callback without the lock held + mCallback.onServicesUpdated(userId, newServices); + return true; + } + + public boolean unsetOffHostSecureElement(int userId, int uid, ComponentName componentName) { + ArrayList<NfcApduServiceInfo> newServices = null; + synchronized (mLock) { + UserServices services = findOrCreateUserLocked(userId); + // Check if we can find this service + NfcApduServiceInfo serviceInfo = getService(userId, componentName); + if (serviceInfo == null) { + Log.e(TAG, "Service " + componentName + " does not exist."); + return false; + } + if (serviceInfo.getUid() != uid) { + // This is probably a good indication something is wrong here. + // Either newer service installed with different uid (but then + // we should have known about it), or somebody calling us from + // a different uid. + Log.e(TAG, "UID mismatch."); + return false; + } + if (serviceInfo.isOnHost() || serviceInfo.getOffHostSecureElement() == null) { + Log.e(TAG, "OffHostSE is not set"); + return false; + } + serviceInfo.unsetOffHostSecureElement(); + DynamicSettings dynSettings = services.dynamicSettings.get(componentName); + if (dynSettings != null) { + String offHostSE = dynSettings.offHostSE; + dynSettings.offHostSE = serviceInfo.getOffHostSecureElement(); + boolean success = writeDynamicSettingsLocked(); + if (!success) { + Log.e(TAG, "Failed to persist AID group."); + dynSettings.offHostSE = offHostSE; + return false; + } + } + + newServices = new ArrayList<NfcApduServiceInfo>(services.services.values()); + } + // Make callback without the lock held + mCallback.onServicesUpdated(userId, newServices); + return true; } public boolean registerAidGroupForService(int userId, int uid, - ComponentName componentName, NxpAidGroup nxpAidGroup) { - ArrayList<NxpApduServiceInfo> newServices = null; + ComponentName componentName, NfcAidGroup nfcAidGroup) { + ArrayList<NfcApduServiceInfo> newServices = null; boolean success; synchronized (mLock) { UserServices services = findOrCreateUserLocked(userId); // Check if we can find this service - NxpApduServiceInfo serviceInfo = getService(userId, componentName); + NfcApduServiceInfo serviceInfo = getService(userId, componentName); if (serviceInfo == null) { Log.e(TAG, "Service " + componentName + " does not exist."); return false; @@ -772,28 +827,29 @@ public class RegisteredServicesCache { return false; } // Do another AID validation, since a caller could have thrown in a modified - // NxpAidGroup object with invalid AIDs over Binder. - List<String> aids = nxpAidGroup.getAids(); + // NfcAidGroup object with invalid AIDs over Binder. + List<String> aids = nfcAidGroup.getAids(); for (String aid : aids) { if (!CardEmulation.isValidAid(aid)) { Log.e(TAG, "AID " + aid + " is not a valid AID"); return false; } } - serviceInfo.setOrReplaceDynamicNxpAidGroup(nxpAidGroup); - DynamicAids dynAids = services.dynamicAids.get(componentName); - if (dynAids == null) { - dynAids = new DynamicAids(uid); - services.dynamicAids.put(componentName, dynAids); + serviceInfo.setOrReplaceDynamicNfcAidGroup(nfcAidGroup); + DynamicSettings dynSettings = services.dynamicSettings.get(componentName); + if (dynSettings == null) { + dynSettings = new DynamicSettings(uid); + dynSettings.offHostSE = serviceInfo.getOffHostSecureElement(); + services.dynamicSettings.put(componentName, dynSettings); } - dynAids.aidGroups.put(nxpAidGroup.getCategory(), nxpAidGroup); - success = writeDynamicAidsLocked(); + dynSettings.aidGroups.put(nfcAidGroup.getCategory(), nfcAidGroup); + success = writeDynamicSettingsLocked(); if (success) { - newServices = new ArrayList<NxpApduServiceInfo>(services.services.values()); + newServices = new ArrayList<NfcApduServiceInfo>(services.services.values()); } else { Log.e(TAG, "Failed to persist AID group."); // Undo registration - dynAids.aidGroups.remove(nxpAidGroup.getCategory()); + dynSettings.aidGroups.remove(nfcAidGroup.getCategory()); } } if (success) { @@ -803,15 +859,15 @@ public class RegisteredServicesCache { return success; } - public NxpAidGroup getAidGroupForService(int userId, int uid, ComponentName componentName, + public NfcAidGroup getAidGroupForService(int userId, int uid, ComponentName componentName, String category) { - NxpApduServiceInfo serviceInfo = getService(userId, componentName); + NfcApduServiceInfo serviceInfo = getService(userId, componentName); if (serviceInfo != null) { if (serviceInfo.getUid() != uid) { Log.e(TAG, "UID mismatch"); return null; } - return serviceInfo.getDynamicNxpAidGroupForCategory(category); + return serviceInfo.getDynamicNfcAidGroupForCategory(category); } else { Log.e(TAG, "Could not find service " + componentName); return null; @@ -821,28 +877,27 @@ public class RegisteredServicesCache { public boolean removeAidGroupForService(int userId, int uid, ComponentName componentName, String category) { boolean success = false; - NxpApduServiceInfo serviceInfo = null; - ArrayList<NxpApduServiceInfo> newServices = null; + ArrayList<NfcApduServiceInfo> newServices = null; synchronized (mLock) { UserServices services = findOrCreateUserLocked(userId); - serviceInfo = getService(userId, componentName); + NfcApduServiceInfo serviceInfo = getService(userId, componentName); if (serviceInfo != null) { if (serviceInfo.getUid() != uid) { // Calling from different uid Log.e(TAG, "UID mismatch"); return false; } - if (!serviceInfo.removeDynamicNxpAidGroupForCategory(category)) { + if (!serviceInfo.removeDynamicNfcAidGroupForCategory(category)) { Log.e(TAG," Could not find dynamic AIDs for category " + category); return false; } // Remove from local cache - DynamicAids dynAids = services.dynamicAids.get(componentName); + DynamicSettings dynAids = services.dynamicSettings.get(componentName); if (dynAids != null) { - NxpAidGroup deletedGroup = dynAids.aidGroups.remove(category); - success = writeDynamicAidsLocked(); + NfcAidGroup deletedGroup = dynAids.aidGroups.remove(category); + success = writeDynamicSettingsLocked(); if (success) { - newServices = new ArrayList<NxpApduServiceInfo>(services.services.values()); + newServices = new ArrayList<NfcApduServiceInfo>(services.services.values()); } else { Log.e(TAG, "Could not persist deleted AID group."); dynAids.aidGroups.put(category, deletedGroup); @@ -858,16 +913,20 @@ public class RegisteredServicesCache { if (success) { mCallback.onServicesUpdated(userId, newServices); } - if ((serviceInfo != null) && (category.equals(CardEmulation.CATEGORY_OTHER))) { - int status = serviceInfo.setServiceState(category, NxpConstants.SERVICE_STATE_ENABLING); - } return success; } + void initialize() { + synchronized (mLock) { + readDynamicSettingsLocked(); + } + invalidateCache(ActivityManager.getCurrentUser()); + } + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("Registered HCE services for current user: "); UserServices userServices = findOrCreateUserLocked(ActivityManager.getCurrentUser()); - for (NxpApduServiceInfo service : userServices.services.values()) { + for (NfcApduServiceInfo service : userServices.services.values()) { service.dump(fd, pw, args); pw.println(""); } @@ -875,14 +934,20 @@ public class RegisteredServicesCache { } public void updateStatusOfServices(boolean commitStatus) { - final UserServices userServices = mUserServices.get(ActivityManager.getCurrentUser()); - for (NxpApduServiceInfo serviceInfo : userServices.services.values()) { - if(!serviceInfo.hasCategory(CardEmulation.CATEGORY_OTHER)) { - continue; - } - serviceInfo.updateServiceCommitStatus(CardEmulation.CATEGORY_OTHER,commitStatus); - } - Log.e(TAG,"3"+Thread.currentThread().getStackTrace()[2].getMethodName()+":WriteServiceStateToFile"); - writeServiceStateToFile(ActivityManager.getCurrentUser()); + final UserServices userServices = mUserServices.get(ActivityManager.getCurrentUser()); + if (userServices != null && userServices.services != null) { + for (NfcApduServiceInfo serviceInfo : userServices.services.values()) { + if (!serviceInfo.hasCategory(CardEmulation.CATEGORY_OTHER)) { + continue; + } + serviceInfo.updateServiceCommitStatus(CardEmulation.CATEGORY_OTHER, commitStatus); + } + Log.e(TAG, + "3" + Thread.currentThread().getStackTrace()[2].getMethodName() + + ":WriteServiceStateToFile"); + writeServiceStateToFile(ActivityManager.getCurrentUser()); + } else { + Log.e(TAG, "updateStatusOfServices failed... "); + } } } diff --git a/src/com/android/nfc/cardemulation/RegisteredT3tIdentifiersCache.java b/src/com/android/nfc/cardemulation/RegisteredT3tIdentifiersCache.java index 8053023a..70481f83 100644..100755 --- a/src/com/android/nfc/cardemulation/RegisteredT3tIdentifiersCache.java +++ b/src/com/android/nfc/cardemulation/RegisteredT3tIdentifiersCache.java @@ -29,11 +29,12 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.HashMap; +import android.os.SystemProperties; public class RegisteredT3tIdentifiersCache { static final String TAG = "RegisteredT3tIdentifiersCache"; - static final boolean DBG = ("1" == (System.getProperty("persist.nfc.ce_debug")) ? true : false); + static final boolean DBG = ((SystemProperties.get("persist.nfc.ce_debug").equals("1")) ? true : false); // All NFC-F services that have registered List<NfcFServiceInfo> mServices = new ArrayList<NfcFServiceInfo>(); @@ -47,6 +48,7 @@ public class RegisteredT3tIdentifiersCache { public final String systemCode; public final String nfcid2; public final String t3tPmm; + T3tIdentifier(String systemCode, String nfcid2, String t3tPmm) { this.systemCode = systemCode; this.nfcid2 = nfcid2; @@ -122,21 +124,21 @@ public class RegisteredT3tIdentifiersCache { } } - updateRoutingLocked(); - } - - void clearT3tidentifiercache() - { - mRoutingManager.onNfccRoutingTableCleared(); + updateRoutingLocked(false); } - void updateRoutingLocked() { + void updateRoutingLocked(boolean force) { if (DBG) Log.d(TAG, "updateRoutingLocked"); if (!mNfcEnabled) { Log.d(TAG, "Not updating routing table because NFC is off."); return; } List<T3tIdentifier> t3tIdentifiers = new ArrayList<T3tIdentifier>(); + + // Sending an empty table will de-register all entries + if (force) { + mRoutingManager.configureRouting(t3tIdentifiers); + } Iterator<Map.Entry<String, NfcFServiceInfo>> it; // Register foreground service it = mForegroundT3tIdentifiersCache.entrySet().iterator(); @@ -149,6 +151,12 @@ public class RegisteredT3tIdentifiersCache { mRoutingManager.configureRouting(t3tIdentifiers); } + public void onSecureNfcToggled() { + synchronized(mLock) { + updateRoutingLocked(true); + } + } + public void onServicesUpdated(int userId, List<NfcFServiceInfo> services) { if (DBG) Log.d(TAG, "onServicesUpdated"); synchronized (mLock) { @@ -197,7 +205,7 @@ public class RegisteredT3tIdentifiersCache { public void onUserSwitched() { synchronized (mLock) { mForegroundT3tIdentifiersCache.clear(); - updateRoutingLocked(); + updateRoutingLocked(false); mEnabledForegroundService = null; } } diff --git a/src/com/android/nfc/cardemulation/SystemCodeRoutingManager.java b/src/com/android/nfc/cardemulation/SystemCodeRoutingManager.java index 6558b22b..337518ec 100644..100755 --- a/src/com/android/nfc/cardemulation/SystemCodeRoutingManager.java +++ b/src/com/android/nfc/cardemulation/SystemCodeRoutingManager.java @@ -25,11 +25,12 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import android.os.SystemProperties; public class SystemCodeRoutingManager { static final String TAG = "SystemCodeRoutingManager"; - static final boolean DBG = ("1" == (System.getProperty("persist.nfc.ce_debug")) ? true : false); + static final boolean DBG = ((SystemProperties.get("persist.nfc.ce_debug").equals("1")) ? true : false); final Object mLock = new Object(); @@ -79,8 +80,6 @@ public class SystemCodeRoutingManager { Log.d(TAG, " " + t3tIdentifier.systemCode + "/" + t3tIdentifier.nfcid2 + "/" + t3tIdentifier.t3tPmm); - - Log.d(TAG, " " + t3tIdentifier.systemCode + "/"); } } mConfiguredT3tIdentifiers = t3tIdentifiers; diff --git a/src/com/android/nfc/cardemulation/TapAgainDialog.java b/src/com/android/nfc/cardemulation/TapAgainDialog.java index cbb3932c..7515d54e 100644..100755 --- a/src/com/android/nfc/cardemulation/TapAgainDialog.java +++ b/src/com/android/nfc/cardemulation/TapAgainDialog.java @@ -113,4 +113,4 @@ public class TapAgainDialog extends AlertActivity implements DialogInterface.OnC public void onClick(DialogInterface dialog, int which) { finish(); } -} +}
\ No newline at end of file diff --git a/src/com/android/nfc/cardemulation/VzwRoutingCache.java b/src/com/android/nfc/cardemulation/VzwRoutingCache.java deleted file mode 100644 index 203eb3b3..00000000 --- a/src/com/android/nfc/cardemulation/VzwRoutingCache.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2015 NXP Semiconductors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.nfc.cardemulation; - -import android.util.Log; - -import java.util.Collections; -import java.util.Hashtable; -import java.util.List; -import java.util.Iterator; -import com.android.nfc.NfcService; -import java.util.Set; -import java.util.HashSet; -import java.util.Map; -import com.vzw.nfc.RouteEntry; -import java.util.HashMap; - -public class VzwRoutingCache { - private static final boolean DBG = - ("1" == (System.getProperty("persist.nfc.ce_debug")) ? true : false); - private static final String TAG = "VzwRoutingCache"; - - // Cached routing table - // final private static Hashtable<String, RouteEntry> mVzwCache = new - // Hashtable<String, RouteEntry>(CAPACITY); - final HashMap<String, RouteEntry> mVzwCache = new HashMap<String, RouteEntry>(); - - VzwRoutingCache() {} - - boolean addAid(byte[] aid, int route, int power, boolean isAllowed) { - RouteEntry elem = new RouteEntry(aid, power, route, isAllowed); - Log.d(TAG, "aid" + toHexString(elem.getAid(), 0, elem.getAid().length).toUpperCase()); - Log.d(TAG, "power " + power); - Log.d(TAG, "power state" + elem.getPowerState()); - Log.d(TAG, "is allowed" + elem.isAllowed()); - mVzwCache.put(toHexString(elem.getAid(), 0, elem.getAid().length).toUpperCase(), elem); - return true; - } - - boolean IsAidAllowed(String aid) { - RouteEntry elem = (RouteEntry) mVzwCache.get(aid); - return elem.isAllowed(); - } - - static String toHexString(byte[] buffer, int offset, int length) { - final char[] HEX_CHARS = "0123456789abcdef".toCharArray(); - char[] chars = new char[2 * length]; - for (int j = offset; j < offset + length; ++j) { - chars[2 * (j - offset)] = HEX_CHARS[(buffer[j] & 0xF0) >>> 4]; - chars[2 * (j - offset) + 1] = HEX_CHARS[buffer[j] & 0x0F]; - } - return new String(chars); - } - - int getPowerState(String aid) { - RouteEntry elem = (RouteEntry) mVzwCache.get(aid); - return elem.getPowerState(); - - } - - boolean isAidPresent(String aid) { - return (mVzwCache.containsKey(aid)); - } - - void clear() { - mVzwCache.clear(); - } -} diff --git a/src/com/android/nfc/handover/BluetoothPeripheralHandover.java b/src/com/android/nfc/handover/BluetoothPeripheralHandover.java index ee718be6..16456565 100644..100755 --- a/src/com/android/nfc/handover/BluetoothPeripheralHandover.java +++ b/src/com/android/nfc/handover/BluetoothPeripheralHandover.java @@ -334,6 +334,7 @@ public class BluetoothPeripheralHandover implements BluetoothProfile.ServiceList void nextStepConnect() { switch (mState) { case STATE_INIT_COMPLETE: + if (mDevice.getBondState() != BluetoothDevice.BOND_BONDED) { requestPairConfirmation(); mState = STATE_WAITING_FOR_BOND_CONFIRMATION; diff --git a/src/com/android/nfc/handover/ConfirmConnectActivity.java b/src/com/android/nfc/handover/ConfirmConnectActivity.java index 75310e17..75310e17 100644..100755 --- a/src/com/android/nfc/handover/ConfirmConnectActivity.java +++ b/src/com/android/nfc/handover/ConfirmConnectActivity.java diff --git a/src/com/android/nfc/handover/HandoverDataParser.java b/src/com/android/nfc/handover/HandoverDataParser.java index 5e90c90a..09bad095 100644..100755 --- a/src/com/android/nfc/handover/HandoverDataParser.java +++ b/src/com/android/nfc/handover/HandoverDataParser.java @@ -20,6 +20,7 @@ import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.nio.charset.Charset; import java.util.Arrays; import java.util.Random; @@ -49,7 +50,9 @@ public class HandoverDataParser { .getBytes(StandardCharsets.US_ASCII); private static final byte[] TYPE_BLE_OOB = "application/vnd.bluetooth.le.oob" .getBytes(StandardCharsets.US_ASCII); + private static final byte[] TYPE_NOKIA = "nokia.com:bt".getBytes(StandardCharsets.US_ASCII); + private static final byte[] RTD_COLLISION_RESOLUTION = {0x63, 0x72}; // "cr"; private static final int CARRIER_POWER_STATE_INACTIVE = 0; @@ -132,7 +135,7 @@ public class HandoverDataParser { NdefRecord createBluetoothOobDataRecord() { byte[] payload = new byte[8]; - // Note: this field should be little-endian per the BTSSP spec + // Note: this field should be little-endian per the BTSSP spec // The Android 4.1 implementation used big-endian order here. // No single Android implementation has ever interpreted this // length field when parsing this record though. @@ -169,9 +172,9 @@ public class HandoverDataParser { createBluetoothOobDataRecord() }; return new NdefMessage( - createHandoverRequestRecord(), + createHandoverRequestRecord(), dataRecords); - } + } NdefMessage createBluetoothHandoverSelectMessage(boolean activating) { return new NdefMessage(createHandoverSelectRecord( @@ -327,9 +330,9 @@ public class HandoverDataParser { if (oob.getTnf() == NdefRecord.TNF_MIME_MEDIA && Arrays.equals(oob.getType(), TYPE_BLE_OOB)) { - return parseBleOob(ByteBuffer.wrap(oob.getPayload())); + return parseBleOob(ByteBuffer.wrap(oob.getPayload())); } - } + } return null; } @@ -349,7 +352,7 @@ public class HandoverDataParser { return parseBleOob(ByteBuffer.wrap(r.getPayload())); } - // Check for Handover Select, followed by a BT OOB record + // Check for Handover Select, followed by a BT OOB record if (tnf == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(type, NdefRecord.RTD_HANDOVER_SELECT)) { return parseBluetoothHandoverSelect(m); @@ -384,7 +387,7 @@ public class HandoverDataParser { Log.i(TAG, "nokia: payload shorter than expected"); } if (result.valid && result.name == null) result.name = ""; - return result; + return result; } BluetoothHandoverData parseBtOob(ByteBuffer payload) { @@ -395,7 +398,7 @@ public class HandoverDataParser { payload.position(2); // length byte[] address = parseMacFromBluetoothRecord(payload); result.device = mBluetoothAdapter.getRemoteDevice(address); - result.valid = true; + result.valid = true; while (payload.remaining() > 0) { boolean success = false; @@ -462,7 +465,7 @@ public class HandoverDataParser { while (payload.remaining() > 0) { int len = payload.get(); int type = payload.get(); - switch (type) { + switch (type) { case BT_HANDOVER_TYPE_MAC: // mac address int startpos = payload.position(); @@ -486,20 +489,19 @@ public class HandoverDataParser { return result; } break; - case BT_HANDOVER_TYPE_LONG_LOCAL_NAME: + case BT_HANDOVER_TYPE_LONG_LOCAL_NAME: byte[] nameBytes = new byte[len - 1]; payload.get(nameBytes); result.name = new String(nameBytes, StandardCharsets.UTF_8); break; - case BT_HANDOVER_TYPE_SECURITY_MANAGER_TK: + case BT_HANDOVER_TYPE_SECURITY_MANAGER_TK: if (len-1 != SECURITY_MANAGER_TK_SIZE) { - Log.i(TAG, "BT OOB: invalid size of SM TK, should be " + + Log.i(TAG, "BT OOB: invalid size of SM TK, should be " + SECURITY_MANAGER_TK_SIZE + " bytes."); break; } byte[] securityManagerTK = new byte[len - 1]; - //TK in AD is in reverse order payload.get(securityManagerTK); if (result.oobData == null) @@ -507,35 +509,36 @@ public class HandoverDataParser { result.oobData.setSecurityManagerTk(securityManagerTK); break; - case BT_HANDOVER_TYPE_LE_SC_CONFIRMATION: - if (len - 1 != SECURITY_MANAGER_LE_SC_C_SIZE) { - Log.i(TAG, "BT OOB: invalid size of LE SC Confirmation, should be " + - SECURITY_MANAGER_LE_SC_C_SIZE + " bytes."); - break; - } - - byte[] leScC = new byte[len - 1]; - payload.get(leScC); - - if (result.oobData == null) - result.oobData = new OobData(); - result.oobData.setLeSecureConnectionsConfirmation(leScC); - break; - - case BT_HANDOVER_TYPE_LE_SC_RANDOM: - if (len-1 != SECURITY_MANAGER_LE_SC_R_SIZE) { - Log.i(TAG, "BT OOB: invalid size of LE SC Random, should be " + - SECURITY_MANAGER_LE_SC_R_SIZE + " bytes."); - break; - } - - byte[] leScR = new byte[len - 1]; - payload.get(leScR); - - if (result.oobData == null) - result.oobData = new OobData(); - result.oobData.setLeSecureConnectionsRandom(leScR); - break; + case BT_HANDOVER_TYPE_LE_SC_CONFIRMATION: + if (len - 1 != SECURITY_MANAGER_LE_SC_C_SIZE) { + Log.i(TAG, "BT OOB: invalid size of LE SC Confirmation, should be " + + SECURITY_MANAGER_LE_SC_C_SIZE + " bytes."); + break; + } + + byte[] leScC = new byte[len - 1]; + payload.get(leScC); + + if (result.oobData == null) + result.oobData = new OobData(); + result.oobData.setLeSecureConnectionsConfirmation(leScC); + break; + + case BT_HANDOVER_TYPE_LE_SC_RANDOM: + if (len-1 != SECURITY_MANAGER_LE_SC_R_SIZE) { + Log.i(TAG, "BT OOB: invalid size of LE SC Random, should be " + + SECURITY_MANAGER_LE_SC_R_SIZE + " bytes."); + break; + } + + byte[] leScR = new byte[len - 1]; + payload.get(leScR); + + if (result.oobData == null) + result.oobData = new OobData(); + result.oobData.setLeSecureConnectionsRandom(leScR); + break; + default: payload.position(payload.position() + len - 1); break; @@ -548,7 +551,7 @@ public class HandoverDataParser { } if (result.valid && result.name == null) result.name = ""; return result; - } + } private byte[] parseMacFromBluetoothRecord(ByteBuffer payload) { byte[] address = new byte[6]; @@ -556,14 +559,14 @@ public class HandoverDataParser { // ByteBuffer.order(LITTLE_ENDIAN) doesn't work for // ByteBuffer.get(byte[]), so manually swap order for (int i = 0; i < 3; i++) { - byte temp = address[i]; + byte temp = address[i]; address[i] = address[5 - i]; address[5 - i] = temp; } return address; } - static byte[] addressToReverseBytes(String address) { + static byte[] addressToReverseBytes(String address) { if (address == null) { Log.w(TAG, "BT address is null"); return null; @@ -576,56 +579,56 @@ public class HandoverDataParser { byte[] result = new byte[split.length]; for (int i = 0; i < split.length; i++) { - // need to parse as int because parseByte() expects a signed byte + // need to parse as int because parseByte() expects a signed byte result[split.length - 1 - i] = (byte)Integer.parseInt(split[i], 16); } return result; } - private ParcelUuid[] parseUuidFromBluetoothRecord(ByteBuffer payload, int type, int len) { - int uuidSize; - switch (type) { - case BT_HANDOVER_TYPE_16_BIT_UUIDS_PARTIAL: - case BT_HANDOVER_TYPE_16_BIT_UUIDS_COMPLETE: - uuidSize = BluetoothUuid.UUID_BYTES_16_BIT; - break; - case BT_HANDOVER_TYPE_32_BIT_UUIDS_PARTIAL: - case BT_HANDOVER_TYPE_32_BIT_UUIDS_COMPLETE: - uuidSize = BluetoothUuid.UUID_BYTES_32_BIT; - break; - case BT_HANDOVER_TYPE_128_BIT_UUIDS_PARTIAL: - case BT_HANDOVER_TYPE_128_BIT_UUIDS_COMPLETE: - uuidSize = BluetoothUuid.UUID_BYTES_128_BIT; - break; - default: - Log.i(TAG, "BT OOB: invalid size of UUID"); - return null; - } - - if (len == 0 || len % uuidSize != 0) { - Log.i(TAG, "BT OOB: invalid size of UUIDs, should be multiples of UUID bytes length"); - return null; - } - - int num = len / uuidSize; - ParcelUuid[] uuids = new ParcelUuid[num]; - byte[] data = new byte[uuidSize]; - for (int i = 0; i < num; i++) { - payload.get(data); - uuids[i] = BluetoothUuid.parseUuidFrom(data); - } - return uuids; - } - - private BluetoothClass parseBluetoothClassFromBluetoothRecord(ByteBuffer payload) { - byte[] btClass = new byte[CLASS_OF_DEVICE_SIZE]; - payload.get(btClass); - - ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES); - buffer.put(btClass); - buffer.order(ByteOrder.LITTLE_ENDIAN); - - return new BluetoothClass(buffer.getInt(0)); - } + private ParcelUuid[] parseUuidFromBluetoothRecord(ByteBuffer payload, int type, int len) { + int uuidSize; + switch (type) { + case BT_HANDOVER_TYPE_16_BIT_UUIDS_PARTIAL: + case BT_HANDOVER_TYPE_16_BIT_UUIDS_COMPLETE: + uuidSize = BluetoothUuid.UUID_BYTES_16_BIT; + break; + case BT_HANDOVER_TYPE_32_BIT_UUIDS_PARTIAL: + case BT_HANDOVER_TYPE_32_BIT_UUIDS_COMPLETE: + uuidSize = BluetoothUuid.UUID_BYTES_32_BIT; + break; + case BT_HANDOVER_TYPE_128_BIT_UUIDS_PARTIAL: + case BT_HANDOVER_TYPE_128_BIT_UUIDS_COMPLETE: + uuidSize = BluetoothUuid.UUID_BYTES_128_BIT; + break; + default: + Log.i(TAG, "BT OOB: invalid size of UUID"); + return null; + } + + if (len == 0 || len % uuidSize != 0) { + Log.i(TAG, "BT OOB: invalid size of UUIDs, should be multiples of UUID bytes length"); + return null; + } + + int num = len / uuidSize; + ParcelUuid[] uuids = new ParcelUuid[num]; + byte[] data = new byte[uuidSize]; + for (int i = 0; i < num; i++) { + payload.get(data); + uuids[i] = BluetoothUuid.parseUuidFrom(data); + } + return uuids; + } + + private BluetoothClass parseBluetoothClassFromBluetoothRecord(ByteBuffer payload) { + byte[] btClass = new byte[CLASS_OF_DEVICE_SIZE]; + payload.get(btClass); + + ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES); + buffer.put(btClass); + buffer.order(ByteOrder.LITTLE_ENDIAN); + + return new BluetoothClass(buffer.getInt(0)); + } } diff --git a/src/com/android/nfc/handover/HandoverServer.java b/src/com/android/nfc/handover/HandoverServer.java index 4a731622..4a731622 100644..100755 --- a/src/com/android/nfc/handover/HandoverServer.java +++ b/src/com/android/nfc/handover/HandoverServer.java diff --git a/src/com/android/nfc/handover/PeripheralHandoverService.java b/src/com/android/nfc/handover/PeripheralHandoverService.java index 48926329..e2687cf8 100644..100755 --- a/src/com/android/nfc/handover/PeripheralHandoverService.java +++ b/src/com/android/nfc/handover/PeripheralHandoverService.java @@ -96,7 +96,7 @@ public class PeripheralHandoverService extends Service implements BluetoothPerip handleBluetoothStateChanged(intent); } } - }; + }; public PeripheralHandoverService() { mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -109,6 +109,7 @@ public class PeripheralHandoverService extends Service implements BluetoothPerip @Override public int onStartCommand(Intent intent, int flags, int startId) { + synchronized (sLock) { if (mStartId != 0) { mStartId = startId; @@ -265,11 +266,6 @@ public class PeripheralHandoverService extends Service implements BluetoothPerip } } - @Override - public IBinder onBind(Intent intent) { - return null; - } - boolean hasConnectedBluetoothDevices() { Set<BluetoothDevice> bondedDevices = mBluetoothAdapter.getBondedDevices(); @@ -305,6 +301,11 @@ public class PeripheralHandoverService extends Service implements BluetoothPerip } @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override public boolean onUnbind(Intent intent) { // prevent any future callbacks to the client, no rebind call needed. return false; diff --git a/src/com/android/nfc/snep/SnepMessenger.java b/src/com/android/nfc/snep/SnepMessenger.java index 0ee507cb..5969d69e 100755 --- a/src/com/android/nfc/snep/SnepMessenger.java +++ b/src/com/android/nfc/snep/SnepMessenger.java @@ -14,6 +14,25 @@ * limitations under the License. */ +/****************************************************************************** +* +* The original Work has been changed by NXP. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +* Copyright 2018 NXP +* +******************************************************************************/ package com.android.nfc.snep; import com.android.nfc.DeviceHost.LlcpSocket; @@ -32,7 +51,7 @@ import java.util.Arrays; public class SnepMessenger { private static final String TAG = "SnepMessenger"; - private static final boolean DBG = false; + private static final boolean DBG = true; private static final int HEADER_LENGTH = 6; final LlcpSocket mSocket; final int mFragmentLength; diff --git a/src/com/android/nfc/snep/SnepServer.java b/src/com/android/nfc/snep/SnepServer.java index 33b64063..33b64063 100644..100755 --- a/src/com/android/nfc/snep/SnepServer.java +++ b/src/com/android/nfc/snep/SnepServer.java diff --git a/src/com/android/nfc/sneptest/DtaSnepClient.java b/src/com/android/nfc/sneptest/DtaSnepClient.java index be6211bd..6087b6e7 100644..100755 --- a/src/com/android/nfc/sneptest/DtaSnepClient.java +++ b/src/com/android/nfc/sneptest/DtaSnepClient.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2018 NXP Semiconductors + * Copyright (C) 2017 NXP Semiconductors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/com/android/nfc/sneptest/ExtDtaSnepServer.java b/src/com/android/nfc/sneptest/ExtDtaSnepServer.java index 350b8be4..a90cc7be 100644..100755 --- a/src/com/android/nfc/sneptest/ExtDtaSnepServer.java +++ b/src/com/android/nfc/sneptest/ExtDtaSnepServer.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2018 NXP Semiconductors + * Copyright (C) 2017 NXP Semiconductors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. |