Merge "Add "Roaming protocol" to APN editor." into ics-mr0
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 15bb878..1da79f8 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1155,6 +1155,7 @@
         <activity android:name=".CryptKeeper"
                   android:immersive="true"
                   android:launchMode="singleTop"
+                  android:excludeFromRecents="true"
                   android:theme="@android:style/Theme.Holo.NoActionBar"
                   android:configChanges="mcc|mnc|keyboard|keyboardHidden|uiMode"
                   android:windowSoftInputMode="stateVisible|adjustResize">
diff --git a/res/values/strings.xml b/res/values/strings.xml
index ddba657..1428145 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -801,7 +801,7 @@
     <string name="unlock_set_unlock_none_summary">No security</string>
 
     <!-- Title for preference that guides the user through a weak biometric lock [CHAR LIMIT=22] -->
-    <string name="unlock_set_unlock_biometric_weak_title">Face unlock</string>
+    <string name="unlock_set_unlock_biometric_weak_title">Face Unlock</string>
     <!-- Summary for preference that disables unlock security [CHAR LIMIT=45]-->
     <string name="unlock_set_unlock_biometric_weak_summary">Low security, experimental</string>
 
diff --git a/src/com/android/settings/CryptKeeper.java b/src/com/android/settings/CryptKeeper.java
index 8968de4..d58dddb 100644
--- a/src/com/android/settings/CryptKeeper.java
+++ b/src/com/android/settings/CryptKeeper.java
@@ -221,7 +221,20 @@
             // Disable the crypt keeper.
             PackageManager pm = getPackageManager();
             ComponentName name = new ComponentName(this, CryptKeeper.class);
-            pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);
+            pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+                    PackageManager.DONT_KILL_APP);
+            // Typically CryptKeeper is launched as the home app.  We didn't
+            // want to be running, so need to finish this activity and re-launch
+            // its intent now that we are not in the way of doing what is really
+            // supposed to happen.
+            // NOTE: This is really grungy.  I think it would be better for the
+            // activity manager to explicitly launch the crypt keeper instead of
+            // home in the situation where we need to decrypt the device
+            finish();
+            Intent intent = getIntent();
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            intent.setComponent(null);
+            startActivity(intent);
             return;
         }
 
diff --git a/src/com/android/settings/inputmethod/InputMethodAndSubtypeUtil.java b/src/com/android/settings/inputmethod/InputMethodAndSubtypeUtil.java
index df58ec0..cb4058f 100644
--- a/src/com/android/settings/inputmethod/InputMethodAndSubtypeUtil.java
+++ b/src/com/android/settings/inputmethod/InputMethodAndSubtypeUtil.java
@@ -317,9 +317,9 @@
                     }
                 }
                 setSubtypesPreferenceEnabled(context, inputMethodInfos, imiId, isEnabled);
-                updateSubtypesPreferenceChecked(context, inputMethodInfos, enabledSubtypes);
             }
         }
+        updateSubtypesPreferenceChecked(context, inputMethodInfos, enabledSubtypes);
     }
 
     public static void setSubtypesPreferenceEnabled(SettingsPreferenceFragment context,
@@ -346,7 +346,8 @@
         PreferenceScreen preferenceScreen = context.getPreferenceScreen();
         for (InputMethodInfo imi : inputMethodProperties) {
             String id = imi.getId();
-            HashSet<String> enabledSubtypesSet = enabledSubtypes.get(id);
+            if (!enabledSubtypes.containsKey(id)) break;
+            final HashSet<String> enabledSubtypesSet = enabledSubtypes.get(id);
             final int subtypeCount = imi.getSubtypeCount();
             for (int i = 0; i < subtypeCount; ++i) {
                 InputMethodSubtype subtype = imi.getSubtypeAt(i);
diff --git a/src/com/android/settings/inputmethod/InputMethodPreference.java b/src/com/android/settings/inputmethod/InputMethodPreference.java
index f222b88..4ecdb8e 100644
--- a/src/com/android/settings/inputmethod/InputMethodPreference.java
+++ b/src/com/android/settings/inputmethod/InputMethodPreference.java
@@ -226,6 +226,7 @@
     public void setChecked(boolean checked) {
         super.setChecked(checked);
         saveImeSettings();
+        updateSummary();
     }
 
     private void showSecurityWarnDialog(InputMethodInfo imi, final CheckBoxPreference chkPref) {
diff --git a/src/com/android/settings/widget/ChartNetworkSeriesView.java b/src/com/android/settings/widget/ChartNetworkSeriesView.java
index c4f45b0..7a4617b 100644
--- a/src/com/android/settings/widget/ChartNetworkSeriesView.java
+++ b/src/com/android/settings/widget/ChartNetworkSeriesView.java
@@ -181,10 +181,13 @@
         final int height = getHeight();
 
         boolean started = false;
-        float firstX = 0;
         float lastX = 0;
-        float lastY = 0;
-        long lastTime = Long.MIN_VALUE;
+        float lastY = height;
+        long lastTime = mHoriz.convertToValue(lastX);
+
+        // move into starting position
+        mPathStroke.moveTo(lastX, lastY);
+        mPathFill.moveTo(lastX, lastY);
 
         // TODO: count fractional data from first bucket crossing start;
         // currently it only accepts first full bucket.
@@ -198,36 +201,42 @@
         for (int i = start; i <= end; i++) {
             entry = mStats.getValues(i, entry);
 
-            lastTime = entry.bucketStart + entry.bucketDuration;
-            final float x = mHoriz.convertToPoint(lastTime);
-            final float y = mVert.convertToPoint(totalData);
+            final long startTime = entry.bucketStart;
+            final long endTime = startTime + entry.bucketDuration;
+
+            final float startX = mHoriz.convertToPoint(startTime);
+            final float endX = mHoriz.convertToPoint(endTime);
 
             // skip until we find first stats on screen
-            if (i > 0 && !started && x > 0) {
-                mPathStroke.moveTo(lastX, lastY);
-                mPathFill.moveTo(lastX, lastY);
-                started = true;
-                firstX = x;
+            if (endX < 0) continue;
+
+            // increment by current bucket total
+            totalData += entry.rxBytes + entry.txBytes;
+
+            final float startY = lastY;
+            final float endY = mVert.convertToPoint(totalData);
+
+            if (lastTime != startTime) {
+                // gap in buckets; line to start of current bucket
+                mPathStroke.lineTo(startX, startY);
+                mPathFill.lineTo(startX, startY);
             }
 
-            if (started) {
-                mPathStroke.lineTo(x, y);
-                mPathFill.lineTo(x, y);
-                totalData += entry.rxBytes + entry.txBytes;
-            }
+            // always draw to end of current bucket
+            mPathStroke.lineTo(endX, endY);
+            mPathFill.lineTo(endX, endY);
 
-            lastX = x;
-            lastY = y;
+            lastX = endX;
+            lastY = endY;
+            lastTime = endTime;
         }
 
         // when data falls short, extend to requested end time
         if (lastTime < mEndTime) {
             lastX = mHoriz.convertToPoint(mEndTime);
 
-            if (started) {
-                mPathStroke.lineTo(lastX, lastY);
-                mPathFill.lineTo(lastX, lastY);
-            }
+            mPathStroke.lineTo(lastX, lastY);
+            mPathFill.lineTo(lastX, lastY);
         }
 
         if (LOGD) {
@@ -239,7 +248,7 @@
 
         // drop to bottom of graph from current location
         mPathFill.lineTo(lastX, height);
-        mPathFill.lineTo(firstX, height);
+        mPathFill.lineTo(0, height);
 
         mMax = totalData;