Merge "Memory leak due to bad destroy sequence"
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index a300776..483e9de 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -2338,7 +2338,7 @@
         }
 
         /**
-         * Sets the maximum and maximum preview fps. This controls the rate of
+         * Sets the minimum and maximum preview fps. This controls the rate of
          * preview frames received in {@link PreviewCallback}. The minimum and
          * maximum preview fps must be one of the elements from {@link
          * #getSupportedPreviewFpsRange}.
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index 1060bd8..ddd62a8 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -43,11 +43,6 @@
     private static String sElapsedFormatMMSS;
     private static String sElapsedFormatHMMSS;
 
-    private static final String FAST_FORMAT_HMMSS = "%1$d:%2$02d:%3$02d";
-    private static final String FAST_FORMAT_MMSS = "%1$02d:%2$02d";
-    private static final char TIME_SEPARATOR = ':';
-
-
     public static final long SECOND_IN_MILLIS = 1000;
     public static final long MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60;
     public static final long HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60;
@@ -616,19 +611,18 @@
     }
 
     /**
-     * Formats an elapsed time in the form "MM:SS" or "H:MM:SS"
-     * for display on the call-in-progress screen.
+     * Formats an elapsed time in a format like "MM:SS" or "H:MM:SS" (using a form
+     * suited to the current locale), similar to that used on the call-in-progress
+     * screen.
      *
-     * @param recycle {@link StringBuilder} to recycle, if possible
+     * @param recycle {@link StringBuilder} to recycle, or null to use a temporary one.
      * @param elapsedSeconds the elapsed time in seconds.
      */
     public static String formatElapsedTime(StringBuilder recycle, long elapsedSeconds) {
-        initFormatStrings();
-
+        // Break the elapsed seconds into hours, minutes, and seconds.
         long hours = 0;
         long minutes = 0;
         long seconds = 0;
-
         if (elapsedSeconds >= 3600) {
             hours = elapsedSeconds / 3600;
             elapsedSeconds -= hours * 3600;
@@ -639,70 +633,23 @@
         }
         seconds = elapsedSeconds;
 
-        String result;
+        // Create a StringBuilder if we weren't given one to recycle.
+        // TODO: if we cared, we could have a thread-local temporary StringBuilder.
+        StringBuilder sb = recycle;
+        if (sb == null) {
+            sb = new StringBuilder(8);
+        } else {
+            sb.setLength(0);
+        }
+
+        // Format the broken-down time in a locale-appropriate way.
+        // TODO: use icu4c when http://unicode.org/cldr/trac/ticket/3407 is fixed.
+        Formatter f = new Formatter(sb, Locale.getDefault());
+        initFormatStrings();
         if (hours > 0) {
-            return formatElapsedTime(recycle, sElapsedFormatHMMSS, hours, minutes, seconds);
+            return f.format(sElapsedFormatHMMSS, hours, minutes, seconds).toString();
         } else {
-            return formatElapsedTime(recycle, sElapsedFormatMMSS, minutes, seconds);
-        }
-    }
-
-    private static void append(StringBuilder sb, long value, boolean pad, char zeroDigit) {
-        if (value < 10) {
-            if (pad) {
-                sb.append(zeroDigit);
-            }
-        } else {
-            sb.append((char) (zeroDigit + (value / 10)));
-        }
-        sb.append((char) (zeroDigit + (value % 10)));
-    }
-
-    /**
-     * Fast formatting of h:mm:ss.
-     */
-    private static String formatElapsedTime(StringBuilder recycle, String format, long hours,
-            long minutes, long seconds) {
-        if (FAST_FORMAT_HMMSS.equals(format)) {
-            char zeroDigit = LocaleData.get(Locale.getDefault()).zeroDigit;
-
-            StringBuilder sb = recycle;
-            if (sb == null) {
-                sb = new StringBuilder(8);
-            } else {
-                sb.setLength(0);
-            }
-            append(sb, hours, false, zeroDigit);
-            sb.append(TIME_SEPARATOR);
-            append(sb, minutes, true, zeroDigit);
-            sb.append(TIME_SEPARATOR);
-            append(sb, seconds, true, zeroDigit);
-            return sb.toString();
-        } else {
-            return String.format(format, hours, minutes, seconds);
-        }
-    }
-
-    /**
-     * Fast formatting of mm:ss.
-     */
-    private static String formatElapsedTime(StringBuilder recycle, String format, long minutes,
-            long seconds) {
-        if (FAST_FORMAT_MMSS.equals(format)) {
-            char zeroDigit = LocaleData.get(Locale.getDefault()).zeroDigit;
-
-            StringBuilder sb = recycle;
-            if (sb == null) {
-                sb = new StringBuilder(8);
-            } else {
-                sb.setLength(0);
-            }
-            append(sb, minutes, false, zeroDigit);
-            sb.append(TIME_SEPARATOR);
-            append(sb, seconds, true, zeroDigit);
-            return sb.toString();
-        } else {
-            return String.format(format, minutes, seconds);
+            return f.format(sElapsedFormatMMSS, minutes, seconds).toString();
         }
     }
 
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index 485bd37..ab36139 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -374,8 +374,13 @@
                 // remove the old view if necessary
                 handleHide();
                 mView = mNextView;
