Merge "Allow CryptKeeper to be started for UI debugging"
diff --git a/res/layout/data_usage_chart.xml b/res/layout/data_usage_chart.xml
index c1f6c27..4dae248 100644
--- a/res/layout/data_usage_chart.xml
+++ b/res/layout/data_usage_chart.xml
@@ -19,8 +19,13 @@
     xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
     android:id="@+id/chart"
     android:layout_width="match_parent"
-    android:layout_height="220dip"
-    android:padding="16dip">
+    android:layout_height="@dimen/data_usage_chart_height"
+    android:paddingLeft="@*android:dimen/preference_item_padding_side"
+    android:paddingRight="@*android:dimen/preference_item_padding_side"
+    android:paddingTop="16dip"
+    android:paddingBottom="16dip"
+    settings:optimalWidth="@dimen/data_usage_chart_optimalWidth"
+    settings:optimalWidthWeight="0.4">
 
     <com.android.settings.widget.ChartGridView
         android:id="@+id/grid"
@@ -48,7 +53,7 @@
         android:layout_gravity="left|bottom"
         settings:strokeColor="#d88d3a"
         settings:fillColor="#c0ba7f3e"
-        settings:fillColorSecondary="#0000" />
+        settings:fillColorSecondary="#60ba7f3e" />
 
     <com.android.settings.widget.ChartSweepView
         android:id="@+id/sweep_warning"
diff --git a/res/layout/data_usage_cycles.xml b/res/layout/data_usage_cycles.xml
index 225fb4b..459ef6e 100644
--- a/res/layout/data_usage_cycles.xml
+++ b/res/layout/data_usage_cycles.xml
@@ -19,8 +19,8 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="horizontal"
-    android:paddingLeft="16dip"
-    android:paddingRight="16dip">
+    android:paddingLeft="@*android:dimen/preference_item_padding_side"
+    android:paddingRight="@*android:dimen/preference_item_padding_side">
 
     <TextView
         android:layout_width="wrap_content"
diff --git a/res/layout/data_usage_detail.xml b/res/layout/data_usage_detail.xml
index 8d0c0cc..639fcf5 100644
--- a/res/layout/data_usage_detail.xml
+++ b/res/layout/data_usage_detail.xml
@@ -17,29 +17,75 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/app_detail"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
+    android:layout_height="wrap_content"
     android:orientation="vertical">
 
-    <ImageView
-        android:id="@+id/app_icon"
-        android:layout_width="48dip"
-        android:layout_height="48dip"
-        android:layout_marginLeft="16dip"
-        android:scaleType="centerInside" />
-
     <LinearLayout
-        android:id="@+id/app_titles"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginLeft="16dip"
-        android:layout_marginTop="8dip"
-        android:orientation="vertical" />
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="@*android:dimen/preference_item_padding_side"
+        android:layout_marginRight="@*android:dimen/preference_item_padding_side"
+        android:orientation="horizontal">
+
+        <LinearLayout
+            android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:layout_marginRight="@*android:dimen/preference_item_padding_inner"
+            android:orientation="vertical">
+
+            <ImageView
+                android:id="@+id/app_icon"
+                android:layout_width="48dip"
+                android:layout_height="48dip"
+                android:scaleType="centerInside" />
+
+            <LinearLayout
+                android:id="@+id/app_titles"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="8dip"
+                android:orientation="vertical" />
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="8dip"
+                android:textColor="#d88d3a"
+                android:text="@string/data_usage_label_foreground" />
+            <TextView
+                android:id="@+id/app_foreground"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:textColor="#d88d3a" />
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="8dip"
+                android:text="@string/data_usage_label_background" />
+            <TextView
+                android:id="@+id/app_background"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content" />
+
+        </LinearLayout>
+
+        <com.android.settings.widget.PieChartView
+            android:id="@+id/app_pie_chart"
+            android:layout_width="160dip"
+            android:layout_height="160dip" />
+
+    </LinearLayout>
 
     <Button
         android:id="@+id/app_settings"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_margin="16dip"
+        android:layout_marginLeft="@*android:dimen/preference_item_padding_side"
+        android:layout_marginRight="@*android:dimen/preference_item_padding_side"
+        android:layout_marginTop="16dip"
+        android:layout_marginBottom="16dip"
         android:text="@string/data_usage_app_settings" />
 
     <LinearLayout
diff --git a/res/layout/data_usage_header.xml b/res/layout/data_usage_header.xml
index 528fc34..ba41c88 100644
--- a/res/layout/data_usage_header.xml
+++ b/res/layout/data_usage_header.xml
@@ -39,8 +39,8 @@
         android:id="@+id/usage_summary"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingLeft="16dip"
-        android:paddingRight="16dip"
+        android:paddingLeft="@*android:dimen/preference_item_padding_side"
+        android:paddingRight="@*android:dimen/preference_item_padding_side"
         android:paddingTop="8dip"
         android:paddingBottom="8dip"
         android:singleLine="true"
@@ -52,8 +52,8 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:visibility="gone"
-        android:paddingLeft="16dip"
-        android:paddingRight="16dip"
+        android:paddingLeft="@*android:dimen/preference_item_padding_side"
+        android:paddingRight="@*android:dimen/preference_item_padding_side"
         android:paddingTop="8dip"
         android:paddingBottom="8dip"
         android:text="@string/data_usage_empty"
diff --git a/res/layout/data_usage_item.xml b/res/layout/data_usage_item.xml
index b41d486..d5c2e7f 100644
--- a/res/layout/data_usage_item.xml
+++ b/res/layout/data_usage_item.xml
@@ -17,8 +17,8 @@
 <GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:paddingLeft="16dip"
-    android:paddingRight="16dip"
+    android:paddingLeft="@*android:dimen/preference_item_padding_side"
+    android:paddingRight="@*android:dimen/preference_item_padding_side"
     android:paddingTop="8dip"
     android:paddingBottom="8dip"
     android:columnCount="3">
diff --git a/res/layout/data_usage_summary.xml b/res/layout/data_usage_summary.xml
index 7e68143..d59e0d6 100644
--- a/res/layout/data_usage_summary.xml
+++ b/res/layout/data_usage_summary.xml
@@ -25,11 +25,20 @@
         android:layout_height="match_parent"
         android:orientation="vertical">
 
-        <TabWidget
-            android:id="@android:id/tabs"
-            android:orientation="horizontal"
+        <HorizontalScrollView
             android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
+            android:layout_height="wrap_content"
+            android:layout_weight="0"
+            android:scrollbars="none">
+
+            <TabWidget
+                android:id="@android:id/tabs"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                style="?android:attr/tabWidgetStyle" />
+
+        </HorizontalScrollView>
 
         <!-- give an empty content area to make tabhost happy -->
         <FrameLayout
diff --git a/res/layout/manage_apps_tab_content.xml b/res/layout/manage_apps_tab_content.xml
index 0391a9d..b8cee87 100644
--- a/res/layout/manage_apps_tab_content.xml
+++ b/res/layout/manage_apps_tab_content.xml
@@ -37,10 +37,10 @@
 
             <TabWidget
                 android:id="@android:id/tabs"
-                android:orientation="horizontal"
-                android:layout_width="match_parent"
+                android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                />
+                android:orientation="horizontal"
+                style="?android:attr/tabWidgetStyle" />
 
         </HorizontalScrollView>
 
@@ -48,7 +48,7 @@
             android:id="@android:id/tabcontent"
             android:layout_width="match_parent"
             android:layout_height="0dip"
-            android:layout_weight="1"/>
+            android:layout_weight="1" />
 
     </LinearLayout>
 </TabHost>
diff --git a/res/layout/preference.xml b/res/layout/preference.xml
index 06d8f24..aef21a1 100644
--- a/res/layout/preference.xml
+++ b/res/layout/preference.xml
@@ -19,17 +19,16 @@
     android:layout_height="wrap_content"
     android:minHeight="48dip"
     android:gravity="center_vertical"
+    android:paddingLeft="@*android:dimen/preference_item_padding_side"
     android:paddingRight="?android:attr/scrollbarSize"
     android:background="?android:attr/selectableItemBackground">
 
     <RelativeLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginLeft="15dip"
-        android:layout_marginRight="6dip"
-        android:layout_marginTop="6dip"
-        android:layout_marginBottom="6dip"
-        android:layout_weight="1">
+        android:layout_weight="1"
+        android:paddingTop="6dip"
+        android:paddingBottom="6dip">
 
         <TextView
             android:id="@+android:id/title"
