Merge "Fix issue with project resources overriding framework resources." into gingerbread
diff --git a/core/java/android/nfc/NdefTagConnection.java b/core/java/android/nfc/NdefTagConnection.java
index 321b0ec..27fa25c 100644
--- a/core/java/android/nfc/NdefTagConnection.java
+++ b/core/java/android/nfc/NdefTagConnection.java
@@ -42,8 +42,8 @@
      * Internal constructor, to be used by NfcAdapter
      * @hide
      */
-    /* package private */ NdefTagConnection(INfcAdapter service, NdefTag tag, String target) throws RemoteException {
-        super(service, tag);
+    /* package private */ NdefTagConnection(NfcAdapter adapter, NdefTag tag, String target) throws RemoteException {
+        super(adapter, tag);
         String[] targets = tag.getNdefTargets();
         int i;
 
@@ -63,8 +63,8 @@
      * Internal constructor, to be used by NfcAdapter
      * @hide
      */
-    /* package private */ NdefTagConnection(INfcAdapter service, NdefTag tag) throws RemoteException {
-        this(service, tag, tag.getNdefTargets()[0]);
+    /* package private */ NdefTagConnection(NfcAdapter adapter, NdefTag tag) throws RemoteException {
+        this(adapter, tag, tag.getNdefTargets()[0]);
     }
 
     /**
@@ -97,7 +97,7 @@
             msgArray[0] = msg;
             return msgArray;
         } catch (RemoteException e) {
-            Log.e(TAG, "NFC service died");
+            attemptDeadServiceRecovery(e);
             return null;
         }
     }
@@ -134,7 +134,7 @@
                     throw new IOException();
             }
         } catch (RemoteException e) {
-            Log.e(TAG, "NFC service died");
+            attemptDeadServiceRecovery(e);
         }
     }
 
@@ -161,7 +161,7 @@
                     throw new IOException();
             }
         } catch (RemoteException e) {
-            Log.e(TAG, "NFC service died");
+            attemptDeadServiceRecovery(e);
             return false;
         }
     }
@@ -188,7 +188,7 @@
             return result;
 
         } catch (RemoteException e) {
-            Log.e(TAG, "NFC service died");
+            attemptDeadServiceRecovery(e);
             return NDEF_MODE_UNKNOWN;
         }
     }
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 7f4b4a2..a093d12 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -168,7 +168,10 @@
     private static boolean sIsInitialized = false;
     private static NfcAdapter sAdapter;
 
-    private final INfcAdapter mService;
+    // Final after construction, except for attemptDeadServiceRecovery()
+    // when NFC crashes.
+    // Not locked - we accept a best effort attempt when NFC crashes.
+    /*package*/ INfcAdapter mService;
 
     private NfcAdapter(INfcAdapter service) {
         mService = service;
@@ -194,6 +197,16 @@
         }
     }
 
+    /** get handle to NFC service interface */
+    private static synchronized INfcAdapter getServiceInterface() {
+        /* get a handle to NFC service */
+        IBinder b = ServiceManager.getService("nfc");
+        if (b == null) {
+            return null;
+        }
+        return INfcAdapter.Stub.asInterface(b);
+    }
+
     /**
      * Get a handle to the default NFC Adapter on this Android device.
      * <p>
@@ -214,18 +227,31 @@
                 return null;
             }
 
-            /* get a handle to NFC service */
-            IBinder b = ServiceManager.getService("nfc");
-            if (b == null) {
+            INfcAdapter service = getServiceInterface();
+            if (service == null) {
                 Log.e(TAG, "could not retrieve NFC service");
                 return null;
             }
 
-            sAdapter = new NfcAdapter(INfcAdapter.Stub.asInterface(b));
+            sAdapter = new NfcAdapter(service);
             return sAdapter;
         }
     }
 
+    /** NFC service dead - attempt best effort recovery */
+    /*package*/ void attemptDeadServiceRecovery(Exception e) {
+        Log.e(TAG, "NFC service dead - attempting to recover", e);
+        INfcAdapter service = getServiceInterface();
+        if (service == null) {
+            Log.e(TAG, "could not retrieve NFC service during service recovery");
+            return;
+        }
+        /* assigning to mService is not thread-safe, but this is best-effort code
+         * and on a well-behaved system should never happen */
+        mService = service;
+        return;
+    }
+
     /**
      * Return true if this NFC Adapter has any features enabled.
      * <p>
@@ -241,7 +267,7 @@
         try {
             return mService.isEnabled();
         } catch (RemoteException e) {
-            Log.e(TAG, "RemoteException in isEnabled()", e);
+            attemptDeadServiceRecovery(e);
             return false;
         }
     }
@@ -258,7 +284,7 @@
         try {
             return mService.enable();
         } catch (RemoteException e) {
-            Log.e(TAG, "RemoteException in enable()", e);
+            attemptDeadServiceRecovery(e);
             return false;
         }
     }
@@ -277,7 +303,7 @@
         try {
             return mService.disable();
         } catch (RemoteException e) {
-            Log.e(TAG, "RemoteException in disable()", e);
+            attemptDeadServiceRecovery(e);
             return false;
         }
     }
@@ -303,7 +329,7 @@
         try {
             mService.localSet(message);
         } catch (RemoteException e) {
-            Log.e(TAG, "NFC service died", e);
+            attemptDeadServiceRecovery(e);
         }
     }
 
@@ -317,7 +343,7 @@
         try {
             return mService.localGet();
         } catch (RemoteException e) {
-            Log.e(TAG, "NFC service died", e);
+            attemptDeadServiceRecovery(e);
             return null;
         }
     }
@@ -331,9 +357,9 @@
             throw new IllegalArgumentException("mock tag cannot be used for connections");
         }
         try {
-            return new RawTagConnection(mService, tag);
+            return new RawTagConnection(this, tag);
         } catch (RemoteException e) {
-            Log.e(TAG, "NFC service died", e);
+            attemptDeadServiceRecovery(e);
             return null;
         }
     }
@@ -347,9 +373,9 @@
             throw new IllegalArgumentException("mock tag cannot be used for connections");
         }
         try {
-            return new RawTagConnection(mService, tag, target);
+            return new RawTagConnection(this, tag, target);
         } catch (RemoteException e) {
-            Log.e(TAG, "NFC service died", e);
+            attemptDeadServiceRecovery(e);
             return null;
         }
     }
@@ -363,9 +389,9 @@
             throw new IllegalArgumentException("mock tag cannot be used for connections");
         }
         try {
-            return new NdefTagConnection(mService, tag);
+            return new NdefTagConnection(this, tag);
         } catch (RemoteException e) {
-            Log.e(TAG, "NFC service died", e);
+            attemptDeadServiceRecovery(e);
             return null;
         }
     }
@@ -379,9 +405,9 @@
             throw new IllegalArgumentException("mock tag cannot be used for connections");
         }
         try {
-            return new NdefTagConnection(mService, tag, target);
+            return new NdefTagConnection(this, tag, target);
         } catch (RemoteException e) {
-            Log.e(TAG, "NFC service died", e);
+            attemptDeadServiceRecovery(e);
             return null;
         }
     }
diff --git a/core/java/android/nfc/RawTagConnection.java b/core/java/android/nfc/RawTagConnection.java
index 8442893..24072e5 100644
--- a/core/java/android/nfc/RawTagConnection.java
+++ b/core/java/android/nfc/RawTagConnection.java
@@ -35,15 +35,20 @@
  */
 public class RawTagConnection {
 
-    /*package*/ final INfcAdapter mService;
-    /*package*/ final INfcTag mTagService;
     /*package*/ final Tag mTag;
     /*package*/ boolean mIsConnected;
     /*package*/ String mSelectedTarget;
+    private final NfcAdapter mAdapter;
+
+    // Following fields are final after construction, except for
+    // during attemptDeadServiceRecovery() when NFC crashes.
+    // Not locked - we accept a best effort attempt when NFC crashes.
+    /*package*/ INfcAdapter mService;
+    /*package*/ INfcTag mTagService;
 
     private static final String TAG = "NFC";
 
-    /* package private */ RawTagConnection(INfcAdapter service, Tag tag, String target) throws RemoteException {
+    /*package*/ RawTagConnection(NfcAdapter adapter, Tag tag, String target) throws RemoteException {
         String[] targets = tag.getRawTargets();
         int i;
 
@@ -58,14 +63,28 @@
             throw new IllegalArgumentException();
         }
 
-        mService = service;
-        mTagService = service.getNfcTagInterface();
+        mAdapter = adapter;
+        mService = mAdapter.mService;
+        mTagService = mService.getNfcTagInterface();
         mTag = tag;
         mSelectedTarget = target;
     }
 
-    /* package private */ RawTagConnection(INfcAdapter service, Tag tag) throws RemoteException {
-        this(service, tag, tag.getRawTargets()[0]);
+    /*package*/ RawTagConnection(NfcAdapter adapter, Tag tag) throws RemoteException {
+        this(adapter, tag, tag.getRawTargets()[0]);
+    }
+
+    /** NFC service dead - attempt best effort recovery */
+    /*package*/ void attemptDeadServiceRecovery(Exception e) {
+        mAdapter.attemptDeadServiceRecovery(e);
+        /* assigning to mService is not thread-safe, but this is best-effort code
+         * and on a well-behaved system should never happen */
+        mService = mAdapter.mService;
+        try {
+            mTagService = mService.getNfcTagInterface();
+        } catch (RemoteException e2) {
+            Log.e(TAG, "second RemoteException trying to recover from dead NFC service", e2);
+        }
     }
 
     /**
@@ -101,7 +120,7 @@
         try {
             return mTagService.isPresent(mTag.mServiceHandle);
         } catch (RemoteException e) {
-            Log.e(TAG, "NFC service died", e);
+            attemptDeadServiceRecovery(e);
             return false;
         }
     }
@@ -136,7 +155,7 @@
         try {
             mTagService.close(mTag.mServiceHandle);
         } catch (RemoteException e) {
-            Log.e(TAG, "NFC service died", e);
+            attemptDeadServiceRecovery(e);
         }
     }
 
@@ -159,7 +178,7 @@
             }
             return response;
         } catch (RemoteException e) {
-            Log.e(TAG, "NFC service died", e);
+            attemptDeadServiceRecovery(e);
             throw new IOException("NFC service died");
         }
     }
diff --git a/data/sounds/AudioPackage5.mk b/data/sounds/AudioPackage5.mk
index ffc97d7..550f990 100755
--- a/data/sounds/AudioPackage5.mk
+++ b/data/sounds/AudioPackage5.mk
@@ -63,10 +63,10 @@
 	$(LOCAL_PATH)/ringtones/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \
 	$(LOCAL_PATH)/ringtones/PERSEUS.ogg:system/media/audio/ringtones/PERSEUS.ogg \
 	$(LOCAL_PATH)/ringtones/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \
-	$(LOCAL_PATH)/ringtones/Rigel.ogg:system/media/audio/notifications/Rigel.ogg \
-	$(LOCAL_PATH)/ringtones/Scarabaeus.ogg:system/media/audio/notifications/Scarabaeus.ogg \
-	$(LOCAL_PATH)/ringtones/Sceptrum.ogg:system/media/audio/notifications/Sceptrum.ogg \
-	$(LOCAL_PATH)/ringtones/Solarium.ogg:system/media/audio/notifications/Solarium.ogg \
-	$(LOCAL_PATH)/ringtones/Testudo.ogg:system/media/audio/notifications/Testudo.ogg \
+	$(LOCAL_PATH)/ringtones/Rigel.ogg:system/media/audio/ringtones/Rigel.ogg \
+	$(LOCAL_PATH)/ringtones/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \
+	$(LOCAL_PATH)/ringtones/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \
+	$(LOCAL_PATH)/ringtones/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \
+	$(LOCAL_PATH)/ringtones/Testudo.ogg:system/media/audio/ringtones/Testudo.ogg \
 	$(LOCAL_PATH)/ringtones/URSAMINOR.ogg:system/media/audio/ringtones/URSAMINOR.ogg \
 	$(LOCAL_PATH)/ringtones/Vespa.ogg:system/media/audio/ringtones/Vespa.ogg
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index 5505f14..c957dba 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -243,19 +243,22 @@
     // derive capture scaling factor from peak value in current buffer
     // this gives more interesting captures for display.
     int32_t shift = 32;
-    for (size_t i = 0; i < inBuffer->frameCount; i++) {
+    int len = inBuffer->frameCount * 2;
+    for (size_t i = 0; i < len; i++) {
         int32_t smp = inBuffer->s16[i];
-        if (smp < 0) smp = -smp;
+        if (smp < 0) smp = -smp - 1; // take care to keep the max negative in range
         int32_t clz = __builtin_clz(smp);
         if (shift > clz) shift = clz;
     }
-    // never scale by less than 8 to avoid returning unaltered PCM signal.
-    // add one to combine the division by 2 needed after summing left and right channels below
-    if (20 > shift) {
-        shift = (31 - 8 + 1) - shift;
-    } else {
-        shift = (3 + 1);
+    // A maximum amplitude signal will have 17 leading zeros, which we want to
+    // translate to a shift of 8 (for converting 16 bit to 8 bit)
+     shift = 25 - shift;
+    // Never scale by less than 8 to avoid returning unaltered PCM signal.
+    if (shift < 3) {
+        shift = 3;
     }
+    // add one to combine the division by 2 needed after summing left and right channels below
+    shift++;
 
     uint32_t captIdx;
     uint32_t inIdx;
@@ -264,7 +267,7 @@
          inIdx < inBuffer->frameCount && captIdx < pContext->mCaptureSize;
          inIdx++, captIdx++) {
         int32_t smp = inBuffer->s16[2 * inIdx] + inBuffer->s16[2 * inIdx + 1];
-        smp = (smp + (1 << (shift - 1))) >> shift;
+        smp = smp >> shift;
         buf[captIdx] = ((uint8_t)smp)^0x80;
     }
     pContext->mCaptureIdx = captIdx;
diff --git a/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp b/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp
index 703b41e..e14fb95 100644
--- a/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp
@@ -112,7 +112,12 @@
 
     mAnchorTimeUs = 0;
     mNumFramesOutput = 0;
-    mNumFramesLeftOnPage = 0;
+
+    // If the source never limits the number of valid frames contained
+    // in the input data, we'll assume that all of the decoded frames are
+    // valid.
+    mNumFramesLeftOnPage = -1;
+
     mStarted = true;
 
     return OK;
@@ -193,12 +198,14 @@
         }
     }
 
-    if (numFrames > mNumFramesLeftOnPage) {
-        LOGV("discarding %d frames at end of page",
-             numFrames - mNumFramesLeftOnPage);
-        numFrames = mNumFramesLeftOnPage;
+    if (mNumFramesLeftOnPage >= 0) {
+        if (numFrames > mNumFramesLeftOnPage) {
+            LOGV("discarding %d frames at end of page",
+                 numFrames - mNumFramesLeftOnPage);
+            numFrames = mNumFramesLeftOnPage;
+        }
+        mNumFramesLeftOnPage -= numFrames;
     }
-    mNumFramesLeftOnPage -= numFrames;
 
     out->set_range(0, numFrames * sizeof(int16_t) * mNumChannels);
 
@@ -241,6 +248,7 @@
     int32_t numPageSamples;
     if (inputBuffer->meta_data()->findInt32(
                 kKeyValidSamples, &numPageSamples)) {
+        CHECK(numPageSamples >= 0);
         mNumFramesLeftOnPage = numPageSamples;
     }
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
index 3908d71..b4ae593 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
@@ -300,6 +300,7 @@
             if (duration <= 0){
                 assertTrue("stressRecordAndPlayback", false);
             }
+            mp.release();
         } catch (Exception e) {
             assertTrue("stressRecordAndPlayback", false);
         }