Add HIDE_NON_SYSTEM_OVERLAY_WINDOWS permission to Nfc am: 9c56b01c57 am: 7ca7643394 am: f23a3ab230 am: 20eecd2075
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Nfc/+/15015608
Change-Id: I4fd9c992377f01aef4e68814bb7f1bd8116af86e
diff --git a/Android.bp b/Android.bp
index b1f9e86..8c68554 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,14 +1,23 @@
+genrule {
+ name: "statslog-Nfc-java-gen",
+ tools: ["stats-log-api-gen"],
+ cmd: "$(location stats-log-api-gen) --java $(out) --module nfc --javaPackage com.android.nfc"
+ + " --javaClass NfcStatsLog",
+ out: ["com/android/nfc/NfcStatsLog.java"],
+}
+
// NCI Configuration
android_app {
name: "NfcNci",
srcs: [
"src/**/*.java",
"nci/**/*.java",
+ ":statslog-Nfc-java-gen",
],
platform_apis: true,
certificate: "platform",
jni_libs: ["libnfc_nci_jni"],
- static_libs: ["androidx.legacy_legacy-support-v4"],
+ static_libs: ["androidx.appcompat_appcompat"],
optimize: {
enabled: false,
},
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 2e2e426..fba2509 100755
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -22,7 +22,6 @@
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
<uses-permission android:name="android.permission.NFC" />
- <uses-permission android:name="android.permission.NFC_UNLOCK" />
<uses-permission android:name="android.permission.BIND_NFC_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.STATUS_BAR" />
@@ -45,10 +44,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MANAGE_USERS" />
<uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
- <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.SET_ACTIVITY_WATCHER" />
- <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
<uses-permission android:name="android.permission.NFC_HANDOVER_STATUS" />
<uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS" />
<uses-permission android:name="com.android.permission.WHITELIST_BLUETOOTH_DEVICE" />
@@ -61,6 +57,8 @@
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND" />
<uses-permission android:name="android.permission.NETWORK_SETTINGS" />
+ <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
<application android:name=".NfcApplication"
android:icon="@drawable/icon"
@@ -118,15 +116,6 @@
android:noHistory="true"
android:configChanges="orientation|keyboardHidden|screenSize"
/>
-
- <activity android:name=".NfcBlockedNotification"
- android:finishOnCloseSystemDialogs="true"
- android:excludeFromRecents="true"
- android:theme="@android:style/Theme.Translucent.NoTitleBar"
- android:noHistory="true"
- android:configChanges="orientation|keyboardHidden|screenSize"
- />
-
<activity android:name=".BeamShareActivity"
android:finishOnCloseSystemDialogs="true"
android:theme="@android:style/Theme.Translucent"
diff --git a/OWNERS b/OWNERS
index 0aa310b..45e7662 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,4 +1,4 @@
zachoverflow@google.com
-rmojumder@google.com
jackcwyu@google.com
georgekgchang@google.com
+alisher@google.com
diff --git a/nci/jni/Android.bp b/nci/jni/Android.bp
index cfbc8a6..65d065d 100644
--- a/nci/jni/Android.bp
+++ b/nci/jni/Android.bp
@@ -45,4 +45,8 @@
cflags: ["-DDCHECK_ALWAYS_ON"],
},
},
+ sanitize: {
+ integer_overflow: true,
+ misc_undefined: ["bounds"],
+ },
}
diff --git a/nci/jni/IntervalTimer.cpp b/nci/jni/IntervalTimer.cpp
index 47bbc52..c361417 100644
--- a/nci/jni/IntervalTimer.cpp
+++ b/nci/jni/IntervalTimer.cpp
@@ -76,6 +76,7 @@
se.sigev_value.sival_ptr = &mTimerId;
se.sigev_notify_function = cb;
se.sigev_notify_attributes = NULL;
+ se.sigev_signo = 0;
mCb = cb;
stat = timer_create(CLOCK_MONOTONIC, &se, &mTimerId);
if (stat == -1) LOG(ERROR) << StringPrintf("fail create timer");
diff --git a/nci/jni/NativeNfcManager.cpp b/nci/jni/NativeNfcManager.cpp
index 65f006f..5048262 100644
--- a/nci/jni/NativeNfcManager.cpp
+++ b/nci/jni/NativeNfcManager.cpp
@@ -64,6 +64,7 @@
extern void nativeNfcTag_resetPresenceCheck();
extern void nativeNfcTag_doReadCompleted(tNFA_STATUS status);
extern void nativeNfcTag_setRfInterface(tNFA_INTF_TYPE rfInterface);
+extern void nativeNfcTag_setActivatedRfProtocol(tNFA_INTF_TYPE rfProtocol);
extern void nativeNfcTag_abortWaits();
extern void nativeLlcpConnectionlessSocket_abortWait();
extern void nativeNfcTag_registerNdefTypeHandler();
@@ -190,7 +191,8 @@
}
void initializeMfcReaderOption() {
legacy_mfc_reader =
- (NfcConfig::getUnsigned(NAME_LEGACY_MIFARE_READER, 1) != 0) ? true : false;
+ (NfcConfig::getUnsigned(NAME_LEGACY_MIFARE_READER, 0) != 0) ? true
+ : false;
DLOG_IF(INFO, nfc_debug_enabled)
<< __func__ <<": mifare reader option=" << legacy_mfc_reader;
@@ -226,18 +228,31 @@
**
*******************************************************************************/
static void handleRfDiscoveryEvent(tNFC_RESULT_DEVT* discoveredDevice) {
+ NfcTag& natTag = NfcTag::getInstance();
+ natTag.setNumDiscNtf(natTag.getNumDiscNtf() + 1);
if (discoveredDevice->more == NCI_DISCOVER_NTF_MORE) {
// there is more discovery notification coming
return;
}
- bool isP2p = NfcTag::getInstance().isP2pDiscovered();
- if (!sReaderModeEnabled && isP2p) {
+ bool isP2p = natTag.isP2pDiscovered();
+
+ if (natTag.getNumDiscNtf() > 1) {
+ natTag.setMultiProtocolTagSupport(true);
+ if (isP2p) {
+ // Remove NFC_DEP NTF count
+ // Skip NFC_DEP protocol in MultiProtocolTag select.
+ natTag.setNumDiscNtf(natTag.getNumDiscNtf() - 1);
+ }
+ }
+
+ if (sP2pEnabled && !sReaderModeEnabled && isP2p) {
// select the peer that supports P2P
- NfcTag::getInstance().selectP2p();
+ natTag.selectP2p();
} else {
+ natTag.setNumDiscNtf(natTag.getNumDiscNtf() - 1);
// select the first of multiple tags that is discovered
- NfcTag::getInstance().selectFirstTag();
+ natTag.selectFirstTag();
}
}
@@ -294,6 +309,8 @@
<< StringPrintf("%s: NFA_RF_DISCOVERY_STOPPED_EVT: status = %u",
__func__, eventData->status);
+ gActivated = false;
+
SyncEventGuard guard(sNfaEnableDisablePollingEvent);
sNfaEnableDisablePollingEvent.notifyOne();
} break;
@@ -303,6 +320,7 @@
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
"%s: NFA_DISC_RESULT_EVT: status = %d", __func__, status);
if (status != NFA_STATUS_OK) {
+ NfcTag::getInstance().setNumDiscNtf(0);
LOG(ERROR) << StringPrintf("%s: NFA_DISC_RESULT_EVT error: status = %d",
__func__, status);
} else {
@@ -339,14 +357,23 @@
break;
case NFA_ACTIVATED_EVT: // NFC link/protocol activated
+ {
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
"%s: NFA_ACTIVATED_EVT: gIsSelectingRfInterface=%d, sIsDisabling=%d",
__func__, gIsSelectingRfInterface, sIsDisabling);
+ uint8_t activatedProtocol =
+ (tNFA_INTF_TYPE)eventData->activated.activate_ntf.protocol;
+ if (NFC_PROTOCOL_T5T == activatedProtocol &&
+ NfcTag::getInstance().getNumDiscNtf()) {
+ /* T5T doesn't support multiproto detection logic */
+ NfcTag::getInstance().setNumDiscNtf(0);
+ }
if ((eventData->activated.activate_ntf.protocol !=
NFA_PROTOCOL_NFC_DEP) &&
(!isListenMode(eventData->activated))) {
nativeNfcTag_setRfInterface(
(tNFA_INTF_TYPE)eventData->activated.activate_ntf.intf_param.type);
+ nativeNfcTag_setActivatedRfProtocol(activatedProtocol);
}
if (EXTNS_GetConnectFlag() == TRUE) {
NfcTag::getInstance().setActivationState();
@@ -397,6 +424,12 @@
}
} else {
NfcTag::getInstance().connectionEventHandler(connEvent, eventData);
+ if (NfcTag::getInstance().getNumDiscNtf()) {
+ /*If its multiprotocol tag, deactivate tag with current selected
+ protocol to sleep . Select tag with next supported protocol after
+ deactivation event is received*/
+ NFA_Deactivate(true);
+ }
// We know it is not activating for P2P. If it activated in
// listen mode then it is likely for an SE transaction.
@@ -405,13 +438,13 @@
sSeRfActive = true;
}
}
- break;
-
+ } break;
case NFA_DEACTIVATED_EVT: // NFC link/protocol deactivated
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
"%s: NFA_DEACTIVATED_EVT Type: %u, gIsTagDeactivating: %d",
__func__, eventData->deactivated.type, gIsTagDeactivating);
NfcTag::getInstance().setDeactivationState(eventData->deactivated);
+ NfcTag::getInstance().selectNextTagIfExists();
if (eventData->deactivated.type != NFA_DEACTIVATE_TYPE_SLEEP) {
{
SyncEventGuard g(gDeactivatedEvent);
@@ -1164,19 +1197,20 @@
}
static void nfcManager_configNfccConfigControl(bool flag) {
- // configure NFCC_CONFIG_CONTROL- NFCC allowed to manage RF configuration.
- if (NFC_GetNCIVersion() != NCI_VERSION_1_0) {
- uint8_t nfa_set_config[] = {0x00};
+ // configure NFCC_CONFIG_CONTROL- NFCC allowed to manage RF configuration.
+ if (NFC_GetNCIVersion() != NCI_VERSION_1_0) {
+ uint8_t nfa_set_config[] = { 0x00 };
- nfa_set_config[0] = (flag == true ? 1 : 0);
+ nfa_set_config[0] = (flag == true ? 1 : 0);
- tNFA_STATUS status =
- NFA_SetConfig(NCI_PARAM_ID_NFCC_CONFIG_CONTROL, sizeof(nfa_set_config),
- &nfa_set_config[0]);
- if (status != NFA_STATUS_OK) {
- LOG(ERROR) << __func__ << ": Failed to configure NFCC_CONFIG_CONTROL";
+ tNFA_STATUS status = NFA_SetConfig(NCI_PARAM_ID_NFCC_CONFIG_CONTROL,
+ sizeof(nfa_set_config),
+ &nfa_set_config[0]);
+ if (status != NFA_STATUS_OK) {
+ LOG(ERROR) << __func__
+ << ": Failed to configure NFCC_CONFIG_CONTROL";
+ }
}
- }
}
/*******************************************************************************
@@ -1246,8 +1280,7 @@
sReaderModeEnabled = true;
NFA_DisableListening();
- // configure NFCC_CONFIG_CONTROL- NFCC not allowed to manage RF
- // configuration.
+ // configure NFCC_CONFIG_CONTROL- NFCC not allowed to manage RF configuration.
nfcManager_configNfccConfigControl(false);
NFA_SetRfDiscoveryDuration(READER_MODE_DISCOVERY_DURATION);
@@ -1256,8 +1289,7 @@
sReaderModeEnabled = false;
NFA_EnableListening();
- // configure NFCC_CONFIG_CONTROL- NFCC allowed to manage RF
- // configuration.
+ // configure NFCC_CONFIG_CONTROL- NFCC allowed to manage RF configuration.
nfcManager_configNfccConfigControl(true);
NFA_SetRfDiscoveryDuration(nat->discovery_duration);
@@ -1959,6 +1991,11 @@
}
return true;
}
+
+static jstring nfcManager_doGetNfaStorageDir(JNIEnv* e, jobject o) {
+ string nfaStorageDir = NfcConfig::getString(NAME_NFA_STORAGE, "/data/nfc");
+ return e->NewStringUTF(nfaStorageDir.c_str());
+}
/*****************************************************************************
**
** JNI functions for android-4.0.1_r1
@@ -2046,6 +2083,9 @@
{"getAidTableSize", "()I", (void*)nfcManager_getAidTableSize},
{"doSetNfcSecure", "(Z)Z", (void*)nfcManager_doSetNfcSecure},
+
+ {"getNfaStorageDir", "()Ljava/lang/String;",
+ (void*)nfcManager_doGetNfaStorageDir},
};
/*******************************************************************************
diff --git a/nci/jni/NativeNfcTag.cpp b/nci/jni/NativeNfcTag.cpp
index cd9f232..ddae94e 100644
--- a/nci/jni/NativeNfcTag.cpp
+++ b/nci/jni/NativeNfcTag.cpp
@@ -87,6 +87,7 @@
static bool sCheckNdefCapable = false; // whether tag has NDEF capability
static tNFA_HANDLE sNdefTypeHandlerHandle = NFA_HANDLE_INVALID;
static tNFA_INTF_TYPE sCurrentRfInterface = NFA_INTERFACE_ISO_DEP;
+static tNFA_INTF_TYPE sCurrentActivatedProtocl = NFA_INTERFACE_ISO_DEP;
static std::basic_string<uint8_t> sRxDataBuffer;
static tNFA_STATUS sRxDataStatus = NFA_STATUS_OK;
static bool sWaitingForTransceive = false;
@@ -121,6 +122,7 @@
static jboolean sMakeReadonlyWaitingForComplete = JNI_FALSE;
static int sCurrentConnectedTargetType = TARGET_TYPE_UNKNOWN;
static int sCurrentConnectedTargetProtocol = NFC_PROTOCOL_UNKNOWN;
+static int sCurrentConnectedHandle = 0;
static int reSelect(tNFA_INTF_TYPE rfInterface, bool fSwitchIfNeeded);
static bool switchRfInterface(tNFA_INTF_TYPE rfInterface);
@@ -157,6 +159,7 @@
}
sem_post(&sMakeReadonlySem);
sCurrentRfInterface = NFA_INTERFACE_ISO_DEP;
+ sCurrentActivatedProtocl = NFA_INTERFACE_ISO_DEP;
sCurrentConnectedTargetType = TARGET_TYPE_UNKNOWN;
sCurrentConnectedTargetProtocol = NFC_PROTOCOL_UNKNOWN;
}
@@ -203,6 +206,19 @@
}
/*******************************************************************************
+ **
+ ** Function: nativeNfcTag_setActivatedRfProtocol
+ **
+ ** Description: Set rf Activated Protocol.
+ **
+ ** Returns: void
+ **
+ *******************************************************************************/
+void nativeNfcTag_setActivatedRfProtocol(tNFA_INTF_TYPE rfProtocol) {
+ sCurrentActivatedProtocl = rfProtocol;
+}
+
+/*******************************************************************************
**
** Function: ndefHandlerCallback
**
@@ -407,6 +423,12 @@
}
} else {
status = NFA_RwFormatTag();
+ if (status != NFA_STATUS_OK) {
+ LOG(ERROR) << StringPrintf("%s: can't format mifare classic tag",
+ __func__);
+ sem_destroy(&sFormatSem);
+ goto TheEnd;
+ }
}
sem_wait(&sFormatSem);
sem_destroy(&sFormatSem);
@@ -546,11 +568,13 @@
sCurrentConnectedTargetType = natTag.mTechList[i];
sCurrentConnectedTargetProtocol = natTag.mTechLibNfcTypes[i];
+ sCurrentConnectedHandle = targetHandle;
- if (sCurrentConnectedTargetProtocol != NFC_PROTOCOL_ISO_DEP) {
- DLOG_IF(INFO, nfc_debug_enabled)
- << StringPrintf("%s() Nfc type = %d, do nothing for non ISO_DEP",
- __func__, sCurrentConnectedTargetProtocol);
+ if (sCurrentConnectedTargetProtocol != NFC_PROTOCOL_ISO_DEP &&
+ sCurrentConnectedTargetProtocol != NFC_PROTOCOL_MIFARE) {
+ DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
+ "%s() Nfc type = %d, do nothing for non ISO_DEP and non Mifare ",
+ __func__, sCurrentConnectedTargetProtocol);
retCode = NFCSTATUS_SUCCESS;
goto TheEnd;
}
@@ -562,6 +586,9 @@
sCurrentConnectedTargetType);
retCode = switchRfInterface(NFA_INTERFACE_FRAME) ? NFA_STATUS_OK
: NFA_STATUS_FAILED;
+ } else if (sCurrentConnectedTargetType == TARGET_TYPE_MIFARE_CLASSIC) {
+ retCode = switchRfInterface(NFA_INTERFACE_MIFARE) ? NFA_STATUS_OK
+ : NFA_STATUS_FAILED;
} else {
retCode = switchRfInterface(NFA_INTERFACE_ISO_DEP) ? NFA_STATUS_OK
: NFA_STATUS_FAILED;
@@ -614,11 +641,11 @@
(NFC_GetNCIVersion() >= NCI_VERSION_2_0)) {
{
SyncEventGuard g3(sReconnectEvent);
- if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_T2T) {
+ if (sCurrentActivatedProtocl == NFA_PROTOCOL_T2T) {
status = NFA_SendRawFrame(RW_TAG_SLP_REQ, sizeof(RW_TAG_SLP_REQ), 0);
- } else if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_ISO_DEP) {
- status =
- NFA_SendRawFrame(RW_DESELECT_REQ, sizeof(RW_DESELECT_REQ), 0);
+ } else if (sCurrentActivatedProtocl == NFA_PROTOCOL_ISO_DEP) {
+ status = NFA_SendRawFrame(RW_DESELECT_REQ,
+ sizeof(RW_DESELECT_REQ), 0);
}
sReconnectEvent.wait(4);
if (status != NFA_STATUS_OK) {
@@ -670,21 +697,39 @@
<< StringPrintf("%s: select interface %u", __func__, rfInterface);
gIsSelectingRfInterface = true;
if (NFA_STATUS_OK !=
- (status = NFA_Select(natTag.mTechHandles[0],
- natTag.mTechLibNfcTypes[0], rfInterface))) {
+ (status = NFA_Select(natTag.mTechHandles[sCurrentConnectedHandle],
+ natTag.mTechLibNfcTypes[sCurrentConnectedHandle],
+ rfInterface))) {
LOG(ERROR) << StringPrintf("%s: NFA_Select failed, status = %d",
__func__, status);
break;
}
sConnectOk = false;
- if (sReconnectEvent.wait(1000) == false) // if timeout occured
+ if (sReconnectEvent.wait(1000) == false) // if timeout occurred
{
LOG(ERROR) << StringPrintf("%s: timeout waiting for select", __func__);
break;
}
}
+ /*Retry logic in case of core Generic error while selecting a tag*/
+ if (sConnectOk == false) {
+ LOG(ERROR) << StringPrintf("%s: waiting for Card to be activated",
+ __func__);
+ int retry = 0;
+ sConnectWaitingForComplete = JNI_TRUE;
+ do {
+ SyncEventGuard reselectEvent(sReconnectEvent);
+ if (sReconnectEvent.wait(500) == false) { // if timeout occurred
+ LOG(ERROR) << StringPrintf("%s: timeout ", __func__);
+ }
+ retry++;
+ LOG(ERROR) << StringPrintf("%s: waiting for Card to be activated %x %x",
+ __func__, retry, sConnectOk);
+ } while (sConnectOk == false && retry < 3);
+ }
+
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
"%s: select completed; sConnectOk=%d", __func__, sConnectOk);
if (NfcTag::getInstance().getActivationState() != NfcTag::Active) {
@@ -723,10 +768,11 @@
static bool switchRfInterface(tNFA_INTF_TYPE rfInterface) {
NfcTag& natTag = NfcTag::getInstance();
- if (sCurrentConnectedTargetProtocol != NFC_PROTOCOL_ISO_DEP) {
- DLOG_IF(INFO, nfc_debug_enabled)
- << StringPrintf("%s: protocol: %d not ISO_DEP, do nothing", __func__,
- natTag.mTechLibNfcTypes[0]);
+ if (sCurrentConnectedTargetProtocol != NFC_PROTOCOL_ISO_DEP &&
+ sCurrentConnectedTargetProtocol != NFC_PROTOCOL_MIFARE) {
+ DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
+ "%s: protocol: %d not ISO_DEP and not Mifare, do nothing", __func__,
+ natTag.mTechLibNfcTypes[0]);
return true;
}
diff --git a/nci/jni/NfcTag.cpp b/nci/jni/NfcTag.cpp
old mode 100644
new mode 100755
index 7194d8c..b9d8d55
--- a/nci/jni/NfcTag.cpp
+++ b/nci/jni/NfcTag.cpp
@@ -34,6 +34,9 @@
using android::base::StringPrintf;
extern bool nfc_debug_enabled;
+static void deleteglobaldata(JNIEnv* e);
+static jobjectArray sTechPollBytes;
+static int sLastSelectedTagId = 0;
/*******************************************************************************
**
@@ -57,12 +60,17 @@
mNdefDetectionTimedOut(false),
mIsDynamicTagId(false),
mPresenceCheckAlgorithm(NFA_RW_PRES_CHK_DEFAULT),
- mIsFelicaLite(false) {
+ mIsFelicaLite(false),
+ mNumDiscNtf(0),
+ mNumDiscTechList(0),
+ mTechListTail(0),
+ mIsMultiProtocolTag(false) {
memset(mTechList, 0, sizeof(mTechList));
memset(mTechHandles, 0, sizeof(mTechHandles));
memset(mTechLibNfcTypes, 0, sizeof(mTechLibNfcTypes));
memset(mTechParams, 0, sizeof(mTechParams));
memset(mLastKovioUid, 0, NFC_KOVIO_MAX_LEN);
+ memset(&mLastKovioTime, 0, sizeof(timespec));
}
/*******************************************************************************
@@ -94,7 +102,6 @@
mIsActivated = false;
mActivationState = Idle;
mProtocol = NFC_PROTOCOL_UNKNOWN;
- mNumTechList = 0;
mtT1tMaxMessageSize = 0;
mReadCompletedStatus = NFA_STATUS_OK;
resetTechnologies();
@@ -280,7 +287,9 @@
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", fn);
tNFC_ACTIVATE_DEVT& rfDetail = activationData.activate_ntf;
- mNumTechList = 0;
+ if (mTechListTail < (MAX_NUM_TECHNOLOGY - 1)) {
+ mNumTechList = mTechListTail;
+ }
mTechHandles[mNumTechList] = rfDetail.rf_disc_id;
mTechLibNfcTypes[mNumTechList] = rfDetail.protocol;
@@ -335,6 +344,17 @@
// type-4 tag uses technology ISO-DEP and technology A or B
mTechList[mNumTechList] =
TARGET_TYPE_ISO14443_4; // is TagTechnology.ISO_DEP by Java API
+ if ((NFC_DISCOVERY_TYPE_POLL_A == rfDetail.rf_tech_param.mode) ||
+ (NFC_DISCOVERY_TYPE_POLL_A_ACTIVE == rfDetail.rf_tech_param.mode)) {
+ uint8_t fwi = rfDetail.intf_param.intf_param.pa_iso.fwi;
+ if (fwi >= MIN_FWI && fwi <= MAX_FWI) {
+ //2^MIN_FWI * 256 * 16 * 1000 / 13560000 is approximately 618
+ int fwt = (1 << (fwi - MIN_FWI)) * 618;
+ DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
+ "Setting the transceive timeout = %d, fwi = %0#x", fwt, fwi);
+ setTransceiveTimeout(mTechList[mNumTechList], fwt);
+ }
+ }
if ((rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) ||
(rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
(rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A) ||
@@ -411,111 +431,29 @@
void NfcTag::discoverTechnologies(tNFA_DISC_RESULT& discoveryData) {
static const char fn[] = "NfcTag::discoverTechnologies (discovery)";
tNFC_RESULT_DEVT& discovery_ntf = discoveryData.discovery_ntf;
+ uint8_t index = mNumDiscNtf;
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
"%s: enter: rf disc. id=%u; protocol=%u, mNumTechList=%u", fn,
discovery_ntf.rf_disc_id, discovery_ntf.protocol, mNumTechList);
- if (mNumTechList >= MAX_NUM_TECHNOLOGY) {
+ if (index >= MAX_NUM_TECHNOLOGY) {
LOG(ERROR) << StringPrintf("%s: exceed max=%d", fn, MAX_NUM_TECHNOLOGY);
goto TheEnd;
}
- mTechHandles[mNumTechList] = discovery_ntf.rf_disc_id;
- mTechLibNfcTypes[mNumTechList] = discovery_ntf.protocol;
-
- // save the stack's data structure for interpretation later
- memcpy(&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param),
- sizeof(discovery_ntf.rf_tech_param));
-
- if (NFC_PROTOCOL_T1T == discovery_ntf.protocol) {
- mTechList[mNumTechList] =
- TARGET_TYPE_ISO14443_3A; // is TagTechnology.NFC_A by Java API
- } else if (NFC_PROTOCOL_T2T == discovery_ntf.protocol) {
- mTechList[mNumTechList] =
- TARGET_TYPE_ISO14443_3A; // is TagTechnology.NFC_A by Java API
- // type-2 tags are identical to Mifare Ultralight, so Ultralight is also
- // discovered
- if ((discovery_ntf.rf_tech_param.param.pa.sel_rsp == 0) &&
- (mNumTechList < (MAX_NUM_TECHNOLOGY - 1))) {
- // Mifare Ultralight
- mNumTechList++;
- mTechHandles[mNumTechList] = discovery_ntf.rf_disc_id;
- mTechLibNfcTypes[mNumTechList] = discovery_ntf.protocol;
- mTechList[mNumTechList] =
- TARGET_TYPE_MIFARE_UL; // is TagTechnology.MIFARE_ULTRALIGHT by Java
- // API
- }
-
- // save the stack's data structure for interpretation later
- memcpy(&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param),
- sizeof(discovery_ntf.rf_tech_param));
- } else if (NFC_PROTOCOL_T3T == discovery_ntf.protocol) {
- mTechList[mNumTechList] = TARGET_TYPE_FELICA;
- } else if (NFC_PROTOCOL_ISO_DEP == discovery_ntf.protocol) {
- // type-4 tag uses technology ISO-DEP and technology A or B
- mTechList[mNumTechList] =
- TARGET_TYPE_ISO14443_4; // is TagTechnology.ISO_DEP by Java API
- if ((discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) ||
- (discovery_ntf.rf_tech_param.mode ==
- NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
- (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A) ||
- (discovery_ntf.rf_tech_param.mode ==
- NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE)) {
- if (mNumTechList < (MAX_NUM_TECHNOLOGY - 1)) {
- mNumTechList++;
- mTechHandles[mNumTechList] = discovery_ntf.rf_disc_id;
- mTechLibNfcTypes[mNumTechList] = discovery_ntf.protocol;
- mTechList[mNumTechList] =
- TARGET_TYPE_ISO14443_3A; // is TagTechnology.NFC_A by Java API
- // save the stack's data structure for interpretation later
- memcpy(&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param),
- sizeof(discovery_ntf.rf_tech_param));
- }
- } else if ((discovery_ntf.rf_tech_param.mode ==
- NFC_DISCOVERY_TYPE_POLL_B) ||
- (discovery_ntf.rf_tech_param.mode ==
- NFC_DISCOVERY_TYPE_POLL_B_PRIME) ||
- (discovery_ntf.rf_tech_param.mode ==
- NFC_DISCOVERY_TYPE_LISTEN_B) ||
- (discovery_ntf.rf_tech_param.mode ==
- NFC_DISCOVERY_TYPE_LISTEN_B_PRIME)) {
- if (mNumTechList < (MAX_NUM_TECHNOLOGY - 1)) {
- mNumTechList++;
- mTechHandles[mNumTechList] = discovery_ntf.rf_disc_id;
- mTechLibNfcTypes[mNumTechList] = discovery_ntf.protocol;
- mTechList[mNumTechList] =
- TARGET_TYPE_ISO14443_3B; // is TagTechnology.NFC_B by Java API
- // save the stack's data structure for interpretation later
- memcpy(&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param),
- sizeof(discovery_ntf.rf_tech_param));
- }
- }
- } else if (NFC_PROTOCOL_T5T == discovery_ntf.protocol) {
- // is TagTechnology.NFC_V by Java API
- mTechList[mNumTechList] = TARGET_TYPE_V;
- } else if (NFC_PROTOCOL_MIFARE == discovery_ntf.protocol) {
- mTechList[mNumTechList] = TARGET_TYPE_MIFARE_CLASSIC;
- if (mNumTechList < (MAX_NUM_TECHNOLOGY - 1)) {
- mNumTechList++;
- mTechHandles[mNumTechList] = discovery_ntf.rf_disc_id;
- mTechLibNfcTypes[mNumTechList] = discovery_ntf.protocol;
- mTechList[mNumTechList] = TARGET_TYPE_ISO14443_3A;
- // save the stack's data structure for interpretation later
- memcpy(&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param),
- sizeof(discovery_ntf.rf_tech_param));
- }
- } else {
- LOG(ERROR) << StringPrintf("%s: unknown protocol ????", fn);
- mTechList[mNumTechList] = TARGET_TYPE_UNKNOWN;
+ mTechHandlesDiscData[index] = discovery_ntf.rf_disc_id;
+ mTechLibNfcTypesDiscData[index] = discovery_ntf.protocol;
+ if (mNumDiscTechList < MAX_NUM_TECHNOLOGY) {
+ mNumDiscTechList++;
}
-
- mNumTechList++;
if (discovery_ntf.more != NCI_DISCOVER_NTF_MORE) {
- for (int i = 0; i < mNumTechList; i++) {
- DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
- "%s: index=%d; tech=%d; handle=%d; nfc type=%d", fn, i, mTechList[i],
- mTechHandles[i], mTechLibNfcTypes[i]);
+ for (int i = 0; i < mNumDiscTechList; i++) {
+ DLOG_IF(INFO, nfc_debug_enabled)
+ << StringPrintf("%s: index=%d; handle=%d; nfc type=%d", fn, i,
+ mTechHandlesDiscData[i], mTechLibNfcTypesDiscData[i]);
}
}
+ DLOG_IF(INFO, nfc_debug_enabled)
+ << StringPrintf("%s; mNumDiscTechList=%x", fn, mNumDiscTechList);
TheEnd:
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", fn);
@@ -576,15 +514,24 @@
}
mNativeData->tag = e->NewGlobalRef(tag.get());
- // notify NFC service about this new tag
DLOG_IF(INFO, nfc_debug_enabled)
- << StringPrintf("%s: try notify nfc service", fn);
- e->CallVoidMethod(mNativeData->manager,
- android::gCachedNfcManagerNotifyNdefMessageListeners,
- tag.get());
- if (e->ExceptionCheck()) {
- e->ExceptionClear();
- LOG(ERROR) << StringPrintf("%s: fail notify nfc service", fn);
+ << StringPrintf("%s; mNumDiscNtf=%x", fn, mNumDiscNtf);
+
+ if (!mNumDiscNtf) {
+ // notify NFC service about this new tag
+ DLOG_IF(INFO, nfc_debug_enabled)
+ << StringPrintf("%s: try notify nfc service", fn);
+ e->CallVoidMethod(mNativeData->manager,
+ android::gCachedNfcManagerNotifyNdefMessageListeners,
+ tag.get());
+ if (e->ExceptionCheck()) {
+ e->ExceptionClear();
+ LOG(ERROR) << StringPrintf("%s: fail notify nfc service", fn);
+ }
+ deleteglobaldata(e);
+ } else {
+ DLOG_IF(INFO, nfc_debug_enabled)
+ << StringPrintf("%s: Selecting next tag", fn);
}
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", fn);
@@ -592,6 +539,25 @@
/*******************************************************************************
**
+** Function: deleteglobaldata
+**
+** Description: Deletes the global data reference after notifying to service
+** e: JVM environment.
+**
+** Returns: None
+**
+*******************************************************************************/
+static void deleteglobaldata(JNIEnv* e) {
+ static const char fn[] = "deleteglobaldata";
+ DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", fn);
+ if (sTechPollBytes != NULL) {
+ e->DeleteGlobalRef(sTechPollBytes);
+ }
+ DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", fn);
+}
+
+/*******************************************************************************
+**
** Function: fillNativeNfcTagMembers1
**
** Description: Fill NativeNfcTag's members: mProtocols, mTechList,
@@ -686,8 +652,20 @@
ScopedLocalRef<jobjectArray> techPollBytes(
e, e->NewObjectArray(mNumTechList, byteArrayClass.get(), 0));
int len = 0;
+ if (mTechListTail == 0) {
+ sTechPollBytes =
+ reinterpret_cast<jobjectArray>(e->NewGlobalRef(techPollBytes.get()));
+ } else {
+ /* Add previously activated tag's tech poll bytes also in the
+ list for multiprotocol tag*/
+ jobject techPollBytesObject;
+ for (int j = 0; j < mTechListTail; j++) {
+ techPollBytesObject = e->GetObjectArrayElement(sTechPollBytes, j);
+ e->SetObjectArrayElement(techPollBytes.get(), j, techPollBytesObject);
+ }
+ }
- for (int i = 0; i < mNumTechList; i++) {
+ for (int i = mTechListTail; i < mNumTechList; i++) {
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
"%s: index=%d; rf tech params mode=%u", fn, i, mTechParams[i].mode);
if (NFC_DISCOVERY_TYPE_POLL_A == mTechParams[i].mode ||
@@ -780,6 +758,13 @@
} // switch: every type of technology
e->SetObjectArrayElement(techPollBytes.get(), i, pollBytes.get());
} // for: every technology in the array
+ if (sTechPollBytes != NULL && mTechListTail != 0) {
+ /* Save tech poll bytes of all activated tags of a multiprotocol tag in
+ * sTechPollBytes*/
+ e->DeleteGlobalRef(sTechPollBytes);
+ sTechPollBytes =
+ reinterpret_cast<jobjectArray>(e->NewGlobalRef(techPollBytes.get()));
+ }
jfieldID f = e->GetFieldID(tag_cls, "mTechPollBytes", "[[B");
e->SetObjectField(tag, f, techPollBytes.get());
}
@@ -808,7 +793,24 @@
ScopedLocalRef<jobjectArray> techActBytes(
e, e->NewObjectArray(mNumTechList, byteArrayClass.get(), 0));
- for (int i = 0; i < mNumTechList; i++) {
+ // merging sak for combi tag
+ if (activationData.activate_ntf.protocol &
+ (NFC_PROTOCOL_T1T | NFC_PROTOCOL_T2T | NFC_PROTOCOL_MIFARE |
+ NFC_PROTOCOL_ISO_DEP)) {
+ uint8_t merge_sak = 0;
+ for (int i = 0; i < mNumTechList; i++) {
+ merge_sak = (merge_sak | mTechParams[i].param.pa.sel_rsp);
+ }
+ for (int i = 0; i < mNumTechList; i++) {
+ mTechParams[i].param.pa.sel_rsp = merge_sak;
+ actBytes.reset(e->NewByteArray(1));
+ e->SetByteArrayRegion(actBytes.get(), 0, 1,
+ (jbyte*)&mTechParams[i].param.pa.sel_rsp);
+ e->SetObjectArrayElement(techActBytes.get(), i, actBytes.get());
+ }
+ }
+
+ for (int i = mTechListTail; i < mNumTechList; i++) {
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: index=%d", fn, i);
if (NFC_PROTOCOL_T1T == mTechLibNfcTypes[i] ||
NFC_PROTOCOL_T2T == mTechLibNfcTypes[i]) {
@@ -914,7 +916,7 @@
actBytes.reset(e->NewByteArray(0));
}
e->SetObjectArrayElement(techActBytes.get(), i, actBytes.get());
- } // for: every technology in the array
+ } // for: every technology in the array of current selected tag
jfieldID f = e->GetFieldID(tag_cls, "mTechActBytes", "[[B");
e->SetObjectField(tag, f, techActBytes.get());
}
@@ -992,6 +994,10 @@
}
jfieldID f = e->GetFieldID(tag_cls, "mUid", "[B");
e->SetObjectField(tag, f, uid.get());
+ mTechListTail = mNumTechList;
+ if (mNumDiscNtf == 0) mTechListTail = 0;
+ DLOG_IF(INFO, nfc_debug_enabled)
+ << StringPrintf("%s;mTechListTail=%x", fn, mTechListTail);
}
/*******************************************************************************
@@ -1007,8 +1013,8 @@
static const char fn[] = "NfcTag::isP2pDiscovered";
bool retval = false;
- for (int i = 0; i < mNumTechList; i++) {
- if (mTechLibNfcTypes[i] == NFA_PROTOCOL_NFC_DEP) {
+ for (int i = 0; i < mNumDiscTechList; i++) {
+ if (mTechLibNfcTypesDiscData[i] == NFA_PROTOCOL_NFC_DEP) {
// if remote device supports P2P
DLOG_IF(INFO, nfc_debug_enabled)
<< StringPrintf("%s: discovered P2P", fn);
@@ -1076,6 +1082,10 @@
static const char fn[] = "NfcTag::resetTechnologies";
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", fn);
mNumTechList = 0;
+ mNumDiscNtf = 0;
+ mNumDiscTechList = 0;
+ mTechListTail = 0;
+ mIsMultiProtocolTag = false;
memset(mTechList, 0, sizeof(mTechList));
memset(mTechHandles, 0, sizeof(mTechHandles));
memset(mTechLibNfcTypes, 0, sizeof(mTechLibNfcTypes));
@@ -1100,26 +1110,27 @@
int foundIdx = -1;
tNFA_INTF_TYPE rf_intf = NFA_INTERFACE_FRAME;
- for (int i = 0; i < mNumTechList; i++) {
+ for (int i = 0; i < mNumDiscTechList; i++) {
DLOG_IF(INFO, nfc_debug_enabled)
<< StringPrintf("%s: nfa target idx=%d h=0x%X; protocol=0x%X", fn, i,
- mTechHandles[i], mTechLibNfcTypes[i]);
- if (mTechLibNfcTypes[i] != NFA_PROTOCOL_NFC_DEP) {
+ mTechHandlesDiscData[i], mTechLibNfcTypesDiscData[i]);
+ if (mTechLibNfcTypesDiscData[i] != NFA_PROTOCOL_NFC_DEP) {
+ sLastSelectedTagId = i;
foundIdx = i;
break;
}
}
if (foundIdx != -1) {
- if (mTechLibNfcTypes[foundIdx] == NFA_PROTOCOL_ISO_DEP) {
+ if (mTechLibNfcTypesDiscData[foundIdx] == NFA_PROTOCOL_ISO_DEP) {
rf_intf = NFA_INTERFACE_ISO_DEP;
- } else if (mTechLibNfcTypes[foundIdx] == NFC_PROTOCOL_MIFARE) {
+ } else if (mTechLibNfcTypesDiscData[foundIdx] == NFC_PROTOCOL_MIFARE) {
rf_intf = NFA_INTERFACE_MIFARE;
} else
rf_intf = NFA_INTERFACE_FRAME;
- tNFA_STATUS stat =
- NFA_Select(mTechHandles[foundIdx], mTechLibNfcTypes[foundIdx], rf_intf);
+ tNFA_STATUS stat = NFA_Select(mTechHandlesDiscData[foundIdx],
+ mTechLibNfcTypesDiscData[foundIdx], rf_intf);
if (stat != NFA_STATUS_OK)
LOG(ERROR) << StringPrintf("%s: fail select; error=0x%X", fn, stat);
} else
@@ -1128,6 +1139,67 @@
/*******************************************************************************
**
+** Function: selectNextTagIfExists
+**
+** Description: When multiple tags are discovered, selects the next tag to
+** activate.
+**
+** Returns: None
+**
+*******************************************************************************/
+void NfcTag::selectNextTagIfExists() {
+ static const char fn[] = "NfcTag::selectNextTagIfExists";
+ int foundIdx = -1;
+ tNFA_INTF_TYPE rf_intf = NFA_INTERFACE_FRAME;
+ tNFA_STATUS stat = NFA_STATUS_FAILED;
+
+ if (mNumDiscNtf == 0) {
+ return;
+ }
+ mNumDiscNtf--;
+ DLOG_IF(INFO, nfc_debug_enabled)
+ << StringPrintf("%s: enter, mNumDiscTechList=%x", fn, mNumDiscTechList);
+ for (int i = 0; i < mNumDiscTechList; i++) {
+ DLOG_IF(INFO, nfc_debug_enabled)
+ << StringPrintf("%s: nfa target idx=%dh=0x%X; protocol=0x%X", fn, i,
+ mTechHandlesDiscData[i], mTechLibNfcTypesDiscData[i]);
+ if (((mTechHandlesDiscData[sLastSelectedTagId] !=
+ mTechHandlesDiscData[i]) ||
+ (mTechLibNfcTypesDiscData[sLastSelectedTagId] !=
+ mTechLibNfcTypesDiscData[i])) &&
+ (mTechLibNfcTypesDiscData[i] != NFA_PROTOCOL_NFC_DEP)) {
+ sLastSelectedTagId = i;
+ foundIdx = i;
+ break;
+ }
+ }
+
+ if (foundIdx != -1) {
+ if (mTechLibNfcTypesDiscData[foundIdx] == NFA_PROTOCOL_ISO_DEP) {
+ rf_intf = NFA_INTERFACE_ISO_DEP;
+ } else if (mTechLibNfcTypesDiscData[foundIdx] == NFC_PROTOCOL_MIFARE) {
+ rf_intf = NFA_INTERFACE_MIFARE;
+ } else {
+ rf_intf = NFA_INTERFACE_FRAME;
+ }
+
+ stat = NFA_Select(mTechHandlesDiscData[foundIdx],
+ mTechLibNfcTypesDiscData[foundIdx], rf_intf);
+ if (stat == NFA_STATUS_OK) {
+ DLOG_IF(ERROR, nfc_debug_enabled)
+ << StringPrintf("%s: Select Success, wait for activated ntf", fn);
+ } else {
+ DLOG_IF(ERROR, nfc_debug_enabled)
+ << StringPrintf("%s: fail select; error=0x%X", fn, stat);
+ }
+ } else {
+ DLOG_IF(ERROR, nfc_debug_enabled)
+ << StringPrintf("%s: only found NFC-DEP technology.", fn);
+ }
+}
+
+/*******************************************************************************
+**
** Function: getT1tMaxMessageSize
**
** Description: Get the maximum size (octet) that a T1T can store.
@@ -1512,3 +1584,44 @@
DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: return=%u", fn, retval);
return retval;
}
+
+/*******************************************************************************
+**
+** Function: setMultiProtocolTagSupport
+**
+** Description: Update mIsMultiProtocolTag
+**
+** Returns: None
+**
+*******************************************************************************/
+
+void NfcTag::setMultiProtocolTagSupport(bool isMultiProtocolSupported) {
+ mIsMultiProtocolTag = isMultiProtocolSupported;
+}
+
+/*******************************************************************************
+**
+** Function: setNumDiscNtf
+**
+** Description: Update number of Discovery NTF received
+**
+** Returns: None
+**
+*******************************************************************************/
+void NfcTag::setNumDiscNtf(int numDiscNtfValue) {
+ if (numDiscNtfValue < MAX_NUM_TECHNOLOGY) {
+ mNumDiscNtf = numDiscNtfValue;
+ }
+}
+
+/*******************************************************************************
+**
+** Function: getNumDiscNtf
+**
+** Description: number of discovery notifications received from NFCC after
+** last RF DISCOVERY state
+**
+** Returns: number of discovery notifications received from NFCC
+**
+*******************************************************************************/
+int NfcTag::getNumDiscNtf() { return mNumDiscNtf; }
\ No newline at end of file
diff --git a/nci/jni/NfcTag.h b/nci/jni/NfcTag.h
index bda0aed..4769df1 100644
--- a/nci/jni/NfcTag.h
+++ b/nci/jni/NfcTag.h
@@ -25,6 +25,9 @@
#include "nfa_rw_api.h"
+#define MIN_FWI (11)
+#define MAX_FWI (14)
+
class NfcTag {
public:
enum ActivationState { Idle, Sleep, Active };
@@ -32,10 +35,13 @@
11; // max number of technologies supported by one or more tags
int mTechList[MAX_NUM_TECHNOLOGY]; // array of NFC technologies according to
// NFC service
- int mTechHandles[MAX_NUM_TECHNOLOGY]; // array of tag handles according to
- // NFC service
- int mTechLibNfcTypes[MAX_NUM_TECHNOLOGY]; // array of detailed tag types
- // according to NFC service
+ int mTechHandles[MAX_NUM_TECHNOLOGY]; // array of tag handles (RF DISC ID)
+ // according to NFC service received
+ // from RF_INTF_ACTIVATED NTF
+ int mTechLibNfcTypes[MAX_NUM_TECHNOLOGY]; // array of detailed tag types (RF
+ // Protocol) according to NFC
+ // service received from
+ // RF_INTF_ACTIVATED NTF
int mNumTechList; // current number of NFC technologies in the list
/*******************************************************************************
@@ -187,6 +193,18 @@
/*******************************************************************************
**
+ ** Function: selectNextTagIfExists
+ **
+ ** Description: When multiple tags are discovered, selects the Next one to
+ ** activate.
+ **
+ ** Returns: None
+ **
+ *******************************************************************************/
+ void selectNextTagIfExists();
+
+ /*******************************************************************************
+ **
** Function: getT1tMaxMessageSize
**
** Description: Get the maximum size (octet) that a T1T can store.
@@ -309,7 +327,7 @@
**
** Description: Get the timeout value for one technology.
** techId: one of the values in TARGET_TYPE_* defined in
- *NfcJniUtil.h
+ ** NfcJniUtil.h
**
** Returns: Timeout value in millisecond.
**
@@ -364,6 +382,40 @@
*******************************************************************************/
bool isKovioType2Tag();
+ /*******************************************************************************
+ **
+ ** Function: setMultiProtocolTagSupport
+ **
+ ** Description: Update mIsMultiProtocolTag
+ **
+ ** Returns: None
+ **
+ *******************************************************************************/
+ void setMultiProtocolTagSupport(bool isMultiProtocolSupported);
+
+ /*******************************************************************************
+ **
+ ** Function: setNumDiscNtf
+ **
+ ** Description: Update mNumDiscNtf
+ **
+ ** Returns: None
+ **
+ *******************************************************************************/
+ void setNumDiscNtf(int numDiscNtfValue);
+
+ /*******************************************************************************
+ **
+ ** Function: getNumDiscNtf
+ **
+ ** Description: number of discovery notifications received from NFCC after
+ ** last RF DISCOVERY state
+ **
+ ** Returns: number of discovery notifications received from NFCC
+ **
+ *******************************************************************************/
+ int getNumDiscNtf();
+
private:
std::vector<int> mTechnologyTimeoutsTable;
std::vector<int> mTechnologyDefaultTimeoutsTable;
@@ -383,6 +435,17 @@
bool mIsDynamicTagId; // whether the tag has dynamic tag ID
tNFA_RW_PRES_CHK_OPTION mPresenceCheckAlgorithm;
bool mIsFelicaLite;
+ int mTechHandlesDiscData[MAX_NUM_TECHNOLOGY]; // array of tag handles (RF
+ // DISC ID) received from
+ // RF_DISC_NTF
+ int mTechLibNfcTypesDiscData[MAX_NUM_TECHNOLOGY]; // array of detailed tag
+ // types ( RF Protocol)
+ // received from
+ // RF_DISC_NTF
+ int mNumDiscNtf;
+ int mNumDiscTechList;
+ int mTechListTail; // Index of Last added entry in mTechList
+ bool mIsMultiProtocolTag;
/*******************************************************************************
**
diff --git a/nci/jni/RoutingManager.cpp b/nci/jni/RoutingManager.cpp
index 69ace9f..93ba9e0 100755
--- a/nci/jni/RoutingManager.cpp
+++ b/nci/jni/RoutingManager.cpp
@@ -61,7 +61,10 @@
static const uint8_t AID_ROUTE_QUAL_PREFIX = 0x10;
-RoutingManager::RoutingManager() : mAidRoutingConfigured(false) {
+RoutingManager::RoutingManager()
+ : mSecureNfcEnabled(false),
+ mNativeData(NULL),
+ mAidRoutingConfigured(false) {
static const char fn[] = "RoutingManager::RoutingManager()";
mDefaultOffHostRoute =
@@ -107,6 +110,10 @@
mDefaultIsoDepRoute = NfcConfig::getUnsigned(NAME_DEFAULT_ISODEP_ROUTE, 0x0);
+ mHostListenTechMask =
+ NfcConfig::getUnsigned(NAME_HOST_LISTEN_TECH_MASK,
+ NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F);
+
memset(&mEeInfo, 0, sizeof(mEeInfo));
mReceivedEeInfo = false;
mSeTechMask = 0x00;
@@ -147,8 +154,10 @@
}
mSeTechMask = updateEeTechRouteSetting();
- // Tell the host-routing to only listen on Nfc-A
- tNFA_STATUS nfaStat = NFA_CeSetIsoDepListenTech(NFA_TECHNOLOGY_MASK_A);
+ // Set the host-routing Tech
+ tNFA_STATUS nfaStat = NFA_CeSetIsoDepListenTech(
+ mHostListenTechMask & (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B));
+
if (nfaStat != NFA_STATUS_OK)
LOG(ERROR) << StringPrintf("Failed to configure CE IsoDep technologies");
@@ -196,7 +205,8 @@
// Route Nfc-A to host if we don't have a SE
tNFA_TECHNOLOGY_MASK techMask = NFA_TECHNOLOGY_MASK_A;
- if ((mSeTechMask & NFA_TECHNOLOGY_MASK_A) == 0) {
+ if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_A) &&
+ (mSeTechMask & NFA_TECHNOLOGY_MASK_A) == 0) {
nfaStat = NFA_EeSetDefaultTechRouting(
NFC_DH_ID, techMask, 0, 0, mSecureNfcEnabled ? 0 : techMask,
mSecureNfcEnabled ? 0 : techMask, mSecureNfcEnabled ? 0 : techMask);
@@ -206,9 +216,23 @@
LOG(ERROR) << fn << "Fail to set default tech routing for Nfc-A";
}
+ // Route Nfc-B to host if we don't have a SE
+ techMask = NFA_TECHNOLOGY_MASK_B;
+ if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_B) &&
+ (mSeTechMask & NFA_TECHNOLOGY_MASK_B) == 0) {
+ nfaStat = NFA_EeSetDefaultTechRouting(
+ NFC_DH_ID, techMask, 0, 0, mSecureNfcEnabled ? 0 : techMask,
+ mSecureNfcEnabled ? 0 : techMask, mSecureNfcEnabled ? 0 : techMask);
+ if (nfaStat == NFA_STATUS_OK)
+ mRoutingEvent.wait();
+ else
+ LOG(ERROR) << fn << "Fail to set default tech routing for Nfc-B";
+ }
+
// Route Nfc-F to host if we don't have a SE
techMask = NFA_TECHNOLOGY_MASK_F;
- if ((mSeTechMask & NFA_TECHNOLOGY_MASK_F) == 0) {
+ if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_F) &&
+ (mSeTechMask & NFA_TECHNOLOGY_MASK_F) == 0) {
nfaStat = NFA_EeSetDefaultTechRouting(
NFC_DH_ID, techMask, 0, 0, mSecureNfcEnabled ? 0 : techMask,
mSecureNfcEnabled ? 0 : techMask, mSecureNfcEnabled ? 0 : techMask);
@@ -224,41 +248,53 @@
tNFA_STATUS nfaStat;
SyncEventGuard guard(mRoutingEvent);
- // Default routing for IsoDep protocol
+ // Clear default routing for IsoDep protocol
if (mDefaultIsoDepRoute == NFC_DH_ID) {
nfaStat =
NFA_EeClearDefaultProtoRouting(NFC_DH_ID, NFA_PROTOCOL_MASK_ISO_DEP);
if (nfaStat == NFA_STATUS_OK)
mRoutingEvent.wait();
else
- LOG(ERROR) << fn << "Fail to set default proto routing for IsoDep";
+ LOG(ERROR) << fn << "Fail to clear default proto routing for IsoDep";
}
- // Default routing for Nfc-A technology if we don't have a SE
- if ((mSeTechMask & NFA_TECHNOLOGY_MASK_A) == 0) {
+ // Clear default routing for Nfc-A technology if we don't have a SE
+ if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_A) &&
+ (mSeTechMask & NFA_TECHNOLOGY_MASK_A) == 0) {
nfaStat = NFA_EeClearDefaultTechRouting(NFC_DH_ID, NFA_TECHNOLOGY_MASK_A);
if (nfaStat == NFA_STATUS_OK)
mRoutingEvent.wait();
else
- LOG(ERROR) << fn << "Fail to set default tech routing for Nfc-A";
+ LOG(ERROR) << fn << "Fail to clear default tech routing for Nfc-A";
}
- // Default routing for Nfc-F technology if we don't have a SE
- if ((mSeTechMask & NFA_TECHNOLOGY_MASK_F) == 0) {
+ // Clear default routing for Nfc-B technology if we don't have a SE
+ if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_B) &&
+ (mSeTechMask & NFA_TECHNOLOGY_MASK_B) == 0) {
+ nfaStat = NFA_EeClearDefaultTechRouting(NFC_DH_ID, NFA_TECHNOLOGY_MASK_B);
+ if (nfaStat == NFA_STATUS_OK)
+ mRoutingEvent.wait();
+ else
+ LOG(ERROR) << fn << "Fail to clear default tech routing for Nfc-B";
+ }
+
+ // Clear default routing for Nfc-F technology if we don't have a SE
+ if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_F) &&
+ (mSeTechMask & NFA_TECHNOLOGY_MASK_F) == 0) {
nfaStat = NFA_EeClearDefaultTechRouting(NFC_DH_ID, NFA_TECHNOLOGY_MASK_F);
if (nfaStat == NFA_STATUS_OK)
mRoutingEvent.wait();
else
- LOG(ERROR) << fn << "Fail to set default tech routing for Nfc-F";
+ LOG(ERROR) << fn << "Fail to clear default tech routing for Nfc-F";
}
- // Default routing for T3T protocol
+ // Clear default routing for T3T protocol
if (!mIsScbrSupported && mDefaultEe == NFC_DH_ID) {
nfaStat = NFA_EeClearDefaultProtoRouting(NFC_DH_ID, NFA_PROTOCOL_MASK_T3T);
if (nfaStat == NFA_STATUS_OK)
mRoutingEvent.wait();
else
- LOG(ERROR) << fn << "Fail to set default proto routing for T3T";
+ LOG(ERROR) << fn << "Fail to clear default proto routing for T3T";
}
}
@@ -661,14 +697,24 @@
}
// Clear DH technology route on NFC-A
- if ((allSeTechMask & NFA_TECHNOLOGY_MASK_A) != 0) {
+ if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_A) &&
+ (allSeTechMask & NFA_TECHNOLOGY_MASK_A) != 0) {
nfaStat = NFA_EeClearDefaultTechRouting(NFC_DH_ID, NFA_TECHNOLOGY_MASK_A);
if (nfaStat != NFA_STATUS_OK)
LOG(ERROR) << "Failed to clear DH technology routing on NFC-A.";
}
+ // Clear DH technology route on NFC-B
+ if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_B) &&
+ (allSeTechMask & NFA_TECHNOLOGY_MASK_B) != 0) {
+ nfaStat = NFA_EeClearDefaultTechRouting(NFC_DH_ID, NFA_TECHNOLOGY_MASK_B);
+ if (nfaStat != NFA_STATUS_OK)
+ LOG(ERROR) << "Failed to clear DH technology routing on NFC-B.";
+ }
+
// Clear DH technology route on NFC-F
- if ((allSeTechMask & NFA_TECHNOLOGY_MASK_F) != 0) {
+ if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_F) &&
+ (allSeTechMask & NFA_TECHNOLOGY_MASK_F) != 0) {
nfaStat = NFA_EeClearDefaultTechRouting(NFC_DH_ID, NFA_TECHNOLOGY_MASK_F);
if (nfaStat != NFA_STATUS_OK)
LOG(ERROR) << "Failed to clear DH technology routing on NFC-F.";
@@ -692,8 +738,11 @@
static const char fn[] = "RoutingManager::nfaEeCallback";
RoutingManager& routingManager = RoutingManager::getInstance();
- if (eventData) routingManager.mCbEventData = *eventData;
-
+ if (!eventData) {
+ LOG(ERROR) << "eventData is null";
+ return;
+ }
+ routingManager.mCbEventData = *eventData;
switch (event) {
case NFA_EE_REGISTER_EVT: {
SyncEventGuard guard(routingManager.mEeRegisterEvent);
diff --git a/nci/jni/RoutingManager.h b/nci/jni/RoutingManager.h
index 4bfc886..51ef4f4 100755
--- a/nci/jni/RoutingManager.h
+++ b/nci/jni/RoutingManager.h
@@ -107,6 +107,7 @@
uint16_t mDefaultSysCodeRoute;
uint8_t mDefaultSysCodePowerstate;
uint8_t mOffHostAidRoutingPowerState;
+ uint8_t mHostListenTechMask;
bool mDeinitializing;
bool mEeInfoChanged;
bool mReceivedEeInfo;
diff --git a/nci/jni/extns/pn54x/inc/phNxpExtns.h b/nci/jni/extns/pn54x/inc/phNxpExtns.h
index 8984aed..17ee6ae 100644
--- a/nci/jni/extns/pn54x/inc/phNxpExtns.h
+++ b/nci/jni/extns/pn54x/inc/phNxpExtns.h
@@ -24,7 +24,7 @@
NFCSTATUS EXTNS_Init(tNFA_DM_CBACK* p_dm_cback, tNFA_CONN_CBACK* p_conn_cback);
void EXTNS_Close(void);
-NFCSTATUS EXTNS_MfcInit(tNFA_ACTIVATED activationData);
+NFCSTATUS EXTNS_MfcInit(tNFA_ACTIVATED& activationData);
NFCSTATUS EXTNS_MfcCheckNDef(void);
NFCSTATUS EXTNS_MfcReadNDef(void);
NFCSTATUS EXTNS_MfcPresenceCheck(void);
diff --git a/nci/jni/extns/pn54x/src/mifare/phFriNfc_MifareStdMap.cpp b/nci/jni/extns/pn54x/src/mifare/phFriNfc_MifareStdMap.cpp
index 78d0ed9..5fcf693 100644
--- a/nci/jni/extns/pn54x/src/mifare/phFriNfc_MifareStdMap.cpp
+++ b/nci/jni/extns/pn54x/src/mifare/phFriNfc_MifareStdMap.cpp
@@ -1379,8 +1379,6 @@
if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD) {
/* if Sector Id > 15 No Sectors to write */
if (SectorID > 15) {
- SectorID =
- phFriNfc_MifStd_H_GetSect(NdefMap->StdMifareContainer.currentBlock);
/*Error: No Ndef Compliant Sectors present */
Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
callbreak = 1;
@@ -1413,8 +1411,6 @@
} else {
phFriNfc_MifStd1k_H_BlkChk(NdefMap, SectorID, &callbreak);
}
- } else {
- phFriNfc_MifStd1k_H_BlkChk(NdefMap, SectorID, &callbreak);
}
} /* End of if*/ /* End of Mifare 2k check*/
else /* Mifare 4k check starts here */
@@ -2676,18 +2672,9 @@
if (*TL4bytesFlag == PH_FRINFC_MIFARESTD_FLAG0) {
(*TempLength) += (NdefMap->SendRecvBuf[TempLen] + PH_FRINFC_MIFARESTD_VAL1);
-
- if (NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG0) {
- LengthRemaining =
- (((*TempLength) < PH_FRINFC_MIFARESTD_BYTES_READ)
- ? PH_FRINFC_MIFARESTD_VAL0
- : (NdefMap->SendRecvBuf[TempLen] - LengthRemaining));
- } else {
- LengthRemaining =
- (((*TempLength) < PH_FRINFC_MIFARESTD_BYTES_READ)
- ? PH_FRINFC_MIFARESTD_VAL0
- : (NdefMap->SendRecvBuf[TempLen] - LengthRemaining));
- }
+ LengthRemaining = (((*TempLength) < PH_FRINFC_MIFARESTD_BYTES_READ)
+ ? PH_FRINFC_MIFARESTD_VAL0
+ : (NdefMap->SendRecvBuf[TempLen] - LengthRemaining));
} else {
*TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0;
if (NdefMap->TLVStruct.NoLbytesinTLV == PH_FRINFC_MIFARESTD_VAL1) {
@@ -3524,8 +3511,8 @@
uint8_t TempLength = PH_FRINFC_MIFARESTD_VAL0;
if (*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) {
- memcpy(&NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL1],
- NdefMap->SendRecvBuf, PH_FRINFC_MIFARESTD_BLOCK_BYTES);
+ memmove(&NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL1],
+ NdefMap->SendRecvBuf, PH_FRINFC_MIFARESTD_BLOCK_BYTES);
/* Write to Ndef TLV Block */
NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
diff --git a/nci/jni/extns/pn54x/src/mifare/phNxpExtns_MifareStd.cpp b/nci/jni/extns/pn54x/src/mifare/phNxpExtns_MifareStd.cpp
index 0693433..3ddc2ca 100644
--- a/nci/jni/extns/pn54x/src/mifare/phNxpExtns_MifareStd.cpp
+++ b/nci/jni/extns/pn54x/src/mifare/phNxpExtns_MifareStd.cpp
@@ -35,7 +35,7 @@
#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
pthread_mutex_t SharedDataMutex = PTHREAD_MUTEX_INITIALIZER;
#endif
-uint8_t current_key[6] = {0};
+uint8_t current_key[PHLIBNFC_MFC_AUTHKEYLEN] = {0};
phNci_mfc_auth_cmd_t gAuthCmdBuf;
static NFCSTATUS phNciNfc_SendMfReq(phNciNfc_TransceiveInfo_t tTranscvInfo,
uint8_t* buff, uint16_t* buffSz);
@@ -637,9 +637,7 @@
/* Set Completion Routine for ReadNdef */
NdefMap->CompletionRoutine[1].CompletionRoutine =
Mfc_ReadNdef_Completion_Routine;
- NdefInfo.NdefContinueRead = (uint8_t)((phLibNfc_Ndef_EBegin == Offset)
- ? PH_FRINFC_NDEFMAP_SEEK_BEGIN
- : PH_FRINFC_NDEFMAP_SEEK_CUR);
+ NdefInfo.NdefContinueRead = (uint8_t)(PH_FRINFC_NDEFMAP_SEEK_BEGIN);
}
PacketData = NdefInfo.psUpperNdefMsg->buffer;
@@ -854,13 +852,15 @@
*******************************************************************************/
NFCSTATUS Mfc_FormatNdef(uint8_t* secretkey, uint8_t len) {
NFCSTATUS status = NFCSTATUS_FAILED;
- uint8_t mif_std_key[6] = {0};
+ uint8_t mif_std_key[PHLIBNFC_MFC_AUTHKEYLEN] = {0};
// static uint8_t Index;
// /*commented to eliminate unused variable warning*/
uint8_t sak = 0;
EXTNS_SetCallBackFlag(false);
+ if (len != PHLIBNFC_MFC_AUTHKEYLEN) return NFCSTATUS_FAILED;
+
memcpy(mif_std_key, secretkey, len);
memcpy(current_key, secretkey, len);
@@ -1534,12 +1534,6 @@
int32_t sdwStat = 0X00;
NFCSTATUS wStatus = NFCSTATUS_INVALID_PARAMETER;
- /*Key Configuration
- uint8_t NdefKey[PHLIBNFC_MFC_AUTHKEYLEN] = {0xD3,0XF7,0xD3,0XF7,0xD3,0XF7};
- uint8_t RawKey[PHLIBNFC_MFC_AUTHKEYLEN] = {0xFF,0XFF,0xFF,0XFF,0xFF,0XFF};
- uint8_t MadKey[PHLIBNFC_MFC_AUTHKEYLEN] = {0xA0,0XA1,0xA2,0XA3,0xA4,0XA5};
- uint8_t Key[PHLIBNFC_MFC_AUTHKEYLEN] = {0x00,0x00,0x00,0x00,0x00,0x00}; */ /*Key used during ndef format*/
-
uint8_t bIndex = 0x00;
uint8_t bNoOfKeys = 0x00;
diff --git a/nci/jni/extns/pn54x/src/mifare/phNxpExtns_MifareStd.h b/nci/jni/extns/pn54x/src/mifare/phNxpExtns_MifareStd.h
index fc40157..465ff9c 100644
--- a/nci/jni/extns/pn54x/src/mifare/phNxpExtns_MifareStd.h
+++ b/nci/jni/extns/pn54x/src/mifare/phNxpExtns_MifareStd.h
@@ -68,16 +68,14 @@
#define NDEF_SENDRCV_BUF_LEN 252U /* Send receive buffer length */
-#define NXP_NUMBER_OF_MFC_KEYS (0x04U)
+#define NXP_NUMBER_OF_MFC_KEYS (0x03U)
#define NXP_MFC_KEY_SIZE (0x06U)
#define NXP_MFC_KEYS \
{ \
{0xA0, 0XA1, 0xA2, 0XA3, 0xA4, 0XA5}, \
- {0xD3, 0XF7, 0xD3, 0XF7, 0xD3, 0XF7}, \
- {0xFF, 0XFF, 0xFF, 0XFF, 0xFF, 0XFF}, { \
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \
- } \
+ {0xD3, 0XF7, 0xD3, 0XF7, 0xD3, 0XF7}, \
+ {0xFF, 0XFF, 0xFF, 0XFF, 0xFF, 0XFF} \
} /* Key used during NDEF format */
#ifndef NCI_MAX_DATA_LEN
diff --git a/nci/jni/extns/pn54x/src/phNxpExtns.cpp b/nci/jni/extns/pn54x/src/phNxpExtns.cpp
index 0c4d0ff..99f03c5 100644
--- a/nci/jni/extns/pn54x/src/phNxpExtns.cpp
+++ b/nci/jni/extns/pn54x/src/phNxpExtns.cpp
@@ -414,7 +414,7 @@
** Returns NFCSTATUS_SUCCESS
**
*******************************************************************************/
-NFCSTATUS EXTNS_MfcInit(tNFA_ACTIVATED activationData) {
+NFCSTATUS EXTNS_MfcInit(tNFA_ACTIVATED& activationData) {
tNFC_ACTIVATE_DEVT rfDetail = activationData.activate_ntf;
NdefMap->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak =
diff --git a/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java b/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java
index 5a57988..027f4ff 100755
--- a/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java
+++ b/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java
@@ -389,6 +389,9 @@
return doSetNfcSecure(enable);
}
+ @Override
+ public native String getNfaStorageDir();
+
/**
* Notifies Ndef Message (TODO: rename into notifyTargetDiscovered)
*/
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index f54d9b8..0c4b54e 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -40,7 +40,7 @@
<string name="status_wifi_connected" msgid="5893022897732105739">"Միացված է"</string>
<string name="title_connect_to_network" msgid="2474034615817280146">"Միանալ ցանցին"</string>
<string name="prompt_connect_to_network" msgid="8511683573657516114">"Միանա՞լ <xliff:g id="NETWORK_SSID">%1$s</xliff:g> ցանցին:"</string>
- <string name="beam_requires_nfc_enabled" msgid="2800366967218600534">"Որպեսզի Android Beam-ն աշխատի, անհրաժեշտ է միացնել NFC-ն: Ցանկանո՞ւմ եք միացնել այն:"</string>
+ <string name="beam_requires_nfc_enabled" msgid="2800366967218600534">"Որպեսզի Android Beam-ն աշխատի, անհրաժեշտ է միացնել NFC-ն։ Ցանկանո՞ւմ եք միացնել այն։"</string>
<string name="android_beam" msgid="1666446406999492763">"Android Beam"</string>
<string name="beam_requires_external_storage_permission" msgid="8798337545702206901">"Հավելվածը չունի արտաքին հիշողություն օգտագործելու թույլտվություն։ Այն անհրաժեշտ է ֆայլը փոխանցելու համար"</string>
<string name="title_confirm_url_open" msgid="8069968913244794478">"Բացե՞լ հղումը"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 8464302..601cf59 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -12,7 +12,7 @@
<string name="beam_canceled" msgid="5425192751826544741">"बीम रद्द"</string>
<string name="cancel" msgid="61873902552555096">"रद्द करा"</string>
<string name="beam_tap_to_view" msgid="7430394753262448349">"पाहण्यासाठी टॅप करा"</string>
- <string name="beam_handover_not_supported" msgid="4083165921751489015">"प्राप्तकर्त्याचे डिव्हाइस बीमद्वारे मोठी फाईल स्थानांतरीत करण्यास सपोर्ट करत नाही."</string>
+ <string name="beam_handover_not_supported" msgid="4083165921751489015">"प्राप्तकर्त्याचे डिव्हाइस बीमद्वारे मोठी फाइल स्थानांतरीत करण्यास सपोर्ट करत नाही."</string>
<string name="beam_try_again" msgid="3364677301009783455">"डिव्हाइसेस पुन्हा एकत्र आणा"</string>
<string name="beam_busy" msgid="5253335587620612576">"बीम करणे सध्या व्यस्त आहे. मागील स्थानांतरीत करणे पूर्ण झाल्यानंतर पुन्हा प्रयत्न करा."</string>
<string name="device" msgid="4459621591392478151">"डिव्हाइस"</string>
diff --git a/res/values-night/styles.xml b/res/values-night/styles.xml
new file mode 100644
index 0000000..64c4afc
--- /dev/null
+++ b/res/values-night/styles.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ 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.
+-->
+
+<resources>
+ <style name="DialogAlertDayNight" parent="@android:style/Theme.DeviceDefault.Dialog.Alert"/>
+</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index aac3e51..7b6eade 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -42,7 +42,7 @@
<string name="prompt_connect_to_network" msgid="8511683573657516114">"Verbinding maken met netwerk <xliff:g id="NETWORK_SSID">%1$s</xliff:g>?"</string>
<string name="beam_requires_nfc_enabled" msgid="2800366967218600534">"NFC moet zijn ingeschakeld voor Android Beam. Wil je dit inschakelen?"</string>
<string name="android_beam" msgid="1666446406999492763">"Android Beam"</string>
- <string name="beam_requires_external_storage_permission" msgid="8798337545702206901">"De app heeft geen toestemming voor externe opslag. Dit recht is nodig om het bestand te beamen."</string>
+ <string name="beam_requires_external_storage_permission" msgid="8798337545702206901">"De app heeft geen rechten voor externe opslag. Dit recht is nodig om het bestand te beamen."</string>
<string name="title_confirm_url_open" msgid="8069968913244794478">"Link openen?"</string>
<string name="summary_confirm_url_open" product="tablet" msgid="3353502750736192055">"Je tablet heeft een link ontvangen via NFC:"</string>
<string name="summary_confirm_url_open" product="default" msgid="1246398412196449226">"Je telefoon heeft een link ontvangen via NFC:"</string>
diff --git a/res/values/config.xml b/res/values/config.xml
index 50ad038..2186cb8 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -5,8 +5,10 @@
<bool name="enable_auto_play">true</bool>
<bool name="enable_notify_dispatch_failed">false</bool>
<bool name="enable_antenna_blocked_alert">false</bool>
+ <bool name="polling_disable_allowed">false</bool>
<integer name="max_antenna_blocked_failure_count">10</integer>
- <integer name="unknown_tag_polling_delay">-1</integer>
+ <integer name="toast_debounce_time_ms">3000</integer>
+ <integer name="unknown_tag_polling_delay">2000</integer>
<!-- List of SKUs where Secure NFC functionality is supported -->
<string-array name="config_skuSupportsSecureNfc" translatable="false" />
diff --git a/res/values/styles.xml b/res/values/styles.xml
new file mode 100644
index 0000000..c98dccc
--- /dev/null
+++ b/res/values/styles.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ 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.
+-->
+
+<resources>
+ <style name="DialogAlertDayNight" parent="@android:style/Theme.DeviceDefault.Light.Dialog.Alert"/>
+</resources>
diff --git a/src/com/android/nfc/BeamShareActivity.java b/src/com/android/nfc/BeamShareActivity.java
index 446e499..37e8d1d 100644
--- a/src/com/android/nfc/BeamShareActivity.java
+++ b/src/com/android/nfc/BeamShareActivity.java
@@ -98,7 +98,7 @@
registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null);
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this,
- AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
+ com.android.nfc.R.style.DialogAlertDayNight);
dialogBuilder.setMessage(msgId);
dialogBuilder.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
diff --git a/src/com/android/nfc/ConfirmConnectToWifiNetworkActivity.java b/src/com/android/nfc/ConfirmConnectToWifiNetworkActivity.java
index eb26198..8752dbb 100644
--- a/src/com/android/nfc/ConfirmConnectToWifiNetworkActivity.java
+++ b/src/com/android/nfc/ConfirmConnectToWifiNetworkActivity.java
@@ -33,7 +33,7 @@
intent.getParcelableExtra(NfcWifiProtectedSetup.EXTRA_WIFI_CONFIG);
String printableSsid = mCurrentWifiConfiguration.getPrintableSsid();
- mAlertDialog = new AlertDialog.Builder(this, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT)
+ mAlertDialog = new AlertDialog.Builder(this, R.style.DialogAlertDayNight)
.setTitle(R.string.title_connect_to_network)
.setMessage(
String.format(getResources().getString(R.string.prompt_connect_to_network),
diff --git a/src/com/android/nfc/DeviceHost.java b/src/com/android/nfc/DeviceHost.java
index 6d3bb12..43722ab 100644
--- a/src/com/android/nfc/DeviceHost.java
+++ b/src/com/android/nfc/DeviceHost.java
@@ -258,4 +258,6 @@
public void shutdown();
public boolean setNfcSecure(boolean enable);
+
+ public String getNfaStorageDir();
}
diff --git a/src/com/android/nfc/ForegroundUtils.java b/src/com/android/nfc/ForegroundUtils.java
index d718537..48d7b88 100644
--- a/src/com/android/nfc/ForegroundUtils.java
+++ b/src/com/android/nfc/ForegroundUtils.java
@@ -112,7 +112,17 @@
}
private boolean isInForegroundLocked(int uid) {
- return mForegroundUidPids.get(uid) != null;
+ if (mForegroundUidPids.get(uid) != null)
+ return true;
+ if (DBG) Log.d(TAG, "Checking UID:" + Integer.toString(uid));
+ try {
+ // If the onForegroundActivitiesChanged() has not yet been called,
+ // check whether the UID is in an active state to use the NFC.
+ return mIActivityManager.isUidActive(uid, NfcApplication.NFC_PROCESS);
+ } catch (RemoteException e) {
+ Log.e(TAG, "ForegroundUtils: could not get isUidActive");
+ }
+ return false;
}
private void handleUidToBackground(int uid) {
diff --git a/src/com/android/nfc/NfcBlockedNotification.java b/src/com/android/nfc/NfcBlockedNotification.java
index 34421cc..9db74f6 100644
--- a/src/com/android/nfc/NfcBlockedNotification.java
+++ b/src/com/android/nfc/NfcBlockedNotification.java
@@ -16,49 +16,61 @@
package com.android.nfc;
-import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
import android.net.Uri;
-import android.os.Bundle;
import android.text.TextUtils;
+
import com.android.nfc.R;
-public class NfcBlockedNotification extends Activity {
+/**
+ * This class handles the Notification Manager for the antenna blocked notification
+ */
+
+public class NfcBlockedNotification {
private static final String NFC_NOTIFICATION_CHANNEL = "nfc_notification_channel";
private NotificationChannel mNotificationChannel;
public static final int NOTIFICATION_ID_NFC = -1000001;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
+ Context mContext;
+
+ /**
+ * Constructor
+ *
+ * @param ctx The context to use to obtain access to the resources
+ */
+ public NfcBlockedNotification(Context ctx) {
+ mContext = ctx;
+ }
+
+ /**
+ * Start the notification.
+ */
+ public void startNotification() {
Intent infoIntent;
- if (TextUtils.isEmpty(getString(R.string.antenna_blocked_alert_link))) {
+ if (TextUtils.isEmpty(mContext.getString(R.string.antenna_blocked_alert_link))) {
// Do nothing after user click the notification if antenna_blocked_alert_link is empty
infoIntent = new Intent();
} else {
// Open the link after user click the notification
infoIntent = new Intent(Intent.ACTION_VIEW);
- infoIntent.setData(Uri.parse(getString(R.string.antenna_blocked_alert_link)));
+ infoIntent.setData(Uri.parse(mContext.getString(R.string.antenna_blocked_alert_link)));
}
- Notification.Builder builder = new Notification.Builder(this, NFC_NOTIFICATION_CHANNEL);
- builder.setContentTitle(getString(R.string.nfc_blocking_alert_title))
- .setContentText(getString(R.string.nfc_blocking_alert_message))
- .setSmallIcon(android.R.drawable.stat_sys_warning)
- .setPriority(NotificationManager.IMPORTANCE_DEFAULT)
- .setAutoCancel(true)
- .setContentIntent(PendingIntent.getActivity(getApplicationContext(), 0, infoIntent,
- PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE));
+ Notification.Builder builder = new Notification.Builder(mContext, NFC_NOTIFICATION_CHANNEL);
+ builder.setContentTitle(mContext.getString(R.string.nfc_blocking_alert_title))
+ .setContentText(mContext.getString(R.string.nfc_blocking_alert_message))
+ .setSmallIcon(android.R.drawable.stat_sys_warning)
+ .setPriority(NotificationManager.IMPORTANCE_DEFAULT)
+ .setAutoCancel(true)
+ .setContentIntent(PendingIntent.getActivity(mContext, 0, infoIntent,
+ PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE));
mNotificationChannel = new NotificationChannel(NFC_NOTIFICATION_CHANNEL,
- getString(R.string.nfcUserLabel), NotificationManager.IMPORTANCE_DEFAULT);
+ mContext.getString(R.string.nfcUserLabel), NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager notificationManager =
- getApplicationContext().getSystemService(NotificationManager.class);
+ mContext.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(mNotificationChannel);
notificationManager.notify(NOTIFICATION_ID_NFC, builder.build());
}
diff --git a/src/com/android/nfc/NfcDiscoveryParameters.java b/src/com/android/nfc/NfcDiscoveryParameters.java
index 1149836..3226aa4 100644
--- a/src/com/android/nfc/NfcDiscoveryParameters.java
+++ b/src/com/android/nfc/NfcDiscoveryParameters.java
@@ -16,6 +16,8 @@
package com.android.nfc;
+import android.util.proto.ProtoOutputStream;
+
/**
* Parameters for enabling NFC tag discovery and polling,
* and host card emulation.
@@ -137,6 +139,15 @@
return sb.toString();
}
+ /** Dumps DiscoveryParamsProto for debugging. */
+ void dumpDebug(ProtoOutputStream proto) {
+ proto.write(DiscoveryParamsProto.TECH_MASK, mTechMask);
+ proto.write(DiscoveryParamsProto.ENABLE_LPD, mEnableLowPowerDiscovery);
+ proto.write(DiscoveryParamsProto.ENABLE_READER, mEnableReaderMode);
+ proto.write(DiscoveryParamsProto.ENABLE_HOST_ROUTING, mEnableHostRouting);
+ proto.write(DiscoveryParamsProto.ENABLE_P2P, mEnableP2p);
+ }
+
public static NfcDiscoveryParameters.Builder newBuilder() {
return new Builder();
}
diff --git a/src/com/android/nfc/NfcDispatcher.java b/src/com/android/nfc/NfcDispatcher.java
index a41cd2e..0f46087 100644
--- a/src/com/android/nfc/NfcDispatcher.java
+++ b/src/com/android/nfc/NfcDispatcher.java
@@ -55,6 +55,7 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
+import android.util.proto.ProtoOutputStream;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
@@ -65,12 +66,12 @@
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.StringJoiner;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
-import android.util.StatsLog;
/**
* Dispatch of NFC events to start activities
*/
@@ -241,7 +242,8 @@
ActivityManager.getCurrentUser());
if (activities.size() > 0) {
context.startActivityAsUser(rootIntent, UserHandle.CURRENT);
- StatsLog.write(StatsLog.NFC_TAG_OCCURRED, StatsLog.NFC_TAG_OCCURRED__TYPE__APP_LAUNCH);
+ NfcStatsLog.write(NfcStatsLog.NFC_TAG_OCCURRED,
+ NfcStatsLog.NFC_TAG_OCCURRED__TYPE__APP_LAUNCH);
return true;
}
return false;
@@ -253,7 +255,8 @@
if (activities.size() > 0) {
rootIntent.putExtra(NfcRootActivity.EXTRA_LAUNCH_INTENT, intentToStart);
context.startActivityAsUser(rootIntent, UserHandle.CURRENT);
- StatsLog.write(StatsLog.NFC_TAG_OCCURRED, StatsLog.NFC_TAG_OCCURRED__TYPE__APP_LAUNCH);
+ NfcStatsLog.write(NfcStatsLog.NFC_TAG_OCCURRED,
+ NfcStatsLog.NFC_TAG_OCCURRED__TYPE__APP_LAUNCH);
return true;
}
return false;
@@ -309,24 +312,28 @@
if (tryOverrides(dispatch, tag, message, overrideIntent, overrideFilters,
overrideTechLists)) {
- StatsLog.write(StatsLog.NFC_TAG_OCCURRED, StatsLog.NFC_TAG_OCCURRED__TYPE__APP_LAUNCH);
+ NfcStatsLog.write(
+ NfcStatsLog.NFC_TAG_OCCURRED, NfcStatsLog.NFC_TAG_OCCURRED__TYPE__APP_LAUNCH);
return screenUnlocked ? DISPATCH_UNLOCK : DISPATCH_SUCCESS;
}
if (tryPeripheralHandover(message)) {
if (DBG) Log.i(TAG, "matched BT HANDOVER");
- StatsLog.write(StatsLog.NFC_TAG_OCCURRED, StatsLog.NFC_TAG_OCCURRED__TYPE__BT_PAIRING);
+ NfcStatsLog.write(
+ NfcStatsLog.NFC_TAG_OCCURRED, NfcStatsLog.NFC_TAG_OCCURRED__TYPE__BT_PAIRING);
return screenUnlocked ? DISPATCH_UNLOCK : DISPATCH_SUCCESS;
}
if (NfcWifiProtectedSetup.tryNfcWifiSetup(ndef, mContext)) {
if (DBG) Log.i(TAG, "matched NFC WPS TOKEN");
- StatsLog.write(StatsLog.NFC_TAG_OCCURRED, StatsLog.NFC_TAG_OCCURRED__TYPE__WIFI_CONNECT);
+ NfcStatsLog.write(
+ NfcStatsLog.NFC_TAG_OCCURRED, NfcStatsLog.NFC_TAG_OCCURRED__TYPE__WIFI_CONNECT);
return screenUnlocked ? DISPATCH_UNLOCK : DISPATCH_SUCCESS;
}
if (provisioningOnly) {
- StatsLog.write(StatsLog.NFC_TAG_OCCURRED, StatsLog.NFC_TAG_OCCURRED__TYPE__PROVISION);
+ NfcStatsLog.write(
+ NfcStatsLog.NFC_TAG_OCCURRED, NfcStatsLog.NFC_TAG_OCCURRED__TYPE__PROVISION);
if (message == null) {
// We only allow NDEF-message dispatch in provisioning mode
return DISPATCH_FAIL;
@@ -361,7 +368,7 @@
}
if (DBG) Log.i(TAG, "no match");
- StatsLog.write(StatsLog.NFC_TAG_OCCURRED, StatsLog.NFC_TAG_OCCURRED__TYPE__OTHERS);
+ NfcStatsLog.write(NfcStatsLog.NFC_TAG_OCCURRED, NfcStatsLog.NFC_TAG_OCCURRED__TYPE__OTHERS);
return DISPATCH_FAIL;
}
@@ -562,7 +569,8 @@
if (dispatch.isWebIntent() && dispatch.hasIntentReceiver()) {
if (DBG) Log.i(TAG, "matched Web link - prompting user");
showWebLinkConfirmation(dispatch);
- StatsLog.write(StatsLog.NFC_TAG_OCCURRED, StatsLog.NFC_TAG_OCCURRED__TYPE__URL);
+ NfcStatsLog.write(
+ NfcStatsLog.NFC_TAG_OCCURRED, NfcStatsLog.NFC_TAG_OCCURRED__TYPE__URL);
return true;
}
@@ -756,7 +764,7 @@
}
AlertDialog.Builder builder = new AlertDialog.Builder(
mContext.getApplicationContext(),
- android.R.style.Theme_DeviceDefault_Light_Dialog_Alert);
+ R.style.DialogAlertDayNight);
builder.setTitle(R.string.title_confirm_url_open);
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.url_open_confirmation, null);
@@ -784,6 +792,30 @@
}
}
+ void dumpDebug(ProtoOutputStream proto) {
+ proto.write(NfcDispatcherProto.DEVICE_SUPPORTS_BLUETOOTH, mDeviceSupportsBluetooth);
+ proto.write(NfcDispatcherProto.BLUETOOTH_ENABLED_BY_NFC, mBluetoothEnabledByNfc.get());
+
+ synchronized (this) {
+ proto.write(NfcDispatcherProto.PROVISIONING_ONLY, mProvisioningOnly);
+ if (mOverrideTechLists != null) {
+ StringJoiner techListsJoiner = new StringJoiner(System.lineSeparator());
+ for (String[] list : mOverrideTechLists) {
+ techListsJoiner.add(Arrays.toString(list));
+ }
+ proto.write(NfcDispatcherProto.OVERRIDE_TECH_LISTS, techListsJoiner.toString());
+ }
+ if (mOverrideIntent != null) {
+ mOverrideIntent.dumpDebug(proto, NfcDispatcherProto.OVERRIDE_INTENT);
+ }
+ if (mOverrideFilters != null) {
+ for (IntentFilter filter : mOverrideFilters) {
+ filter.dumpDebug(proto, NfcDispatcherProto.OVERRIDE_FILTERS);
+ }
+ }
+ }
+ }
+
private class MessageHandler extends Handler {
@Override
public void handleMessage(Message msg) {
diff --git a/src/com/android/nfc/NfcPermissions.java b/src/com/android/nfc/NfcPermissions.java
index 50adf23..c4528a9 100644
--- a/src/com/android/nfc/NfcPermissions.java
+++ b/src/com/android/nfc/NfcPermissions.java
@@ -18,6 +18,14 @@
static final String NFC_PERMISSION = android.Manifest.permission.NFC;
private static final String NFC_PERM_ERROR = "NFC permission required";
+ /**
+ * NFC PREFERRED PAYMENT INFO permission
+ */
+ static final String NFC_PREFERRED_PAYMENT_INFO_PERMISSION =
+ android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO;
+ private static final String NFC_PREFERRED_PAYMENT_INFO_PERM_ERROR =
+ "NFC_PREFERRED_PAYMENT_INFO permission required";
+
public static void validateUserId(int userId) {
if (userId != UserHandle.getCallingUserId()) {
throw new SecurityException("userId passed in is not the calling user.");
@@ -32,4 +40,9 @@
public static void enforceUserPermissions(Context context) {
context.enforceCallingOrSelfPermission(NFC_PERMISSION, NFC_PERM_ERROR);
}
+
+ public static void enforcePreferredPaymentInfoPermissions(Context context) {
+ context.enforceCallingOrSelfPermission(NFC_PREFERRED_PAYMENT_INFO_PERMISSION,
+ NFC_PREFERRED_PAYMENT_INFO_PERM_ERROR);
+ }
}
diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java
index f1ba3be..0bbe4ce 100644
--- a/src/com/android/nfc/NfcService.java
+++ b/src/com/android/nfc/NfcService.java
@@ -18,11 +18,11 @@
import android.app.ActivityManager;
import android.app.Application;
-import android.app.backup.BackupManager;
+import android.app.BroadcastOptions;
import android.app.KeyguardManager;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
-import android.app.BroadcastOptions;
+import android.app.backup.BackupManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -37,7 +37,6 @@
import android.content.pm.UserInfo;
import android.content.res.Resources.NotFoundException;
import android.media.AudioAttributes;
-import android.media.AudioManager;
import android.media.SoundPool;
import android.net.Uri;
import android.nfc.BeamShareData;
@@ -82,6 +81,7 @@
import android.service.vr.IVrStateCallbacks;
import android.text.TextUtils;
import android.util.Log;
+import android.util.proto.ProtoOutputStream;
import android.widget.Toast;
import com.android.internal.logging.MetricsLogger;
@@ -103,16 +103,16 @@
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.Arrays;
+import java.nio.file.Files;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Scanner;
-
-import android.util.StatsLog;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
public class NfcService implements DeviceHostListener {
static final boolean DBG = false;
@@ -138,7 +138,8 @@
static final String TRON_NFC_P2P = "nfc_p2p";
static final String TRON_NFC_TAG = "nfc_tag";
- static final String NATIVE_LOG_FILE_NAME = "native_logs";
+ static final String NATIVE_LOG_FILE_NAME = "native_crash_logs";
+ static final int NATIVE_CRASH_FILE_SIZE = 1024 * 1024;
static final int MSG_NDEF_TAG = 0;
static final int MSG_LLCP_LINK_ACTIVATION = 1;
@@ -158,6 +159,8 @@
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_PREFERRED_PAYMENT_CHANGED = 18;
+ static final int MSG_TOAST_DEBOUNCE_EVENT = 19;
// Negative value for NO polling delay
static final int NO_POLL_DELAY = -1;
@@ -166,6 +169,8 @@
static final long STATS_UPDATE_INTERVAL_MS = 4 * 60 * 60 * 1000;
static final long MAX_POLLING_PAUSE_TIMEOUT = 40000;
+ static final int MAX_TOAST_DEBOUNCE_TIME = 10000;
+
static final int TASK_ENABLE = 1;
static final int TASK_DISABLE = 2;
static final int TASK_BOOT = 3;
@@ -228,6 +233,9 @@
private static int nci_version = NCI_VERSION_1_0;
// NFC Execution Environment
// fields below are protected by this
+ private final boolean mPollingDisableAllowed;
+ private HashMap<Integer, ReaderModeDeathRecipient> mPollingDisableDeathRecipients =
+ new HashMap<Integer, ReaderModeDeathRecipient>();
private final ReaderModeDeathRecipient mReaderModeDeathRecipient =
new ReaderModeDeathRecipient();
private final NfcUnlockManager mNfcUnlockManager;
@@ -237,6 +245,10 @@
// cached version of installed packages requesting Android.permission.NFC_TRANSACTION_EVENTS
List<String> mNfcEventInstalledPackages = new ArrayList<String>();
+ // cached version of installed packages requesting
+ // Android.permission.NFC_PREFERRED_PAYMENT_INFO
+ List<String> mNfcPreferredPaymentChangedInstalledPackages = new ArrayList<String>();
+
// fields below are used in multiple threads and protected by synchronized(this)
final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>();
int mScreenState;
@@ -312,7 +324,8 @@
private ForegroundUtils mForegroundUtils;
private static NfcService sService;
- private static Toast mToast;
+ private static boolean sToast_debounce = false;
+ private static int sToast_debounce_time_ms = 3000;
public static boolean sIsDtaMode = false;
private IVrManager vrManager;
@@ -395,7 +408,8 @@
public void onNfcTransactionEvent(byte[] aid, byte[] data, String seName) {
byte[][] dataObj = {aid, data, seName.getBytes()};
sendMessage(NfcService.MSG_TRANSACTION_EVENT, dataObj);
- StatsLog.write(StatsLog.NFC_CARDEMULATION_OCCURRED, StatsLog.NFC_CARDEMULATION_OCCURRED__CATEGORY__OFFHOST, seName);
+ NfcStatsLog.write(NfcStatsLog.NFC_CARDEMULATION_OCCURRED,
+ NfcStatsLog.NFC_CARDEMULATION_OCCURRED__CATEGORY__OFFHOST, seName);
}
@Override
@@ -519,6 +533,11 @@
mIsSecureNfcCapable;
mDeviceHost.setNfcSecure(mIsSecureNfcEnabled);
+ sToast_debounce_time_ms =
+ mContext.getResources().getInteger(R.integer.toast_debounce_time_ms);
+ if(sToast_debounce_time_ms > MAX_TOAST_DEBOUNCE_TIME) {
+ sToast_debounce_time_ms = MAX_TOAST_DEBOUNCE_TIME;
+ }
// Notification message variables
mDispatchFailedCount = 0;
@@ -535,6 +554,8 @@
mPollDelay = mContext.getResources().getInteger(R.integer.unknown_tag_polling_delay);
mNotifyDispatchFailed = mContext.getResources().getBoolean(R.bool.enable_notify_dispatch_failed);
+ mPollingDisableAllowed = mContext.getResources().getBoolean(R.bool.polling_disable_allowed);
+
// Make sure this is only called when object construction is complete.
ServiceManager.addService(SERVICE_NAME, mNfcAdapter);
@@ -596,11 +617,19 @@
List<PackageInfo> packagesNfcEvents = pm.getPackagesHoldingPermissions(
new String[] {android.Manifest.permission.NFC_TRANSACTION_EVENT},
PackageManager.GET_ACTIVITIES);
+ List<PackageInfo> packagesNfcPreferredPaymentChanged = pm.getPackagesHoldingPermissions(
+ new String[] {android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO},
+ PackageManager.GET_ACTIVITIES);
synchronized (this) {
mNfcEventInstalledPackages.clear();
for (int i = 0; i < packagesNfcEvents.size(); i++) {
mNfcEventInstalledPackages.add(packagesNfcEvents.get(i).packageName);
}
+ mNfcPreferredPaymentChangedInstalledPackages.clear();
+ for (int i = 0; i < packagesNfcPreferredPaymentChanged.size(); i++) {
+ mNfcPreferredPaymentChangedInstalledPackages.add(
+ packagesNfcPreferredPaymentChanged.get(i).packageName);
+ }
}
}
@@ -696,7 +725,8 @@
return true;
}
Log.i(TAG, "Enabling NFC");
- StatsLog.write(StatsLog.NFC_STATE_CHANGED, StatsLog.NFC_STATE_CHANGED__STATE__ON);
+ NfcStatsLog.write(
+ NfcStatsLog.NFC_STATE_CHANGED, NfcStatsLog.NFC_STATE_CHANGED__STATE__ON);
updateState(NfcAdapter.STATE_TURNING_ON);
WatchDogThread watchDog = new WatchDogThread("enableInternal", INIT_WATCHDOG_MS);
@@ -730,6 +760,8 @@
mP2pLinkManager.enableDisable(mIsNdefPushEnabled, true);
}
updateState(NfcAdapter.STATE_ON);
+
+ onPreferredPaymentChanged(NfcAdapter.PREFERRED_PAYMENT_LOADED);
}
initSoundPool();
@@ -743,6 +775,8 @@
mDeviceHost.doSetScreenState(screen_state_mask);
+ sToast_debounce = false;
+
/* Start polling loop */
applyRouting(true);
@@ -758,7 +792,8 @@
return true;
}
Log.i(TAG, "Disabling NFC");
- StatsLog.write(StatsLog.NFC_STATE_CHANGED, StatsLog.NFC_STATE_CHANGED__STATE__OFF);
+ NfcStatsLog.write(
+ NfcStatsLog.NFC_STATE_CHANGED, NfcStatsLog.NFC_STATE_CHANGED__STATE__OFF);
updateState(NfcAdapter.STATE_TURNING_OFF);
/* Sometimes mDeviceHost.deinitialize() hangs, use a watch-dog.
@@ -994,9 +1029,11 @@
mCardEmulationManager.onSecureNfcToggled();
}
if (enable)
- StatsLog.write(StatsLog.NFC_STATE_CHANGED, StatsLog.NFC_STATE_CHANGED__STATE__ON_LOCKED);
+ NfcStatsLog.write(NfcStatsLog.NFC_STATE_CHANGED,
+ NfcStatsLog.NFC_STATE_CHANGED__STATE__ON_LOCKED);
else
- StatsLog.write(StatsLog.NFC_STATE_CHANGED, StatsLog.NFC_STATE_CHANGED__STATE__ON);
+ NfcStatsLog.write(
+ NfcStatsLog.NFC_STATE_CHANGED, NfcStatsLog.NFC_STATE_CHANGED__STATE__ON);
return true;
}
@@ -1213,39 +1250,68 @@
public void setReaderMode(IBinder binder, IAppCallback callback, int flags, Bundle extras)
throws RemoteException {
int callingUid = Binder.getCallingUid();
- if (callingUid != Process.SYSTEM_UID && !mForegroundUtils.isInForeground(callingUid)) {
+ int callingPid = Binder.getCallingPid();
+ // Allow non-foreground callers with system uid or systemui
+ boolean privilegedCaller = (callingUid == Process.SYSTEM_UID
+ || getPackageNameFromUid(callingUid).equals("com.android.systemui"));
+ if (!privilegedCaller && !mForegroundUtils.isInForeground(callingUid)) {
Log.e(TAG, "setReaderMode: Caller is not in foreground and is not system process.");
return;
}
+ boolean disablePolling = flags != 0 && getReaderModeTechMask(flags) == 0;
+ // Only allow to disable polling for specific callers
+ if (disablePolling && !(privilegedCaller && mPollingDisableAllowed)) {
+ Log.e(TAG, "setReaderMode() called with invalid flag parameter.");
+ return;
+ }
synchronized (NfcService.this) {
- if (!isNfcEnabled()) {
+ if (!isNfcEnabled() && !privilegedCaller) {
Log.e(TAG, "setReaderMode() called while NFC is not enabled.");
return;
}
if (flags != 0) {
try {
- mReaderModeParams = new ReaderModeParams();
- mReaderModeParams.callback = callback;
- mReaderModeParams.flags = flags;
- mReaderModeParams.presenceCheckDelay = extras != null
- ? (extras.getInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY,
- DEFAULT_PRESENCE_CHECK_DELAY))
- : DEFAULT_PRESENCE_CHECK_DELAY;
- binder.linkToDeath(mReaderModeDeathRecipient, 0);
+ if (disablePolling) {
+ ReaderModeDeathRecipient pollingDisableDeathRecipient =
+ new ReaderModeDeathRecipient();
+ binder.linkToDeath(pollingDisableDeathRecipient, 0);
+ mPollingDisableDeathRecipients.put(
+ callingPid, pollingDisableDeathRecipient);
+ } else {
+ if (mPollingDisableDeathRecipients.size() != 0) {
+ Log.e(TAG, "active polling is forced to disable now.");
+ return;
+ }
+ binder.linkToDeath(mReaderModeDeathRecipient, 0);
+ }
+ updateReaderModeParams(callback, flags, extras);
} catch (RemoteException e) {
Log.e(TAG, "Remote binder has already died.");
return;
}
} else {
try {
- mReaderModeParams = null;
- StopPresenceChecking();
- binder.unlinkToDeath(mReaderModeDeathRecipient, 0);
+ ReaderModeDeathRecipient pollingDisableDeathRecipient =
+ mPollingDisableDeathRecipients.get(callingPid);
+ mPollingDisableDeathRecipients.remove(callingPid);
+
+ if (mPollingDisableDeathRecipients.size() == 0) {
+ mReaderModeParams = null;
+ StopPresenceChecking();
+ }
+
+ if (pollingDisableDeathRecipient != null) {
+ binder.unlinkToDeath(pollingDisableDeathRecipient, 0);
+ } else {
+ binder.unlinkToDeath(mReaderModeDeathRecipient, 0);
+ }
} catch (NoSuchElementException e) {
Log.e(TAG, "Reader mode Binder was never registered.");
}
}
- applyRouting(false);
+ if (isNfcEnabled()) {
+ applyRouting(false);
+ }
}
}
@@ -1316,6 +1382,50 @@
return mask;
}
+
+ private int getReaderModeTechMask(int flags) {
+ int techMask = 0;
+ if ((flags & NfcAdapter.FLAG_READER_NFC_A) != 0) {
+ techMask |= NFC_POLL_A;
+ }
+ if ((flags & NfcAdapter.FLAG_READER_NFC_B) != 0) {
+ techMask |= NFC_POLL_B;
+ }
+ if ((flags & NfcAdapter.FLAG_READER_NFC_F) != 0) {
+ techMask |= NFC_POLL_F;
+ }
+ if ((flags & NfcAdapter.FLAG_READER_NFC_V) != 0) {
+ techMask |= NFC_POLL_V;
+ }
+ if ((flags & NfcAdapter.FLAG_READER_NFC_BARCODE) != 0) {
+ techMask |= NFC_POLL_KOVIO;
+ }
+
+ return techMask;
+ }
+
+ private String getPackageNameFromUid(int uid) {
+ PackageManager packageManager = mContext.getPackageManager();
+ if (packageManager != null) {
+ String[] packageName = packageManager.getPackagesForUid(uid);
+ if (packageName != null && packageName.length > 0) {
+ return packageName[0];
+ }
+ }
+ return null;
+ }
+
+ private void updateReaderModeParams(IAppCallback callback, int flags, Bundle extras) {
+ synchronized (NfcService.this) {
+ mReaderModeParams = new ReaderModeParams();
+ mReaderModeParams.callback = callback;
+ mReaderModeParams.flags = flags;
+ mReaderModeParams.presenceCheckDelay = extras != null
+ ? (extras.getInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY,
+ DEFAULT_PRESENCE_CHECK_DELAY))
+ : DEFAULT_PRESENCE_CHECK_DELAY;
+ }
+ }
}
final class ReaderModeDeathRecipient implements IBinder.DeathRecipient {
@@ -1323,8 +1433,11 @@
public void binderDied() {
synchronized (NfcService.this) {
if (mReaderModeParams != null) {
- mReaderModeParams = null;
- applyRouting(false);
+ mPollingDisableDeathRecipients.values().remove(this);
+ if (mPollingDisableDeathRecipients.size() == 0) {
+ mReaderModeParams = null;
+ applyRouting(false);
+ }
}
}
}
@@ -1776,7 +1889,8 @@
mRoutingWakeLock.release();
}
Log.e(TAG, "Watchdog triggered, aborting.");
- StatsLog.write(StatsLog.NFC_STATE_CHANGED, StatsLog.NFC_STATE_CHANGED__STATE__CRASH_RESTART);
+ NfcStatsLog.write(NfcStatsLog.NFC_STATE_CHANGED,
+ NfcStatsLog.NFC_STATE_CHANGED__STATE__CRASH_RESTART);
storeNativeCrashLogs();
mDeviceHost.doAbort(getName());
}
@@ -1873,6 +1987,9 @@
paramsBuilder.setTechMask(techMask);
paramsBuilder.setEnableReaderMode(true);
+ if (mReaderModeParams.flags != 0 && techMask == 0) {
+ paramsBuilder.setEnableHostRouting(true);
+ }
} else {
paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT);
paramsBuilder.setEnableP2p(mIsBeamCapable);
@@ -2082,6 +2199,10 @@
return mDeviceHost.sendRawFrame(data);
}
+ public void onPreferredPaymentChanged(int reason) {
+ sendMessage(MSG_PREFERRED_PAYMENT_CHANGED, reason);
+ }
+
void sendMessage(int what, Object obj) {
Message msg = mHandler.obtainMessage();
msg.what = what;
@@ -2171,10 +2292,6 @@
case MSG_NDEF_TAG:
if (DBG) Log.d(TAG, "Tag detected, notifying applications");
- if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) {
- mPowerManager.userActivity(SystemClock.uptimeMillis(),
- PowerManager.USER_ACTIVITY_EVENT_OTHER, 0);
- }
mNumTagsDetected.incrementAndGet();
TagEndpoint tag = (TagEndpoint) msg.obj;
byte[] debounceTagUid;
@@ -2224,12 +2341,13 @@
if (!tag.reconnect()) {
tag.disconnect();
if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) {
- if (mToast != null) {
- if (mToast.getView().isShown()) mToast.cancel();
+ if (!sToast_debounce) {
+ Toast.makeText(mContext, R.string.tag_read_error,
+ Toast.LENGTH_SHORT).show();
+ sToast_debounce = true;
+ mHandler.sendEmptyMessageDelayed(MSG_TOAST_DEBOUNCE_EVENT,
+ sToast_debounce_time_ms);
}
- mToast = Toast.makeText(mContext, R.string.tag_read_error,
- Toast.LENGTH_SHORT);
- mToast.show();
}
break;
}
@@ -2381,6 +2499,18 @@
sendOffHostTransactionEvent(data[0], data[1], data[2]);
break;
+ case MSG_PREFERRED_PAYMENT_CHANGED:
+ Intent preferredPaymentChangedIntent =
+ new Intent(NfcAdapter.ACTION_PREFERRED_PAYMENT_CHANGED);
+ preferredPaymentChangedIntent.putExtra(
+ NfcAdapter.EXTRA_PREFERRED_PAYMENT_CHANGED_REASON, (int)msg.obj);
+ sendPreferredPaymentChangedEvent(preferredPaymentChangedIntent);
+ break;
+
+ case MSG_TOAST_DEBOUNCE_EVENT:
+ sToast_debounce = false;
+ break;
+
default:
Log.e(TAG, "Unknown message received");
break;
@@ -2510,6 +2640,94 @@
}
}
+ /* Returns the list of packages request for nfc preferred payment service changed and
+ * have access to NFC Events on any SE */
+ private ArrayList<String> getNfcPreferredPaymentChangedSEAccessAllowedPackages() {
+ if (!isSEServiceAvailable() || mNfcPreferredPaymentChangedInstalledPackages.isEmpty()) {
+ return null;
+ }
+ String[] readers = null;
+ try {
+ readers = mSEService.getReaders();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error in getReaders() " + e);
+ return null;
+ }
+
+ if (readers == null || readers.length == 0) {
+ return null;
+ }
+ boolean[] nfcAccessFinal = null;
+ String[] installedPackages =
+ new String[mNfcPreferredPaymentChangedInstalledPackages.size()];
+ for (String reader : readers) {
+ try {
+ boolean[] accessList = mSEService.isNFCEventAllowed(reader, null,
+ mNfcPreferredPaymentChangedInstalledPackages.toArray(installedPackages)
+ );
+ if (accessList == null) {
+ continue;
+ }
+ if (nfcAccessFinal == null) {
+ nfcAccessFinal = accessList;
+ }
+ for (int i = 0; i < accessList.length; i++) {
+ if (accessList[i]) {
+ nfcAccessFinal[i] = true;
+ }
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error in isNFCEventAllowed() " + e);
+ }
+ }
+ if (nfcAccessFinal == null) {
+ return null;
+ }
+ ArrayList<String> packages = new ArrayList<String>();
+ for (int i = 0; i < nfcAccessFinal.length; i++) {
+ if (nfcAccessFinal[i]) {
+ packages.add(mNfcPreferredPaymentChangedInstalledPackages.get(i));
+ }
+ }
+ return packages;
+ }
+
+ private void sendPreferredPaymentChangedEvent(Intent intent) {
+ intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
+ // Resume app switches so the receivers can start activities without delay
+ mNfcDispatcher.resumeAppSwitches();
+ synchronized (this) {
+ ArrayList<String> SEPackages =
+ getNfcPreferredPaymentChangedSEAccessAllowedPackages();
+ if (SEPackages!= null && !SEPackages.isEmpty()) {
+ for (String packageName : SEPackages) {
+ intent.setPackage(packageName);
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ mContext.sendBroadcast(intent);
+ }
+ }
+ PackageManager pm = mContext.getPackageManager();
+ for (String packageName : mNfcPreferredPaymentChangedInstalledPackages) {
+ try {
+ PackageInfo info = pm.getPackageInfo(packageName, 0);
+ if (SEPackages != null && SEPackages.contains(packageName)) {
+ continue;
+ }
+ if (info.applicationInfo != null &&
+ ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 ||
+ (info.applicationInfo.privateFlags &
+ ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0)) {
+ intent.setPackage(packageName);
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ mContext.sendBroadcast(intent);
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Exception in getPackageInfo " + e);
+ }
+ }
+ }
+ }
+
private boolean llcpActivated(NfcDepEndpoint device) {
Log.d(TAG, "LLCP Activation message");
@@ -2577,6 +2795,10 @@
playSound(SOUND_END);
}
if (readerParams.callback != null) {
+ if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) {
+ mPowerManager.userActivity(SystemClock.uptimeMillis(),
+ PowerManager.USER_ACTIVITY_EVENT_OTHER, 0);
+ }
readerParams.callback.onTagDiscovered(tag);
return;
} else {
@@ -2601,21 +2823,18 @@
} else {
Log.e(TAG, "Keep presence checking.");
}
- if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED &&
- mContext.getResources().getBoolean(R.bool.enable_notify_dispatch_failed)) {
- if (mToast != null) {
- if (mToast.getView().isShown()) mToast.cancel();
+ if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED && mNotifyDispatchFailed) {
+ if (!sToast_debounce) {
+ Toast.makeText(mContext, R.string.tag_dispatch_failed,
+ Toast.LENGTH_SHORT).show();
+ sToast_debounce = true;
+ mHandler.sendEmptyMessageDelayed(MSG_TOAST_DEBOUNCE_EVENT,
+ sToast_debounce_time_ms);
}
- mToast = Toast.makeText(mContext, R.string.tag_dispatch_failed,
- Toast.LENGTH_SHORT);
- mToast.show();
playSound(SOUND_ERROR);
}
if (!mAntennaBlockedMessageShown && mDispatchFailedCount++ > mDispatchFailedMax) {
- Intent dialogIntent = new Intent(mContext, NfcBlockedNotification.class);
- dialogIntent.setFlags(
- Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- mContext.startActivity(dialogIntent);
+ new NfcBlockedNotification(mContext).startNotification();
mPrefsEditor.putBoolean(PREF_ANTENNA_BLOCKED_MESSAGE_SHOWN, true);
mPrefsEditor.apply();
mBackupManager.dataChanged();
@@ -2624,6 +2843,10 @@
if (DBG) Log.d(TAG, "Tag dispatch failed notification");
}
} else if (dispatchResult == NfcDispatcher.DISPATCH_SUCCESS) {
+ if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) {
+ mPowerManager.userActivity(SystemClock.uptimeMillis(),
+ PowerManager.USER_ACTIVITY_EVENT_OTHER, 0);
+ }
mDispatchFailedCount = 0;
mVibrator.vibrate(mVibrationEffect);
playSound(SOUND_END);
@@ -2686,6 +2909,7 @@
sendMessage(NfcService.MSG_APPLY_SCREEN_STATE, screenState);
} else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+ mUserId = userId;
if (mIsBeamCapable) {
int beamSetting =
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
@@ -2700,7 +2924,6 @@
Log.e(TAG, "Error int getComponentEnabledSetting for BeamShareActivity");
}
synchronized (this) {
- mUserId = userId;
if (beamSetting == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
mIsNdefPushEnabled = false;
} else {
@@ -2785,9 +3008,28 @@
}
}
+ static int stateToProtoEnum(int state) {
+ switch (state) {
+ case NfcAdapter.STATE_OFF:
+ return NfcServiceDumpProto.STATE_OFF;
+ case NfcAdapter.STATE_TURNING_ON:
+ return NfcServiceDumpProto.STATE_TURNING_ON;
+ case NfcAdapter.STATE_ON:
+ return NfcServiceDumpProto.STATE_ON;
+ case NfcAdapter.STATE_TURNING_OFF:
+ return NfcServiceDumpProto.STATE_TURNING_OFF;
+ default:
+ return NfcServiceDumpProto.STATE_UNKNOWN;
+ }
+ }
+
+ public String getNfaStorageDir() {
+ return mDeviceHost.getNfaStorageDir();
+ }
+
private void copyNativeCrashLogsIfAny(PrintWriter pw) {
try {
- File file = new File(mContext.getFilesDir(), NATIVE_LOG_FILE_NAME);
+ File file = new File(getNfaStorageDir(), NATIVE_LOG_FILE_NAME);
if (!file.exists()) {
return;
}
@@ -2806,12 +3048,12 @@
private void storeNativeCrashLogs() {
try {
- File file = new File(mContext.getFilesDir(), NATIVE_LOG_FILE_NAME);
- if (!file.exists()) {
+ File file = new File(getNfaStorageDir(), NATIVE_LOG_FILE_NAME);
+ if (file.length() >= NATIVE_CRASH_FILE_SIZE) {
file.createNewFile();
}
- FileOutputStream fos = new FileOutputStream(file);
+ FileOutputStream fos = new FileOutputStream(file, true);
mDeviceHost.dump(fos.getFD());
fos.flush();
fos.close();
@@ -2829,13 +3071,26 @@
return;
}
+ for (String arg : args) {
+ if ("--proto".equals(arg)) {
+ ProtoOutputStream proto = new ProtoOutputStream(new FileOutputStream(fd));
+ synchronized (this) {
+ dumpDebug(proto);
+ }
+ proto.flush();
+ return;
+ }
+ }
+
synchronized (this) {
pw.println("mState=" + stateToString(mState));
pw.println("mIsZeroClickRequested=" + mIsNdefPushEnabled);
pw.println("mScreenState=" + ScreenStateHelper.screenStateToString(mScreenState));
+ pw.println("mIsSecureNfcEnabled=" + mIsSecureNfcEnabled);
pw.println(mCurrentDiscoveryParameters);
- if (mIsBeamCapable)
+ if (mIsBeamCapable) {
mP2pLinkManager.dump(fd, pw, args);
+ }
if (mIsHceCapable) {
mCardEmulationManager.dump(fd, pw, args);
}
@@ -2845,4 +3100,63 @@
mDeviceHost.dump(fd);
}
}
+
+ /**
+ * Dump debugging information as a NfcServiceDumpProto
+ *
+ * Note:
+ * See proto definition in frameworks/base/core/proto/android/nfc/nfc_service.proto
+ * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
+ * {@link ProtoOutputStream#end(long)} after.
+ * Never reuse a proto field number. When removing a field, mark it as reserved.
+ */
+ private void dumpDebug(ProtoOutputStream proto) {
+ proto.write(NfcServiceDumpProto.STATE, stateToProtoEnum(mState));
+ proto.write(NfcServiceDumpProto.IN_PROVISION_MODE, mInProvisionMode);
+ proto.write(NfcServiceDumpProto.NDEF_PUSH_ENABLED, mIsNdefPushEnabled);
+ proto.write(NfcServiceDumpProto.SCREEN_STATE,
+ ScreenStateHelper.screenStateToProtoEnum(mScreenState));
+ proto.write(NfcServiceDumpProto.SECURE_NFC_ENABLED, mIsSecureNfcEnabled);
+ proto.write(NfcServiceDumpProto.POLLING_PAUSED, mPollingPaused);
+ proto.write(NfcServiceDumpProto.NUM_TAGS_DETECTED, mNumTagsDetected.get());
+ proto.write(NfcServiceDumpProto.NUM_P2P_DETECTED, mNumP2pDetected.get());
+ proto.write(NfcServiceDumpProto.NUM_HCE_DETECTED, mNumHceDetected.get());
+ proto.write(NfcServiceDumpProto.HCE_CAPABLE, mIsHceCapable);
+ proto.write(NfcServiceDumpProto.HCE_F_CAPABLE, mIsHceFCapable);
+ proto.write(NfcServiceDumpProto.BEAM_CAPABLE, mIsBeamCapable);
+ proto.write(NfcServiceDumpProto.SECURE_NFC_CAPABLE, mIsSecureNfcCapable);
+ proto.write(NfcServiceDumpProto.VR_MODE_ENABLED, mIsVrModeEnabled);
+
+ long token = proto.start(NfcServiceDumpProto.DISCOVERY_PARAMS);
+ mCurrentDiscoveryParameters.dumpDebug(proto);
+ proto.end(token);
+
+ if (mIsBeamCapable) {
+ token = proto.start(NfcServiceDumpProto.P2P_LINK_MANAGER);
+ mP2pLinkManager.dumpDebug(proto);
+ proto.end(token);
+ }
+
+ if (mIsHceCapable) {
+ token = proto.start(NfcServiceDumpProto.CARD_EMULATION_MANAGER);
+ mCardEmulationManager.dumpDebug(proto);
+ proto.end(token);
+ }
+
+ token = proto.start(NfcServiceDumpProto.NFC_DISPATCHER);
+ mNfcDispatcher.dumpDebug(proto);
+ proto.end(token);
+
+ // Dump native crash logs if any
+ File file = new File(getNfaStorageDir(), NATIVE_LOG_FILE_NAME);
+ if (!file.exists()) {
+ return;
+ }
+ try {
+ String logs = Files.lines(file.toPath()).collect(Collectors.joining("\n"));
+ proto.write(NfcServiceDumpProto.NATIVE_CRASH_LOGS, logs);
+ } catch (IOException e) {
+ Log.e(TAG, "IOException in dumpDebug(ProtoOutputStream): " + e);
+ }
+ }
}
diff --git a/src/com/android/nfc/P2pLinkManager.java b/src/com/android/nfc/P2pLinkManager.java
index ae818a3..89ac067 100755
--- a/src/com/android/nfc/P2pLinkManager.java
+++ b/src/com/android/nfc/P2pLinkManager.java
@@ -61,7 +61,8 @@
import java.util.List;
import java.io.UnsupportedEncodingException;
-import android.util.StatsLog;
+import android.util.proto.ProtoOutputStream;
+
/**
* Interface to listen for P2P events.
* All callbacks are made from the UI thread.
@@ -1108,7 +1109,8 @@
mSendState = SEND_STATE_NOTHING_TO_SEND;
if (DBG) Log.d(TAG, "onP2pReceiveComplete()");
mEventListener.onP2pReceiveComplete(false);
- StatsLog.write(StatsLog.NFC_BEAM_OCCURRED, StatsLog.NFC_BEAM_OCCURRED__OPERATION__RECEIVE);
+ NfcStatsLog.write(NfcStatsLog.NFC_BEAM_OCCURRED,
+ NfcStatsLog.NFC_BEAM_OCCURRED__OPERATION__RECEIVE);
}
break;
case MSG_RECEIVE_COMPLETE:
@@ -1124,7 +1126,8 @@
if (DBG) Log.d(TAG, "onP2pReceiveComplete()");
mEventListener.onP2pReceiveComplete(true);
NfcService.getInstance().sendMockNdefTag(m);
- StatsLog.write(StatsLog.NFC_BEAM_OCCURRED, StatsLog.NFC_BEAM_OCCURRED__OPERATION__RECEIVE);
+ NfcStatsLog.write(NfcStatsLog.NFC_BEAM_OCCURRED,
+ NfcStatsLog.NFC_BEAM_OCCURRED__OPERATION__RECEIVE);
}
break;
case MSG_HANDOVER_NOT_SUPPORTED:
@@ -1157,7 +1160,8 @@
Log.e(TAG, "Failed NDEF completed callback: " + e.getMessage());
}
}
- StatsLog.write(StatsLog.NFC_BEAM_OCCURRED, StatsLog.NFC_BEAM_OCCURRED__OPERATION__SEND);
+ NfcStatsLog.write(NfcStatsLog.NFC_BEAM_OCCURRED,
+ NfcStatsLog.NFC_BEAM_OCCURRED__OPERATION__SEND);
}
break;
case MSG_HANDOVER_BUSY:
@@ -1242,6 +1246,23 @@
}
}
+ static int sendStateToProtoEnum(int state) {
+ switch (state) {
+ case SEND_STATE_NOTHING_TO_SEND:
+ return P2pLinkManagerProto.SEND_STATE_NOTHING_TO_SEND;
+ case SEND_STATE_NEED_CONFIRMATION:
+ return P2pLinkManagerProto.SEND_STATE_NEED_CONFIRMATION;
+ case SEND_STATE_SENDING:
+ return P2pLinkManagerProto.SEND_STATE_SENDING;
+ case SEND_STATE_COMPLETE:
+ return P2pLinkManagerProto.SEND_STATE_COMPLETE;
+ case SEND_STATE_CANCELED:
+ return P2pLinkManagerProto.SEND_STATE_CANCELED;
+ default:
+ return P2pLinkManagerProto.SEND_STATE_UNKNOWN;
+ }
+ }
+
static String linkStateToString(int state) {
switch (state) {
case LINK_STATE_DOWN:
@@ -1255,6 +1276,19 @@
}
}
+ static int linkStateToProtoEnum(int state) {
+ switch (state) {
+ case LINK_STATE_DOWN:
+ return P2pLinkManagerProto.LINK_STATE_DOWN;
+ case LINK_STATE_DEBOUNCE:
+ return P2pLinkManagerProto.LINK_STATE_DEBOUNCE;
+ case LINK_STATE_UP:
+ return P2pLinkManagerProto.LINK_STATE_UP;
+ default:
+ return P2pLinkManagerProto.LINK_STATE_UNKNOWN;
+ }
+ }
+
void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
synchronized (this) {
pw.println("mIsSendEnabled=" + mIsSendEnabled);
@@ -1267,4 +1301,34 @@
pw.println("mUrisToSend=" + mUrisToSend);
}
}
+
+ /**
+ * Dump debugging information as a P2pLinkManagerProto
+ *
+ * Note:
+ * See proto definition in frameworks/base/core/proto/android/nfc/nfc_service.proto
+ * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
+ * {@link ProtoOutputStream#end(long)} after.
+ * Never reuse a proto field number. When removing a field, mark it as reserved.
+ */
+ void dumpDebug(ProtoOutputStream proto) {
+ proto.write(P2pLinkManagerProto.DEFAULT_MIU, mDefaultMiu);
+ proto.write(P2pLinkManagerProto.DEFAULT_RW_SIZE, mDefaultRwSize);
+ proto.write(P2pLinkManagerProto.LINK_STATE, linkStateToProtoEnum(mLinkState));
+ proto.write(P2pLinkManagerProto.SEND_STATE, sendStateToProtoEnum(mSendState));
+ proto.write(P2pLinkManagerProto.SEND_FLAGS, mSendFlags);
+ proto.write(P2pLinkManagerProto.SEND_ENABLED, mIsSendEnabled);
+ proto.write(P2pLinkManagerProto.RECEIVE_ENABLED, mIsReceiveEnabled);
+ proto.write(P2pLinkManagerProto.CALLBACK_NDEF, String.valueOf(mCallbackNdef));
+ if (mMessageToSend != null) {
+ long token = proto.start(P2pLinkManagerProto.MESSAGE_TO_SEND);
+ mMessageToSend.dumpDebug(proto);
+ proto.end(token);
+ }
+ if (mUrisToSend != null && mUrisToSend.length > 0) {
+ for (Uri uri : mUrisToSend) {
+ proto.write(P2pLinkManagerProto.URIS_TO_SEND, uri.toString());
+ }
+ }
+ }
}
diff --git a/src/com/android/nfc/ScreenStateHelper.java b/src/com/android/nfc/ScreenStateHelper.java
index 92ba168..22ff13d 100644
--- a/src/com/android/nfc/ScreenStateHelper.java
+++ b/src/com/android/nfc/ScreenStateHelper.java
@@ -61,4 +61,19 @@
return "UNKNOWN";
}
}
+
+ static int screenStateToProtoEnum(int screenState) {
+ switch (screenState) {
+ case SCREEN_STATE_OFF_LOCKED:
+ return NfcServiceDumpProto.SCREEN_STATE_OFF_LOCKED;
+ case SCREEN_STATE_ON_LOCKED:
+ return NfcServiceDumpProto.SCREEN_STATE_ON_LOCKED;
+ case SCREEN_STATE_ON_UNLOCKED:
+ return NfcServiceDumpProto.SCREEN_STATE_ON_UNLOCKED;
+ case SCREEN_STATE_OFF_UNLOCKED:
+ return NfcServiceDumpProto.SCREEN_STATE_OFF_UNLOCKED;
+ default:
+ return NfcServiceDumpProto.SCREEN_STATE_UNKNOWN;
+ }
+ }
}
diff --git a/src/com/android/nfc/beam/SendUi.java b/src/com/android/nfc/beam/SendUi.java
index ab35467..49f893c 100644
--- a/src/com/android/nfc/beam/SendUi.java
+++ b/src/com/android/nfc/beam/SendUi.java
@@ -241,7 +241,7 @@
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.OPAQUE);
mWindowLayoutParams.privateFlags |=
- WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+ WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
mWindowLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
mWindowLayoutParams.token = new Binder();
@@ -542,7 +542,7 @@
mContext.unregisterReceiver(mReceiver);
if (mToastString != null) {
Toast toast = Toast.makeText(mContext, mToastString, Toast.LENGTH_LONG);
- toast.getWindowParams().privateFlags |= LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+ toast.getWindowParams().privateFlags |= LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
toast.show();
}
mToastString = null;
diff --git a/src/com/android/nfc/cardemulation/AidRoutingManager.java b/src/com/android/nfc/cardemulation/AidRoutingManager.java
index d5c81e3..b1e6713 100644
--- a/src/com/android/nfc/cardemulation/AidRoutingManager.java
+++ b/src/com/android/nfc/cardemulation/AidRoutingManager.java
@@ -17,20 +17,19 @@
import android.util.Log;
import android.util.SparseArray;
+import android.util.proto.ProtoOutputStream;
import com.android.nfc.NfcService;
-
+import com.android.nfc.NfcStatsLog;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.util.Arrays;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import android.util.StatsLog;
-
public class AidRoutingManager {
static final String TAG = "AidRoutingManager";
@@ -201,7 +200,10 @@
boolean aidRouteResolved = false;
HashMap<String, AidEntry> aidRoutingTableCache = new HashMap<String, AidEntry>(aidMap.size());
ArrayList<Integer> seList = new ArrayList<Integer>();
- seList.add(ROUTE_HOST);
+ seList.add(mDefaultRoute);
+ if (mDefaultRoute != ROUTE_HOST) {
+ seList.add(ROUTE_HOST);
+ }
SparseArray<Set<String>> aidRoutingTable = new SparseArray<Set<String>>(aidMap.size());
HashMap<String, Integer> routeForAid = new HashMap<String, Integer>(aidMap.size());
@@ -357,7 +359,8 @@
if(aidRouteResolved == true) {
commit(aidRoutingTableCache);
} else {
- StatsLog.write(StatsLog.NFC_ERROR_OCCURRED, StatsLog.NFC_ERROR_OCCURRED__TYPE__AID_OVERFLOW, 0, 0);
+ NfcStatsLog.write(NfcStatsLog.NFC_ERROR_OCCURRED,
+ NfcStatsLog.NFC_ERROR_OCCURRED__TYPE__AID_OVERFLOW, 0, 0);
Log.e(TAG, "RoutingTable unchanged because it's full, not updating");
}
}
@@ -408,4 +411,27 @@
}
}
}
+
+ /**
+ * Dump debugging information as a AidRoutingManagerProto
+ *
+ * Note:
+ * See proto definition in frameworks/base/core/proto/android/nfc/card_emulation.proto
+ * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
+ * {@link ProtoOutputStream#end(long)} after.
+ * Never reuse a proto field number. When removing a field, mark it as reserved.
+ */
+ void dumpDebug(ProtoOutputStream proto) {
+ proto.write(AidRoutingManagerProto.DEFAULT_ROUTE, mDefaultRoute);
+ synchronized (mLock) {
+ for (int i = 0; i < mAidRoutingTable.size(); i++) {
+ long token = proto.start(AidRoutingManagerProto.ROUTES);
+ proto.write(AidRoutingManagerProto.Route.ID, mAidRoutingTable.keyAt(i));
+ mAidRoutingTable.valueAt(i).forEach(aid -> {
+ proto.write(AidRoutingManagerProto.Route.AIDS, aid);
+ });
+ proto.end(token);
+ }
+ }
+ }
}
diff --git a/src/com/android/nfc/cardemulation/AppChooserActivity.java b/src/com/android/nfc/cardemulation/AppChooserActivity.java
index 5ed96c0..b5fb515 100644
--- a/src/com/android/nfc/cardemulation/AppChooserActivity.java
+++ b/src/com/android/nfc/cardemulation/AppChooserActivity.java
@@ -80,7 +80,7 @@
protected void onCreate(Bundle savedInstanceState, String category,
ArrayList<ApduServiceInfo> options, ComponentName failedComponent) {
super.onCreate(savedInstanceState);
- setTheme(R.style.Theme_DeviceDefault_Light_Dialog_Alert);
+ setTheme(com.android.nfc.R.style.DialogAlertDayNight);
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
registerReceiver(mReceiver, filter);
diff --git a/src/com/android/nfc/cardemulation/CardEmulationManager.java b/src/com/android/nfc/cardemulation/CardEmulationManager.java
index 7f0ed55..489196e 100644
--- a/src/com/android/nfc/cardemulation/CardEmulationManager.java
+++ b/src/com/android/nfc/cardemulation/CardEmulationManager.java
@@ -19,11 +19,13 @@
import java.io.PrintWriter;
import java.util.List;
+import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.nfc.INfcCardEmulation;
import android.nfc.INfcFCardEmulation;
+import android.nfc.NfcAdapter;
import android.nfc.cardemulation.AidGroup;
import android.nfc.cardemulation.ApduServiceInfo;
import android.nfc.cardemulation.NfcFServiceInfo;
@@ -36,6 +38,7 @@
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Log;
+import android.util.proto.ProtoOutputStream;
import com.android.nfc.NfcPermissions;
import com.android.nfc.NfcService;
@@ -191,6 +194,49 @@
mHostNfcFEmulationManager.dump(fd, pw, args);
}
+ /**
+ * Dump debugging information as a CardEmulationManagerProto
+ *
+ * Note:
+ * See proto definition in frameworks/base/core/proto/android/nfc/card_emulation.proto
+ * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
+ * {@link ProtoOutputStream#end(long)} after.
+ * Never reuse a proto field number. When removing a field, mark it as reserved.
+ */
+ public void dumpDebug(ProtoOutputStream proto) {
+ long token = proto.start(CardEmulationManagerProto.REGISTERED_SERVICES_CACHE);
+ mServiceCache.dumpDebug(proto);
+ proto.end(token);
+
+ token = proto.start(CardEmulationManagerProto.REGISTERED_NFC_F_SERVICES_CACHE);
+ mNfcFServicesCache.dumpDebug(proto);
+ proto.end(token);
+
+ token = proto.start(CardEmulationManagerProto.PREFERRED_SERVICES);
+ mPreferredServices.dumpDebug(proto);
+ proto.end(token);
+
+ token = proto.start(CardEmulationManagerProto.ENABLED_NFC_F_SERVICES);
+ mEnabledNfcFServices.dumpDebug(proto);
+ proto.end(token);
+
+ token = proto.start(CardEmulationManagerProto.AID_CACHE);
+ mAidCache.dumpDebug(proto);
+ proto.end(token);
+
+ token = proto.start(CardEmulationManagerProto.T3T_IDENTIFIERS_CACHE);
+ mT3tIdentifiersCache.dumpDebug(proto);
+ proto.end(token);
+
+ token = proto.start(CardEmulationManagerProto.HOST_EMULATION_MANAGER);
+ mHostEmulationManager.dumpDebug(proto);
+ proto.end(token);
+
+ token = proto.start(CardEmulationManagerProto.HOST_NFC_F_EMULATION_MANAGER);
+ mHostNfcFEmulationManager.dumpDebug(proto);
+ proto.end(token);
+ }
+
@Override
public void onServicesUpdated(int userId, List<ApduServiceInfo> services) {
// Verify defaults are still sane
@@ -199,6 +245,8 @@
mAidCache.onServicesUpdated(userId, services);
// Update the preferred services list
mPreferredServices.onServicesUpdated();
+
+ NfcService.getInstance().onPreferredPaymentChanged(NfcAdapter.PREFERRED_PAYMENT_UPDATED);
}
@Override
@@ -211,7 +259,7 @@
void verifyDefaults(int userId, List<ApduServiceInfo> services) {
ComponentName defaultPaymentService =
- getDefaultServiceForCategory(userId, CardEmulation.CATEGORY_PAYMENT, false);
+ getDefaultServiceForCategory(userId, CardEmulation.CATEGORY_PAYMENT, true);
if (DBG) Log.d(TAG, "Current default: " + defaultPaymentService);
if (defaultPaymentService == null) {
// A payment service may have been removed, leaving only one;
@@ -376,8 +424,13 @@
if (!isServiceRegistered(userId, service)) {
return false;
}
- return mServiceCache.registerAidGroupForService(userId, Binder.getCallingUid(), service,
- aidGroup);
+ if (!mServiceCache.registerAidGroupForService(userId, Binder.getCallingUid(), service,
+ aidGroup)) {
+ return false;
+ }
+ NfcService.getInstance().onPreferredPaymentChanged(
+ NfcAdapter.PREFERRED_PAYMENT_UPDATED);
+ return true;
}
@Override
@@ -387,8 +440,13 @@
if (!isServiceRegistered(userId, service)) {
return false;
}
- return mServiceCache.setOffHostSecureElement(userId, Binder.getCallingUid(), service,
- offHostSE);
+ if (!mServiceCache.setOffHostSecureElement(userId, Binder.getCallingUid(), service,
+ offHostSE)) {
+ return false;
+ }
+ NfcService.getInstance().onPreferredPaymentChanged(
+ NfcAdapter.PREFERRED_PAYMENT_UPDATED);
+ return true;
}
@Override
@@ -398,7 +456,12 @@
if (!isServiceRegistered(userId, service)) {
return false;
}
- return mServiceCache.unsetOffHostSecureElement(userId, Binder.getCallingUid(), service);
+ if (!mServiceCache.unsetOffHostSecureElement(userId, Binder.getCallingUid(), service)) {
+ return false;
+ }
+ NfcService.getInstance().onPreferredPaymentChanged(
+ NfcAdapter.PREFERRED_PAYMENT_UPDATED);
+ return true;
}
@Override
@@ -421,8 +484,13 @@
if (!isServiceRegistered(userId, service)) {
return false;
}
- return mServiceCache.removeAidGroupForService(userId, Binder.getCallingUid(), service,
- category);
+ if (!mServiceCache.removeAidGroupForService(userId, Binder.getCallingUid(), service,
+ category)) {
+ return false;
+ }
+ NfcService.getInstance().onPreferredPaymentChanged(
+ NfcAdapter.PREFERRED_PAYMENT_UPDATED);
+ return true;
}
@Override
@@ -456,6 +524,14 @@
public boolean supportsAidPrefixRegistration() throws RemoteException {
return mAidCache.supportsAidPrefixRegistration();
}
+
+ @Override
+ public ApduServiceInfo getPreferredPaymentService(int userId) throws RemoteException {
+ NfcPermissions.validateUserId(userId);
+ NfcPermissions.enforceUserPermissions(mContext);
+ NfcPermissions.enforcePreferredPaymentInfoPermissions(mContext);
+ return mServiceCache.getService(userId, mAidCache.getPreferredService());
+ }
}
/**
@@ -562,12 +638,18 @@
public void onPreferredPaymentServiceChanged(ComponentName service) {
mAidCache.onPreferredPaymentServiceChanged(service);
mHostEmulationManager.onPreferredPaymentServiceChanged(service);
+
+ NfcService.getInstance().onPreferredPaymentChanged(
+ NfcAdapter.PREFERRED_PAYMENT_CHANGED);
}
@Override
public void onPreferredForegroundServiceChanged(ComponentName service) {
mAidCache.onPreferredForegroundServiceChanged(service);
mHostEmulationManager.onPreferredForegroundServiceChanged(service);
+
+ NfcService.getInstance().onPreferredPaymentChanged(
+ NfcAdapter.PREFERRED_PAYMENT_CHANGED);
}
@Override
diff --git a/src/com/android/nfc/cardemulation/EnabledNfcFServices.java b/src/com/android/nfc/cardemulation/EnabledNfcFServices.java
index c06ca26..0e7edbe 100644
--- a/src/com/android/nfc/cardemulation/EnabledNfcFServices.java
+++ b/src/com/android/nfc/cardemulation/EnabledNfcFServices.java
@@ -27,6 +27,7 @@
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
+import android.util.proto.ProtoOutputStream;
public class EnabledNfcFServices implements com.android.nfc.ForegroundUtils.Callback {
static final String TAG = "EnabledNfcFCardEmulationServices";
@@ -217,4 +218,25 @@
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
}
+
+ /**
+ * Dump debugging information as a EnabledNfcFServicesProto
+ *
+ * Note:
+ * See proto definition in frameworks/base/core/proto/android/nfc/card_emulation.proto
+ * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
+ * {@link ProtoOutputStream#end(long)} after.
+ * Never reuse a proto field number. When removing a field, mark it as reserved.
+ */
+ void dumpDebug(ProtoOutputStream proto) {
+ if (mForegroundComponent != null) {
+ mForegroundComponent.dumpDebug(proto, EnabledNfcFServicesProto.FOREGROUND_COMPONENT);
+ }
+ if (mForegroundRequested != null) {
+ mForegroundRequested.dumpDebug(proto, EnabledNfcFServicesProto.FOREGROUND_REQUESTED);
+ }
+ proto.write(EnabledNfcFServicesProto.ACTIVATED, mActivated);
+ proto.write(EnabledNfcFServicesProto.COMPUTE_FG_REQUESTED, mComputeFgRequested);
+ proto.write(EnabledNfcFServicesProto.FOREGROUND_UID, mForegroundUid);
+ }
}
diff --git a/src/com/android/nfc/cardemulation/HostEmulationManager.java b/src/com/android/nfc/cardemulation/HostEmulationManager.java
index df701f2..2d763f9 100644
--- a/src/com/android/nfc/cardemulation/HostEmulationManager.java
+++ b/src/com/android/nfc/cardemulation/HostEmulationManager.java
@@ -34,16 +34,15 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
+import android.util.proto.ProtoOutputStream;
import com.android.nfc.NfcService;
+import com.android.nfc.NfcStatsLog;
import com.android.nfc.cardemulation.RegisteredAidCache.AidResolveInfo;
-
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
-import android.util.StatsLog;
-
public class HostEmulationManager {
static final String TAG = "HostEmulationManager";
static final boolean DBG = false;
@@ -225,12 +224,12 @@
mState = STATE_W4_SERVICE;
}
if(CardEmulation.CATEGORY_PAYMENT.equals(resolveInfo.category))
- StatsLog.write(StatsLog.NFC_CARDEMULATION_OCCURRED,
- StatsLog.NFC_CARDEMULATION_OCCURRED__CATEGORY__HCE_PAYMENT,
+ NfcStatsLog.write(NfcStatsLog.NFC_CARDEMULATION_OCCURRED,
+ NfcStatsLog.NFC_CARDEMULATION_OCCURRED__CATEGORY__HCE_PAYMENT,
"HCE");
else
- StatsLog.write(StatsLog.NFC_CARDEMULATION_OCCURRED,
- StatsLog.NFC_CARDEMULATION_OCCURRED__CATEGORY__HCE_OTHER,
+ NfcStatsLog.write(NfcStatsLog.NFC_CARDEMULATION_OCCURRED,
+ NfcStatsLog.NFC_CARDEMULATION_OCCURRED__CATEGORY__HCE_OTHER,
"HCE");
} else {
@@ -551,4 +550,22 @@
pw.println(" other: " + mServiceName);
}
}
+
+ /**
+ * Dump debugging information as a HostEmulationManagerProto
+ *
+ * Note:
+ * See proto definition in frameworks/base/core/proto/android/nfc/card_emulation.proto
+ * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
+ * {@link ProtoOutputStream#end(long)} after.
+ * Never reuse a proto field number. When removing a field, mark it as reserved.
+ */
+ void dumpDebug(ProtoOutputStream proto) {
+ if (mPaymentServiceBound) {
+ mPaymentServiceName.dumpDebug(proto, HostEmulationManagerProto.PAYMENT_SERVICE_NAME);
+ }
+ if (mServiceBound) {
+ mServiceName.dumpDebug(proto, HostEmulationManagerProto.SERVICE_NAME);
+ }
+ }
}
diff --git a/src/com/android/nfc/cardemulation/HostNfcFEmulationManager.java b/src/com/android/nfc/cardemulation/HostNfcFEmulationManager.java
index 1880a7a..8b9e7de 100644
--- a/src/com/android/nfc/cardemulation/HostNfcFEmulationManager.java
+++ b/src/com/android/nfc/cardemulation/HostNfcFEmulationManager.java
@@ -20,8 +20,8 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
-import android.nfc.cardemulation.NfcFServiceInfo;
import android.nfc.cardemulation.HostNfcFService;
+import android.nfc.cardemulation.NfcFServiceInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -30,14 +30,13 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
+import android.util.proto.ProtoOutputStream;
import com.android.nfc.NfcService;
-
+import com.android.nfc.NfcStatsLog;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import android.util.StatsLog;
-
public class HostNfcFEmulationManager {
static final String TAG = "HostNfcFEmulationManager";
static final boolean DBG = false;
@@ -135,8 +134,8 @@
mPendingPacket = data;
mState = STATE_W4_SERVICE;
}
- StatsLog.write(StatsLog.NFC_CARDEMULATION_OCCURRED,
- StatsLog.NFC_CARDEMULATION_OCCURRED__CATEGORY__HCE_PAYMENT,
+ NfcStatsLog.write(NfcStatsLog.NFC_CARDEMULATION_OCCURRED,
+ NfcStatsLog.NFC_CARDEMULATION_OCCURRED__CATEGORY__HCE_PAYMENT,
"HCEF");
break;
case STATE_W4_SERVICE:
@@ -372,4 +371,19 @@
pw.println(" service: " + mServiceName);
}
}
+
+ /**
+ * Dump debugging information as a HostNfcFEmulationManagerProto
+ *
+ * Note:
+ * See proto definition in frameworks/base/core/proto/android/nfc/card_emulation.proto
+ * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
+ * {@link ProtoOutputStream#end(long)} after.
+ * Never reuse a proto field number. When removing a field, mark it as reserved.
+ */
+ void dumpDebug(ProtoOutputStream proto) {
+ if (mServiceBound) {
+ mServiceName.dumpDebug(proto, HostNfcFEmulationManagerProto.SERVICE_NAME);
+ }
+ }
}
diff --git a/src/com/android/nfc/cardemulation/PreferredServices.java b/src/com/android/nfc/cardemulation/PreferredServices.java
index fadb879..7b0a6e6 100644
--- a/src/com/android/nfc/cardemulation/PreferredServices.java
+++ b/src/com/android/nfc/cardemulation/PreferredServices.java
@@ -35,6 +35,7 @@
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.util.Log;
+import android.util.proto.ProtoOutputStream;
/**
* This class keeps track of what HCE/SE-based services are
@@ -385,4 +386,35 @@
pw.println(" Payment settings allows override: " + mPaymentDefaults.preferForeground);
pw.println("");
}
+
+ /**
+ * Dump debugging information as a PreferredServicesProto
+ *
+ * Note:
+ * See proto definition in frameworks/base/core/proto/android/nfc/card_emulation.proto
+ * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
+ * {@link ProtoOutputStream#end(long)} after.
+ * Never reuse a proto field number. When removing a field, mark it as reserved.
+ */
+ void dumpDebug(ProtoOutputStream proto) {
+ if (mForegroundCurrent != null) {
+ mForegroundCurrent.dumpDebug(proto, PreferredServicesProto.FOREGROUND_CURRENT);
+ }
+ if (mPaymentDefaults.currentPreferred != null) {
+ mPaymentDefaults.currentPreferred.dumpDebug(proto,
+ PreferredServicesProto.FOREGROUND_CURRENT);
+ }
+ if (mNextTapDefault != null) {
+ mNextTapDefault.dumpDebug(proto, PreferredServicesProto.NEXT_TAP_DEFAULT);
+ }
+ proto.write(PreferredServicesProto.FOREGROUND_UID, mForegroundUid);
+ if (mForegroundRequested != null) {
+ mForegroundRequested.dumpDebug(proto, PreferredServicesProto.FOREGROUND_REQUESTED);
+ }
+ if (mPaymentDefaults.settingsDefault != null) {
+ mPaymentDefaults.settingsDefault.dumpDebug(proto,
+ PreferredServicesProto.SETTINGS_DEFAULT);
+ }
+ proto.write(PreferredServicesProto.PREFER_FOREGROUND, mPaymentDefaults.preferForeground);
+ }
}
diff --git a/src/com/android/nfc/cardemulation/RegisteredAidCache.java b/src/com/android/nfc/cardemulation/RegisteredAidCache.java
index b8ad8fc..7618d38 100644
--- a/src/com/android/nfc/cardemulation/RegisteredAidCache.java
+++ b/src/com/android/nfc/cardemulation/RegisteredAidCache.java
@@ -22,6 +22,7 @@
import android.nfc.cardemulation.ApduServiceInfo;
import android.nfc.cardemulation.CardEmulation;
import android.util.Log;
+import android.util.proto.ProtoOutputStream;
import com.google.android.collect.Maps;
import java.util.Collections;
@@ -885,6 +886,16 @@
}
}
+ public ComponentName getPreferredService() {
+ if (mPreferredForegroundService != null) {
+ // return current foreground service
+ return mPreferredForegroundService;
+ } else {
+ // return current preferred service
+ return mPreferredPaymentService;
+ }
+ }
+
public void onNfcDisabled() {
synchronized (mLock) {
mNfcEnabled = false;
@@ -935,4 +946,45 @@
mRoutingManager.dump(fd, pw, args);
pw.println("");
}
+
+ /**
+ * Dump debugging information as a RegisteredAidCacheProto
+ *
+ * Note:
+ * See proto definition in frameworks/base/core/proto/android/nfc/card_emulation.proto
+ * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
+ * {@link ProtoOutputStream#end(long)} after.
+ * Never reuse a proto field number. When removing a field, mark it as reserved.
+ */
+ void dumpDebug(ProtoOutputStream proto) {
+ for (Map.Entry<String, AidResolveInfo> entry : mAidCache.entrySet()) {
+ long token = proto.start(RegisteredAidCacheProto.AID_CACHE_ENTRIES);
+ proto.write(RegisteredAidCacheProto.AidCacheEntry.KEY, entry.getKey());
+ proto.write(RegisteredAidCacheProto.AidCacheEntry.CATEGORY, entry.getValue().category);
+ ApduServiceInfo defaultServiceInfo = entry.getValue().defaultService;
+ ComponentName defaultComponent = defaultServiceInfo != null ?
+ defaultServiceInfo.getComponent() : null;
+ if (defaultComponent != null) {
+ defaultComponent.dumpDebug(proto,
+ RegisteredAidCacheProto.AidCacheEntry.DEFAULT_COMPONENT);
+ }
+ for (ApduServiceInfo serviceInfo : entry.getValue().services) {
+ long sToken = proto.start(RegisteredAidCacheProto.AidCacheEntry.SERVICES);
+ serviceInfo.dumpDebug(proto);
+ proto.end(sToken);
+ }
+ proto.end(token);
+ }
+ if (mPreferredForegroundService != null) {
+ mPreferredForegroundService.dumpDebug(proto,
+ RegisteredAidCacheProto.PREFERRED_FOREGROUND_SERVICE);
+ }
+ if (mPreferredPaymentService != null) {
+ mPreferredPaymentService.dumpDebug(proto,
+ RegisteredAidCacheProto.PREFERRED_PAYMENT_SERVICE);
+ }
+ long token = proto.start(RegisteredAidCacheProto.ROUTING_MANAGER);
+ mRoutingManager.dumpDebug(proto);
+ proto.end(token);
+ }
}
diff --git a/src/com/android/nfc/cardemulation/RegisteredNfcFServicesCache.java b/src/com/android/nfc/cardemulation/RegisteredNfcFServicesCache.java
index 5867b3c..a89f370 100644
--- a/src/com/android/nfc/cardemulation/RegisteredNfcFServicesCache.java
+++ b/src/com/android/nfc/cardemulation/RegisteredNfcFServicesCache.java
@@ -38,6 +38,7 @@
import android.util.Log;
import android.util.SparseArray;
import android.util.Xml;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.util.FastXmlSerializer;
import com.google.android.collect.Maps;
@@ -726,4 +727,24 @@
}
}
+ /**
+ * Dump debugging information as a RegisteredNfcFServicesCacheProto
+ *
+ * Note:
+ * See proto definition in frameworks/base/core/proto/android/nfc/card_emulation.proto
+ * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
+ * {@link ProtoOutputStream#end(long)} after.
+ * Never reuse a proto field number. When removing a field, mark it as reserved.
+ */
+ void dumpDebug(ProtoOutputStream proto) {
+ synchronized (mLock) {
+ UserServices userServices = findOrCreateUserLocked(ActivityManager.getCurrentUser());
+ for (NfcFServiceInfo service : userServices.services.values()) {
+ long token = proto.start(RegisteredNfcFServicesCacheProto.NFC_FSERVICE_INFO);
+ service.dumpDebug(proto);
+ proto.end(token);
+ }
+ }
+ }
+
}
diff --git a/src/com/android/nfc/cardemulation/RegisteredServicesCache.java b/src/com/android/nfc/cardemulation/RegisteredServicesCache.java
index f16a60e..2f0d898 100644
--- a/src/com/android/nfc/cardemulation/RegisteredServicesCache.java
+++ b/src/com/android/nfc/cardemulation/RegisteredServicesCache.java
@@ -40,6 +40,7 @@
import android.util.Log;
import android.util.SparseArray;
import android.util.Xml;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.util.FastXmlSerializer;
import com.google.android.collect.Maps;
@@ -657,4 +658,21 @@
pw.println("");
}
+ /**
+ * Dump debugging information as a RegisteredServicesCacheProto
+ *
+ * Note:
+ * See proto definition in frameworks/base/core/proto/android/nfc/card_emulation.proto
+ * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
+ * {@link ProtoOutputStream#end(long)} after.
+ * Never reuse a proto field number. When removing a field, mark it as reserved.
+ */
+ void dumpDebug(ProtoOutputStream proto) {
+ UserServices userServices = findOrCreateUserLocked(ActivityManager.getCurrentUser());
+ for (ApduServiceInfo service : userServices.services.values()) {
+ long token = proto.start(RegisteredServicesCacheProto.APDU_SERVICE_INFOS);
+ service.dumpDebug(proto);
+ proto.end(token);
+ }
+ }
}
diff --git a/src/com/android/nfc/cardemulation/RegisteredT3tIdentifiersCache.java b/src/com/android/nfc/cardemulation/RegisteredT3tIdentifiersCache.java
index bc11ba0..f24ee69 100644
--- a/src/com/android/nfc/cardemulation/RegisteredT3tIdentifiersCache.java
+++ b/src/com/android/nfc/cardemulation/RegisteredT3tIdentifiersCache.java
@@ -21,6 +21,7 @@
import android.content.Context;
import android.nfc.cardemulation.NfcFServiceInfo;
import android.util.Log;
+import android.util.proto.ProtoOutputStream;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -221,4 +222,25 @@
mRoutingManager.dump(fd, pw, args);
pw.println("");
}
+
+ /**
+ * Dump debugging information as a RegisteredT3tIdentifiersCacheProto
+ *
+ * Note:
+ * See proto definition in frameworks/base/core/proto/android/nfc/card_emulation.proto
+ * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
+ * {@link ProtoOutputStream#end(long)} after.
+ * Never reuse a proto field number. When removing a field, mark it as reserved.
+ */
+ void dumpDebug(ProtoOutputStream proto) {
+ for (NfcFServiceInfo serviceInfo : mForegroundT3tIdentifiersCache.values()) {
+ long token = proto.start(
+ RegisteredT3tIdentifiersCacheProto.T3T_IDENTIFIER_CACHE_ENTRIES);
+ serviceInfo.dumpDebug(proto);
+ proto.end(token);
+ }
+ long token = proto.start(RegisteredT3tIdentifiersCacheProto.ROUTING_MANAGER);
+ mRoutingManager.dumpDebug(proto);
+ proto.end(token);
+ }
}
diff --git a/src/com/android/nfc/cardemulation/SystemCodeRoutingManager.java b/src/com/android/nfc/cardemulation/SystemCodeRoutingManager.java
index a2d2a77..eb8c9cb 100644
--- a/src/com/android/nfc/cardemulation/SystemCodeRoutingManager.java
+++ b/src/com/android/nfc/cardemulation/SystemCodeRoutingManager.java
@@ -17,6 +17,7 @@
package com.android.nfc.cardemulation;
import android.util.Log;
+import android.util.proto.ProtoOutputStream;
import com.android.nfc.NfcService;
import com.android.nfc.cardemulation.RegisteredT3tIdentifiersCache.T3tIdentifier;
@@ -113,4 +114,26 @@
}
}
}
+
+ /**
+ * Dump debugging information as a SystemCodeRoutingManagerProto
+ *
+ * Note:
+ * See proto definition in frameworks/base/core/proto/android/nfc/card_emulation.proto
+ * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
+ * {@link ProtoOutputStream#end(long)} after.
+ * Never reuse a proto field number. When removing a field, mark it as reserved.
+ */
+ void dumpDebug(ProtoOutputStream proto) {
+ synchronized (mLock) {
+ for (T3tIdentifier t3tIdentifier : mConfiguredT3tIdentifiers) {
+ long token = proto.start(SystemCodeRoutingManagerProto.T3T_IDENTIFIERS);
+ proto.write(SystemCodeRoutingManagerProto.T3tIdentifier.SYSTEM_CODE,
+ t3tIdentifier.systemCode);
+ proto.write(SystemCodeRoutingManagerProto.T3tIdentifier.NFCID2,
+ t3tIdentifier.nfcid2);
+ proto.end(token);
+ }
+ }
+ }
}
diff --git a/src/com/android/nfc/cardemulation/TapAgainDialog.java b/src/com/android/nfc/cardemulation/TapAgainDialog.java
index 7515d54..e786ab3 100644
--- a/src/com/android/nfc/cardemulation/TapAgainDialog.java
+++ b/src/com/android/nfc/cardemulation/TapAgainDialog.java
@@ -56,7 +56,7 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setTheme(R.style.Theme_DeviceDefault_Light_Dialog_Alert);
+ setTheme(com.android.nfc.R.style.DialogAlertDayNight);
final NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
mCardEmuManager = CardEmulation.getInstance(adapter);
diff --git a/src/com/android/nfc/handover/BluetoothPeripheralHandover.java b/src/com/android/nfc/handover/BluetoothPeripheralHandover.java
index 09cdf04..98d4057 100644
--- a/src/com/android/nfc/handover/BluetoothPeripheralHandover.java
+++ b/src/com/android/nfc/handover/BluetoothPeripheralHandover.java
@@ -234,10 +234,12 @@
mAction = ACTION_DISCONNECT;
} else {
// Check if each profile of the device is disabled or not
- if (mHeadset.getPriority(mDevice) == BluetoothProfile.PRIORITY_OFF) {
+ if (mHeadset.getConnectionPolicy(mDevice) ==
+ BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
mIsHeadsetAvailable = false;
}
- if (mA2dp.getPriority(mDevice) == BluetoothProfile.PRIORITY_OFF) {
+ if (mA2dp.getConnectionPolicy(mDevice) ==
+ BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
mIsA2dpAvailable = false;
}
if (!mIsHeadsetAvailable && !mIsA2dpAvailable) {
@@ -586,7 +588,7 @@
boolean hasA2dpCapability(ParcelUuid[] uuids, BluetoothClass btClass) {
if (uuids != null) {
for (ParcelUuid uuid : uuids) {
- if (BluetoothUuid.isAudioSink(uuid) || BluetoothUuid.isAdvAudioDist(uuid)) {
+ if (uuid.equals(BluetoothUuid.A2DP_SINK) || uuid.equals(BluetoothUuid.ADV_AUDIO_DIST)) {
return true;
}
}
@@ -600,7 +602,7 @@
boolean hasHeadsetCapability(ParcelUuid[] uuids, BluetoothClass btClass) {
if (uuids != null) {
for (ParcelUuid uuid : uuids) {
- if (BluetoothUuid.isHandsfree(uuid) || BluetoothUuid.isHeadset(uuid)) {
+ if (uuid.equals(BluetoothUuid.HFP) || uuid.equals(BluetoothUuid.HSP)) {
return true;
}
}
diff --git a/src/com/android/nfc/handover/ConfirmConnectActivity.java b/src/com/android/nfc/handover/ConfirmConnectActivity.java
index d029a3e..159eee0 100644
--- a/src/com/android/nfc/handover/ConfirmConnectActivity.java
+++ b/src/com/android/nfc/handover/ConfirmConnectActivity.java
@@ -39,7 +39,7 @@
super.onCreate(savedInstanceState);
getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
AlertDialog.Builder builder = new AlertDialog.Builder(this,
- AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
+ R.style.DialogAlertDayNight);
Intent launchIntent = getIntent();
mDevice = launchIntent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (mDevice == null) finish();