Merge "Make the size of "shirt pocket" 0 when the icon of "shirt pocket" is invisible"
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index dd71b3f..7340486 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -85,6 +85,16 @@
      * @param thumb Drawable representing the thumb
      */
     public void setThumb(Drawable thumb) {
+        boolean needUpdate;
+        // This way, calling setThumb again with the same bitmap will result in
+        // it recalcuating mThumbOffset (if for example it the bounds of the
+        // drawable changed)
+        if (mThumb != null && thumb != mThumb) {
+            mThumb.setCallback(null);
+            needUpdate = true;
+        } else {
+            needUpdate = false;
+        }
         if (thumb != null) {
             thumb.setCallback(this);
 
@@ -92,9 +102,25 @@
             // such that the thumb will hang halfway off either edge of the
             // progress bar.
             mThumbOffset = thumb.getIntrinsicWidth() / 2;
+
+            // If we're updating get the new states
+            if (needUpdate &&
+                    (thumb.getIntrinsicWidth() != mThumb.getIntrinsicWidth()
+                        || thumb.getIntrinsicHeight() != mThumb.getIntrinsicHeight())) {
+                requestLayout();
+            }
         }
         mThumb = thumb;
         invalidate();
+        if (needUpdate) {
+            updateThumbPos(getWidth(), getHeight());
+            if (thumb.isStateful()) {
+                // Note that if the states are different this won't work.
+                // For now, let's consider that an app bug.
+                int[] state = getDrawableState();
+                thumb.setState(state);
+            }
+        }
     }
 
     /**
@@ -191,6 +217,10 @@
     
     @Override
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        updateThumbPos(w, h);
+    }
+
+    private void updateThumbPos(int w, int h) {
         Drawable d = getCurrentDrawable();
         Drawable thumb = mThumb;
         int thumbHeight = thumb == null ? 0 : thumb.getIntrinsicHeight();
diff --git a/core/res/res/drawable-mdpi/scrubber_control_holo.png b/core/res/res/drawable-mdpi/scrubber_control_holo.png
index 135b2aa..8457833 100644
--- a/core/res/res/drawable-mdpi/scrubber_control_holo.png
+++ b/core/res/res/drawable-mdpi/scrubber_control_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_primary_holo.9.png b/core/res/res/drawable-mdpi/scrubber_primary_holo.9.png
new file mode 100644
index 0000000..8582b13
--- /dev/null
+++ b/core/res/res/drawable-mdpi/scrubber_primary_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_secondary_holo.9.png b/core/res/res/drawable-mdpi/scrubber_secondary_holo.9.png
new file mode 100644
index 0000000..6ad876e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/scrubber_secondary_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_track_holo_dark.9.png b/core/res/res/drawable-mdpi/scrubber_track_holo_dark.9.png
index 7b48cf9..baf70cd 100644
--- a/core/res/res/drawable-mdpi/scrubber_track_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/scrubber_track_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_track_holo_light.9.png b/core/res/res/drawable-mdpi/scrubber_track_holo_light.9.png
index 7c84ac9..6f31497 100644
--- a/core/res/res/drawable-mdpi/scrubber_track_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/scrubber_track_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable/scrubber_progress_horizontal_holo_dark.xml b/core/res/res/drawable/scrubber_progress_horizontal_holo_dark.xml
index 90172a5..b117bb8 100644
--- a/core/res/res/drawable/scrubber_progress_horizontal_holo_dark.xml
+++ b/core/res/res/drawable/scrubber_progress_horizontal_holo_dark.xml
@@ -15,11 +15,14 @@
 -->
 
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-
     <item android:id="@android:id/background"
-          android:drawable="@android:drawable/scrubber_track_holo_dark" />
-    <item android:id="@android:id/secondaryProgress"
-          android:drawable="@android:drawable/scrubber_track_holo_dark" />
-    <item android:id="@android:id/progress"
-          android:drawable="@android:drawable/scrubber_track_holo_dark" />
+            android:drawable="@android:drawable/scrubber_track_holo_dark" />
+    <item android:id="@android:id/secondaryProgress">
+        <scale android:scaleWidth="100%"
+                android:drawable="@android:drawable/scrubber_secondary_holo" />
+    </item>
+    <item android:id="@android:id/progress">
+        <scale android:scaleWidth="100%"
+                android:drawable="@android:drawable/scrubber_primary_holo" />
+    </item>
 </layer-list>
diff --git a/core/res/res/drawable/scrubber_progress_horizontal_holo_light.xml b/core/res/res/drawable/scrubber_progress_horizontal_holo_light.xml
index 5fc9697..6cd08ea 100644
--- a/core/res/res/drawable/scrubber_progress_horizontal_holo_light.xml
+++ b/core/res/res/drawable/scrubber_progress_horizontal_holo_light.xml
@@ -15,11 +15,14 @@
 -->
 
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-
     <item android:id="@android:id/background"
-          android:drawable="@android:drawable/scrubber_track_holo_light" />
-    <item android:id="@android:id/secondaryProgress"
-          android:drawable="@android:drawable/scrubber_track_holo_light" />
-    <item android:id="@android:id/progress"
-          android:drawable="@android:drawable/scrubber_track_holo_light" />
+            android:drawable="@android:drawable/scrubber_track_holo_light" />
+    <item android:id="@android:id/secondaryProgress">
+        <scale android:scaleWidth="100%"
+                android:drawable="@android:drawable/scrubber_secondary_holo" />
+    </item>
+    <item android:id="@android:id/progress">
+        <scale android:scaleWidth="100%"
+                android:drawable="@android:drawable/scrubber_primary_holo" />
+    </item>
 </layer-list>
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index 7ca289d..ebffd34 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -42,6 +42,9 @@
     mXDivs = new int32_t[mXCount];
     mYDivs = new int32_t[mYCount];
 
+    PATCH_LOGD("    patch: xCount = %d, yCount = %d, emptyQuads = %d, vertices = %d",
+            xCount, yCount, emptyQuads, verticesCount);
+
     glGenBuffers(1, &meshBuffer);
 }
 
@@ -208,7 +211,15 @@
 
 void Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2,
             float u1, float v1, float u2, float v2, uint32_t& quadCount) {
-    if (((mColorKey >> quadCount++) & 0x1) == 1) {
+    uint32_t oldQuadCount = quadCount;
+
+    // Degenerate quads are an artifact of our implementation and should not
+    // be taken into account when checking for transparent quads
+    if (x2 - x1 > 0.999f && y2 - y1 > 0.999f) {
+        quadCount++;
+    }
+
+    if (((mColorKey >> oldQuadCount) & 0x1) == 1) {
         return;
     }
 
diff --git a/packages/SystemUI/res/drawable-mdpi/scrubber_control_disabled_holo.png b/packages/SystemUI/res/drawable-mdpi/scrubber_control_disabled_holo.png
new file mode 100644
index 0000000..b8adc97
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/scrubber_control_disabled_holo.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/scrubber_control_holo.png b/packages/SystemUI/res/drawable-mdpi/scrubber_control_holo.png
new file mode 100644
index 0000000..621e980
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/scrubber_control_holo.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/status_bar_toggle_button.xml b/packages/SystemUI/res/drawable/status_bar_toggle_button.xml
new file mode 100644
index 0000000..e17c62f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/status_bar_toggle_button.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true"
+         android:drawable="@*android:drawable/scrubber_primary_holo" />
+    <item
+         android:drawable="@*android:drawable/scrubber_track_holo_dark" />
+</selector>
+
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml b/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
index 6dd97c3..5e867e5 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
@@ -17,11 +17,13 @@
 
 <com.android.systemui.statusbar.tablet.SettingsView
         xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="vertical"
         android:background="@drawable/status_bar_item_background"
         android:paddingLeft="16dp"
+        android:paddingRight="46dp"
         >
 
     <!-- Airplane mode -->
@@ -39,11 +41,12 @@
                 style="@style/StatusBarPanelSettingsContents"
                 android:text="@string/status_bar_settings_airplane"
                 />
-        <CheckBox
+        <Switch
                 android:id="@+id/airplane_checkbox"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center_vertical"
+                android:layout_marginRight="5dp"
                 />
     </LinearLayout>
     <View style="@style/StatusBarPanelSettingsPanelSeparator" />
@@ -67,7 +70,7 @@
             android:layout_height="wrap_content"
             android:layout_gravity="top"
             android:layout_marginTop="16dp"
-            android:layout_marginRight="8dp"
+            android:layout_marginRight="2dp"
             android:src="@drawable/ic_notification_open"
             />
     </LinearLayout>
@@ -88,11 +91,12 @@
                 style="@style/StatusBarPanelSettingsContents"
                 android:text="@string/status_bar_settings_rotation_lock"
                 />
-        <CheckBox
+        <Switch
                 android:id="@+id/rotate_checkbox"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center_vertical"
+                android:layout_marginRight="5dp"
                 />
     </LinearLayout>
     <View style="@style/StatusBarPanelSettingsPanelSeparator" />
@@ -104,6 +108,14 @@
                 style="@style/StatusBarPanelSettingsIcon"
                 android:src="@drawable/ic_sysbar_brightness"
                 />
+        <com.android.systemui.statusbar.policy.ToggleSlider
+                android:id="@+id/brightness"
+                android:layout_width="0dp"
+                android:layout_height="fill_parent"
+                android:layout_weight="1"
+                android:layout_marginRight="2dp"
+                systemui:text="@string/status_bar_settings_auto_brightness_label"
+                />
     </LinearLayout>
     <View style="@style/StatusBarPanelSettingsPanelSeparator" />
 
@@ -114,6 +126,14 @@
                 style="@style/StatusBarPanelSettingsIcon"
                 android:src="@drawable/ic_sysbar_sound_on"
                 />
+        <com.android.systemui.statusbar.policy.ToggleSlider
+                android:id="@+id/volume"
+                android:layout_width="0dp"
+                android:layout_height="fill_parent"
+                android:layout_weight="1"
+                android:layout_marginRight="2dp"
+                systemui:text="@string/status_bar_settings_mute_label"
+                />
     </LinearLayout>
     <View style="@style/StatusBarPanelSettingsPanelSeparator" />
 
@@ -131,11 +151,12 @@
                 style="@style/StatusBarPanelSettingsContents"
                 android:text="@string/status_bar_settings_notifications"
                 />
-        <CheckBox
+        <Switch
                 android:id="@+id/do_not_disturb_checkbox"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center_vertical"
+                android:layout_marginRight="5dp"
                 />
     </LinearLayout>
     <View style="@style/StatusBarPanelSettingsPanelSeparator" />
@@ -160,7 +181,7 @@
             android:layout_height="wrap_content"
             android:layout_gravity="top"
             android:layout_marginTop="16dp"
-            android:layout_marginRight="8dp"
+            android:layout_marginRight="2dp"
             android:src="@drawable/ic_notification_open"
             />
     </LinearLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_toggle_slider.xml b/packages/SystemUI/res/layout/status_bar_toggle_slider.xml
new file mode 100644
index 0000000..cdf56c5
--- /dev/null
+++ b/packages/SystemUI/res/layout/status_bar_toggle_slider.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2010 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.
+-->
+
+<!--    android:background="@drawable/status_bar_closed_default_background" -->
+<merge
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+    >
+    <CheckBox
+        android:id="@+id/toggle"
+        android:layout_width="48dp"
+        android:layout_height="0dp"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentBottom="true"
+        android:button="@drawable/status_bar_toggle_button"
+        />
+    <SeekBar
+        android:id="@+id/slider"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_toRightOf="@id/toggle"
+        android:layout_centerVertical="true"
+        android:layout_alignParentRight="true"
+        android:paddingLeft="20dp"
+        android:paddingRight="20dp"
+        />
+    <TextView
+        android:id="@+id/label"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_alignLeft="@id/toggle"
+        android:layout_alignRight="@id/toggle"
+        android:layout_centerVertical="true"
+        android:gravity="center"
+        android:paddingTop="26dp"
+        android:textColor="#666666"
+        android:textSize="12sp"
+        />
+</merge>
diff --git a/packages/SystemUI/res/values-xlarge/strings.xml b/packages/SystemUI/res/values-xlarge/strings.xml
index e3e5148..279a135 100644
--- a/packages/SystemUI/res/values-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-xlarge/strings.xml
@@ -26,44 +26,16 @@
     <!-- Text to display underneath the graphical signal strength meter when
          no connection is available. [CHAR LIMIT=20] -->
     <string name="status_bar_settings_signal_meter_disconnected">
-        no internet connection
-    </string>
-
-    <!-- Text to display underneath the graphical signal strength meter when
-         it is displaying information about a connected, named Wi-Fi network.
-         [CHAR LIMIT=20] -->
-    <string name="status_bar_settings_signal_meter_wifi_ssid_format">
-        <xliff:g id="ssid">%s</xliff:g>
+        No Internet connection
     </string>
 
     <!-- Text to display underneath the graphical signal strength meter when
          it is displaying Wi-Fi status and Wi-Fi is connected to a network
          whose SSID is not available.
          [CHAR LIMIT=20] -->
-    <string name="status_bar_settings_signal_meter_wifi_nossid">
-        Wi-Fi: connected
-    </string>
+    <string name="status_bar_settings_signal_meter_wifi_nossid">Wi-Fi connected</string>
 
-    <!-- Text to display underneath the graphical signal strength meter when
-         it is displaying Wi-Fi status and Wi-Fi is in the process of
-         connecting to a network.  [CHAR LIMIT=20] -->
-    <string name="status_bar_settings_signal_meter_wifi_connecting">
-        Wi-Fi: connecting…
-    </string>
- 
-    <!-- Text to display underneath the graphical signal strength meter when
-         it is displaying mobile data (3G) status and a network connection is
-         available.
-         [CHAR LIMIT=20] -->
-    <string name="status_bar_settings_signal_meter_data_connected">
-        Mobile data: connected
-    </string>
+    <!-- Separator for PLMN and SPN in network name. -->
+    <string name="status_bar_network_name_separator" translatable="false">" – "</string>
 
-    <!-- Text to display underneath the graphical signal strength meter when
-         it is displaying mobile data (3G) status and a network connection is
-         unavailable.
-         [CHAR LIMIT=20] -->
-    <string name="status_bar_settings_signal_meter_data_connecting">
-        Mobile data: connecting…
-    </string>
 </resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 23bcf20..87395c1 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -18,5 +18,8 @@
     <declare-styleable name="KeyButtonView">
         <attr name="keyCode" format="integer" />
     </declare-styleable>
+    <declare-styleable name="ToggleSlider">
+        <attr name="text" format="string" />
+    </declare-styleable>
 </resources>
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index ed31a34..644cca0 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -80,6 +80,12 @@
     <!-- Label in system panel saying the device will use the orientation sensor to rotate [CHAR LIMIT=30] -->
     <string name="status_bar_settings_rotation_lock">Lock screen orientation</string>
 
+    <!-- Abbreviation / label for mute brightness mode button. Should be all caps. [CHAR LIMIT=6] -->
+    <string name="status_bar_settings_mute_label">MUTE</string>
+
+    <!-- Abbreviation / label for automatic brightness mode button. Should be all caps. [CHAR LIMIT=6] -->
+    <string name="status_bar_settings_auto_brightness_label">AUTO</string>
+
     <!-- Label in system panel saying the device will show notifications [CHAR LIMIT=30] -->
     <string name="status_bar_settings_notifications">Notifications</string>
 
@@ -88,6 +94,9 @@
         <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g>
     </string>
 
+    <!-- Separator for PLMN and SPN in network name. -->
+    <string name="status_bar_network_name_separator" translatable="false">"\n"</string>
+
     <!-- Recent Tasks dialog: title [CHAR LIMIT=30] -->
     <string name="recent_tasks_title">Recent</string>
     <!-- Recent Tasks dialog: message when there are no recent applications [CHAR LIMIT=NONE]-->
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java
new file mode 100644
index 0000000..c11d04e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2010 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.systemui.statusbar.policy;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.os.IPowerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+import android.util.Slog;
+import android.view.IWindowManager;
+import android.widget.CompoundButton;
+
+public class BrightnessController implements ToggleSlider.Listener {
+    private static final String TAG = "StatusBar.BrightnessController";
+
+    // Backlight range is from 0 - 255. Need to make sure that user
+    // doesn't set the backlight to 0 and get stuck
+    private static final int MINIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_DIM + 10;
+    private static final int MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON;
+
+    private Context mContext;
+    private ToggleSlider mControl;
+    private IPowerManager mPower;
+
+    public BrightnessController(Context context, ToggleSlider control) {
+        mContext = context;
+        mControl = control;
+
+        boolean automaticAvailable = context.getResources().getBoolean(
+                com.android.internal.R.bool.config_automatic_brightness_available);
+        mPower = IPowerManager.Stub.asInterface(ServiceManager.getService("power"));
+
+        if (automaticAvailable) {
+            int automatic;
+            try {
+                automatic = Settings.System.getInt(mContext.getContentResolver(),
+                        Settings.System.SCREEN_BRIGHTNESS_MODE);
+            } catch (SettingNotFoundException snfe) {
+                automatic = 0;
+            }
+            control.setChecked(automatic != 0);
+        } else {
+            control.setChecked(false);
+            //control.hideToggle();
+        }
+        
+        int value;
+        try {
+            value = Settings.System.getInt(mContext.getContentResolver(), 
+                    Settings.System.SCREEN_BRIGHTNESS);
+        } catch (SettingNotFoundException ex) {
+            value = MAXIMUM_BACKLIGHT;
+        }
+
+        control.setMax(MAXIMUM_BACKLIGHT - MINIMUM_BACKLIGHT);
+        control.setValue(value - MINIMUM_BACKLIGHT);
+
+        control.setOnChangedListener(this);
+    }
+
+    public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value) {
+        setMode(automatic ? Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
+                : Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
+        if (!automatic) {
+            setBrightness(value + MINIMUM_BACKLIGHT);
+        }
+    }
+
+    private void setMode(int mode) {
+        Settings.System.putInt(mContext.getContentResolver(),
+                Settings.System.SCREEN_BRIGHTNESS_MODE, mode);
+    }
+    
+    private void setBrightness(int brightness) {
+        try {
+            mPower.setBacklightBrightness(brightness);
+        } catch (RemoteException ex) {
+        }        
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index ec23a3d..1090463 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -32,6 +32,7 @@
 import android.os.Binder;
 import android.os.RemoteException;
 import android.provider.Settings;
+import android.provider.Telephony;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
@@ -65,6 +66,9 @@
     ServiceState mServiceState;
     SignalStrength mSignalStrength;
     int[] mDataIconList = TelephonyIcons.DATA_G[0];
+    String mNetworkName;
+    String mNetworkNameDefault;
+    String mNetworkNameSeparator;
     int mPhoneSignalIconId;
     int mDataDirectionIconId;
     int mDataSignalIconId;
@@ -116,7 +120,10 @@
                         | PhoneStateListener.LISTEN_DATA_ACTIVITY);
         mHspaDataDistinguishable = mContext.getResources().getBoolean(
                 R.bool.config_hspa_data_distinguishable);
-        
+        mNetworkNameSeparator = mContext.getString(R.string.status_bar_network_name_separator);
+        mNetworkNameDefault = mContext.getString(
+                com.android.internal.R.string.lockscreen_carrier_default);
+        mNetworkName = mNetworkNameDefault;
 
         // wifi
         mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
@@ -127,6 +134,9 @@
         filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
         filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
         filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
+        filter.addAction(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION);
+        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+        filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
         context.registerReceiver(this, filter);
 
         // yuck
@@ -168,6 +178,12 @@
             updateSimState(intent);
             updateDataIcon();
             refreshViews();
+        } else if (action.equals(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION)) {
+            updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false),
+                        intent.getStringExtra(Telephony.Intents.EXTRA_SPN),
+                        intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false),
+                        intent.getStringExtra(Telephony.Intents.EXTRA_PLMN));
+            refreshViews();
         } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
                  action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
             updateConnectivity(intent);
@@ -516,6 +532,31 @@
         mDataConnected = visible;
     }
 
+    void updateNetworkName(boolean showSpn, String spn, boolean showPlmn, String plmn) {
+        if (false) {
+            Slog.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn + " spn=" + spn
+                    + " showPlmn=" + showPlmn + " plmn=" + plmn);
+        }
+        StringBuilder str = new StringBuilder();
+        boolean something = false;
+        if (showPlmn && plmn != null) {
+            str.append(plmn);
+            something = true;
+        }
+        if (showSpn && spn != null) {
+            if (something) {
+                str.append(mNetworkNameSeparator);
+            }
+            str.append(spn);
+            something = true;
+        }
+        if (something) {
+            mNetworkName = str.toString();
+        } else {
+            mNetworkName = mNetworkNameDefault;
+        }
+    }
+
     // ===== Wifi ===================================================================
 
     private void updateWifiState(Intent intent) {
@@ -618,14 +659,13 @@
             if (mWifiSsid == null) {
                 label = context.getString(R.string.status_bar_settings_signal_meter_wifi_nossid);
             } else {
-                label = context.getString(R.string.status_bar_settings_signal_meter_wifi_ssid_format,
-                                      mWifiSsid);
+                label = mWifiSsid;
             }
             combinedSignalIconId = mWifiIconId;
             dataTypeIconId = 0;
         } else {
             if (mDataConnected) {
-                label = context.getString(R.string.status_bar_settings_signal_meter_data_connected);
+                label = mNetworkName;
             } else {
                 label = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ToggleSlider.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ToggleSlider.java
new file mode 100644
index 0000000..46207ee
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ToggleSlider.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2010 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.systemui.statusbar.policy;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.View;
+import android.widget.CompoundButton;
+import android.widget.RelativeLayout;
+import android.widget.SeekBar;
+import android.widget.TextView;
+import android.widget.CompoundButton;
+
+import com.android.systemui.R;
+
+public class ToggleSlider extends RelativeLayout 
+        implements CompoundButton.OnCheckedChangeListener, SeekBar.OnSeekBarChangeListener {
+    private static final String TAG = "StatusBar.ToggleSlider";
+
+    public interface Listener {
+        public void onChanged(ToggleSlider v, boolean tracking, boolean checked, int value);
+    }
+
+    private Listener mListener;
+    private boolean mTracking;
+
+    private CompoundButton mToggle;
+    private SeekBar mSlider;
+    private TextView mLabel;
+
+    public ToggleSlider(Context context) {
+        this(context, null);
+    }
+
+    public ToggleSlider(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public ToggleSlider(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        View.inflate(context, R.layout.status_bar_toggle_slider, this);
+
+        final Resources res = context.getResources();
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ToggleSlider,
+                defStyle, 0);
+
+        mToggle = (CompoundButton)findViewById(R.id.toggle);
+        mToggle.setOnCheckedChangeListener(this);
+        mToggle.setBackgroundDrawable(res.getDrawable(R.drawable.status_bar_toggle_button));
+
+        mSlider = (SeekBar)findViewById(R.id.slider);
+        mSlider.setOnSeekBarChangeListener(this);
+
+        mLabel = (TextView)findViewById(R.id.label);
+        mLabel.setText(a.getString(R.styleable.ToggleSlider_text));
+
+        a.recycle();
+    }
+
+    public void onCheckedChanged(CompoundButton toggle, boolean checked) {
+        Drawable thumb;
+        final Resources res = getContext().getResources();
+        if (checked) {
+            thumb = res.getDrawable(R.drawable.scrubber_control_disabled_holo);
+        } else {
+            thumb = res.getDrawable(R.drawable.scrubber_control_holo);
+        }
+        mSlider.setThumb(thumb);
+
+        if (mListener != null) {
+            mListener.onChanged(this, mTracking, checked, mSlider.getProgress());
+        }
+    }
+
+    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+        if (mListener != null) {
+            mListener.onChanged(this, mTracking, mToggle.isChecked(), progress);
+        }
+    }
+
+    public void onStartTrackingTouch(SeekBar seekBar) {
+        mTracking = true;
+        if (mListener != null) {
+            mListener.onChanged(this, mTracking, mToggle.isChecked(), mSlider.getProgress());
+        }
+        mToggle.setChecked(false);
+    }
+
+    public void onStopTrackingTouch(SeekBar seekBar) {
+        mTracking = false;
+        if (mListener != null) {
+            mListener.onChanged(this, mTracking, mToggle.isChecked(), mSlider.getProgress());
+        }
+    }
+
+    public void setOnChangedListener(Listener l) {
+        mListener = l;
+    }
+
+    public void setChecked(boolean checked) {
+        mToggle.setChecked(checked);
+    }
+
+    public boolean isChecked() {
+        return mToggle.isChecked();
+    }
+
+    public void setMax(int max) {
+        mSlider.setMax(max);
+    }
+
+    public void setValue(int value) {
+        mSlider.setProgress(value);
+    }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
new file mode 100644
index 0000000..c9da01a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 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.systemui.statusbar.policy;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.media.AudioManager;
+import android.provider.Settings;
+import android.util.Slog;
+import android.view.IWindowManager;
+import android.widget.CompoundButton;
+
+public class VolumeController implements ToggleSlider.Listener {
+    private static final String TAG = "StatusBar.VolumeController";
+    private static final int STREAM = AudioManager.STREAM_NOTIFICATION;
+
+    private Context mContext;
+    private ToggleSlider mControl;
+    private AudioManager mAudioManager;
+
+    private boolean mMute;
+    private int mVolume;
+
+    public VolumeController(Context context, ToggleSlider control) {
+        mContext = context;
+        mControl = control;
+        mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
+
+        mMute = mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
+        mVolume = mAudioManager.getStreamVolume(STREAM);
+        control.setMax(mAudioManager.getStreamMaxVolume(STREAM));
+        control.setValue(mVolume);
+        control.setChecked(mMute);
+
+        control.setOnChangedListener(this);
+    }
+
+    public void onChanged(ToggleSlider view, boolean tracking, boolean mute, int level) {
+        if (!tracking) {
+            if (mute) {
+                boolean vibeInSilent = (1 == Settings.System.getInt(mContext.getContentResolver(),
+                        Settings.System.VIBRATE_IN_SILENT, 1));
+                mAudioManager.setRingerMode(
+                        vibeInSilent ? AudioManager.RINGER_MODE_VIBRATE
+                                     : AudioManager.RINGER_MODE_SILENT);
+            } else {
+                mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+                mAudioManager.setStreamVolume(STREAM, level, AudioManager.FLAG_PLAY_SOUND);
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java
index d1f8dd0b..0491baa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java
@@ -31,13 +31,18 @@
 import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.AirplaneModeController;
 import com.android.systemui.statusbar.policy.AutoRotateController;
+import com.android.systemui.statusbar.policy.BrightnessController;
 import com.android.systemui.statusbar.policy.DoNotDisturbController;
+import com.android.systemui.statusbar.policy.ToggleSlider;
+import com.android.systemui.statusbar.policy.VolumeController;
 
 public class SettingsView extends LinearLayout implements View.OnClickListener {
     static final String TAG = "SettingsView";
 
     AirplaneModeController mAirplane;
     AutoRotateController mRotate;
+    VolumeController mVolume;
+    BrightnessController mBrightness;
     DoNotDisturbController mDoNotDisturb;
 
     public SettingsView(Context context, AttributeSet attrs) {
@@ -59,6 +64,10 @@
         findViewById(R.id.network).setOnClickListener(this);
         mRotate = new AutoRotateController(context,
                 (CompoundButton)findViewById(R.id.rotate_checkbox));
+        mVolume = new VolumeController(context,
+                (ToggleSlider)findViewById(R.id.volume));
+        mBrightness = new BrightnessController(context,
+                (ToggleSlider)findViewById(R.id.brightness));
         mDoNotDisturb = new DoNotDisturbController(context,
                 (CompoundButton)findViewById(R.id.do_not_disturb_checkbox));
         findViewById(R.id.settings).setOnClickListener(this);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 59fcc52..392717e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -16,6 +16,7 @@
 
 package com.android.layoutlib.bridge;
 
+import com.android.layoutlib.api.Capabilities;
 import com.android.layoutlib.api.ILayoutLog;
 import com.android.layoutlib.api.IProjectCallback;
 import com.android.layoutlib.api.IResourceValue;
@@ -40,6 +41,7 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.util.Arrays;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.locks.ReentrantLock;
@@ -152,11 +154,19 @@
         }
     };
 
+    private EnumSet<Capabilities> mCapabilities;
+
+
     @Override
     public int getApiLevel() {
         return LayoutBridge.API_CURRENT;
     }
 
+    @Override
+    public EnumSet<Capabilities> getCapabilities() {
+        return mCapabilities;
+    }
+
     /*
      * (non-Javadoc)
      * @see com.android.layoutlib.api.ILayoutLibBridge#init(java.lang.String, java.util.Map)
@@ -165,6 +175,15 @@
     public boolean init(String fontOsLocation, Map<String, Map<String, Integer>> enumValueMap) {
         sEnumValueMap = enumValueMap;
 
+        // don't use EnumSet.allOf(), because the bridge doesn't come with it's specific version
+        // of layoutlib_api. It is provided by the client which could have a more recent version
+        // with newer, unsupported capabilities.
+        mCapabilities = EnumSet.of(
+                Capabilities.RENDER,
+                Capabilities.VIEW_MANIPULATION,
+                Capabilities.ANIMATE);
+
+
         Finalizers.init();
 
         BridgeAssetManager.initSystem();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
index 2f7ef48..a491901 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
@@ -119,7 +119,7 @@
 
     @Override
     public SceneResult moveChild(Object parentView, Object childView, int index,
-            IAnimationListener listener) {
+            Map<String, String> layoutParams, IAnimationListener listener) {
         if (parentView instanceof ViewGroup == false) {
             throw new IllegalArgumentException("parentView is not a ViewGroup");
         }
diff --git a/voip/java/android/net/sip/SipAudioCall.java b/voip/java/android/net/sip/SipAudioCall.java
index f275e39..51236fe9 100644
--- a/voip/java/android/net/sip/SipAudioCall.java
+++ b/voip/java/android/net/sip/SipAudioCall.java
@@ -594,12 +594,10 @@
      */
     public void holdCall(int timeout) throws SipException {
         synchronized (this) {
-        if (mHold) return;
+            if (mHold) return;
             mSipSession.changeCall(createHoldOffer().encode(), timeout);
             mHold = true;
-
-            AudioGroup audioGroup = getAudioGroup();
-            if (audioGroup != null) audioGroup.setMode(AudioGroup.MODE_ON_HOLD);
+            setAudioGroupMode();
         }
     }
 