diff --git a/res/layout/preference_dialog_ringervolume.xml b/res/layout/preference_dialog_ringervolume.xml
index 66067b3..2c83f12 100644
--- a/res/layout/preference_dialog_ringervolume.xml
+++ b/res/layout/preference_dialog_ringervolume.xml
@@ -68,8 +68,7 @@
                         android:layout_height="wrap_content"
                         android:layout_weight="1"
                         android:paddingTop="2dip"
-                        android:paddingLeft="12dip"
-                        android:paddingRight="20dip" />
+                        android:layout_marginRight="@dimen/volume_seekbar_side_margin" />
         </LinearLayout>
 
         <!-- Used for the ringer/notification volume -->
@@ -109,8 +108,7 @@
                             android:layout_height="wrap_content"
                             android:layout_weight="1"
                             android:paddingTop="2dip"
-                            android:paddingLeft="12dip"
-                            android:paddingRight="20dip" />
+                            android:layout_marginRight="@dimen/volume_seekbar_side_margin" />
             </LinearLayout>
 
         </LinearLayout>
@@ -152,8 +150,7 @@
                             android:layout_height="wrap_content"
                             android:layout_weight="1"
                             android:paddingTop="2dip"
-                            android:paddingLeft="12dip"
-                            android:paddingRight="20dip" />
+                            android:layout_marginRight="@dimen/volume_seekbar_side_margin" />
             </LinearLayout>
 
         </LinearLayout>
@@ -187,8 +184,7 @@
                         android:layout_height="wrap_content"
                         android:layout_weight="1"
                         android:paddingTop="2dip"
-                        android:paddingLeft="12dip"
-                        android:paddingRight="20dip" />
+                        android:layout_marginRight="@dimen/volume_seekbar_side_margin" />
         </LinearLayout>
 
     </LinearLayout>
diff --git a/res/layout/tab_indicator_thin_holo.xml b/res/layout/tab_indicator_thin_holo.xml
deleted file mode 100644
index e4c4652..0000000
--- a/res/layout/tab_indicator_thin_holo.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<RelativeLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="0dp"
-    android:layout_height="48dp"
-    android:layout_weight="1"
-    android:background="@*android:drawable/tab_indicator_holo">
-
-    <TextView
-        android:id="@android:id/title"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:gravity="center"
-        android:textAppearance="?android:attr/textAppearanceMedium" />
-
-</RelativeLayout>
diff --git a/res/menu/data_usage.xml b/res/menu/data_usage.xml
index 24b0de4..4e938aa 100644
--- a/res/menu/data_usage.xml
+++ b/res/menu/data_usage.xml
@@ -16,30 +16,23 @@
 
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
     <item
-        android:id="@+id/action_settings"
-        android:icon="@drawable/ic_sysbar_quicksettings"
-        android:showAsAction="always">
-        <menu>
-            <item
-                android:id="@+id/data_usage_menu_roaming"
-                android:title="@string/data_usage_menu_roaming"
-                android:checkable="true" />
-            <item
-                android:id="@+id/data_usage_menu_restrict_background"
-                android:title="@string/data_usage_menu_restrict_background"
-                android:checkable="true" />
-            <item
-                android:id="@+id/data_usage_menu_split_4g"
-                android:title="@string/data_usage_menu_split_4g"
-                android:checkable="true" />
-            <item
-                android:id="@+id/data_usage_menu_show_wifi"
-                android:title="@string/data_usage_menu_show_wifi"
-                android:checkable="true" />
-            <item
-                android:id="@+id/data_usage_menu_show_ethernet"
-                android:title="@string/data_usage_menu_show_ethernet"
-                android:checkable="true" />
-        </menu>
-    </item>
+        android:id="@+id/data_usage_menu_roaming"
+        android:title="@string/data_usage_menu_roaming"
+        android:checkable="true" />
+    <item
+        android:id="@+id/data_usage_menu_restrict_background"
+        android:title="@string/data_usage_menu_restrict_background"
+        android:checkable="true" />
+    <item
+        android:id="@+id/data_usage_menu_split_4g"
+        android:title="@string/data_usage_menu_split_4g"
+        android:checkable="true" />
+    <item
+        android:id="@+id/data_usage_menu_show_wifi"
+        android:title="@string/data_usage_menu_show_wifi"
+        android:checkable="true" />
+    <item
+        android:id="@+id/data_usage_menu_show_ethernet"
+        android:title="@string/data_usage_menu_show_ethernet"
+        android:checkable="true" />
 </menu>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index f9138c2..aeda585 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -291,16 +291,27 @@
     </string-array>
 
     <!-- Match this with the constants in AccessPoint. --> <skip />
-    <!-- Wi-Fi settings.  The type of security a Wi-Fi network has. -->
+    <!-- Wi-Fi security choices used when manually added a Wi-Fi network -->
     <string-array name="wifi_security">
         <!-- The Wi-Fi network does not have any security. -->
-        <item>Open</item>
+        <item>@string/wifi_security_none</item>
         <!-- Do not translate. -->
-        <item>WEP</item>
+        <item>@string/wifi_security_wep</item>
         <!-- Do not translate. -->
-        <item>WPA/WPA2 PSK</item>
+        <item>@string/wifi_security_psk_generic</item>
         <!-- Do not translate. -->
-        <item>802.1x EAP</item>
+        <item>@string/wifi_security_eap</item>
+    </string-array>
+
+    <!-- Match this with the constants in AccessPoint. --> <skip />
+    <!-- Wi-Fi security types for New User Dialog. EAP is not configurable. -->
+    <string-array name="wifi_security_no_eap">
+        <!-- The Wi-Fi network does not have any security. -->
+        <item>@string/wifi_security_none</item>
+        <!-- Do not translate. -->
+        <item>@string/wifi_security_wep</item>
+        <!-- Do not translate. -->
+        <item>@string/wifi_security_psk_generic</item>
     </string-array>
 
    <!-- Wi-Fi AP settings.  The type of security a Wi-Fi AP supports. -->
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 6c63d13..684811c 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -50,6 +50,13 @@
         <attr name="minTickWidth" format="dimension" />
     </declare-styleable>
 
+    <declare-styleable name="ChartView">
+        <!-- optimal width of the chart -->
+        <attr name="optimalWidth" format="dimension" />
+        <!-- how to weight extra space beyond optimal width -->
+        <attr name="optimalWidthWeight" format="float" />
+    </declare-styleable>
+
     <declare-styleable name="ChartSweepView">
         <attr name="sweepDrawable" format="reference" />
         <attr name="followAxis">
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 5394743..dbe4c32 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -17,7 +17,6 @@
 <resources>
     <dimen name="device_memory_usage_button_width">16dip</dimen>
     <dimen name="device_memory_usage_button_height">32dip</dimen>
-    <dimen name="data_usage_chart_height">220dip</dimen>
     <dimen name="action_bar_switch_padding">16dip</dimen>
 
     <dimen name="app_icon_size">56dip</dimen>
@@ -28,4 +27,9 @@
     <dimen name="content_margin_left">16dip</dimen>
     <dimen name="description_margin_top">26dip</dimen>
     <dimen name="description_margin_sides">40dip</dimen>
+
+    <dimen name="data_usage_chart_height">220dip</dimen>
+    <dimen name="data_usage_chart_optimalWidth">440dip</dimen>
+
+    <dimen name="volume_seekbar_side_margin">8dip</dimen>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a91e6df..4610c35c9 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1213,19 +1213,59 @@
     <!-- Hint for unspecified fields -->
     <string name="wifi_unspecified">(unspecified)</string>
     <!-- Summary for the remembered network. -->
-    <string name="wifi_remembered">Remembered</string>
-    <!-- Summary for the disabled network. -->
-    <string name="wifi_disabled">Disabled</string>
+    <string name="wifi_remembered">Saved</string>
+    <!-- Status for networks disabled for unknown reason -->
+    <string name="wifi_disabled_generic">Disabled</string>
+    <!-- Status for networked disabled from a DNS or DHCP failure -->
+    <string name="wifi_disabled_network_failure">Avoided poor connection</string>
+    <!-- Status for networks disabled from authentication failure (wrong password
+         or certificate). -->
+    <string name="wifi_disabled_password_failure">Authentication problem</string>
     <!-- Summary for the remembered network but currently not in range. -->
     <string name="wifi_not_in_range">Not in range</string>
