Merge "Fixing possible race condition."
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
old mode 100644
new mode 100755
index 803446f..1a35112
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -115,8 +115,8 @@
 
         public static final int STATUS_NONE = -1;
         public static final int STATUS_COMPLETE = 0;
-        public static final int STATUS_PENDING = 64;
-        public static final int STATUS_FAILED = 128;
+        public static final int STATUS_PENDING = 32;
+        public static final int STATUS_FAILED = 64;
 
         /**
          * The subject of the message, if present
diff --git a/core/java/android/text/InputFilter.java b/core/java/android/text/InputFilter.java
index 2f55677..8d4b08e 100644
--- a/core/java/android/text/InputFilter.java
+++ b/core/java/android/text/InputFilter.java
@@ -88,7 +88,14 @@
             } else if (keep >= end - start) {
                 return null; // keep original
             } else {
-                return source.subSequence(start, start + keep);
+                keep += start;
+                if (Character.isHighSurrogate(source.charAt(keep - 1))) {
+                    --keep;
+                    if (keep == start) {
+                        return "";
+                    }
+                }
+                return source.subSequence(start, keep);
             }
         }
 
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index f54b207..e36602f 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -58,7 +58,11 @@
         // Load libwebcore during static initialization. This happens in the
         // zygote process so it will be shared read-only across all app
         // processes.
-        System.loadLibrary("webcore");
+        try {
+            System.loadLibrary("webcore");
+        } catch (UnsatisfiedLinkError e) {
+            Log.e(LOGTAG, "Unable to load webcore library");
+        }
     }
 
     /*
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index 8aaa325..433f1f7 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -975,7 +975,6 @@
 {
     int32_t* const outTemp = state->outputTemp;
     const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
-    memset(outTemp, 0, size);
 
     size_t numFrames = state->frameCount;
 
@@ -997,6 +996,7 @@
         }
         e0 &= ~(e1);
         int32_t *out = t1.mainBuffer;
+        memset(outTemp, 0, size);
         while (e1) {
             const int i = 31 - __builtin_clz(e1);
             e1 &= ~(1<<i);
diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
old mode 100644
new mode 100755
index f93e494..e68df2d
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
@@ -65,6 +65,7 @@
 
 public abstract class SMSDispatcher extends Handler {
     private static final String TAG = "SMS";
+    private static final String SEND_NEXT_MSG_EXTRA = "SendNextMsg";
 
     /** Default checking period for SMS sent without user permit */
     private static final int DEFAULT_SMS_CHECK_PERIOD = 3600000;
@@ -156,6 +157,8 @@
     protected boolean mStorageAvailable = true;
     protected boolean mReportMemoryStatusPending = false;
 
+    protected static int mRemainingMessages = -1;
+
     protected static int getNextConcatenatedRef() {
         sConcatenatedRef += 1;
         return sConcatenatedRef;
@@ -469,7 +472,17 @@
 
             if (sentIntent != null) {
                 try {
-                    sentIntent.send(Activity.RESULT_OK);
+                    if (mRemainingMessages > -1) {
+                        mRemainingMessages--;
+                    }
+
+                    if (mRemainingMessages == 0) {
+                        Intent sendNext = new Intent();
+                        sendNext.putExtra(SEND_NEXT_MSG_EXTRA, true);
+                        sentIntent.send(mContext, Activity.RESULT_OK, sendNext);
+                    } else {
+                        sentIntent.send(Activity.RESULT_OK);
+                    }
                 } catch (CanceledException ex) {}
             }
         } else {
@@ -508,8 +521,15 @@
                     if (ar.result != null) {
                         fillIn.putExtra("errorCode", ((SmsResponse)ar.result).errorCode);
                     }
-                    tracker.mSentIntent.send(mContext, error, fillIn);
+                    if (mRemainingMessages > -1) {
+                        mRemainingMessages--;
+                    }
 
+                    if (mRemainingMessages == 0) {
+                        fillIn.putExtra(SEND_NEXT_MSG_EXTRA, true);
+                    }
+
+                    tracker.mSentIntent.send(mContext, error, fillIn);
                 } catch (CanceledException ex) {}
             }
         }
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
old mode 100644
new mode 100755
index 40ee0b0..8355046
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
@@ -23,6 +23,7 @@
 import android.os.AsyncResult;
 import android.os.Message;
 import android.os.SystemProperties;
+import android.provider.Telephony.Sms;
 import android.provider.Telephony.Sms.Intents;
 import android.telephony.ServiceState;
 import android.telephony.SmsCbMessage;
@@ -68,13 +69,17 @@
         String pduString = (String) ar.result;
         SmsMessage sms = SmsMessage.newFromCDS(pduString);
 