@@ -643,8 +641,7 @@
             if (!mHold) return;
             mSipSession.changeCall(createContinueOffer().encode(), timeout);
             mHold = false;
-            AudioGroup audioGroup = getAudioGroup();
-            if (audioGroup != null) audioGroup.setMode(AudioGroup.MODE_NORMAL);
+            setAudioGroupMode();
         }
     }
 
@@ -767,13 +764,8 @@
     /** Toggles mute. */
     public void toggleMute() {
         synchronized (this) {
-            AudioGroup audioGroup = getAudioGroup();
-            if (audioGroup != null) {
-                audioGroup.setMode(mMuted
-                        ? AudioGroup.MODE_NORMAL
-                        : AudioGroup.MODE_MUTED);
-                mMuted = !mMuted;
-            }
+            mMuted = !mMuted;
+            setAudioGroupMode();
         }
     }
 
@@ -792,14 +784,22 @@
      * Puts the device to speaker mode.
      * <p class="note"><strong>Note:</strong> Requires the
      *   {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS} permission.</p>
+     *
+     * @param speakerMode set true to enable speaker mode; false to disable
      */
     public void setSpeakerMode(boolean speakerMode) {
         synchronized (this) {
             ((AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE))
                     .setSpeakerphoneOn(speakerMode);
+            setAudioGroupMode();
         }
     }
 
