merge in ics-mr0-release history after reset to ics-mr0
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 0b53850..7db8abd 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -425,14 +425,10 @@
         // Initialize Harfbuzz Shaper
         initShaperItem(shaperItem, &font, &fontData, paint, chars, contextCount);
 
+        bool useSingleRun = false;
+        bool isRTL = forceRTL;
         if (forceLTR || forceRTL) {
-#if DEBUG_GLYPHS
-                    LOGD("computeValuesWithHarfbuzz -- forcing run with LTR=%d RTL=%d",
-                            forceLTR, forceRTL);
-#endif
-            computeRunValuesWithHarfbuzz(shaperItem, paint,
-                    start, count, forceRTL,
-                    outAdvances, outTotalAdvance, outGlyphs);
+            useSingleRun = true;
         } else {
             UBiDi* bidi = ubidi_open();
             if (bidi) {
@@ -443,43 +439,54 @@
                 ubidi_setPara(bidi, chars, contextCount, bidiReq, NULL, &status);
                 if (U_SUCCESS(status)) {
                     int paraDir = ubidi_getParaLevel(bidi) & kDirection_Mask; // 0 if ltr, 1 if rtl
-                    size_t rc = ubidi_countRuns(bidi, &status);
+                    ssize_t rc = ubidi_countRuns(bidi, &status);
 #if DEBUG_GLYPHS
                     LOGD("computeValuesWithHarfbuzz -- dirFlags=%d run-count=%d paraDir=%d",
                             dirFlags, rc, paraDir);
 #endif
-                    if (rc == 1 || !U_SUCCESS(status)) {
-                        bool isRTL = (paraDir == 1);
-#if DEBUG_GLYPHS
-                        LOGD("computeValuesWithHarfbuzz -- processing SINGLE run "
-                                "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
-#endif
-                        computeRunValuesWithHarfbuzz(shaperItem, paint,
-                                start, count, isRTL,
-                                outAdvances, outTotalAdvance, outGlyphs);
+                    if (U_SUCCESS(status) && rc == 1) {
+                        // Normal case: one run, status is ok
+                        isRTL = (paraDir == 1);
+                        useSingleRun = true;
+                    } else if (!U_SUCCESS(status) || rc < 1) {
+                        LOGW("computeValuesWithHarfbuzz -- need to force to single run");
+                        isRTL = (paraDir == 1);
+                        useSingleRun = true;
                     } else {
                         int32_t end = start + count;
-                        for (size_t i = 0; i < rc; ++i) {
-                            int32_t startRun;
-                            int32_t lengthRun;
+                        for (size_t i = 0; i < size_t(rc); ++i) {
+                            int32_t startRun = -1;
+                            int32_t lengthRun = -1;
                             UBiDiDirection runDir = ubidi_getVisualRun(bidi, i, &startRun, &lengthRun);
 
+                            if (startRun == -1 || lengthRun == -1) {
+                                // Something went wrong when getting the visual run, need to clear
+                                // already computed data before doing a single run pass
+                                LOGW("computeValuesWithHarfbuzz -- visual run is not valid");
+                                outGlyphs->clear();
+                                outAdvances->clear();
+                                *outTotalAdvance = 0;
+                                isRTL = (paraDir == 1);
+                                useSingleRun = true;
+                                break;
+                            }
+
                             if (startRun >= end) {
                                 continue;
                             }
                             int32_t endRun = startRun + lengthRun;
-                            if (endRun <= start) {
+                            if (endRun <= int32_t(start)) {
                                 continue;
                             }
-                            if (startRun < start) {
-                                startRun = start;
+                            if (startRun < int32_t(start)) {
+                                startRun = int32_t(start);
                             }
                             if (endRun > end) {
                                 endRun = end;
                             }
 
                             lengthRun = endRun - startRun;
-                            bool isRTL = (runDir == UBIDI_RTL);
+                            isRTL = (runDir == UBIDI_RTL);
                             jfloat runTotalAdvance = 0;
 #if DEBUG_GLYPHS
                             LOGD("computeValuesWithHarfbuzz -- run-start=%d run-len=%d isRTL=%d",
@@ -492,21 +499,30 @@
                             *outTotalAdvance += runTotalAdvance;
                         }
                     }
+                } else {
+                    LOGW("computeValuesWithHarfbuzz -- cannot set Para");
+                    useSingleRun = true;
+                    isRTL = (bidiReq = 1) || (bidiReq = UBIDI_DEFAULT_RTL);
                 }
                 ubidi_close(bidi);
             } else {
-                // Cannot run BiDi, just consider one Run
-                bool isRTL = (bidiReq = 1) || (bidiReq = UBIDI_DEFAULT_RTL);
-#if DEBUG_GLYPHS
-                LOGD("computeValuesWithHarfbuzz -- cannot run BiDi, considering a SINGLE Run "
-                        "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
-#endif
-                computeRunValuesWithHarfbuzz(shaperItem, paint,
-                        start, count, isRTL,
-                        outAdvances, outTotalAdvance, outGlyphs);
+                LOGW("computeValuesWithHarfbuzz -- cannot ubidi_open()");
+                useSingleRun = true;
+                isRTL = (bidiReq = 1) || (bidiReq = UBIDI_DEFAULT_RTL);
             }
         }
 
+        // Default single run case
+        if (useSingleRun){
+#if DEBUG_GLYPHS
+            LOGD("computeValuesWithHarfbuzz -- Using a SINGLE Run "
+                    "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
+#endif
+            computeRunValuesWithHarfbuzz(shaperItem, paint,
+                    start, count, isRTL,
+                    outAdvances, outTotalAdvance, outGlyphs);
+        }
+
         // Cleaning
         freeShaperItem(shaperItem);
 
diff --git a/core/jni/android_net_TrafficStats.cpp b/core/jni/android_net_TrafficStats.cpp
index c22b071..7a61432 100644
--- a/core/jni/android_net_TrafficStats.cpp
+++ b/core/jni/android_net_TrafficStats.cpp
@@ -68,6 +68,7 @@
     "rmnet1",
     "rmnet2",
     "rmnet3",
+    "cdma_rmnet4",
     "ppp0",
     0
 };
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index bde2c72..48e8f1e 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -182,12 +182,14 @@
     <!-- Regex of wired ethernet ifaces -->
     <string translatable="false" name="config_ethernet_iface_regex">eth\\d</string>
 
-    <!-- If the mobile hotspot feature requires provisioning, an intent string can be provided
-        to the launch a supported application that provisions the devices.
+    <!-- If the mobile hotspot feature requires provisioning, a package name and class name
+        can be provided to launch a supported application that provisions the devices.
 
         Example Usage:
 
-        Intent intent = new Intent(R.string.config_mobile_hotspot_provision_intent);
+        String[] appDetails = getStringArray(R.array.config_mobile_hotspot_provision_app);
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setClassName(appDetails[0], appDetails[1]);
         startActivityForResult(intent, 0);
 
         public void onActivityResult(int requestCode, int resultCode, Intent intent) {
@@ -202,7 +204,14 @@
 
         See src/com/android/settings/TetherSettings.java for more details.
         -->
-    <string translatable="false" name="config_mobile_hotspot_provision_intent"></string>
+    <!-- The first element is the package name and the second element is the class name
+         of the provisioning app -->
+    <string-array translatable="false" name="config_mobile_hotspot_provision_app">
+    <!--
+        <item>com.example.provisioning</item>
+        <item>com.example.provisioning.Activity</item>
+    -->
+    </string-array>
 
     <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
     <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
diff --git a/docs/html/guide/topics/appwidgets/index.jd b/docs/html/guide/topics/appwidgets/index.jd
index 20ce701..61337b7 100644
--- a/docs/html/guide/topics/appwidgets/index.jd
+++ b/docs/html/guide/topics/appwidgets/index.jd
@@ -321,6 +321,10 @@
   <li>{@link android.widget.ProgressBar}</li>
   <li>{@link android.widget.TextView}</li>
   <li>{@link android.widget.ViewFlipper}</li>
+  <li>{@link android.widget.ListView}</li>
+  <li>{@link android.widget.GridView}</li>
+  <li>{@link android.widget.StackView}</li>
+  <li>{@link android.widget.AdapterViewFlipper}</li>
 </ul>
 
 <p>Descendants of these classes are not supported.</p>
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index e610782..bdad82a 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -186,8 +186,10 @@
 
     private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS;
 
-    private static final int MSG_RULES_CHANGED = 0x1;
-    private static final int MSG_METERED_IFACES_CHANGED = 0x2;
+    private static final int MSG_RULES_CHANGED = 1;
+    private static final int MSG_METERED_IFACES_CHANGED = 2;
+    private static final int MSG_FOREGROUND_ACTIVITIES_CHANGED = 3;
+    private static final int MSG_PROCESS_DIED = 4;
 
     private final Context mContext;
     private final IActivityManager mActivityManager;
@@ -335,37 +337,13 @@
     private IProcessObserver mProcessObserver = new IProcessObserver.Stub() {
         @Override
         public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
-            // only someone like AMS should only be calling us
-            mContext.enforceCallingOrSelfPermission(MANAGE_APP_TOKENS, TAG);
-
-            synchronized (mRulesLock) {
-                // because a uid can have multiple pids running inside, we need to
-                // remember all pid states and summarize foreground at uid level.
-
-                // record foreground for this specific pid
-                SparseBooleanArray pidForeground = mUidPidForeground.get(uid);
-                if (pidForeground == null) {
-                    pidForeground = new SparseBooleanArray(2);
-                    mUidPidForeground.put(uid, pidForeground);
-                }
-                pidForeground.put(pid, foregroundActivities);
-                computeUidForegroundLocked(uid);
-            }
+            mHandler.obtainMessage(MSG_FOREGROUND_ACTIVITIES_CHANGED,
+                    pid, uid, foregroundActivities).sendToTarget();
         }
 
         @Override
         public void onProcessDied(int pid, int uid) {
-            // only someone like AMS should only be calling us
-            mContext.enforceCallingOrSelfPermission(MANAGE_APP_TOKENS, TAG);
-
-            synchronized (mRulesLock) {
-                // clear records and recompute, when they exist
-                final SparseBooleanArray pidForeground = mUidPidForeground.get(uid);
-                if (pidForeground != null) {
-                    pidForeground.delete(pid);
-                    computeUidForegroundLocked(uid);
-                }
-            }
+            mHandler.obtainMessage(MSG_PROCESS_DIED, pid, uid).sendToTarget();
         }
     };
 
@@ -1469,6 +1447,40 @@
                     mListeners.finishBroadcast();
                     return true;
                 }
+                case MSG_FOREGROUND_ACTIVITIES_CHANGED: {
+                    final int pid = msg.arg1;
+                    final int uid = msg.arg2;
+                    final boolean foregroundActivities = (Boolean) msg.obj;
+
+                    synchronized (mRulesLock) {
+                        // because a uid can have multiple pids running inside, we need to
+                        // remember all pid states and summarize foreground at uid level.
+
+                        // record foreground for this specific pid
+                        SparseBooleanArray pidForeground = mUidPidForeground.get(uid);
+                        if (pidForeground == null) {
+                            pidForeground = new SparseBooleanArray(2);
+                            mUidPidForeground.put(uid, pidForeground);
+                        }
+                        pidForeground.put(pid, foregroundActivities);
+                        computeUidForegroundLocked(uid);
+                    }
+                    return true;
+                }
+                case MSG_PROCESS_DIED: {
+                    final int pid = msg.arg1;
+                    final int uid = msg.arg2;
+
+                    synchronized (mRulesLock) {
+                        // clear records and recompute, when they exist
+                        final SparseBooleanArray pidForeground = mUidPidForeground.get(uid);
+                        if (pidForeground != null) {
+                            pidForeground.delete(pid);
+                            computeUidForegroundLocked(uid);
+                        }
+                    }
+                    return true;
+                }
                 default: {
                     return false;
                 }
diff --git a/services/jni/com_android_server_BatteryService.cpp b/services/jni/com_android_server_BatteryService.cpp
index b9f2c1f..2ceb535 100644
--- a/services/jni/com_android_server_BatteryService.cpp
+++ b/services/jni/com_android_server_BatteryService.cpp
@@ -141,10 +141,10 @@
         return -1;
     }
     
-    size_t count = read(fd, buf, size);
+    ssize_t count = read(fd, buf, size);
     if (count > 0) {
-        count = (count < size) ? count : size - 1;
-        while (count > 0 && buf[count-1] == '\n') count--;
+        while (count > 0 && buf[count-1] == '\n')
+            count--;
         buf[count] = '\0';
     } else {
         buf[0] = '\0';