-    <!-- Summary for an open network with WPS being available [CHAR LIMIT=50]-->
-    <string name="wifi_open_with_wps">WPS available</string>
-    <!-- Summary for the secured network. -->
-    <string name="wifi_secured">Secured with <xliff:g id="wifi_security">%1$s</xliff:g></string>
-    <!-- Summary for the secured network with WPS being available [CHAR LIMIT=50]-->
-    <string name="wifi_secured_with_wps">Secured with <xliff:g id="wifi_security">%1$s</xliff:g> (WPS available)</string>
-    <!-- Summary for the secured and remembered network. Status can be "Remembered", "Disabled" or "Not in range". -->
-    <string name="wifi_secured_with_status"><xliff:g id="wifi_status">%2$s</xliff:g>, secured with <xliff:g id="wifi_security">%1$s</xliff:g></string>
+    <!-- Substring of status line when Wi-Fi Protected Setup (WPS) is available and
+         string is listed first -->
+    <string name="wifi_wps_available_first_item">WPS available</string>
+    <!-- Substring of wifi status when Wi-Fi Protected Setup (WPS) is available and
+         string is listed after a wifi_secured_* string-->
+    <string name="wifi_wps_available_second_item">\u0020(WPS available)</string>
+    <!-- Substring of wifi status for wifi with authentication.  This version is for when the
+         string is first in the list (titlecase in english) -->
+    <string name="wifi_secured_first_item">Secured with <xliff:g id="wifi_security_short">%1$s</xliff:g></string>
+    <!-- Substring of wifi status for wifi with authentication.  This version is for when the
+         string is not first in the list (lowercase in english) -->
+    <string name="wifi_secured_second_item">, secured with <xliff:g id="wifi_security_short">%1$s</xliff:g></string>
+
+    <!-- Do not translate.  Concise terminology for wifi with WEP security -->
+    <string name="wifi_security_short_wep">WEP</string>
+    <!-- Do not translate.  Concise terminology for wifi with WPA security -->
+    <string name="wifi_security_short_wpa">WPA</string>
+    <!-- Do not translate.  Concise terminology for wifi with WPA2 security -->
+    <string name="wifi_security_short_wpa2">WPA2</string>
+    <!-- Do not translate.  Concise terminology for wifi with both WPA/WPA2 security -->
+    <string name="wifi_security_short_wpa_wpa2">WPA/WPA2</string>
+    <!-- Do not translate.  Concise terminology for wifi with unknown PSK type -->
+    <string name="wifi_security_short_psk_generic">@string/wifi_security_short_wpa_wpa2</string>
+    <!-- Do not translate.  Concise terminology for wifi with 802.1x EAP security -->
+    <string name="wifi_security_short_eap">802.1x</string>
+
+    <!-- Used in Wi-Fi settings dialogs when Wi-Fi does not have any security. -->
+    <string name="wifi_security_none">None</string>
+
+    <!-- Do not translate.  Terminology for wifi with WEP security -->
+    <string name="wifi_security_wep">WEP</string>
+    <!-- Do not translate.  Terminology for wifi with WPA security -->
+    <string name="wifi_security_wpa">WPA PSK</string>
+    <!-- Do not translate.  Terminology for wifi with WPA2 security -->
+    <string name="wifi_security_wpa2">WPA2 PSK</string>
+    <!-- Do not translate.  Terminology for wifi with both WPA/WPA2 security, or unknown -->
+    <string name="wifi_security_wpa_wpa2">WPA/WPA2 PSK</string>
+    <!-- Do not translate.  Terminology for wifi with unknown PSK type -->
+    <string name="wifi_security_psk_generic">@string/wifi_security_wpa_wpa2</string>
+    <!-- Do not translate.  Concise terminology for wifi with 802.1x EAP security -->
+    <string name="wifi_security_eap">802.1x EAP</string>
+
+
     <!-- Button label to connect to a Wi-Fi network -->
     <string name="wifi_connect">Connect</string>
     <!-- Button label to delete a Wi-Fi network -->
@@ -1550,7 +1590,7 @@
     <!-- Sound & display settings screen, setting option summary displaying the currently selected font size -->
     <string name="summary_font_size" translatable="false">%1$s</string>
     <!-- [CHAR LIMIT=40] Sound & display settings screen, title of dialog for picking font size -->
-    <string name="dialog_title_font_size">Select font size</string>
+    <string name="dialog_title_font_size">Font size</string>
 
     <!-- SIM lock settings title -->
     <string name="sim_lock_settings">SIM card lock settings</string>
@@ -3392,7 +3432,7 @@
     <!-- Title for checkbox menu option to restrict background data usage. [CHAR LIMIT=32] -->
     <string name="data_usage_menu_restrict_background">Restrict background data</string>
     <!-- Title for checkbox menu option to show 4G mobile data usage separate from other mobile data usage. [CHAR LIMIT=32] -->
-    <string name="data_usage_menu_split_4g">Split 4G usage</string>
+    <string name="data_usage_menu_split_4g">Separate 4G usage</string>
     <!-- Title for checkbox menu option to show Wi-Fi data usage. [CHAR LIMIT=32] -->
     <string name="data_usage_menu_show_wifi">Show Wi-Fi usage</string>
     <!-- Title for checkbox menu option to show Ethernet data usage. [CHAR LIMIT=32] -->
@@ -3403,6 +3443,10 @@
     <string name="data_usage_pick_cycle_day">Day of month to reset data usage cycle:</string>
     <!-- Label shown when no applications used data during selected time period. [CHAR LIMIT=48] -->
     <string name="data_usage_empty">No applications used data during this period.</string>
+    <!-- Label for data usage occuring while application in foreground. [CHAR LIMIT=48] -->
+    <string name="data_usage_label_foreground">Foreground</string>
+    <!-- Label for data usage occuring while application in background. [CHAR LIMIT=48] -->
+    <string name="data_usage_label_background">Background</string>
 
     <!-- Checkbox label that will disable mobile network data connection when user-defined limit is reached. [CHAR LIMIT=32] -->
     <string name="data_usage_disable_mobile_limit">Disable mobile data at limit</string>
@@ -3471,7 +3515,7 @@
     <!-- Combination of total network bytes sent and received by an application. [CHAR LIMIT=NONE] -->
     <string name="data_usage_received_sent"><xliff:g id="received" example="128KB">%1$s</xliff:g> received, <xliff:g id="sent" example="1.3GB">%2$s</xliff:g> sent</string>
     <!-- Label displaying total network data transferred during a specific time period. [CHAR LIMIT=64] -->
-    <string name="data_usage_total_during_range">Data usage: <xliff:g id="total" example="128KB">%1$s</xliff:g> on <xliff:g id="range" example="Jul 1 - Jul 31">%2$s</xliff:g></string>
+    <string name="data_usage_total_during_range"><xliff:g id="range" example="Jul 1 - Jul 31">%2$s</xliff:g>: <xliff:g id="total" example="128KB">%1$s</xliff:g> used</string>
 
     <!-- Button at the bottom of the CryptKeeper screen to make an emergency call. -->
     <string name="cryptkeeper_emergency_call">Emergency call</string>
diff --git a/src/com/android/settings/DataUsageSummary.java b/src/com/android/settings/DataUsageSummary.java
index bccc5a5..a95ab3f 100644
--- a/src/com/android/settings/DataUsageSummary.java
+++ b/src/com/android/settings/DataUsageSummary.java
@@ -25,6 +25,8 @@
 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
 import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
 import static android.net.NetworkPolicyManager.computeNextCycleBoundary;
+import static android.net.NetworkStats.SET_DEFAULT;
+import static android.net.NetworkStats.SET_FOREGROUND;
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStatsHistory.FIELD_RX_BYTES;
 import static android.net.NetworkStatsHistory.FIELD_TX_BYTES;
@@ -60,6 +62,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
+import android.graphics.Color;
 import android.graphics.drawable.Drawable;
 import android.net.ConnectivityManager;
 import android.net.INetworkPolicyManager;
@@ -83,6 +86,7 @@
 import android.text.format.DateUtils;
 import android.text.format.Formatter;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -119,6 +123,7 @@
 import com.android.settings.net.SummaryForAllUidLoader;
 import com.android.settings.widget.DataUsageChartView;
 import com.android.settings.widget.DataUsageChartView.DataUsageChartListener;
+import com.android.settings.widget.PieChartView;
 import com.google.android.collect.Lists;
 
 import java.util.ArrayList;
@@ -196,6 +201,9 @@
     private View mAppDetail;
     private ImageView mAppIcon;
     private ViewGroup mAppTitles;
+    private PieChartView mAppPieChart;
+    private TextView mAppForeground;
+    private TextView mAppBackground;
     private Button mAppSettings;
 
     private LinearLayout mAppSwitches;
@@ -216,6 +224,8 @@
 
     private NetworkStatsHistory mHistory;
     private NetworkStatsHistory mDetailHistory;
+    private NetworkStatsHistory mDetailHistoryDefault;
+    private NetworkStatsHistory mDetailHistoryForeground;
 
     private String mCurrentTab = null;
     private String mIntentTab = null;
