Merge "Fix setting audio group mode in SipPhone." into gingerbread
diff --git a/core/java/android/nfc/technology/IsoDep.java b/core/java/android/nfc/technology/IsoDep.java
index 118bff7..52a453fa 100644
--- a/core/java/android/nfc/technology/IsoDep.java
+++ b/core/java/android/nfc/technology/IsoDep.java
@@ -64,19 +64,4 @@
* 3B only
*/
public byte[] getAttrib() { return mAttrib; }
-
- /**
- * Attempts to select the given application on the tag. Note that this only works
- * if the tag supports ISO7816-4, which not all IsoDep tags support. If the tag doesn't
- * support ISO7816-4 this will throw {@link UnsupportedOperationException}.
- *
- * This method requires that you call {@link #connect} before calling it.
- *
- * @throws IOException, UnsupportedOperationException
- */
- public void selectAid(byte[] aid) throws IOException, UnsupportedOperationException {
- checkConnected();
-
- throw new UnsupportedOperationException();
- }
}
diff --git a/core/java/android/nfc/technology/MifareClassic.java b/core/java/android/nfc/technology/MifareClassic.java
index 8a9ebf1..799f0a78 100644
--- a/core/java/android/nfc/technology/MifareClassic.java
+++ b/core/java/android/nfc/technology/MifareClassic.java
@@ -205,6 +205,15 @@
return getBlockCount(sector) * 16;
}
+ public int getTotalBlockCount() {
+ int totalBlocks = 0;
+ for (int sec = 0; sec < getSectorCount(); sec++) {
+ totalBlocks += getSectorSize(sec);
+ }
+
+ return totalBlocks;
+ }
+
public int getBlockCount(int sector) {
if (sector >= getSectorCount()) {
throw new IllegalArgumentException("this card only has " + getSectorCount() +
@@ -343,9 +352,27 @@
checkConnected();
byte addr = (byte) block;
- byte[] incr_cmd = { (byte) 0xC0, (byte) block };
+ byte[] decr_cmd = { (byte) 0xC0, (byte) block };
- transceive(incr_cmd);
+ transceive(decr_cmd);
+ }
+
+ public void transfer(int block) throws IOException {
+ checkConnected();
+
+ byte addr = (byte) block;
+ byte[] trans_cmd = { (byte) 0xB0, (byte) block };
+
+ transceive(trans_cmd);
+ }
+
+ public void restore(int block) throws IOException {
+ checkConnected();
+
+ byte addr = (byte) block;
+ byte[] rest_cmd = { (byte) 0xC2, (byte) block };
+
+ transceive(rest_cmd);
}
/**
diff --git a/core/java/android/nfc/technology/Ndef.java b/core/java/android/nfc/technology/Ndef.java
index 53db0c5..05872fe 100644
--- a/core/java/android/nfc/technology/Ndef.java
+++ b/core/java/android/nfc/technology/Ndef.java
@@ -54,9 +54,22 @@
/** @hide */
public static final String EXTRA_NDEF_CARDSTATE = "ndefcardstate";
+ /** @hide */
+ public static final String EXTRA_NDEF_TYPE = "ndeftype";
+
+ //TODO: consider removing OTHER entirely - and not allowing Ndef to
+ // enumerate for tag types outside of (NFC Forum 1-4, MifareClassic)
+ public static final int OTHER = -1;
+ public static final int NFC_FORUM_TYPE_1 = 1;
+ public static final int NFC_FORUM_TYPE_2 = 2;
+ public static final int NFC_FORUM_TYPE_3 = 3;
+ public static final int NFC_FORUM_TYPE_4 = 4;
+ public static final int MIFARE_CLASSIC = 105;
+
private final int mMaxNdefSize;
private final int mCardState;
private final NdefMessage mNdefMsg;
+ private final int mNdefType;
/**
* Internal constructor, to be used by NfcAdapter
@@ -68,6 +81,7 @@
mMaxNdefSize = extras.getInt(EXTRA_NDEF_MAXLENGTH);
mCardState = extras.getInt(EXTRA_NDEF_CARDSTATE);
mNdefMsg = extras.getParcelable(EXTRA_NDEF_MSG);
+ mNdefType = extras.getInt(EXTRA_NDEF_TYPE);
} else {
throw new NullPointerException("NDEF tech extras are null.");
}
@@ -92,6 +106,24 @@
}
/**
+ * Get NDEF tag type.
+ * <p>Returns one of {@link #NFC_FORUM_TYPE_1}, {@link #NFC_FORUM_TYPE_2},
+ * {@link #NFC_FORUM_TYPE_3}, {@link #NFC_FORUM_TYPE_4},
+ * {@link #MIFARE_CLASSIC} or {@link #OTHER}.
+ * <p>Platforms of this API revision will always return one of the above
+ * values. Platforms at future API revisions may return other values, which
+ * can be treated as {@link #OTHER} by applications targeting this API.
+ * <p>Android devices with NFC support must always correctly enumerate
+ * NFC Forum tag types, and may optionally enumerate
+ * {@link #MIFARE_CLASSIC} since it requires proprietary technology.
+ * Devices that cannot enumerate {@link #MIFARE_CLASSIC} will use
+ * {@link #OTHER} instead.
+ */
+ public int getType() {
+ return mNdefType;
+ }
+
+ /**
* Get maximum NDEF message size in bytes
*/
public int getMaxSize() {
diff --git a/core/java/android/nfc/technology/NfcB.java b/core/java/android/nfc/technology/NfcB.java
index 64cb08a..de528f8 100644
--- a/core/java/android/nfc/technology/NfcB.java
+++ b/core/java/android/nfc/technology/NfcB.java
@@ -44,6 +44,7 @@
public NfcB(NfcAdapter adapter, Tag tag, Bundle extras)
throws RemoteException {
super(adapter, tag, TagTechnology.NFC_B);
+ mAtqb = extras.getByteArray(EXTRA_ATQB);
}
/**
diff --git a/core/java/android/nfc/technology/NfcV.java b/core/java/android/nfc/technology/NfcV.java
index 9b6a16a..460de6a 100644
--- a/core/java/android/nfc/technology/NfcV.java
+++ b/core/java/android/nfc/technology/NfcV.java
@@ -36,8 +36,27 @@
* permission.
*/
public final class NfcV extends BasicTagTechnology {
+ /** @hide */
+ public static final String EXTRA_RESP_FLAGS = "respflags";
+
+ /** @hide */
+ public static final String EXTRA_DSFID = "dsfid";
+
+ private byte mRespFlags;
+ private byte mDsfId;
+
public NfcV(NfcAdapter adapter, Tag tag, Bundle extras)
throws RemoteException {
super(adapter, tag, TagTechnology.NFC_V);
+ mRespFlags = extras.getByte(EXTRA_RESP_FLAGS);
+ mDsfId = extras.getByte(EXTRA_DSFID);
+ }
+
+ public byte getResponseFlags() {
+ return mRespFlags;
+ }
+
+ public byte getDsfId() {
+ return mDsfId;
}
}
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 3d410fd..7d31687 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -370,23 +370,26 @@
case EVENT_WAKE_LOCK_TIMEOUT:
// Haven't heard back from the last request. Assume we're
// not getting a response and release the wake lock.
- // TODO should we clean up mRequestList and mRequestPending
synchronized (mWakeLock) {
if (mWakeLock.isHeld()) {
- if (RILJ_LOGD) {
- synchronized (mRequestsList) {
- int count = mRequestsList.size();
- Log.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
- " mReqPending=" + mRequestMessagesPending +
- " mRequestList=" + count);
-
- for (int i = 0; i < count; i++) {
- rr = mRequestsList.get(i);
- Log.d(LOG_TAG, i + ": [" + rr.mSerial + "] " +
- requestToString(rr.mRequest));
-
- }
- }
+ // The timer of WAKE_LOCK_TIMEOUT is reset with each
+ // new send request. So when WAKE_LOCK_TIMEOUT occurs
+ // all requests in mRequestList already waited at
+ // least DEFAULT_WAKE_LOCK_TIMEOUT but no response.
+ // Therefore all should be treated as lost requests.
+ // Those lost requests return GENERIC_FAILURE and
+ // request list is cleared.
+ //
+ // Note: mRequestMessagesPending shows how many
+ // requests are waiting to be sent (and before
+ // to be added in request list) since star the
+ // timer. It should be
+ // zero here since all request should already
+ // be put in request list while TIMEOUT occurs.
+ clearRequestsList(GENERIC_FAILURE, true);
+ if (mRequestMessagesPending != 0) {
+ Log.e(LOG_TAG, "ERROR: mReqPending is NOT 0 at TIMEOUT, "
+ + "mReqPending = " + mRequestMessagesPending);
}
mWakeLock.release();
}
@@ -558,15 +561,7 @@
RILRequest.resetSerial();
// Clear request list on close
- synchronized (mRequestsList) {
- for (int i = 0, sz = mRequestsList.size() ; i < sz ; i++) {
- RILRequest rr = mRequestsList.get(i);
- rr.onError(RADIO_NOT_AVAILABLE, null);
- rr.release();
- }
-
- mRequestsList.clear();
- }
+ clearRequestsList(RADIO_NOT_AVAILABLE, false);
}} catch (Throwable tr) {
Log.e(LOG_TAG,"Uncaught exception", tr);
}
@@ -2061,6 +2056,34 @@
releaseWakeLockIfDone();
}
+ /**
+ * Release each request in mReqeustsList then clear the list
+ * @param error is the RIL_Errno sent back
+ * @param loggable true means to print all requests in mRequestslist
+ */
+ private void clearRequestsList(int error, boolean loggable) {
+ RILRequest rr;
+ synchronized (mRequestsList) {
+ int count = mRequestsList.size();
+ if (RILJ_LOGD && loggable) {
+ Log.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
+ " mReqPending=" + mRequestMessagesPending +
+ " mRequestList=" + count);
+ }
+
+ for (int i = 0; i < count ; i++) {
+ rr = mRequestsList.get(i);
+ if (RILJ_LOGD && loggable) {
+ Log.d(LOG_TAG, i + ": [" + rr.mSerial + "] " +
+ requestToString(rr.mRequest));
+ }
+ rr.onError(error, null);
+ rr.release();
+ }
+ mRequestsList.clear();
+ }
+ }
+
private RILRequest findAndRemoveRequestFromList(int serial) {
synchronized (mRequestsList) {
for (int i = 0, s = mRequestsList.size() ; i < s ; i++) {
diff --git a/voip/jni/rtp/AudioGroup.cpp b/voip/jni/rtp/AudioGroup.cpp
index 0c8a725..60abf2a 100644
--- a/voip/jni/rtp/AudioGroup.cpp
+++ b/voip/jni/rtp/AudioGroup.cpp
@@ -63,6 +63,14 @@
// real jitter buffer. For a stream at 8000Hz it takes 8192 bytes. These numbers
// are chosen by experiments and each of them can be adjusted as needed.
+// Originally a stream does not send packets when it is receive-only or there is
+// nothing to mix. However, this causes some problems with certain firewalls and
+// proxies. A firewall might remove a port mapping when there is no outgoing
+// packet for a preiod of time, and a proxy might wait for incoming packets from
+// both sides before start forwarding. To solve these problems, we send out a
+// silence packet on the stream for every second. It should be good enough to
+// keep the stream alive with relatively low resources.
+
// Other notes:
// + We use elapsedRealtime() to get the time. Since we use 32bit variables
// instead of 64bit ones, comparison must be done by subtraction.
@@ -110,7 +118,7 @@
int mSampleRate;
int mSampleCount;
int mInterval;
- int mLogThrottle;
+ int mKeepAlive;
int16_t *mBuffer;
int mBufferMask;
@@ -262,12 +270,8 @@
++mSequence;
mTimestamp += mSampleCount;
- if (mMode == RECEIVE_ONLY) {
- return;
- }
-
// If there is an ongoing DTMF event, send it now.
- if (mDtmfEvent != -1) {
+ if (mMode != RECEIVE_ONLY && mDtmfEvent != -1) {
int duration = mTimestamp - mDtmfStart;
// Make sure duration is reasonable.
if (duration >= 0 && duration < mSampleRate * 100) {
@@ -289,43 +293,55 @@
mDtmfEvent = -1;
}
- // It is time to mix streams.
- bool mixed = false;
int32_t buffer[mSampleCount + 3];
- memset(buffer, 0, sizeof(buffer));
- while (chain) {
- if (chain != this &&
- chain->mix(buffer, tick - mInterval, tick, mSampleRate)) {
- mixed = true;
+ int16_t samples[mSampleCount];
+ if (mMode == RECEIVE_ONLY) {
+ if ((mTick ^ mKeepAlive) >> 10 == 0) {
+ return;
}
- chain = chain->mNext;
- }
- if (!mixed) {
- if ((mTick ^ mLogThrottle) >> 10) {
- mLogThrottle = mTick;
+ mKeepAlive = mTick;
+ memset(samples, 0, sizeof(samples));
+ } else {
+ // Mix all other streams.
+ bool mixed = false;
+ memset(buffer, 0, sizeof(buffer));
+ while (chain) {
+ if (chain != this &&
+ chain->mix(buffer, tick - mInterval, tick, mSampleRate)) {
+ mixed = true;
+ }
+ chain = chain->mNext;
+ }
+
+ if (mixed) {
+ // Saturate into 16 bits.
+ for (int i = 0; i < mSampleCount; ++i) {
+ int32_t sample = buffer[i];
+ if (sample < -32768) {
+ sample = -32768;
+ }
+ if (sample > 32767) {
+ sample = 32767;
+ }
+ samples[i] = sample;
+ }
+ } else {
+ if ((mTick ^ mKeepAlive) >> 10 == 0) {
+ return;
+ }
+ mKeepAlive = mTick;
+ memset(samples, 0, sizeof(samples));
LOGV("stream[%d] no data", mSocket);
}
- return;
}
- // Cook the packet and send it out.
- int16_t samples[mSampleCount];
- for (int i = 0; i < mSampleCount; ++i) {
- int32_t sample = buffer[i];
- if (sample < -32768) {
- sample = -32768;
- }
- if (sample > 32767) {
- sample = 32767;
- }
- samples[i] = sample;
- }
if (!mCodec) {
// Special case for device stream.
send(mSocket, samples, sizeof(samples), MSG_DONTWAIT);
return;
}
+ // Cook the packet and send it out.
buffer[0] = htonl(mCodecMagic | mSequence);
buffer[1] = htonl(mTimestamp);
buffer[2] = mSsrc;
@@ -883,7 +899,7 @@
int codecType = -1;
char codecName[16];
int sampleRate = -1;
- sscanf(codecSpec, "%d %[^/]%*c%d", &codecType, codecName, &sampleRate);
+ sscanf(codecSpec, "%d %15[^/]%*c%d", &codecType, codecName, &sampleRate);
codec = newAudioCodec(codecName);
int sampleCount = (codec ? codec->set(sampleRate, codecSpec) : -1);
env->ReleaseStringUTFChars(jCodecSpec, codecSpec);