+        int tpStatus = sms.getStatus();
+
         if (sms != null) {
             int messageRef = sms.messageRef;
             for (int i = 0, count = deliveryPendingList.size(); i < count; i++) {
                 SmsTracker tracker = deliveryPendingList.get(i);
                 if (tracker.mMessageRef == messageRef) {
                     // Found it.  Remove from list and broadcast.
-                    deliveryPendingList.remove(i);
+                    if(tpStatus >= Sms.STATUS_FAILED || tpStatus < Sms.STATUS_PENDING ) {
+                       deliveryPendingList.remove(i);
+                    }
                     PendingIntent intent = tracker.mDeliveryIntent;
                     Intent fillIn = new Intent();
                     fillIn.putExtra("pdu", IccUtils.hexStringToBytes(pduString));
@@ -183,6 +188,8 @@
         int msgCount = parts.size();
         int encoding = android.telephony.SmsMessage.ENCODING_UNKNOWN;
 
+        mRemainingMessages = msgCount;
+
         for (int i = 0; i < msgCount; i++) {
             TextEncodingDetails details = SmsMessage.calculateLength(parts.get(i), false);
             if (encoding != details.codeUnitSize
@@ -272,6 +279,8 @@
         int msgCount = parts.size();
         int encoding = android.telephony.SmsMessage.ENCODING_UNKNOWN;
 
+        mRemainingMessages = msgCount;
+
         for (int i = 0; i < msgCount; i++) {
             TextEncodingDetails details = SmsMessage.calculateLength(parts.get(i), false);
             if (encoding != details.codeUnitSize
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
old mode 100644
new mode 100755
index 438996f..3b133da
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -144,6 +144,25 @@
     private static final int EVENT_GET_CFIS_DONE = 32;
     private static final int EVENT_GET_CSP_CPHS_DONE = 33;
 
+    // Lookup table for carriers known to produce SIMs which incorrectly indicate MNC length.
+
+    private static final String[] MCCMNC_CODES_HAVING_3DIGITS_MNC = {
+        "405025", "405026", "405027", "405028", "405029", "405030", "405031", "405032",
+        "405033", "405034", "405035", "405036", "405037", "405038", "405039", "405040",
+        "405041", "405042", "405043", "405044", "405045", "405046", "405047", "405750",
+        "405751", "405752", "405753", "405754", "405755", "405756", "405799", "405800",
+        "405801", "405802", "405803", "405804", "405805", "405806", "405807", "405808",
+        "405809", "405810", "405811", "405812", "405813", "405814", "405815", "405816",
+        "405817", "405818", "405819", "405820", "405821", "405822", "405823", "405824",
+        "405825", "405826", "405827", "405828", "405829", "405830", "405831", "405832",
+        "405833", "405834", "405835", "405836", "405837", "405838", "405839", "405840",
+        "405841", "405842", "405843", "405844", "405845", "405846", "405847", "405848",
+        "405849", "405850", "405851", "405852", "405853", "405875", "405876", "405877",
+        "405878", "405879", "405880", "405881", "405882", "405883", "405884", "405885",
+        "405886", "405908", "405909", "405910", "405911", "405925", "405926", "405927",
+        "405928", "405929", "405932"
+    };
+
     // ***** Constructor
 
     SIMRecords(GSMPhone p) {
@@ -501,6 +520,17 @@
 
                 Log.d(LOG_TAG, "IMSI: " + imsi.substring(0, 6) + "xxxxxxx");
 
+                if (((mncLength == UNKNOWN) || (mncLength == 2)) &&
+                        ((imsi != null) && (imsi.length() >= 6))) {
+                    String mccmncCode = imsi.substring(0, 6);
+                    for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) {
+                        if (mccmnc.equals(mccmncCode)) {
+                            mncLength = 3;
+                            break;
+                        }
+                    }
+                }
+
                 if (mncLength == UNKNOWN) {
                     // the SIM has told us all it knows, but it didn't know the mnc length.
                     // guess using the mcc
@@ -752,6 +782,17 @@
                         mncLength = UNKNOWN;
                     }
                 } finally {
+                    if (((mncLength == UNINITIALIZED) || (mncLength == UNKNOWN) ||
+                            (mncLength == 2)) && ((imsi != null) && (imsi.length() >= 6))) {
+                        String mccmncCode = imsi.substring(0, 6);
+                        for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) {
+                            if (mccmnc.equals(mccmncCode)) {
+                                mncLength = 3;
+                                break;
+                            }
+                        }
+                    }
+
                     if (mncLength == UNKNOWN || mncLength == UNINITIALIZED) {
                         if (imsi != null) {
                             try {