Merge "Telephony: Control operator selection using EF_CSP data."
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
old mode 100644
new mode 100755
index 38ac9b7..4e197cd
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -749,6 +749,9 @@
         if (line == getLineCount() - 1)
             max++;
 
+        if (line != getLineCount() - 1)
+            max = TextUtils.getOffsetBefore(mText, getLineEnd(line));
+
         int best = min;
         float bestdist = Math.abs(getPrimaryHorizontal(best) - horiz);
 
@@ -893,7 +896,7 @@
         Directions dirs = getLineDirections(line);
 
         if (line != getLineCount() - 1)
-            end--;
+            end = TextUtils.getOffsetBefore(mText, end);
 
         float horiz = getPrimaryHorizontal(offset);
 
@@ -993,7 +996,7 @@
         Directions dirs = getLineDirections(line);
 
         if (line != getLineCount() - 1)
-            end--;
+            end = TextUtils.getOffsetBefore(mText, end);
 
         float horiz = getPrimaryHorizontal(offset);
 
@@ -1564,7 +1567,8 @@
                         h = dir * nextTab(text, start, end, h * dir, tabs);
                     }
 
-                    if (bm != null) {
+                    if (j != there && bm != null) {
+                        if (offset == start + j) return h;
                         workPaint.set(paint);
                         Styled.measureText(paint, workPaint, text,
                                            j, j + 2, null);
@@ -1958,4 +1962,3 @@
                                        new Directions(new short[] { 0, 32767 });
 
 }
-
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
old mode 100644
new mode 100755
index f02ad2a..d0d2482
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -313,7 +313,9 @@
                                                       class);
 
                 if (spanned == null) {
-                    paint.getTextWidths(sub, i, next, widths);
+                    final int actualNum = paint.getTextWidths(sub, i, next, widths);
+                    if (next - i > actualNum)
+                        adjustTextWidths(widths, sub, i, next, actualNum);
                     System.arraycopy(widths, 0, widths,
                                      end - start + (i - start), next - i);
                                      
@@ -321,9 +323,11 @@
                 } else {
                     mWorkPaint.baselineShift = 0;
 
-                    Styled.getTextWidths(paint, mWorkPaint,
-                                         spanned, i, next,
-                                         widths, fm);
+                    final int actualNum = Styled.getTextWidths(paint, mWorkPaint,
+                            spanned, i, next,
+                            widths, fm);
+                    if (next - i > actualNum)
+                        adjustTextWidths(widths, spanned, i, next, actualNum);
                     System.arraycopy(widths, 0, widths,
                                      end - start + (i - start), next - i);
 
@@ -966,6 +970,22 @@
             return low;
     }
 
+    private static void adjustTextWidths(float[] widths, CharSequence text,
+                              int curPos, int nextPos, int actualNum) {
+        try {
+            int dstIndex = nextPos - curPos - 1;
+            for (int srcIndex = actualNum - 1; srcIndex >= 0; srcIndex--) {
+                final char c = text.charAt(dstIndex + curPos);
+                if (c >= 0xD800 && c <= 0xDFFF) {
+                    widths[dstIndex--] = 0.0f;
+                }
+                widths[dstIndex--] = widths[srcIndex];
+            }
+        } catch (IndexOutOfBoundsException e) {
+            Log.e("text", "adjust text widths failed");
+        }
+    }
+
     private int out(CharSequence text, int start, int end,
                       int above, int below, int top, int bottom, int v,
                       float spacingmult, float spacingadd,
diff --git a/core/java/android/text/Styled.java b/core/java/android/text/Styled.java
old mode 100644
new mode 100755
index 513b2cd..13cc42c
--- a/core/java/android/text/Styled.java
+++ b/core/java/android/text/Styled.java
@@ -203,9 +203,10 @@
 			}
 		}
 	
+        int result;
         if (replacement == null) {
             workPaint.getFontMetricsInt(fmi);
-            workPaint.getTextWidths(text, start, end, widths);
+            result = workPaint.getTextWidths(text, start, end, widths);
         } else {
             int wid = replacement.getSize(workPaint, text, start, end, fmi);
 
@@ -214,8 +215,9 @@
                 for (int i = start + 1; i < end; i++)
                     widths[i - start] = 0;
             }
+            result = end - start;
         }
-        return end - start;
+        return result;
     }
 
     /**
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index 5cf61bd..6ac35fd 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -136,7 +136,13 @@
 
     final boolean isPowered() {
         // assume we are powered if battery state is unknown so the "stay on while plugged in" option will work.
-        return (mAcOnline || mUsbOnline || mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN);
+        // Do not look at the plug status to check if we are powered.
+        // Charger can be plugged but not charging because of i.e. USB suspend,
+        // battery temperature reasons etc. We are powered only if battery is
+        // being charged. This function fill return false if charger is
+        // connected and battery is reported full.
+        return (mBatteryStatus == BatteryManager.BATTERY_STATUS_CHARGING ||
+                mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN);
     }
 
     final boolean isPowered(int plugTypeSet) {
@@ -148,11 +154,13 @@
         if (plugTypeSet == 0) {
             return false;
         }
+
+        // we are not powered when plug is connected and not charging
         int plugTypeBit = 0;
-        if (mAcOnline) {
+        if (mAcOnline && mBatteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) {
             plugTypeBit |= BatteryManager.BATTERY_PLUGGED_AC;
         }
-        if (mUsbOnline) {
+        if (mUsbOnline && mBatteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) {
             plugTypeBit |= BatteryManager.BATTERY_PLUGGED_USB;
         }
         return (plugTypeSet & plugTypeBit) != 0;
@@ -183,7 +191,11 @@
     private final void shutdownIfNoPower() {
         // shut down gracefully if our battery is critically low and we are not powered.
         // wait until the system has booted before attempting to display the shutdown dialog.
-        if (mBatteryLevel == 0 && !isPowered() && ActivityManagerNative.isSystemReady()) {
+        // Also shutdown if battery is reported to be 'dead' independent of
+        // battery level and power supply.
+        if (((mBatteryLevel == 0 && !isPowered()) ||
+             mBatteryHealth == BatteryManager.BATTERY_HEALTH_DEAD) &&
+            ActivityManagerNative.isSystemReady()) {
             Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
             intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);