-                mWM = (WindowManager)mView.getContext().getApplicationContext()
-                        .getSystemService(Context.WINDOW_SERVICE);
+                Context context = mView.getContext();
+                if (context.getApplicationContext() != null) {
+                    // Use application context, except when called from system
+                    // service where there is no application context.
+                    context = context.getApplicationContext();
+                }
+                mWM = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
                 // We can resolve the Gravity here by using the Locale for getting
                 // the layout direction
                 final Configuration config = mView.getContext().getResources().getConfiguration();
diff --git a/core/jni/android_media_JetPlayer.cpp b/core/jni/android_media_JetPlayer.cpp
index a785f52..5795aba 100644
--- a/core/jni/android_media_JetPlayer.cpp
+++ b/core/jni/android_media_JetPlayer.cpp
@@ -130,9 +130,10 @@
 {
     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
-    if (lpJet == NULL ) {
+    if (lpJet == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve JetPlayer pointer for openFile()");
+        return JNI_FALSE;
     }
 
     // set up event callback function
@@ -166,9 +167,10 @@
 {
     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
-    if (lpJet == NULL ) {
+    if (lpJet == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve JetPlayer pointer for openFile()");
+        return JNI_FALSE;
     }
 
     // set up event callback function
@@ -195,9 +197,10 @@
 {
     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
-    if (lpJet == NULL ) {
+    if (lpJet == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve JetPlayer pointer for closeFile()");
+        return JNI_FALSE;
     }
 
     if (lpJet->closeFile()==EAS_SUCCESS) {
@@ -216,9 +219,10 @@
 {
     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
-    if (lpJet == NULL ) {
+    if (lpJet == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve JetPlayer pointer for play()");
+        return JNI_FALSE;
     }
 
     EAS_RESULT result = lpJet->play();
@@ -239,9 +243,10 @@
 {
     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
-    if (lpJet == NULL ) {
+    if (lpJet == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve JetPlayer pointer for pause()");
+        return JNI_FALSE;
     }
 
     EAS_RESULT result = lpJet->pause();
@@ -268,9 +273,10 @@
 {
     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
-    if (lpJet == NULL ) {
+    if (lpJet == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve JetPlayer pointer for queueSegment()");
+        return JNI_FALSE;
     }
 
     EAS_RESULT result
@@ -294,9 +300,10 @@
 {
     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
-    if (lpJet == NULL ) {
+    if (lpJet == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve JetPlayer pointer for queueSegmentMuteArray()");
+        return JNI_FALSE;
     }
 
     EAS_RESULT result=EAS_FAILURE;
@@ -339,9 +346,10 @@
 {
     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
-    if (lpJet == NULL ) {
+    if (lpJet == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve JetPlayer pointer for setMuteFlags()");
+        return JNI_FALSE;
     }
 
     EAS_RESULT result;
@@ -363,9 +371,10 @@
 {
     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
-    if (lpJet == NULL ) {
+    if (lpJet == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve JetPlayer pointer for setMuteArray()");
+        return JNI_FALSE;
     }
 
     EAS_RESULT result=EAS_FAILURE;
@@ -408,9 +417,10 @@
 {
     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
-    if (lpJet == NULL ) {
+    if (lpJet == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve JetPlayer pointer for setMuteFlag()");
+        return JNI_FALSE;
     }
 
     EAS_RESULT result;
@@ -433,9 +443,10 @@
 {
     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
-    if (lpJet == NULL ) {
+    if (lpJet == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve JetPlayer pointer for triggerClip()");
+        return JNI_FALSE;
     }
 
     EAS_RESULT result;
@@ -457,9 +468,10 @@
 {
     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
-    if (lpJet == NULL ) {
+    if (lpJet == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "Unable to retrieve JetPlayer pointer for clearQueue()");
+        return JNI_FALSE;
     }
 
     EAS_RESULT result = lpJet->clearQueue();
diff --git a/libs/androidfw/BackupHelpers.cpp b/libs/androidfw/BackupHelpers.cpp
index 7a817a7..dcf41b7 100644
--- a/libs/androidfw/BackupHelpers.cpp
+++ b/libs/androidfw/BackupHelpers.cpp
@@ -710,7 +710,7 @@
     }
 
 cleanup:
-    delete [] buf;
+    free(buf);
 done:
     close(fd);
     return err;
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
old mode 100644
new mode 100755
index d1f8ef1..3dc77d4
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -408,7 +408,12 @@
     /** {@inheritDoc} */
     public void onDismiss(DialogInterface dialog) {
         if (SHOW_SILENT_TOGGLE) {
-            mContext.unregisterReceiver(mRingerModeReceiver);
+            try {
+                mContext.unregisterReceiver(mRingerModeReceiver);
+            } catch (IllegalArgumentException ie) {
+                // ignore this
+                Log.w(TAG, ie);
+            }
         }
     }