Merge "Add a new attribute to LinearLayout: useLargestChild. Bug #2379138"
diff --git a/api/current.xml b/api/current.xml
index 689f5dd..d329f3d 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -199211,6 +199211,223 @@
 </parameter>
 </method>
 </interface>
+<class name="NumberPicker"
+ extends="android.widget.LinearLayout"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="NumberPicker"
+ type="android.widget.NumberPicker"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+</constructor>
+<constructor name="NumberPicker"
+ type="android.widget.NumberPicker"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="attrs" type="android.util.AttributeSet">
+</parameter>
+</constructor>
+<method name="changeCurrent"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="current" type="int">
+</parameter>
+</method>
+<method name="getBeginRange"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+</method>
+<method name="getCurrent"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getEndRange"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+</method>
+<method name="setCurrent"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="current" type="int">
+</parameter>
+</method>
+<method name="setFormatter"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="formatter" type="android.widget.NumberPicker.Formatter">
+</parameter>
+</method>
+<method name="setOnChangeListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.widget.NumberPicker.OnChangedListener">
+</parameter>
+</method>
+<method name="setRange"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="start" type="int">
+</parameter>
+<parameter name="end" type="int">
+</parameter>
+</method>
+<method name="setRange"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="start" type="int">
+</parameter>
+<parameter name="end" type="int">
+</parameter>
+<parameter name="displayedValues" type="java.lang.String[]">
+</parameter>
+</method>
+<method name="setSpeed"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="speed" type="long">
+</parameter>
+</method>
+<field name="TWO_DIGIT_FORMATTER"
+ type="android.widget.NumberPicker.Formatter"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<interface name="NumberPicker.Formatter"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="toString"
+ return="java.lang.String"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="int">
+</parameter>
+</method>
+</interface>
+<interface name="NumberPicker.OnChangedListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onChanged"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="picker" type="android.widget.NumberPicker">
+</parameter>
+<parameter name="oldVal" type="int">
+</parameter>
+<parameter name="newVal" type="int">
+</parameter>
+</method>
+</interface>
 <class name="PopupWindow"
  extends="java.lang.Object"
  abstract="false"
