Merge "Import translations. DO NOT MERGE" into rvc-dev
diff --git a/nci/jni/NativeNfcManager.cpp b/nci/jni/NativeNfcManager.cpp
index c99e982..5048262 100644
--- a/nci/jni/NativeNfcManager.cpp
+++ b/nci/jni/NativeNfcManager.cpp
@@ -234,12 +234,19 @@
// there is more discovery notification coming
return;
}
- if (natTag.getNumDiscNtf() > 1) {
- natTag.setMultiProtocolTagSupport(true);
- }
bool isP2p = natTag.isP2pDiscovered();
- if (!sReaderModeEnabled && isP2p) {
+
+ 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
natTag.selectP2p();
} else {
diff --git a/nci/jni/NfcTag.cpp b/nci/jni/NfcTag.cpp
index 6f5f9b8..b9d8d55 100755
--- a/nci/jni/NfcTag.cpp
+++ b/nci/jni/NfcTag.cpp
@@ -1013,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);
diff --git a/res/values/config.xml b/res/values/config.xml
index 21c31e2..2186cb8 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -5,6 +5,7 @@
<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="toast_debounce_time_ms">3000</integer>
<integer name="unknown_tag_polling_delay">2000</integer>
diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java
index 0116142..2a52842 100644
--- a/src/com/android/nfc/NfcService.java
+++ b/src/com/android/nfc/NfcService.java
@@ -233,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;
@@ -551,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);
@@ -1245,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);
+ }
}
}
@@ -1348,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 {
@@ -1355,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);
+ }
}
}
}
@@ -1906,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);