@@ -301,6 +311,9 @@
             mAppDetail = mHeader.findViewById(R.id.app_detail);
             mAppIcon = (ImageView) mAppDetail.findViewById(R.id.app_icon);
             mAppTitles = (ViewGroup) mAppDetail.findViewById(R.id.app_titles);
+            mAppPieChart = (PieChartView) mAppDetail.findViewById(R.id.app_pie_chart);
+            mAppForeground = (TextView) mAppDetail.findViewById(R.id.app_foreground);
+            mAppBackground = (TextView) mAppDetail.findViewById(R.id.app_background);
             mAppSwitches = (LinearLayout) mAppDetail.findViewById(R.id.app_switches);
 
             mAppSettings = (Button) mAppDetail.findViewById(R.id.app_settings);
@@ -539,12 +552,8 @@
      * Build {@link TabSpec} with thin indicator, and empty content.
      */
     private TabSpec buildTabSpec(String tag, int titleRes) {
-        final LayoutInflater inflater = LayoutInflater.from(mTabWidget.getContext());
-        final View indicator = inflater.inflate(
-                R.layout.tab_indicator_thin_holo, mTabWidget, false);
-        final TextView title = (TextView) indicator.findViewById(android.R.id.title);
-        title.setText(titleRes);
-        return mTabHost.newTabSpec(tag).setIndicator(indicator).setContent(mEmptyTabContent);
+        return mTabHost.newTabSpec(tag).setIndicator(getText(titleRes)).setContent(
+                mEmptyTabContent);
     }
 
     private OnTabChangeListener mTabListener = new OnTabChangeListener() {
@@ -658,6 +667,10 @@
             mAppDetail.setVisibility(View.GONE);
             mCycleAdapter.setChangeVisible(true);
 
+            mDetailHistory = null;
+            mDetailHistoryDefault = null;
+            mDetailHistoryForeground = null;
+
             // hide detail stats when not in detail mode
             mChart.bindDetailNetworkStats(null);
             return;
@@ -697,15 +710,20 @@
 
         try {
             // load stats for current uid and template
-            // TODO: read template from extras
-            mDetailHistory = mStatsService.getHistoryForUid(
-                    mTemplate, mUid, TAG_NONE, FIELD_RX_BYTES | FIELD_TX_BYTES);
+            mDetailHistoryDefault = mStatsService.getHistoryForUid(
+                    mTemplate, mUid, SET_DEFAULT, TAG_NONE, FIELD_RX_BYTES | FIELD_TX_BYTES);
+            mDetailHistoryForeground = mStatsService.getHistoryForUid(
+                    mTemplate, mUid, SET_FOREGROUND, TAG_NONE, FIELD_RX_BYTES | FIELD_TX_BYTES);
         } catch (RemoteException e) {
             // since we can't do much without history, and we don't want to
             // leave with half-baked UI, we bail hard.
             throw new RuntimeException("problem reading network stats", e);
         }
 
+        mDetailHistory = new NetworkStatsHistory(mDetailHistoryForeground.getBucketDuration());
+        mDetailHistory.recordEntireHistory(mDetailHistoryDefault);
+        mDetailHistory.recordEntireHistory(mDetailHistoryForeground);
+
         // bind chart to historical stats
         mChart.bindDetailNetworkStats(mDetailHistory);
 
@@ -1012,14 +1030,28 @@
         final long now = System.currentTimeMillis();
 
         final Context context = getActivity();
-        final NetworkStatsHistory.Entry entry;
 
-        if (isAppDetailMode()) {
-            if (mDetailHistory != null) {
-                entry = mDetailHistory.getValues(start, end, now, null);
-            } else {
-                entry = null;
-            }
+        NetworkStatsHistory.Entry entry = null;
+        if (isAppDetailMode() && mDetailHistory != null) {
+            // bind foreground/background to piechart and labels
+            entry = mDetailHistoryDefault.getValues(start, end, now, entry);
+            final long defaultBytes = entry.rxBytes + entry.txBytes;
+            entry = mDetailHistoryForeground.getValues(start, end, now, entry);
+            final long foregroundBytes = entry.rxBytes + entry.txBytes;
+
+            mAppPieChart.setOriginAngle(175);
+
+            mAppPieChart.removeAllSlices();
+            mAppPieChart.addSlice(foregroundBytes, Color.parseColor("#d88d3a"));
+            mAppPieChart.addSlice(defaultBytes, Color.parseColor("#666666"));
+
+            mAppPieChart.generatePath();
+
+            mAppBackground.setText(Formatter.formatFileSize(context, defaultBytes));
+            mAppForeground.setText(Formatter.formatFileSize(context, foregroundBytes));
+
+            // and finally leave with summary data for label below
+            entry = mDetailHistory.getValues(start, end, now, null);
 
             getLoaderManager().destroyLoader(LOADER_SUMMARY);
 
@@ -1206,31 +1238,38 @@
         public void bindStats(NetworkStats stats) {
             mItems.clear();
 
-            if (stats != null) {
-                final AppUsageItem systemItem = new AppUsageItem();
-                systemItem.uid = android.os.Process.SYSTEM_UID;
+            final AppUsageItem systemItem = new AppUsageItem();
+            systemItem.uid = android.os.Process.SYSTEM_UID;
 
-                NetworkStats.Entry entry = null;
-                for (int i = 0; i < stats.size(); i++) {
-                    entry = stats.getValues(i, entry);
+            final SparseArray<AppUsageItem> knownUids = new SparseArray<AppUsageItem>();
 
-                    final boolean isApp = entry.uid >= android.os.Process.FIRST_APPLICATION_UID
-                            && entry.uid <= android.os.Process.LAST_APPLICATION_UID;
-                    if (isApp || entry.uid == TrafficStats.UID_REMOVED) {
-                        final AppUsageItem item = new AppUsageItem();
-                        item.uid = entry.uid;
-                        item.total = entry.rxBytes + entry.txBytes;
+            NetworkStats.Entry entry = null;
+            final int size = stats != null ? stats.size() : 0;
+            for (int i = 0; i < size; i++) {
+                entry = stats.getValues(i, entry);
+
+                final int uid = entry.uid;
+                final boolean isApp = uid >= android.os.Process.FIRST_APPLICATION_UID
+                        && uid <= android.os.Process.LAST_APPLICATION_UID;
+                if (isApp || uid == TrafficStats.UID_REMOVED) {
+                    AppUsageItem item = knownUids.get(uid);
+                    if (item == null) {
+                        item = new AppUsageItem();
+                        item.uid = uid;
+                        knownUids.put(uid, item);
                         mItems.add(item);
-                    } else {
-                        systemItem.total += entry.rxBytes + entry.txBytes;
                     }
-                }
 
-                if (systemItem.total > 0) {
-                    mItems.add(systemItem);
+                    item.total += entry.rxBytes + entry.txBytes;
+                } else {
+                    systemItem.total += entry.rxBytes + entry.txBytes;
                 }
             }
 
+            if (systemItem.total > 0) {
+                mItems.add(systemItem);
+            }
+
             Collections.sort(mItems);
             mLargest = (mItems.size() > 0) ? mItems.get(0).total : 0;
             notifyDataSetChanged();
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 272c0d1..2572cef 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -63,7 +63,7 @@
     private static final String META_DATA_KEY_PARENT_FRAGMENT_CLASS =
         "com.android.settings.PARENT_FRAGMENT_CLASS";
 
-    private static final String EXTRA_THEME = "settings:theme";
+    private static final String EXTRA_CLEAR_UI_OPTIONS = "settings:remove_ui_options";
 
     private static final String SAVE_KEY_CURRENT_HEADER = "com.android.settings.CURRENT_HEADER";
     private static final String SAVE_KEY_PARENT_HEADER = "com.android.settings.PARENT_HEADER";
@@ -82,9 +82,9 @@
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
-        final int theme = getIntent().getIntExtra(
-                EXTRA_THEME, android.R.style.Theme_Holo);
-        setTheme(theme);
+        if (getIntent().getBooleanExtra(EXTRA_CLEAR_UI_OPTIONS, false)) {
+            getWindow().setUiOptions(0);
+        }
 
         getMetaData();
         mInLocalHeaderSwitch = true;
@@ -288,12 +288,12 @@
         Intent intent = super.onBuildStartFragmentIntent(fragmentName, args,
                 titleRes, shortTitleRes);
 
-        // some fragments would like a custom activity theme
+        // some fragments want to avoid split actionbar
         if (DataUsageSummary.class.getName().equals(fragmentName) ||
                 PowerUsageSummary.class.getName().equals(fragmentName) ||
                 AccountSyncSettings.class.getName().equals(fragmentName) ||
                 UserDictionarySettings.class.getName().equals(fragmentName)) {
-            intent.putExtra(EXTRA_THEME, android.R.style.Theme_Holo);
+            intent.putExtra(EXTRA_CLEAR_UI_OPTIONS, true);
         }
 
         intent.setClass(this, SubSettings.class);
diff --git a/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java b/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java
index c00aff3..4996858 100644
--- a/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java
+++ b/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java
@@ -40,7 +40,7 @@
 /**
  * Dialog fragment for renaming the local Bluetooth device.
  */
-final class BluetoothNameDialogFragment extends DialogFragment implements TextWatcher {
+public final class BluetoothNameDialogFragment extends DialogFragment implements TextWatcher {
     private static final int BLUETOOTH_NAME_MAX_LENGTH_BYTES = 248;
 
     private AlertDialog mAlertDialog;
@@ -54,6 +54,13 @@
     // This flag is set when the name is updated by code, to distinguish from user changes
     private boolean mDeviceNameUpdated;
 
+    // This flag is set when the user edits the name (preserved on rotation)
+    private boolean mDeviceNameEdited;
+
+    // Key to save the edited name and edit status for restoring after rotation
+    private static final String KEY_NAME = "device_name";
+    private static final String KEY_NAME_EDITED = "device_name_edited";
+
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -68,16 +75,22 @@
         }
     };
 
-    public BluetoothNameDialogFragment(LocalBluetoothAdapter adapter) {
-        mLocalAdapter = adapter;
+    public BluetoothNameDialogFragment() {
+        LocalBluetoothManager localManager = LocalBluetoothManager.getInstance(getActivity());
+        mLocalAdapter = localManager.getBluetoothAdapter();
     }
 
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
+        String deviceName = mLocalAdapter.getName();
+        if (savedInstanceState != null) {
+            deviceName = savedInstanceState.getString(KEY_NAME, deviceName);
+            mDeviceNameEdited = savedInstanceState.getBoolean(KEY_NAME_EDITED, false);
+        }
         mAlertDialog = new AlertDialog.Builder(getActivity())
                 .setIcon(android.R.drawable.ic_dialog_info)
                 .setTitle(R.string.bluetooth_rename_device)
-                .setView(createDialogView())
+                .setView(createDialogView(deviceName))
                 .setPositiveButton(R.string.bluetooth_rename_button,
                         new DialogInterface.OnClickListener() {
                             public void onClick(DialogInterface dialog, int which) {
@@ -94,7 +107,13 @@
         return mAlertDialog;
     }
 
-    private View createDialogView() {
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        outState.putString(KEY_NAME, mDeviceNameView.getText().toString());
+        outState.putBoolean(KEY_NAME_EDITED, mDeviceNameEdited);
+    }
+
+    private View createDialogView(String deviceName) {
         final LayoutInflater layoutInflater = (LayoutInflater)getActivity()
             .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         View view = layoutInflater.inflate(R.layout.dialog_edittext, null);
@@ -102,6 +121,7 @@
         mDeviceNameView.setFilters(new InputFilter[] {
                 new Utf8ByteLengthFilter(BLUETOOTH_NAME_MAX_LENGTH_BYTES)
         });
+        mDeviceNameView.setText(deviceName);    // set initial value before adding listener
         mDeviceNameView.addTextChangedListener(this);
         return view;
     }
@@ -119,13 +139,12 @@
         super.onResume();
         if (mOkButton == null) {
             mOkButton = mAlertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
-            mOkButton.setEnabled(false);    // Ok button is enabled when the user edits the name
+            mOkButton.setEnabled(mDeviceNameEdited);    // Ok button enabled after user edits
         }
         IntentFilter filter = new IntentFilter();
         filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
         filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
         getActivity().registerReceiver(mReceiver, filter);
-        updateDeviceName();
     }
 
     @Override
@@ -137,6 +156,7 @@
     void updateDeviceName() {
         if (mLocalAdapter != null && mLocalAdapter.isEnabled()) {
             mDeviceNameUpdated = true;
+            mDeviceNameEdited = false;
             mDeviceNameView.setText(mLocalAdapter.getName());
         }
     }
@@ -147,7 +167,10 @@
             mDeviceNameUpdated = false;
             mOkButton.setEnabled(false);
         } else {
-            mOkButton.setEnabled(s.length() != 0);
+            mDeviceNameEdited = true;
+            if (mOkButton != null) {
+                mOkButton.setEnabled(s.length() != 0);
+            }
         }
     }
 
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index af21149..91bcffd 100644
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -194,12 +194,12 @@
                 return true;
 
             case MENU_ID_RENAME_DEVICE:
-                new BluetoothNameDialogFragment(mLocalAdapter).show(
+                new BluetoothNameDialogFragment().show(
                         getFragmentManager(), "rename device");
                 return true;
 
             case MENU_ID_VISIBILITY_TIMEOUT:
-                new BluetoothVisibilityTimeoutFragment(mDiscoverableEnabler).show(
+                new BluetoothVisibilityTimeoutFragment().show(
                         getFragmentManager(), "visibility timeout");
                 return true;
 
@@ -261,6 +261,8 @@
                     mDiscoverableEnabler = new BluetoothDiscoverableEnabler(getActivity(),
                             mLocalAdapter, mMyDevicePreference);
                     mDiscoverableEnabler.resume();
+                    LocalBluetoothManager.getInstance(getActivity()).setDiscoverableEnabler(
+                            mDiscoverableEnabler);
                 }
 
                 // Paired devices category
diff --git a/src/com/android/settings/bluetooth/BluetoothVisibilityTimeoutFragment.java b/src/com/android/settings/bluetooth/BluetoothVisibilityTimeoutFragment.java
index 7c518fb..a65c6c1 100644
--- a/src/com/android/settings/bluetooth/BluetoothVisibilityTimeoutFragment.java
+++ b/src/com/android/settings/bluetooth/BluetoothVisibilityTimeoutFragment.java
@@ -41,13 +41,14 @@
 /**
  * Dialog fragment for setting the discoverability timeout.
  */
-final class BluetoothVisibilityTimeoutFragment extends DialogFragment
+public final class BluetoothVisibilityTimeoutFragment extends DialogFragment
         implements DialogInterface.OnClickListener {
 
     private final BluetoothDiscoverableEnabler mDiscoverableEnabler;
 
-    public BluetoothVisibilityTimeoutFragment(BluetoothDiscoverableEnabler enabler) {
-        mDiscoverableEnabler = enabler;
+    public BluetoothVisibilityTimeoutFragment() {
+        mDiscoverableEnabler = LocalBluetoothManager.getInstance(getActivity())
+                .getDiscoverableEnabler();
     }
 
     @Override
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothManager.java b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
old mode 100755
new mode 100644
index a1edca1..3357e59
--- a/src/com/android/settings/bluetooth/LocalBluetoothManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
@@ -36,6 +36,8 @@
     /** If a BT-related activity is in the foreground, this will be it. */
     private Context mForegroundActivity;
 
+    private BluetoothDiscoverableEnabler mDiscoverableEnabler;
+
     private final LocalBluetoothAdapter mLocalAdapter;
 
     private final CachedBluetoothDeviceManager mCachedDeviceManager;
@@ -60,6 +62,14 @@
         return sInstance;
     }
 
+    public void setDiscoverableEnabler(BluetoothDiscoverableEnabler discoverableEnabler) {
+        mDiscoverableEnabler = discoverableEnabler;
+    }
+
+    public BluetoothDiscoverableEnabler getDiscoverableEnabler() {
+        return mDiscoverableEnabler;
+    }
+
     private LocalBluetoothManager(LocalBluetoothAdapter adapter, Context context) {
         mContext = context;
         mLocalAdapter = adapter;
diff --git a/src/com/android/settings/widget/ChartNetworkSeriesView.java b/src/com/android/settings/widget/ChartNetworkSeriesView.java
index 481f7cc..f0ccc1b 100644
--- a/src/com/android/settings/widget/ChartNetworkSeriesView.java
+++ b/src/com/android/settings/widget/ChartNetworkSeriesView.java
@@ -105,7 +105,7 @@
 
     public void setChartColor(int stroke, int fill, int fillSecondary) {
         mPaintStroke = new Paint();
-        mPaintStroke.setStrokeWidth(6.0f);
+        mPaintStroke.setStrokeWidth(4.0f * getResources().getDisplayMetrics().density);
         mPaintStroke.setColor(stroke);
         mPaintStroke.setStyle(Style.STROKE);
         mPaintStroke.setAntiAlias(true);
@@ -165,7 +165,10 @@
         mPathEstimate.reset();
 
         // bail when not enough stats to render
-        if (mStats == null || mStats.size() < 2) return;
+        if (mStats == null || mStats.size() < 2) {
+            invalidate();
+            return;
+        }
 
         final int width = getWidth();
         final int height = getHeight();
@@ -263,6 +266,8 @@
         }
 
         mMaxEstimate = totalData;
+
+        invalidate();
     }
 
     public void setEndTime(long endTime) {
diff --git a/src/com/android/settings/widget/ChartSweepView.java b/src/com/android/settings/widget/ChartSweepView.java
index d5e8de8..81aeb84 100644
--- a/src/com/android/settings/widget/ChartSweepView.java
+++ b/src/com/android/settings/widget/ChartSweepView.java
@@ -32,7 +32,6 @@
 import android.util.MathUtils;
 import android.view.MotionEvent;
 import android.view.View;
-import android.widget.FrameLayout;
 
 import com.android.settings.R;
 import com.google.common.base.Preconditions;
@@ -41,7 +40,7 @@
  * Sweep across a {@link ChartView} at a specific {@link ChartAxis} value, which
  * a user can drag.
  */
-public class ChartSweepView extends FrameLayout {
+public class ChartSweepView extends View {
 
     private Drawable mSweep;
     private Rect mSweepPadding = new Rect();
@@ -78,7 +77,7 @@
     private MotionEvent mTracking;
 
     public ChartSweepView(Context context) {
-        this(context, null, 0);
+        this(context, null);
     }
 
     public ChartSweepView(Context context, AttributeSet attrs) {
@@ -101,8 +100,6 @@
 
         a.recycle();
 
-        setClipToPadding(false);
-        setClipChildren(false);
         setWillNotDraw(false);
     }
 
diff --git a/src/com/android/settings/widget/ChartView.java b/src/com/android/settings/widget/ChartView.java
index a5b8b09..e3a658a 100644
--- a/src/com/android/settings/widget/ChartView.java
+++ b/src/com/android/settings/widget/ChartView.java
@@ -19,12 +19,16 @@
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import android.content.Context;
+import android.content.res.TypedArray;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.View;
+import android.view.ViewDebug;
 import android.widget.FrameLayout;
 
+import com.android.settings.R;
+
 /**
  * Container for two-dimensional chart, drawn with a combination of
  * {@link ChartGridView}, {@link ChartNetworkSeriesView} and {@link ChartSweepView}
@@ -41,6 +45,10 @@
     ChartAxis mHoriz;
     ChartAxis mVert;
 
+    @ViewDebug.ExportedProperty
+    private int mOptimalWidth = -1;
+    private float mOptimalWidthWeight = 0;
+
     private Rect mContent = new Rect();
 
     public ChartView(Context context) {
@@ -54,6 +62,12 @@
     public ChartView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
 
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.ChartView, defStyle, 0);
+        setOptimalWidth(a.getDimensionPixelSize(R.styleable.ChartView_optimalWidth, -1),
+                a.getFloat(R.styleable.ChartView_optimalWidthWeight, 0));
+        a.recycle();
+
         setClipToPadding(false);
         setClipChildren(false);
     }
@@ -63,6 +77,24 @@
         mVert = checkNotNull(vert, "missing vert");
     }
 
+    public void setOptimalWidth(int optimalWidth, float optimalWidthWeight) {
+        mOptimalWidth = optimalWidth;
+        mOptimalWidthWeight = optimalWidthWeight;
+        requestLayout();
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        final int slack = getMeasuredWidth() - mOptimalWidth;
+        if (mOptimalWidth > 0 && slack > 0) {
+            final int targetWidth = (int) (mOptimalWidth + (slack * mOptimalWidthWeight));
+            widthMeasureSpec = MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY);
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        }
+    }
+
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         mContent.set(getPaddingLeft(), getPaddingTop(), r - l - getPaddingRight(),
diff --git a/src/com/android/settings/widget/DataUsageChartView.java b/src/com/android/settings/widget/DataUsageChartView.java
index a1c92e1..f6ae5a0 100644
--- a/src/com/android/settings/widget/DataUsageChartView.java
+++ b/src/com/android/settings/widget/DataUsageChartView.java
@@ -226,8 +226,6 @@
             mDetailSeries.generatePath();
 
             mGrid.invalidate();
-            mSeries.invalidate();
-            mDetailSeries.invalidate();
 
             // since we just changed axis, make sweep recalculate its value
             if (activeSweep != null) {
@@ -362,7 +360,6 @@
 
         requestLayout();
         mSeries.generatePath();
-        mSeries.invalidate();
 
         updateVertAxisBounds(null);
         updateEstimateVisible();
diff --git a/src/com/android/settings/widget/PieChartView.java b/src/com/android/settings/widget/PieChartView.java
new file mode 100644
index 0000000..85d45a2
--- /dev/null
+++ b/src/com/android/settings/widget/PieChartView.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.widget;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Paint.Style;
+import android.graphics.Path;
+import android.graphics.Path.Direction;
+import android.graphics.RadialGradient;
+import android.graphics.RectF;
+import android.graphics.Shader.TileMode;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+
+import com.google.common.collect.Lists;
+
+import java.util.ArrayList;
+
+/**
+ * Pie chart with multiple items.
+ */
+public class PieChartView extends View {
+    public static final String TAG = "PieChartView";
+    public static final boolean LOGD = true;
+
+    private ArrayList<Slice> mSlices = Lists.newArrayList();
+
+    private int mOriginAngle;
+
+    private Paint mPaintPrimary = new Paint();
+    private Paint mPaintShadow = new Paint();
+
+    private Path mPathSide = new Path();
+    private Path mPathSideShadow = new Path();
+
+    private Path mPathShadow = new Path();
+
+    private int mSideWidth;
+
+    public class Slice {
+        public long value;
+
+        public Path pathPrimary = new Path();
+        public Path pathShadow = new Path();
+
+        public Paint paintPrimary;
+
+        public Slice(long value, int color) {
+            this.value = value;
+            this.paintPrimary = buildFillPaint(color, getResources());
+        }
+    }
+
+    public PieChartView(Context context) {
+        this(context, null);
+    }
+
+    public PieChartView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public PieChartView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        mPaintPrimary = buildFillPaint(Color.parseColor("#666666"), getResources());
+
+        mPaintShadow.setColor(Color.BLACK);
+        mPaintShadow.setStyle(Style.STROKE);
+        mPaintShadow.setStrokeWidth(3f * getResources().getDisplayMetrics().density);
+        mPaintShadow.setAntiAlias(true);
+
+        mSideWidth = (int) (20 * getResources().getDisplayMetrics().density);
+
+        setWillNotDraw(false);
+    }
+
+    private static Paint buildFillPaint(int color, Resources res) {
+        final Paint paint = new Paint();
+
+        paint.setColor(color);
+        paint.setStyle(Style.FILL_AND_STROKE);
+        paint.setAntiAlias(true);
+
+        final int width = (int) (280 * res.getDisplayMetrics().density);
+        paint.setShader(new RadialGradient(0, 0, width, color, darken(color), TileMode.MIRROR));
+
+        return paint;
+    }
+
+    public void setOriginAngle(int originAngle) {
+        mOriginAngle = originAngle;
+    }
+
+    public void addSlice(long value, int color) {
+        mSlices.add(new Slice(value, color));
+    }
+
+    public void removeAllSlices() {
+        mSlices.clear();
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        generatePath();
+    }
+
+    public void generatePath() {
+        if (LOGD) Log.d(TAG, "generatePath()");
+
+        long total = 0;
+        for (Slice slice : mSlices) {
+            slice.pathPrimary.reset();
+            slice.pathShadow.reset();
+            total += slice.value;
+        }
+
+        mPathSide.reset();
+        mPathSideShadow.reset();
+        mPathShadow.reset();
+
+        // bail when not enough stats to render
+        if (total == 0) {
+            invalidate();
+            return;
+        }
+
+        final int width = getWidth();
+        final int height = getHeight();
+
+        final RectF rect = new RectF(0, 0, width, height);
+
+        mPathSide.addOval(rect, Direction.CW);
+        mPathSideShadow.addOval(rect, Direction.CW);
+        mPathShadow.addOval(rect, Direction.CW);
+
+        int startAngle = mOriginAngle;
+        for (Slice slice : mSlices) {
+            final int sweepAngle = (int) (slice.value * 360 / total);
+
+            slice.pathPrimary.moveTo(rect.centerX(), rect.centerY());
+            slice.pathPrimary.arcTo(rect, startAngle, sweepAngle);
+            slice.pathPrimary.lineTo(rect.centerX(), rect.centerY());
+
+            slice.pathShadow.moveTo(rect.centerX(), rect.centerY());
+            slice.pathShadow.arcTo(rect, startAngle, 0);
+            slice.pathShadow.moveTo(rect.centerX(), rect.centerY());
+            slice.pathShadow.arcTo(rect, startAngle + sweepAngle, 0);
+
+            startAngle += sweepAngle;
+        }
+
+        invalidate();
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+
+        canvas.translate(getWidth() * 0.25f, getHeight() * -0.05f);
+        canvas.rotate(-40, getWidth() * 0.5f, getHeight());
+        canvas.scale(0.7f, 1.0f, getWidth(), getHeight());
+
+        canvas.save();
+        canvas.translate(-mSideWidth, 0);
+        canvas.drawPath(mPathSide, mPaintPrimary);
+        canvas.drawPath(mPathSideShadow, mPaintShadow);
+        canvas.restore();
+
+        for (Slice slice : mSlices) {
+            canvas.drawPath(slice.pathPrimary, slice.paintPrimary);
+            canvas.drawPath(slice.pathShadow, mPaintShadow);
+        }
+        canvas.drawPath(mPathShadow, mPaintShadow);
+    }
+
+    public static int darken(int color) {
+        float[] hsv = new float[3];
+        Color.colorToHSV(color, hsv);
+        hsv[2] /= 2;
+        hsv[1] /= 2;
+        return Color.HSVToColor(hsv);
+    }
+
+}
diff --git a/src/com/android/settings/wifi/AccessPoint.java b/src/com/android/settings/wifi/AccessPoint.java
index 8181746..799a8da 100644
--- a/src/com/android/settings/wifi/AccessPoint.java
+++ b/src/com/android/settings/wifi/AccessPoint.java
@@ -16,8 +16,6 @@
 
 package com.android.settings.wifi;
 
-import com.android.settings.R;
-
 import android.content.Context;
 import android.net.NetworkInfo.DetailedState;
 import android.net.wifi.ScanResult;
@@ -27,35 +25,48 @@
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.preference.Preference;
+import android.util.Log;
 import android.view.View;
 import android.widget.ImageView;
 
-import java.util.Comparator;
+import com.android.settings.R;
 
 class AccessPoint extends Preference {
+    static final String TAG = "Settings.AccessPoint";
 
     private static final String KEY_DETAILEDSTATE = "key_detailedstate";
     private static final String KEY_WIFIINFO = "key_wifiinfo";
     private static final String KEY_SCANRESULT = "key_scanresult";
     private static final String KEY_CONFIG = "key_config";
 
-    private static final int[] STATE_SECURED = {R.attr.state_encrypted};
+    private static final int[] STATE_SECURED = {
+        R.attr.state_encrypted
+    };
     private static final int[] STATE_NONE = {};
 
-
+    /** These values are matched in string arrays -- changes must be kept in sync */
     static final int SECURITY_NONE = 0;
     static final int SECURITY_WEP = 1;
     static final int SECURITY_PSK = 2;
     static final int SECURITY_EAP = 3;
 
+    enum PskType {
+        UNKNOWN,
+        WPA,
+        WPA2,
+        WPA_WPA2
+    }
+
     String ssid;
     String bssid;
     int security;
     int networkId;
     boolean wpsAvailable = false;
 
+    PskType pskType = PskType.UNKNOWN;
+
     private WifiConfiguration mConfig;
-    /*package*/ScanResult mScanResult;
+    /* package */ScanResult mScanResult;
 
     private int mRssi;
     private WifiInfo mInfo;
@@ -84,6 +95,52 @@
         return SECURITY_NONE;
     }
 
+    public String getSecurityString(boolean concise) {
+        Context context = getContext();
+        switch(security) {
+            case SECURITY_EAP:
+                return concise ? context.getString(R.string.wifi_security_short_eap) :
+                    context.getString(R.string.wifi_security_eap);
+            case SECURITY_PSK:
+                switch (pskType) {
+                    case WPA:
+                        return concise ? context.getString(R.string.wifi_security_short_wpa) :
+                            context.getString(R.string.wifi_security_wpa);
+                    case WPA2:
+                        return concise ? context.getString(R.string.wifi_security_short_wpa2) :
+                            context.getString(R.string.wifi_security_wpa2);
+                    case WPA_WPA2:
+                        return concise ? context.getString(R.string.wifi_security_short_wpa_wpa2) :
+                            context.getString(R.string.wifi_security_wpa_wpa2);
+                    case UNKNOWN:
+                    default:
+                        return concise ? context.getString(R.string.wifi_security_short_psk_generic)
+                                : context.getString(R.string.wifi_security_psk_generic);
+                }
+            case SECURITY_WEP:
+                return concise ? context.getString(R.string.wifi_security_short_wep) :
+                    context.getString(R.string.wifi_security_wep);
+            case SECURITY_NONE:
+            default:
+                return concise ? "" : context.getString(R.string.wifi_security_none);
+        }
+    }
+
+    private static PskType getPskType(ScanResult result) {
+        boolean wpa = result.capabilities.contains("WPA-PSK");
+        boolean wpa2 = result.capabilities.contains("WPA2-PSK");
+        if (wpa2 && wpa) {
+            return PskType.WPA_WPA2;
+        } else if (wpa2) {
+            return PskType.WPA2;
+        } else if (wpa) {
+            return PskType.WPA;
+        } else {
+            Log.w(TAG, "Received abnormal flag string: " + result.capabilities);
+            return PskType.UNKNOWN;
+        }
+    }
+
     AccessPoint(Context context, WifiConfiguration config) {
         super(context);
         setWidgetLayoutResource(R.layout.preference_widget_wifi_signal);
@@ -138,6 +195,8 @@
         bssid = result.BSSID;
         security = getSecurity(result);
         wpsAvailable = security != SECURITY_EAP && result.capabilities.contains("WPS");
+        if (security == SECURITY_PSK)
+            pskType = getPskType(result);
         networkId = -1;
         mRssi = result.level;
         mScanResult = result;
@@ -185,13 +244,15 @@
         return ssid.compareToIgnoreCase(other.ssid);
     }
 
-
     boolean update(ScanResult result) {
         // We do not call refresh() since this is called before onBindView().
         if (ssid.equals(result.SSID) && security == getSecurity(result)) {
             if (WifiManager.compareSignalLevel(result.level, mRssi) > 0) {
                 mRssi = result.level;
             }
+            // This flag only comes from scans, is not easily saved in config
+            if (security == SECURITY_PSK)
+                pskType = getPskType(result);
             return true;
         }
         return false;
@@ -255,34 +316,46 @@
         Context context = getContext();
         mSignal.setImageLevel(getLevel());
 
-        if (mState != null) {
+        if (mState != null) { // This is the active connection
             setSummary(Summary.get(context, mState));
-        } else {
-            String status = null;
-            if (mRssi == Integer.MAX_VALUE) {
-                status = context.getString(R.string.wifi_not_in_range);
-            } else if (mConfig != null) {
-                status = context.getString((mConfig.status == WifiConfiguration.Status.DISABLED) ?
-                        R.string.wifi_disabled : R.string.wifi_remembered);
+        } else if (mRssi == Integer.MAX_VALUE) { // Wifi out of range
+            setSummary(context.getString(R.string.wifi_not_in_range));
+        } else if (mConfig != null && mConfig.status == WifiConfiguration.Status.DISABLED) {
+            switch (mConfig.disableReason) {
+                case WifiConfiguration.DISABLED_AUTH_FAILURE:
+                    setSummary(context.getString(R.string.wifi_disabled_password_failure));
+                    break;
+                case WifiConfiguration.DISABLED_DHCP_FAILURE:
+                case WifiConfiguration.DISABLED_DNS_FAILURE:
+                    setSummary(context.getString(R.string.wifi_disabled_network_failure));
+                    break;
+                case WifiConfiguration.DISABLED_UNKNOWN_REASON:
+                    setSummary(context.getString(R.string.wifi_disabled_generic));
+            }
+        } else { // In range, not disabled.
+            StringBuilder summary = new StringBuilder();
+            if (mConfig != null) { // Is saved network
+                summary.append(context.getString(R.string.wifi_remembered));
             }
 
-            if (security == SECURITY_NONE) {
-                if (wpsAvailable && mConfig == null) {
-                    setSummary(context.getString(R.string.wifi_open_with_wps));
+            if (security != SECURITY_NONE) {
+                String securityStrFormat;
+                if (summary.length() == 0) {
+                    securityStrFormat = context.getString(R.string.wifi_secured_first_item);
                 } else {
-                    setSummary(status);
+                    securityStrFormat = context.getString(R.string.wifi_secured_second_item);
                 }
-            } else {
-                String format;
-                if (wpsAvailable && mConfig == null) {
-                    format = context.getString(R.string.wifi_secured_with_wps);
-                } else {
-                    format = context.getString((status == null) ?
-                            R.string.wifi_secured : R.string.wifi_secured_with_status);
-                }
-                String[] type = context.getResources().getStringArray(R.array.wifi_security);
-                setSummary(String.format(format, type[security], status));
+                summary.append(String.format(securityStrFormat, getSecurityString(true)));
             }
+
+            if (mConfig == null && wpsAvailable) { // Only list WPS available for unsaved networks
+                if (summary.length() == 0) {
+                    summary.append(context.getString(R.string.wifi_wps_available_first_item));
+                } else {
+                    summary.append(context.getString(R.string.wifi_wps_available_second_item));
+                }
+            }
+            setSummary(summary.toString());
         }
     }
 }
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index 876fd99..f879b85 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -158,10 +158,11 @@
                 mView.findViewById(R.id.type_ssid).setVisibility(View.VISIBLE);
                 mView.findViewById(R.id.type_security).setVisibility(View.VISIBLE);
                 // We want custom layout. The content must be same as the other cases.
-                mSecuritySpinner.setAdapter(
-                        new ArrayAdapter<String>(context, R.layout.wifi_setup_custom_list_item_1,
-                                android.R.id.text1,
-                                context.getResources().getStringArray(R.array.wifi_security)));
+
+                ArrayAdapter<String> adapter = new ArrayAdapter<String>(context,
+                        R.layout.wifi_setup_custom_list_item_1, android.R.id.text1,
+                        context.getResources().getStringArray(R.array.wifi_security_no_eap));
+                mSecuritySpinner.setAdapter(adapter);
             } else {
                 mView.findViewById(R.id.type).setVisibility(View.VISIBLE);
             }
@@ -181,8 +182,7 @@
                 addRow(group, R.string.wifi_status, Summary.get(mConfigUi.getContext(), state));
             }
 
-            String[] type = resources.getStringArray(R.array.wifi_security);
-            addRow(group, R.string.wifi_security, type[mAccessPoint.security]);
+            addRow(group, R.string.wifi_security, mAccessPoint.getSecurityString(false));
 
             int level = mAccessPoint.getLevel();
             if (level != -1) {
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index b3259e0..dff6d2a 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -511,6 +511,7 @@
                 for (AccessPoint accessPoint : accessPoints) {
                     if (accessPoint.update(result)) {
                         found = true;
+                        break;
                     }
                 }
                 if (!found) {
diff --git a/src/com/android/settings/wifi/p2p/WifiP2pEnabler.java b/src/com/android/settings/wifi/p2p/WifiP2pEnabler.java
index fd79a58..608aa02 100644
--- a/src/com/android/settings/wifi/p2p/WifiP2pEnabler.java
+++ b/src/com/android/settings/wifi/p2p/WifiP2pEnabler.java
@@ -43,6 +43,7 @@
     private final IntentFilter mIntentFilter;
     private final Handler mHandler = new WifiP2pHandler();
     private WifiP2pManager mWifiP2pManager;
+    private WifiP2pManager.Channel mChannel;
 
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
@@ -61,11 +62,16 @@
         mSwitch = switch_;
 
         mWifiP2pManager = (WifiP2pManager) context.getSystemService(Context.WIFI_P2P_SERVICE);
-        if (!mWifiP2pManager.connectHandler(mContext, mHandler)) {
-            //Failure to set up connection
-            Log.e(TAG, "Failed to set up connection with wifi p2p service");
-            mWifiP2pManager = null;
-            mSwitch.setEnabled(false);
+        if (mWifiP2pManager != null) {
+            mChannel = mWifiP2pManager.initialize(mContext, mHandler);
+            if (mChannel == null) {
+                //Failure to set up connection
+                Log.e(TAG, "Failed to set up connection with wifi p2p service");
+                mWifiP2pManager = null;
+                mSwitch.setEnabled(false);
+            }
+        } else {
+            Log.e(TAG, "mWifiP2pManager is null!");
         }
         mIntentFilter = new IntentFilter(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
 
@@ -97,9 +103,9 @@
         if (mWifiP2pManager == null) return;
 
         if (isChecked) {
-            mWifiP2pManager.enableP2p();
+            mWifiP2pManager.enableP2p(mChannel);
         } else {
-            mWifiP2pManager.disableP2p();
+            mWifiP2pManager.disableP2p(mChannel);
         }
     }
 
diff --git a/src/com/android/settings/wifi/p2p/WifiP2pSettings.java b/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
index 6ec3a1a..fe6d392 100644
--- a/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
+++ b/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
@@ -26,6 +26,7 @@
 import android.content.DialogInterface.OnClickListener;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.net.NetworkInfo;
 import android.net.wifi.p2p.WifiP2pConfig;
 import android.net.wifi.p2p.WifiP2pDevice;
 import android.net.wifi.p2p.WifiP2pDeviceList;
@@ -64,6 +65,7 @@
     private final IntentFilter mIntentFilter = new IntentFilter();
     private final Handler mHandler = new WifiP2pHandler();
     private WifiP2pManager mWifiP2pManager;
+    private WifiP2pManager.Channel mChannel;
     private WifiP2pEnabler mWifiP2pEnabler;
     private WifiP2pDialog mConnectDialog;
     private OnClickListener mConnectListener;
@@ -81,7 +83,18 @@
             if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
                 //TODO: nothing right now
             } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
-                if (mWifiP2pManager != null) mWifiP2pManager.requestPeers();
+                if (mWifiP2pManager != null) mWifiP2pManager.requestPeers(mChannel);
+            } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
+                if (mWifiP2pManager == null) return;
+                NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra(
+                        WifiP2pManager.EXTRA_NETWORK_INFO);
+                if (networkInfo.isConnected()) {
+                    Log.d(TAG, "Start peer connections");
+                    mWifiP2pManager.startPeerCommunication();
+                } else {
+                    Log.d(TAG, "Stop peer connections");
+                    mWifiP2pManager.stopPeerCommunication();
+                }
             }
         }
     };
@@ -93,13 +106,19 @@
 
         mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
         mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
+        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
 
         final Activity activity = getActivity();
         mWifiP2pManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
-        if (!mWifiP2pManager.connectHandler(activity, mHandler)) {
-            //Failure to set up connection
-            Log.e(TAG, "Failed to set up connection with wifi p2p service");
-            mWifiP2pManager = null;
+        if (mWifiP2pManager != null) {
+            mChannel = mWifiP2pManager.initialize(activity, mHandler);
+            if (mChannel == null) {
+                //Failure to set up connection
+                Log.e(TAG, "Failed to set up connection with wifi p2p service");
+                mWifiP2pManager = null;
+            }
+        } else {
+            Log.e(TAG, "mWifiP2pManager is null !");
         }
 
         Switch actionBarSwitch = new Switch(activity);
@@ -128,7 +147,7 @@
                 if (which == DialogInterface.BUTTON_POSITIVE) {
                     WifiP2pConfig config = mConnectDialog.getConfig();
                     if (mWifiP2pManager != null) {
-                        mWifiP2pManager.connect(config);
+                        mWifiP2pManager.connect(mChannel, config);
                     }
                 }
             }
@@ -140,7 +159,7 @@
             public void onClick(DialogInterface dialog, int which) {
                 if (which == DialogInterface.BUTTON_POSITIVE) {
                     if (mWifiP2pManager != null) {
-                        mWifiP2pManager.disconnect();
+                        mWifiP2pManager.disconnect(mChannel);
                     }
                 }
             }
@@ -155,7 +174,8 @@
         if (mWifiP2pEnabler != null) {
             mWifiP2pEnabler.resume();
         }
-        if (mWifiP2pManager != null) mWifiP2pManager.discoverPeers();
+
+        if (mWifiP2pManager != null) mWifiP2pManager.discoverPeers(mChannel);
     }
 
     @Override
@@ -182,10 +202,14 @@
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case MENU_ID_SEARCH:
-                mWifiP2pManager.discoverPeers();
+                if (mWifiP2pManager != null) {
+                    mWifiP2pManager.discoverPeers(mChannel);
+                }
                 return true;
             case MENU_ID_CREATE_GROUP:
-                mWifiP2pManager.createGroup();
+                if (mWifiP2pManager != null) {
+                    mWifiP2pManager.createGroup(mChannel);
+                }
                 return true;
             case MENU_ID_ADVANCED:
                 //TODO: add advanced settings for p2p