diff --git a/core/java/android/app/DeviceAdmin.java b/core/java/android/app/DeviceAdmin.java
index 4da3fee..16832db 100644
--- a/core/java/android/app/DeviceAdmin.java
+++ b/core/java/android/app/DeviceAdmin.java
@@ -77,10 +77,10 @@
     /**
      * Action sent to a device administrator when the user has changed the
      * password of their device.  You can at this point check the characteristics
-     * of the new password with {@link DevicePolicyManager#getActivePasswordMode()
+     * of the new password with {@link DevicePolicyManager#getPasswordMode()
      * DevicePolicyManager.getActivePasswordMode()} and
-     * {@link DevicePolicyManager#getActiveMinimumPasswordLength()
-     * DevicePolicyManager.getActiveMinimumPasswordLength()}.  You will generally
+     * {@link DevicePolicyManager#getMinimumPasswordLength()
+     * DevicePolicyManager.getMinimumPasswordLength()}.  You will generally
      * handle this in {@link DeviceAdmin#onPasswordChanged(Context, Intent)}.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index b657e8e..299ed8a 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -25,9 +25,9 @@
 import android.util.AttributeSet;
 import android.util.SparseArray;
 import android.view.LayoutInflater;
+import android.widget.NumberPicker;
+import android.widget.NumberPicker.OnChangedListener;
 
-import com.android.common.widget.NumberPicker;
-import com.android.common.widget.NumberPicker.OnChangedListener;
 import com.android.internal.R;
 
 import java.text.DateFormatSymbols;
diff --git a/common/java/com/android/common/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
similarity index 65%
rename from common/java/com/android/common/widget/NumberPicker.java
rename to core/java/android/widget/NumberPicker.java
index 64b436f..2d36bc8 100644
--- a/common/java/com/android/common/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.common.widget;
+package android.widget;
 
+import android.annotation.Widget;
 import android.content.Context;
 import android.os.Handler;
 import android.text.InputFilter;
@@ -34,13 +35,29 @@
 
 import com.android.internal.R;
 
-public class NumberPicker extends LinearLayout implements OnClickListener,
-        OnFocusChangeListener, OnLongClickListener {
+/**
+ * A view for selecting a number
+ *
+ * For a dialog using this view, see {@link android.app.TimePickerDialog}.
+ */
+@Widget
+public class NumberPicker extends LinearLayout {
 
+    /**
+     * The callback interface used to indicate the number value has been adjusted.
+     */
     public interface OnChangedListener {
+        /**
+         * @param picker The NumberPicker associated with this listener.
+         * @param oldVal The previous value.
+         * @param newVal The new value.
+         */
         void onChanged(NumberPicker picker, int oldVal, int newVal);
     }
 
+    /**
+     * Interface used to format the number into a string for presentation
+     */
     public interface Formatter {
         String toString(int value);
     }
@@ -81,10 +98,26 @@
     private final InputFilter mNumberInputFilter;
 
     private String[] mDisplayedValues;
-    protected int mStart;
-    protected int mEnd;
-    protected int mCurrent;
-    protected int mPrevious;
+
+    /**
+     * Lower value of the range of numbers allowed for the NumberPicker
+     */
+    private int mStart;
+
+    /**
+     * Upper value of the range of numbers allowed for the NumberPicker
+     */
+    private int mEnd;
+
+    /**
+     * Current value of this NumberPicker
+     */
+    private int mCurrent;
+
+    /**
+     * Previous value of this NumberPicker.
+     */
+    private int mPrevious;
     private OnChangedListener mListener;
     private Formatter mFormatter;
     private long mSpeed = 300;
@@ -92,35 +125,89 @@
     private boolean mIncrement;
     private boolean mDecrement;
 
+    /**
+     * Create a new number picker
+     * @param context the application environment
+     */
     public NumberPicker(Context context) {
         this(context, null);
     }
 
+    /**
+     * Create a new number picker
+     * @param context the application environment
+     * @param attrs a collection of attributes
+     */
     public NumberPicker(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    @SuppressWarnings({"UnusedDeclaration"})
-    public NumberPicker(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs);
         setOrientation(VERTICAL);
         LayoutInflater inflater =
                 (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         inflater.inflate(R.layout.number_picker, this, true);
         mHandler = new Handler();
+
+        OnClickListener clickListener = new OnClickListener() {
+            public void onClick(View v) {
+                validateInput(mText);
+                if (!mText.hasFocus()) mText.requestFocus();
+
+                // now perform the increment/decrement
+                if (R.id.increment == v.getId()) {
+                    changeCurrent(mCurrent + 1);
+                } else if (R.id.decrement == v.getId()) {
+                    changeCurrent(mCurrent - 1);
+                }
+            }
+        };
+
+        OnFocusChangeListener focusListener = new OnFocusChangeListener() {
+            public void onFocusChange(View v, boolean hasFocus) {
+
+                /* When focus is lost check that the text field
+                 * has valid values.
+                 */
+                if (!hasFocus) {
+                    validateInput(v);
+                }
+            }
+        };
+
+        OnLongClickListener longClickListener = new OnLongClickListener() {
+            /**
+             * We start the long click here but rely on the {@link NumberPickerButton}
+             * to inform us when the long click has ended.
+             */
+            public boolean onLongClick(View v) {
+                /* The text view may still have focus so clear it's focus which will
+                 * trigger the on focus changed and any typed values to be pulled.
+                 */
+                mText.clearFocus();
+
+                if (R.id.increment == v.getId()) {
+                    mIncrement = true;
+                    mHandler.post(mRunnable);
+                } else if (R.id.decrement == v.getId()) {
+                    mDecrement = true;
+                    mHandler.post(mRunnable);
+                }
+                return true;
+            }
+        };
+
         InputFilter inputFilter = new NumberPickerInputFilter();
         mNumberInputFilter = new NumberRangeKeyListener();
         mIncrementButton = (NumberPickerButton) findViewById(R.id.increment);
-        mIncrementButton.setOnClickListener(this);
-        mIncrementButton.setOnLongClickListener(this);
+        mIncrementButton.setOnClickListener(clickListener);
+        mIncrementButton.setOnLongClickListener(longClickListener);
         mIncrementButton.setNumberPicker(this);
+
         mDecrementButton = (NumberPickerButton) findViewById(R.id.decrement);
-        mDecrementButton.setOnClickListener(this);
-        mDecrementButton.setOnLongClickListener(this);
+        mDecrementButton.setOnClickListener(clickListener);
+        mDecrementButton.setOnLongClickListener(longClickListener);
         mDecrementButton.setNumberPicker(this);
 
         mText = (EditText) findViewById(R.id.timepicker_input);
-        mText.setOnFocusChangeListener(this);
+        mText.setOnFocusChangeListener(focusListener);
         mText.setFilters(new InputFilter[] {inputFilter});
         mText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
 
@@ -129,6 +216,12 @@
         }
     }
 
+    /**
+     * Set the enabled state of this view. The interpretation of the enabled
+     * state varies by subclass.
+     *
+     * @param enabled True if this view is enabled, false otherwise.
+     */
     @Override
     public void setEnabled(boolean enabled) {
         super.setEnabled(enabled);
@@ -137,10 +230,19 @@
         mText.setEnabled(enabled);
     }
 
+    /**
+     * Set the callback that indicates the number has been adjusted by the user.
+     * @param listener the callback, should not be null.
+     */
     public void setOnChangeListener(OnChangedListener listener) {
         mListener = listener;
     }
 
+    /**
+     * Set the formatter that will be used to format the number for presentation
+     * @param formatter the formatter object.  If formatter is null, String.valueOf()
+     * will be used
+     */
     public void setFormatter(Formatter formatter) {
         mFormatter = formatter;
     }
@@ -153,10 +255,7 @@
      * @param end the end of the range (inclusive)
      */
     public void setRange(int start, int end) {
-        mStart = start;
-        mEnd = end;
-        mCurrent = start;
-        updateView();
+        setRange(start, end, null/*displayedValues*/);
     }
 
     /**
@@ -176,39 +275,49 @@
         updateView();
     }
 
+    /**
+     * Set the current value for the number picker.
+     *
+     * @param current the current value the start of the range (inclusive)
+     * @throws IllegalArgumentException when current is not within the range
+     *         of of the number picker
+     */
     public void setCurrent(int current) {
+        if (current < mStart || current > mEnd) {
+            throw new IllegalArgumentException(
+                    "current should be >= start and <= end");
+        }
         mCurrent = current;
         updateView();
     }
 
     /**
-     * The speed (in milliseconds) at which the numbers will scroll
-     * when the the +/- buttons are longpressed. Default is 300ms.
+     * Sets the speed at which the numbers will scroll when the +/-
+     * buttons are longpressed
+     *
+     * @param speed The speed (in milliseconds) at which the numbers will scroll
+     * default 300ms
      */
     public void setSpeed(long speed) {
         mSpeed = speed;
     }
 
-    public void onClick(View v) {
-        validateInput(mText);
-        if (!mText.hasFocus()) mText.requestFocus();
-
-        // now perform the increment/decrement
-        if (R.id.increment == v.getId()) {
-            changeCurrent(mCurrent + 1);
-        } else if (R.id.decrement == v.getId()) {
-            changeCurrent(mCurrent - 1);
-        }
-    }
-
     private String formatNumber(int value) {
         return (mFormatter != null)
                 ? mFormatter.toString(value)
                 : String.valueOf(value);
     }
 
+    /**
+     * Sets the current value of this NumberPicker, and sets mPrevious to the previous
+     * value.  If current is greater than mEnd less than mStart, the value of mCurrent
+     * is wrapped around.
+     *
+     * Subclasses can override this to change the wrapping behavior
+     *
+     * @param current the new value of the NumberPicker
+     */
     protected void changeCurrent(int current) {
-
         // Wrap around the values if we go past the start or end
         if (current > mEnd) {
             current = mStart;
@@ -221,14 +330,23 @@
         updateView();
     }
 
-    protected void notifyChange() {
+    /**
+     * Notifies the listener, if registered, of a change of the value of this
+     * NumberPicker.
+     */
+    private void notifyChange() {
         if (mListener != null) {
             mListener.onChanged(this, mPrevious, mCurrent);
         }
     }
 
-    protected void updateView() {
-
+    /**
+     * Updates the view of this NumberPicker.  If displayValues were specified
+     * in {@link #setRange}, the string corresponding to the index specified by
+     * the current value will be returned.  Otherwise, the formatter specified
+     * in {@link setFormatter} will be used to format the number.
+     */
+    private void updateView() {
         /* If we don't have displayed values then use the
          * current number else find the correct value in the
          * displayed values for the current number.
@@ -253,16 +371,6 @@
         updateView();
     }
 
-    public void onFocusChange(View v, boolean hasFocus) {
-
-        /* When focus is lost check that the text field
-         * has valid values.
-         */
-        if (!hasFocus) {
-            validateInput(v);
-        }
-    }
-
     private void validateInput(View v) {
         String str = String.valueOf(((TextView) v).getText());
         if ("".equals(str)) {
@@ -277,30 +385,15 @@
     }
 
     /**
-     * We start the long click here but rely on the {@link NumberPickerButton}
-     * to inform us when the long click has ended.
+     * @hide
      */
-    public boolean onLongClick(View v) {
-
-        /* The text view may still have focus so clear it's focus which will
-         * trigger the on focus changed and any typed values to be pulled.
-         */
-        mText.clearFocus();
-
-        if (R.id.increment == v.getId()) {
-            mIncrement = true;
-            mHandler.post(mRunnable);
-        } else if (R.id.decrement == v.getId()) {
-            mDecrement = true;
-            mHandler.post(mRunnable);
-        }
-        return true;
-    }
-
     public void cancelIncrement() {
         mIncrement = false;
     }
 
+    /**
+     * @hide
+     */
     public void cancelDecrement() {
         mDecrement = false;
     }
@@ -404,9 +497,26 @@
     }
 
     /**
+     * Returns the current value of the NumberPicker
      * @return the current value.
      */
     public int getCurrent() {
         return mCurrent;
     }
+
+    /**
+     * Returns the upper value of the range of the NumberPicker
+     * @return the uppper number of the range.
+     */
+    protected int getEndRange() {
+        return mEnd;
+    }
+
+    /**
+     * Returns the lower value of the range of the NumberPicker
+     * @return the lower number of the range.
+     */
+    protected int getBeginRange() {
+        return mStart;
+    }
 }
diff --git a/common/java/com/android/common/widget/NumberPickerButton.java b/core/java/android/widget/NumberPickerButton.java
similarity index 91%
rename from common/java/com/android/common/widget/NumberPickerButton.java
rename to core/java/android/widget/NumberPickerButton.java
index f6b6d5d..1c8579c 100644
--- a/common/java/com/android/common/widget/NumberPickerButton.java
+++ b/core/java/android/widget/NumberPickerButton.java
@@ -14,20 +14,22 @@
  * limitations under the License.
  */
 
-package com.android.common.widget;
+package android.widget;
 
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.widget.ImageButton;
+import android.widget.NumberPicker;
 
 import com.android.internal.R;
 
 /**
- * This class exists purely to cancel long click events.
+ * This class exists purely to cancel long click events, that got
+ * started in NumberPicker
  */
-public class NumberPickerButton extends ImageButton {
+class NumberPickerButton extends ImageButton {
 
     private NumberPicker mNumberPicker;
 
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index b87e278..caed308 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -23,9 +23,9 @@
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.widget.NumberPicker;
 
 import com.android.internal.R;
-import com.android.common.widget.NumberPicker;
 
 import java.text.DateFormatSymbols;
 import java.util.Calendar;
diff --git a/core/java/android/widget/ZoomButtonsController.java b/core/java/android/widget/ZoomButtonsController.java
index bea009c0..3df419a 100644
--- a/core/java/android/widget/ZoomButtonsController.java
+++ b/core/java/android/widget/ZoomButtonsController.java
@@ -546,6 +546,11 @@
     public boolean onTouch(View v, MotionEvent event) {
         int action = event.getAction();
 
+        if (event.getPointerCount() > 1) {
+            // ZoomButtonsController doesn't handle mutitouch. Give up control.
+            return false;
+        }
+
         if (mReleaseTouchListenerOnUp) {
             // The controls were dismissed but we need to throw away all events until the up
             if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
diff --git a/core/java/com/android/internal/widget/SlidingTab.java b/core/java/com/android/internal/widget/SlidingTab.java
index adafbb41..eb6d1a6 100644
--- a/core/java/com/android/internal/widget/SlidingTab.java
+++ b/core/java/com/android/internal/widget/SlidingTab.java
@@ -145,20 +145,6 @@
         void onGrabbedStateChange(View v, int grabbedState);
     }
 
-    // TODO: For debugging; remove after glitches debugged.
-    @Override
-    protected void dispatchDraw(Canvas canvas) {
-        int orientation = getResources().getConfiguration().orientation;
-        if (mOrientation == HORIZONTAL && orientation != Configuration.ORIENTATION_PORTRAIT
-                || mOrientation == VERTICAL && orientation != Configuration.ORIENTATION_LANDSCAPE) {
-            // UBER HACK ALERT.  This is a workaround for a configuration race condition between
-            // orientation changed notification and the resize notification. This just prevents
-            // us from drawing under this circumstance, though the view will still be wrong.
-            return;
-        }
-        super.dispatchDraw(canvas);
-    }
-
     /**
      * Simple container class for all things pertinent to a slider.
      * A slider consists of 3 Views:
@@ -433,7 +419,7 @@
         /**
          * Start animating the slider. Note we need two animations since an Animator
          * keeps internal state of the invalidation region which is just the view being animated.
-         * 
+         *
          * @param anim1
          * @param anim2
          */
@@ -671,7 +657,7 @@
                     resetView();
                 }
                 anim.setAnimationListener(mAnimationDoneListener);
-                
+
                 /* Animation can be the same for these since the animation just holds */
                 mLeftSlider.startAnimation(anim, anim);
                 mRightSlider.startAnimation(anim, anim);
diff --git a/core/res/res/layout/date_picker.xml b/core/res/res/layout/date_picker.xml
index 56d5494..4fd46b3 100644
--- a/core/res/res/layout/date_picker.xml
+++ b/core/res/res/layout/date_picker.xml
@@ -29,7 +29,7 @@
     android:layout_height="wrap_content">
 
     <!-- Month -->
-    <com.android.common.widget.NumberPicker
+    <NumberPicker
         android:id="@+id/month"
         android:layout_width="80dip"
         android:layout_height="wrap_content"
@@ -40,7 +40,7 @@
         />
 
     <!-- Day -->
-    <com.android.common.widget.NumberPicker
+    <NumberPicker
         android:id="@+id/day"
         android:layout_width="80dip"
         android:layout_height="wrap_content"
@@ -51,7 +51,7 @@
         />
 
     <!-- Year -->
-    <com.android.common.widget.NumberPicker
+    <NumberPicker
         android:id="@+id/year"
         android:layout_width="95dip"
         android:layout_height="wrap_content"
diff --git a/core/res/res/layout/number_picker.xml b/core/res/res/layout/number_picker.xml
index 44dca33..9241708 100644
--- a/core/res/res/layout/number_picker.xml
+++ b/core/res/res/layout/number_picker.xml
@@ -19,7 +19,7 @@
 
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <com.android.common.widget.NumberPickerButton android:id="@+id/increment"
+    <NumberPickerButton android:id="@+id/increment"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:background="@drawable/timepicker_up_btn" />
@@ -34,7 +34,7 @@
         android:textSize="30sp"
         android:background="@drawable/timepicker_input" />
 
-    <com.android.common.widget.NumberPickerButton android:id="@+id/decrement"
+    <NumberPickerButton android:id="@+id/decrement"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:background="@drawable/timepicker_down_btn" />
diff --git a/core/res/res/layout/time_picker.xml b/core/res/res/layout/time_picker.xml
index b9f42ce..6124ea8 100644
--- a/core/res/res/layout/time_picker.xml
+++ b/core/res/res/layout/time_picker.xml
@@ -26,7 +26,7 @@
     android:layout_height="wrap_content">
 
     <!-- hour -->
-    <com.android.common.widget.NumberPicker
+    <NumberPicker
         android:id="@+id/hour"
         android:layout_width="70dip"
         android:layout_height="wrap_content"
@@ -35,7 +35,7 @@
         />
     
     <!-- minute -->
-    <com.android.common.widget.NumberPicker
+    <NumberPicker
         android:id="@+id/minute"
         android:layout_width="70dip"
         android:layout_height="wrap_content"
diff --git a/core/res/res/values-land/donottranslate.xml b/core/res/res/values-land/donottranslate.xml
new file mode 100644
index 0000000..75a7b06
--- /dev/null
+++ b/core/res/res/values-land/donottranslate.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2009, 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- @hide DO NOT TRANSLATE. Workaround for resource race condition in lockscreen -->
+    <bool name="lockscreen_isPortrait">false</bool>
+</resources>
diff --git a/core/res/res/values/donottranslate.xml b/core/res/res/values/donottranslate.xml
index 6def3bf..78d4d36d 100644
--- a/core/res/res/values/donottranslate.xml
+++ b/core/res/res/values/donottranslate.xml
@@ -20,4 +20,6 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- Default text encoding for WebSettings. -->
     <string name="default_text_encoding">Latin-1</string>
+    <!-- @hide DO NOT TRANSLATE. Workaround for resource race condition in lockscreen. -->
+    <bool name="lockscreen_isPortrait">true</bool>
 </resources>
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 091856f..ac9b6b0 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -370,8 +370,23 @@
 
 LayerBuffer::BufferSource::~BufferSource()
 {    
+    class MessageDestroyTexture : public MessageBase {
+        SurfaceFlinger* flinger;
+        GLuint name;
+    public:
+        MessageDestroyTexture(
+                SurfaceFlinger* flinger, GLuint name)
+            : flinger(flinger), name(name) { }
+        virtual bool handler() {
+            glDeleteTextures(1, &name);
+            return true;
+        }
+    };
+
     if (mTexture.name != -1U) {
-        glDeleteTextures(1, &mTexture.name);
+        // GL textures can only be destroyed from the GL thread
+        mLayer.mFlinger->mEventQueue.postMessage(
+                new MessageDestroyTexture(mLayer.mFlinger.get(), mTexture.name) );
     }
     if (mTexture.image != EGL_NO_IMAGE_KHR) {
         EGLDisplay dpy(mLayer.mFlinger->graphicPlane(0).getEGLDisplay());
@@ -444,6 +459,10 @@
     NativeBuffer src(ourBuffer->getBuffer());
     const Rect transformedBounds(mLayer.getTransformedBounds());
 
+    if (UNLIKELY(mTexture.name == -1LU)) {
+        mTexture.name = mLayer.createTexture();
+    }
+
 #if defined(EGL_ANDROID_image_native_buffer)
     if (mLayer.mFlags & DisplayHardware::DIRECT_TEXTURE) {
         copybit_device_t* copybit = mLayer.mBlitEngine;
@@ -483,9 +502,6 @@
         t.format = src.img.format;
         t.data = (GGLubyte*)src.img.base;
         const Region dirty(Rect(t.width, t.height));
-        if (UNLIKELY(mTexture.name == -1LU)) {
-            mTexture.name = mLayer.createTexture();
-        }
         mLayer.loadTexture(&mTexture, dirty, t);
     }
 
@@ -566,11 +582,17 @@
 
 void LayerBuffer::BufferSource::clearTempBufferImage() const
 {
+    // delete the image
     EGLDisplay dpy(mLayer.mFlinger->graphicPlane(0).getEGLDisplay());
-    glDeleteTextures(1, &mTexture.name);
     eglDestroyImageKHR(dpy, mTexture.image);
+
+    // and the associated texture (recreate a name)
+    glDeleteTextures(1, &mTexture.name);
     Texture defaultTexture;
     mTexture = defaultTexture;
+    mTexture.name = mLayer.createTexture();
+
+    // and the associated buffer
     mTempGraphicBuffer.clear();
 }
 
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index fd42538..36da4eb 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -28,7 +28,6 @@
 import android.app.DevicePolicyManager;
 import android.app.IDevicePolicyManager;
 import android.content.ComponentName;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -36,11 +35,9 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.IPowerManager;
-import android.os.PowerManager;
 import android.os.RecoverySystem;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.provider.Settings;
 import android.util.Log;
 import android.util.Xml;
 
@@ -114,6 +111,12 @@
         mContext.sendBroadcast(intent);
     }
     
+    void sendAdminCommandLocked(String action) {
+        if (mActiveAdmin != null) {
+            sendAdminCommandLocked(mActiveAdmin, action);
+        }
+    }
+    
     ComponentName getActiveAdminLocked() {
         if (mActiveAdmin != null) {
             return mActiveAdmin.info.getComponent();
@@ -498,8 +501,7 @@
                     mActivePasswordMode = mode;
                     mActivePasswordLength = length;
                     mFailedPasswordAttempts = 0;
-                    sendAdminCommandLocked(mActiveAdmin,
-                            DeviceAdmin.ACTION_PASSWORD_CHANGED);
+                    sendAdminCommandLocked(DeviceAdmin.ACTION_PASSWORD_CHANGED);
                 } finally {
                     Binder.restoreCallingIdentity(ident);
                 }
@@ -515,8 +517,7 @@
             long ident = Binder.clearCallingIdentity();
             try {
                 mFailedPasswordAttempts++;
-                sendAdminCommandLocked(mActiveAdmin,
-                        DeviceAdmin.ACTION_PASSWORD_FAILED);
+                sendAdminCommandLocked(DeviceAdmin.ACTION_PASSWORD_FAILED);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -532,8 +533,7 @@
                 long ident = Binder.clearCallingIdentity();
                 try {
                     mFailedPasswordAttempts = 0;
-                    sendAdminCommandLocked(mActiveAdmin,
-                            DeviceAdmin.ACTION_PASSWORD_SUCCEEDED);
+                    sendAdminCommandLocked(DeviceAdmin.ACTION_PASSWORD_SUCCEEDED);
                 } finally {
                     Binder.restoreCallingIdentity(ident);
                 }
diff --git a/tests/AndroidTests/Android.mk b/tests/AndroidTests/Android.mk
index 757044f..a81b779 100644
--- a/tests/AndroidTests/Android.mk
+++ b/tests/AndroidTests/Android.mk
@@ -5,7 +5,7 @@
 
 LOCAL_JAVA_LIBRARIES := framework-tests android.test.runner services
 
-LOCAL_STATIC_JAVA_LIBRARIES := googlelogin-client
+LOCAL_STATIC_JAVA_LIBRARIES := gsf-client
 
 # Resource unit tests use a private locale
 LOCAL_AAPT_FLAGS = -c xx_YY -c cs -c 160dpi -c 32dpi -c 240dpi
diff --git a/tests/AndroidTests/src/com/android/unit_tests/GoogleLoginServiceTest.java b/tests/AndroidTests/src/com/android/unit_tests/GoogleLoginServiceTest.java
index 59f14bf..1d48030 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/GoogleLoginServiceTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/GoogleLoginServiceTest.java
@@ -17,9 +17,9 @@
 import android.test.suitebuilder.annotation.Suppress;
 import android.util.Log;
 
-import com.google.android.googleapps.GoogleLoginCredentialsResult;
-import com.google.android.googleapps.IGoogleLoginService;
-import com.google.android.googlelogin.GoogleLoginServiceConstants;
+import com.google.android.gsf.GoogleLoginCredentialsResult;
+import com.google.android.gsf.IGoogleLoginService;
+import com.google.android.gsf.GoogleLoginServiceConstants;
 
 import junit.framework.Assert;
 
@@ -60,8 +60,8 @@
     protected void setUp() throws Exception {
         super.setUp();
         getContext().bindService((new Intent())
-                                 .setClassName("com.google.android.googleapps",
-                                               "com.google.android.googleapps.GoogleLoginService"),
+                                 .setClassName("com.google.android.gsf",
+                                               "com.google.android.gsf.loginservice.GoogleLoginService"),
                                  mConnection, Context.BIND_AUTO_CREATE);
 
         // wait for the service to cnnnect
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas.java b/tools/layoutlib/bridge/src/android/graphics/Canvas.java
index c49e11e..8bf5e85 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas.java
@@ -31,6 +31,7 @@
 import android.graphics.Region.Op;
 
 import java.awt.AlphaComposite;
+import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Composite;
 import java.awt.Graphics2D;
@@ -103,13 +104,37 @@
      * Creates a new {@link Graphics2D} based on the {@link Paint} parameters.
      * <p/>The object must be disposed ({@link Graphics2D#dispose()}) after being used.
      */
-    private Graphics2D getNewGraphics(Paint paint, Graphics2D g) {
+    private Graphics2D getCustomGraphics(Paint paint) {
         // make new one
+        Graphics2D g = getGraphics2d();
         g = (Graphics2D)g.create();
+
+        // configure it
         g.setColor(new Color(paint.getColor()));
         int alpha = paint.getAlpha();
         float falpha = alpha / 255.f;
 
+        Style style = paint.getStyle();
+        if (style == Style.STROKE || style == Style.FILL_AND_STROKE) {
+            PathEffect e = paint.getPathEffect();
+            if (e instanceof DashPathEffect) {
+                DashPathEffect dpe = (DashPathEffect)e;
+                g.setStroke(new BasicStroke(
+                        paint.getStrokeWidth(),
+                        paint.getStrokeCap().getJavaCap(),
+                        paint.getStrokeJoin().getJavaJoin(),
+                        paint.getStrokeMiter(),
+                        dpe.getIntervals(),
+                        dpe.getPhase()));
+            } else {
+                g.setStroke(new BasicStroke(
+                        paint.getStrokeWidth(),
+                        paint.getStrokeCap().getJavaCap(),
+                        paint.getStrokeJoin().getJavaJoin(),
+                        paint.getStrokeMiter()));
+            }
+        }
+
         Xfermode xfermode = paint.getXfermode();
         if (xfermode instanceof PorterDuffXfermode) {
             PorterDuff.Mode mode = ((PorterDuffXfermode)xfermode).getMode();
@@ -783,11 +808,9 @@
     }
 
     private final void doDrawRect(int left, int top, int width, int height, Paint paint) {
-        // get current graphisc
-        if (width != 0 && height != 0) {
-            Graphics2D g = getGraphics2d();
-
-            g = getNewGraphics(paint, g);
+        if (width > 0 && height > 0) {
+            // get a Graphics2D object configured with the drawing parameters.
+            Graphics2D g = getCustomGraphics(paint);
 
             Style style = paint.getStyle();
 
@@ -810,11 +833,9 @@
      */
     @Override
     public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
-        // get current graphisc
-        if (rect.width() != 0 && rect.height() != 0) {
-            Graphics2D g = getGraphics2d();
-
-            g = getNewGraphics(paint, g);
+        if (rect.width() > 0 && rect.height() > 0) {
+            // get a Graphics2D object configured with the drawing parameters.
+            Graphics2D g = getCustomGraphics(paint);
 
             Style style = paint.getStyle();
 
@@ -844,10 +865,8 @@
      */
     @Override
     public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) {
-        // get current graphisc
-        Graphics2D g = getGraphics2d();
-
-        g = getNewGraphics(paint, g);
+        // get a Graphics2D object configured with the drawing parameters.
+        Graphics2D g = getCustomGraphics(paint);
 
         g.drawLine((int)startX, (int)startY, (int)stopX, (int)stopY);
 
@@ -860,10 +879,8 @@
      */
     @Override
     public void drawLines(float[] pts, int offset, int count, Paint paint) {
-        // get current graphisc
-        Graphics2D g = getGraphics2d();
-
-        g = getNewGraphics(paint, g);
+        // get a Graphics2D object configured with the drawing parameters.
+        Graphics2D g = getCustomGraphics(paint);
 
         for (int i = 0 ; i < count ; i += 4) {
             g.drawLine((int)pts[i + offset], (int)pts[i + offset + 1],
@@ -887,10 +904,8 @@
      */
     @Override
     public void drawCircle(float cx, float cy, float radius, Paint paint) {
-        // get current graphisc
-        Graphics2D g = getGraphics2d();
-
-        g = getNewGraphics(paint, g);
+        // get a Graphics2D object configured with the drawing parameters.
+        Graphics2D g = getCustomGraphics(paint);
 
         Style style = paint.getStyle();
 
@@ -914,10 +929,8 @@
      */
     @Override
     public void drawOval(RectF oval, Paint paint) {
-        // get current graphics
-        Graphics2D g = getGraphics2d();
-
-        g = getNewGraphics(paint, g);
+        // get a Graphics2D object configured with the drawing parameters.
+        Graphics2D g = getCustomGraphics(paint);
 
         Style style = paint.getStyle();
 
@@ -939,10 +952,8 @@
      */
     @Override
     public void drawPath(Path path, Paint paint) {
-        // get current graphics
-        Graphics2D g = getGraphics2d();
-
-        g = getNewGraphics(paint, g);
+        // get a Graphics2D object configured with the drawing parameters.
+        Graphics2D g = getCustomGraphics(paint);
 
         Style style = paint.getStyle();
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect.java b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect.java
new file mode 100644
index 0000000..46d4c70
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect.java
@@ -0,0 +1,54 @@
+/*
+ * 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 android.graphics;
+
+public class DashPathEffect extends PathEffect {
+
+    private final float[] mIntervals;
+    private final float mPhase;
+
+    /**
+     * The intervals array must contain an even number of entries (>=2), with
+     * the even indices specifying the "on" intervals, and the odd indices
+     * specifying the "off" intervals. phase is an offset into the intervals
+     * array (mod the sum of all of the intervals). The intervals array
+     * controls the length of the dashes. The paint's strokeWidth controls the
+     * thickness of the dashes.
+     * Note: this patheffect only affects drawing with the paint's style is set
+     * to STROKE or STROKE_AND_FILL. It is ignored if the drawing is done with
+     * style == FILL.
+     * @param intervals array of ON and OFF distances
+     * @param phase offset into the intervals array
+     */
+    public DashPathEffect(float intervals[], float phase) {
+        if (intervals.length < 2) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        mIntervals = intervals;
+        mPhase = phase;
+    }
+
+    public float[] getIntervals() {
+        return mIntervals;
+    }
+
+    public float getPhase() {
+        return mPhase;
+    }
+}
+
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint.java b/tools/layoutlib/bridge/src/android/graphics/Paint.java
index 312dab3..2d03618 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint.java
@@ -21,6 +21,7 @@
 import android.text.SpannedString;
 import android.text.TextUtils;
 
+import java.awt.BasicStroke;
 import java.awt.Font;
 import java.awt.Toolkit;
 import java.awt.font.FontRenderContext;
@@ -127,6 +128,19 @@
             this.nativeInt = nativeInt;
         }
         final int nativeInt;
+
+        /** custom for layoutlib */
+        public int getJavaCap() {
+            switch (this) {
+                case BUTT:
+                    return BasicStroke.CAP_BUTT;
+                case ROUND:
+                    return BasicStroke.CAP_ROUND;
+                default:
+                case SQUARE:
+                    return BasicStroke.CAP_SQUARE;
+            }
+        }
     }
 
     /**
@@ -151,6 +165,19 @@
             this.nativeInt = nativeInt;
         }
         final int nativeInt;
+
+        /** custom for layoutlib */
+        public int getJavaJoin() {
+            switch (this) {
+                default:
+                case MITER:
+                    return BasicStroke.JOIN_MITER;
+                case ROUND:
+                    return BasicStroke.JOIN_ROUND;
+                case BEVEL:
+                    return BasicStroke.JOIN_BEVEL;
+            }
+        }
     }
 
     /**
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 2623570..2ed8641 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -47,6 +47,7 @@
             "android.graphics.BitmapShader",        "android.graphics._Original_BitmapShader",
             "android.graphics.Canvas",              "android.graphics._Original_Canvas",
             "android.graphics.ComposeShader",       "android.graphics._Original_ComposeShader",
+            "android.graphics.DashPathEffect",       "android.graphics._Original_DashPathEffect",
             "android.graphics.LinearGradient",      "android.graphics._Original_LinearGradient",
             "android.graphics.Matrix",              "android.graphics._Original_Matrix",
             "android.graphics.Paint",               "android.graphics._Original_Paint",
diff --git a/tools/preload/Policy.java b/tools/preload/Policy.java
index 7a190ac..a8d761d 100644
--- a/tools/preload/Policy.java
+++ b/tools/preload/Policy.java
@@ -46,7 +46,6 @@
         "com.android.phone",
         "com.google.android.apps.maps.FriendService",
         "com.google.android.apps.maps.LocationFriendService",
-        "com.google.android.googleapps",
         "com.google.process.gapps",
         "android.tts"
     ));