+    private boolean isSpeakerOn() {
+        return ((AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE))
+                .isSpeakerphoneOn();
+    }
+
     /**
      * Sends a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2883</a>,
      * event 0--9 maps to decimal
@@ -876,7 +876,11 @@
     /**
      * Sets the {@link AudioGroup} object which the {@link AudioStream} object
      * joins. If {@code audioGroup} is null, then the {@code AudioGroup} object
-     * will be dynamically created when needed.
+     * will be dynamically created when needed. Note that the mode of the
+     * {@code AudioGroup} is not changed according to the audio settings (i.e.,
+     * hold, mute, speaker phone) of this object. This is mainly used to merge
+     * multiple {@code SipAudioCall} objects to form a conference call. The
+     * settings of the first object (that merges others) override others'.
      *
      * @see #getAudioStream
      * @hide
@@ -992,16 +996,25 @@
         // AudioGroup logic:
         AudioGroup audioGroup = getAudioGroup();
         if (mHold) {
-            if (audioGroup != null) {
-                audioGroup.setMode(AudioGroup.MODE_ON_HOLD);
-            }
             // don't create an AudioGroup here; doing so will fail if
             // there's another AudioGroup out there that's active
         } else {
             if (audioGroup == null) audioGroup = new AudioGroup();
             stream.join(audioGroup);
-            if (mMuted) {
+        }
+        setAudioGroupMode();
+    }
+
+    // set audio group mode based on current audio configuration
+    private void setAudioGroupMode() {
+        AudioGroup audioGroup = getAudioGroup();
+        if (audioGroup != null) {
+            if (mHold) {
+                audioGroup.setMode(AudioGroup.MODE_ON_HOLD);
+            } else if (mMuted) {
                 audioGroup.setMode(AudioGroup.MODE_MUTED);
+            } else if (isSpeakerOn()) {
+                audioGroup.setMode(AudioGroup.MODE_ECHO_SUPPRESSION);
             } else {
                 audioGroup.setMode(AudioGroup.MODE_NORMAL);
             }