Merge "Add documentation to NetworkStateTracker and a small change to the API."
diff --git a/api/current.xml b/api/current.xml
index b0056d7..d35037e 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -10657,6 +10657,17 @@
  visibility="public"
 >
 </field>
+<field name="windowActionBarSize"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843563"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="windowActionBarStyle"
  type="int"
  transient="false"
@@ -73982,7 +73993,7 @@
 <method name="setShadowLayer"
  return="void"
  abstract="false"
- native="true"
+ native="false"
  synchronized="false"
  static="false"
  final="false"
@@ -86983,6 +86994,24 @@
 </parameter>
 <parameter name="modeId" type="int">
 </parameter>
+<parameter name="width" type="int">
+</parameter>
+<parameter name="height" type="int">
+</parameter>
+</constructor>
+<constructor name="Keyboard"
+ type="android.inputmethodservice.Keyboard"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="xmlLayoutResId" type="int">
+</parameter>
+<parameter name="modeId" type="int">
+</parameter>
 </constructor>
 <constructor name="Keyboard"
  type="android.inputmethodservice.Keyboard"
@@ -147418,11 +147447,11 @@
  visibility="public"
 >
 </field>
-<field name="CAPABILITY_HAS_VIDEO_PLAYBACK_ONLY"
+<field name="CAPABILITY_HAS_VIDEO"
  type="int"
  transient="false"
  volatile="false"
- value="1"
+ value="2"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -147433,7 +147462,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="2"
+ value="1"
  static="true"
  final="true"
  deprecated="not deprecated"
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index e1d431f..8105843 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -851,8 +851,14 @@
      */
     public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
             throws FileNotFoundException {
+        if ("*/*".equals(mimeTypeFilter)) {
+            // If they can take anything, the untyped open call is good enough.
+            return openAssetFile(uri, "r");
+        }
         String baseType = getType(uri);
         if (baseType != null && compareMimeTypes(baseType, mimeTypeFilter)) {
+            // Use old untyped open call if this provider has a type for this
+            // URI and it matches the request.
             return openAssetFile(uri, "r");
         }
         throw new FileNotFoundException("Can't open " + uri + " as type " + mimeTypeFilter);
diff --git a/core/java/android/inputmethodservice/Keyboard.java b/core/java/android/inputmethodservice/Keyboard.java
index 4814b0a..885a6b8 100755
--- a/core/java/android/inputmethodservice/Keyboard.java
+++ b/core/java/android/inputmethodservice/Keyboard.java
@@ -500,7 +500,30 @@
     public Keyboard(Context context, int xmlLayoutResId) {
         this(context, xmlLayoutResId, 0);
     }
-    
+
+    /**
+     * Creates a keyboard from the given xml key layout file. Weeds out rows
+     * that have a keyboard mode defined but don't match the specified mode.
+     * @param context the application or service context
+     * @param xmlLayoutResId the resource file that contains the keyboard layout and keys.
+     * @param modeId keyboard mode identifier
+     * @param width sets width of keyboard
+     * @param height sets height of keyboard
+     */
+    public Keyboard(Context context, int xmlLayoutResId, int modeId, int width, int height) {
+        mDisplayWidth = width;
+        mDisplayHeight = height;
+
+        mDefaultHorizontalGap = 0;
+        mDefaultWidth = mDisplayWidth / 10;
+        mDefaultVerticalGap = 0;
+        mDefaultHeight = mDefaultWidth;
+        mKeys = new ArrayList<Key>();
+        mModifierKeys = new ArrayList<Key>();
+        mKeyboardMode = modeId;
+        loadKeyboard(context, context.getResources().getXml(xmlLayoutResId));
+    }
+
     /**
      * Creates a keyboard from the given xml key layout file. Weeds out rows
      * that have a keyboard mode defined but don't match the specified mode. 
diff --git a/core/java/android/preference/PreferenceScreen.java b/core/java/android/preference/PreferenceScreen.java
index f34f4a3..c7f8ab2 100644
--- a/core/java/android/preference/PreferenceScreen.java
+++ b/core/java/android/preference/PreferenceScreen.java
@@ -91,7 +91,8 @@
 
     /**
      * Returns an adapter that can be attached to a {@link PreferenceActivity}
-     * to show the preferences contained in this {@link PreferenceScreen}.
+     * or {@link PreferenceFragment} to show the preferences contained in this
+     * {@link PreferenceScreen}.
      * <p>
      * This {@link PreferenceScreen} will NOT appear in the returned adapter, instead
      * it appears in the hierarchy above this {@link PreferenceScreen}.
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index c93d9b2..1981780 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -2461,18 +2461,19 @@
         public static final String CHAT_CAPABILITY = "chat_capability";
 
         /**
-         * An allowed value of {@link #CHAT_CAPABILITY}. Indicates that the contact's device can
+         * An allowed flag of {@link #CHAT_CAPABILITY}. Indicates audio-chat capability (microphone
+         * and speaker)
+         */
+        public static final int CAPABILITY_HAS_VOICE = 1;
+
+        /**
+         * An allowed flag of {@link #CHAT_CAPABILITY}. Indicates that the contact's device can
          * display a video feed.
          */
-        public static final int CAPABILITY_HAS_VIDEO_PLAYBACK_ONLY = 1;
+        public static final int CAPABILITY_HAS_VIDEO = 2;
 
         /**
-         * An allowed value of {@link #CHAT_CAPABILITY}. Indicates audio-chat capability.
-         */
-        public static final int CAPABILITY_HAS_VOICE = 2;
-
-        /**
-         * An allowed value of {@link #CHAT_CAPABILITY}. Indicates that the contact's device has a
+         * An allowed flag of {@link #CHAT_CAPABILITY}. Indicates that the contact's device has a
          * camera that can be used for video chat (e.g. a front-facing camera on a phone).
          */
         public static final int CAPABILITY_HAS_CAMERA = 4;
@@ -3632,10 +3633,11 @@
      * <td>int</td>
      * <td>{@link #CHAT_CAPABILITY}</td>
      * <td>read/write</td>
-     * <td>Contact IM chat compatibility value. The allowed values are:
+     * <td>Contact IM chat compatibility value. The allowed values combinations of the following
+     * flags. If None of these flags is set, the device can only do text messaging.
      * <p>
      * <ul>
-     * <li>{@link #CAPABILITY_HAS_VIDEO_PLAYBACK_ONLY}</li>
+     * <li>{@link #CAPABILITY_HAS_VIDEO}</li>
      * <li>{@link #CAPABILITY_HAS_VOICE}</li>
      * <li>{@link #CAPABILITY_HAS_CAMERA}</li>
      * </ul>
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 91dbe1f..4c72e95 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -756,6 +756,12 @@
     private boolean setupModifiers(Paint paint) {
         boolean hasModifier = false;
 
+        if (paint.hasShadow) {
+            nSetupShadow(mRenderer, paint.shadowRadius, paint.shadowDx, paint.shadowDy,
+                    paint.shadowColor);
+            hasModifier = true;
+        }
+
         final Shader shader = paint.getShader();
         if (shader != null) {
             nSetupShader(mRenderer, shader.native_shader);
@@ -770,7 +776,7 @@
 
         return hasModifier;
     }
-    
+
     private boolean setupColorFilter(Paint paint) {
         final ColorFilter filter = paint.getColorFilter();
         if (filter != null) {
@@ -782,5 +788,7 @@
     
     private native void nSetupShader(int renderer, int shader);
     private native void nSetupColorFilter(int renderer, int colorFilter);
+    private native void nSetupShadow(int renderer, float radius, float dx, float dy, int color);
+
     private native void nResetModifiers(int renderer);
 }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 32009be..9f60f44 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3557,11 +3557,11 @@
         InputMethodManager imm = (InputMethodManager)
                 getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
 
-        // bring it back to the default scale so that user can enter text
-        boolean zoom = mZoomManager.getScale() < mZoomManager.getDefaultScale();
+        // bring it back to the reading level scale so that user can enter text
+        boolean zoom = mZoomManager.getScale() < mZoomManager.getReadingLevelScale();
         if (zoom) {
             mZoomManager.setZoomCenter(mLastTouchX, mLastTouchY);
-            mZoomManager.setZoomScale(mZoomManager.getDefaultScale(), false);
+            mZoomManager.setZoomScale(mZoomManager.getReadingLevelScale(), false);
         }
         if (isTextView) {
             rebuildWebTextView();
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 7f7f46e..8033c9c 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -56,6 +56,13 @@
     private ZoomControlExternal mExternalZoomControl;
 
     /*
+     * For large screen devices, the defaultScale usually set to 1.0 and
+     * equal to the overview scale, to differentiate the zoom level for double tapping,
+     * a minimum reading level scale is used.
+     */
+    private static final float MIN_READING_LEVEL_SCALE = 1.5f;
+
+    /*
      * The scale factors that determine the upper and lower bounds for the
      * default zoom scale.
      */
@@ -245,6 +252,10 @@
         return mDefaultScale;
     }
 
+    public final float getReadingLevelScale() {
+      return Math.max(mDefaultScale, MIN_READING_LEVEL_SCALE);
+    }
+
     public final float getInvDefaultScale() {
         return mInvDefaultScale;
     }
@@ -337,9 +348,9 @@
         mInitialScrollX = mWebView.getScrollX();
         mInitialScrollY = mWebView.getScrollY();
 
-        // snap to DEFAULT_SCALE if it is close
-        if (!exceedsMinScaleIncrement(scale, mDefaultScale)) {
-            scale = mDefaultScale;
+        // snap to reading level scale if it is close
+        if (!exceedsMinScaleIncrement(scale, getReadingLevelScale())) {
+            scale = getReadingLevelScale();
         }
 
         setZoomScale(scale, reflowText);
@@ -535,7 +546,7 @@
         } else if (!mInZoomOverview) {
             zoomToOverview();
         } else {
-            zoomToDefaultLevel();
+            zoomToReadingLevel();
         }
     }
 
@@ -563,7 +574,8 @@
         startZoomAnimation(getZoomOverviewScale(), true);
     }
 
-    private void zoomToDefaultLevel() {
+    private void zoomToReadingLevel() {
+        final float readingScale = getReadingLevelScale();
         int left = mWebView.nativeGetBlockLeftEdge(mAnchorX, mAnchorY, mActualScale);
         if (left != WebView.NO_LEFTEDGE) {
             // add a 5pt padding to the left edge.
@@ -572,13 +584,13 @@
             // Re-calculate the zoom center so that the new scroll x will be
             // on the left edge.
             if (viewLeft > 0) {
-                mZoomCenterX = viewLeft * mDefaultScale / (mDefaultScale - mActualScale);
+                mZoomCenterX = viewLeft * readingScale / (readingScale - mActualScale);
             } else {
                 mWebView.scrollBy(viewLeft, 0);
                 mZoomCenterX = 0;
             }
         }
-        startZoomAnimation(mDefaultScale, true);
+        startZoomAnimation(readingScale, true);
     }
 
     public void updateMultiTouchSupport(Context context) {
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index 2b723c9..ef00d88 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -685,14 +685,6 @@
             verticalOffset = 0;
         }
 
-        void setHorizontalOffset(int newHorizontalOffset) {
-            horizontalOffset = newHorizontalOffset;
-            if (mView != null) {
-                mView.requestLayout();
-                mView.invalidate();
-            }
-        }
-
         private Rect parentRect = new Rect();
         void invalidateGlobalRegion(View v, Rect r) {
             View p = v;
@@ -722,5 +714,17 @@
                 invalidateGlobalRegion(mView, invalidateRect);
             }
         }
+
+        public void setHorizontalOffset(int newHorizontalOffset) {
+            int offsetDelta = newHorizontalOffset - horizontalOffset;
+            horizontalOffset = newHorizontalOffset;
+            if (mView != null) {
+                mView.requestLayout();
+                int left = Math.min(mView.getLeft() + offsetDelta, mView.getLeft());
+                int right = Math.max(mView.getRight() + offsetDelta, mView.getRight());
+                invalidateRect.set(left, mView.getTop(), right, mView.getBottom());
+                invalidateGlobalRegion(mView, invalidateRect);
+            }
+        }
     }
 }
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 4cd44d9..e3aca6a 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -20,6 +20,12 @@
 
 import android.animation.PropertyAnimator;
 import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -72,11 +78,9 @@
      * These variables are all related to the current state of touch interaction
      * with the stack
      */
-    private boolean mGestureComplete = false;
     private float mInitialY;
     private float mInitialX;
     private int mActivePointerId;
-    private int mYOffset = 0;
     private int mYVelocity = 0;
     private int mSwipeGestureType = GESTURE_NONE;
     private int mViewHeight;
@@ -85,6 +89,8 @@
     private int mMaximumVelocity;
     private VelocityTracker mVelocityTracker;
 
+    private ImageView mHighlight;
+    private StackSlider mStackSlider;
     private boolean mFirstLayoutHappened = false;
 
     // TODO: temp hack to get this thing started
@@ -107,6 +113,15 @@
         mTouchSlop = configuration.getScaledTouchSlop();// + 5;
         mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
         mActivePointerId = INVALID_POINTER;
+
+        mHighlight = new ImageView(getContext());
+        mHighlight.setLayoutParams(new LayoutParams(mHighlight));
+        addViewInLayout(mHighlight, -1, new LayoutParams(mHighlight));
+        mStackSlider = new StackSlider();
+
+        if (!sPaintsInitialized) {
+            initializePaints(getContext());
+        }
     }
 
     /**
@@ -124,6 +139,7 @@
         } else if (fromIndex == mNumActiveViews - 1 && toIndex == mNumActiveViews - 2) {
             // Slide item in
             view.setVisibility(VISIBLE);
+
             LayoutParams lp = (LayoutParams) view.getLayoutParams();
 
             int largestDuration = (int) Math.round(
@@ -136,19 +152,18 @@
             duration = Math.min(duration, largestDuration);
             duration = Math.max(duration, MINIMUM_ANIMATION_DURATION);
 
-            PropertyAnimator slideDown = new PropertyAnimator(duration, lp,
-                    "verticalOffset", lp.verticalOffset, 0);
-            slideDown.start();
+            PropertyAnimator slideInY = new PropertyAnimator(duration, mStackSlider,
+                    "YProgress", mStackSlider.getYProgress(), 0);
+            slideInY.start();
+            PropertyAnimator slideInX = new PropertyAnimator(duration, mStackSlider,
+                    "XProgress", mStackSlider.getXProgress(), 0);
+            slideInX.start();
 
-            PropertyAnimator fadeIn = new PropertyAnimator(duration, view,
-                    "alpha", view.getAlpha(), 1.0f);
-            fadeIn.start();
         } else if (fromIndex == mNumActiveViews - 2 && toIndex == mNumActiveViews - 1) {
             // Slide item out
             LayoutParams lp = (LayoutParams) view.getLayoutParams();
 
-            int largestDuration = (int) Math.round(
-                    (1 - (lp.verticalOffset*1.0f/-mViewHeight))*DEFAULT_ANIMATION_DURATION);
+            int largestDuration = (int) Math.round(mStackSlider.getYProgress()*DEFAULT_ANIMATION_DURATION);
             int duration = largestDuration;
             if (mYVelocity != 0) {
                 duration = 1000*(lp.verticalOffset + mViewHeight)/Math.abs(mYVelocity);
@@ -157,13 +172,13 @@
             duration = Math.min(duration, largestDuration);
             duration = Math.max(duration, MINIMUM_ANIMATION_DURATION);
 
-            PropertyAnimator slideUp = new PropertyAnimator(duration, lp,
-                    "verticalOffset", lp.verticalOffset, -mViewHeight);
-            slideUp.start();
+            PropertyAnimator slideOutY = new PropertyAnimator(duration, mStackSlider,
+                    "YProgress", mStackSlider.getYProgress(), 1);
+            slideOutY.start();
+            PropertyAnimator slideOutX = new PropertyAnimator(duration, mStackSlider,
+                    "XProgress", mStackSlider.getXProgress(), 0);
+            slideOutX.start();
 
-            PropertyAnimator fadeOut = new PropertyAnimator(duration, view,
-                    "alpha", view.getAlpha(), 0.0f);
-            fadeOut.start();
         } else if (fromIndex == -1 && toIndex == mNumActiveViews - 1) {
             // Make sure this view that is "waiting in the wings" is invisible
             view.setAlpha(0.0f);
@@ -233,7 +248,6 @@
                 view.setClipChildren(false);
                 view.setClipToPadding(false);
             }
-
             mFirstLayoutHappened = true;
         }
     }
@@ -258,16 +272,10 @@
                     Log.d(TAG, "Error: No data for our primary pointer.");
                     return false;
                 }
-
                 float newY = ev.getY(pointerIndex);
                 float deltaY = newY - mInitialY;
 
-                if ((int) Math.abs(deltaY) > mTouchSlop && mSwipeGestureType == GESTURE_NONE) {
-                    mSwipeGestureType = deltaY < 0 ? GESTURE_SLIDE_UP : GESTURE_SLIDE_DOWN;
-                    mGestureComplete = false;
-                    cancelLongPress();
-                    requestDisallowInterceptTouchEvent(true);
-                }
+                beginGestureIfNeeded(deltaY);
                 break;
             }
             case MotionEvent.ACTION_POINTER_UP: {
@@ -278,13 +286,33 @@
             case MotionEvent.ACTION_CANCEL: {
                 mActivePointerId = INVALID_POINTER;
                 mSwipeGestureType = GESTURE_NONE;
-                mGestureComplete = true;
             }
         }
 
         return mSwipeGestureType != GESTURE_NONE;
     }
 
+    private void beginGestureIfNeeded(float deltaY) {
+        if ((int) Math.abs(deltaY) > mTouchSlop && mSwipeGestureType == GESTURE_NONE) {
+            mSwipeGestureType = deltaY < 0 ? GESTURE_SLIDE_UP : GESTURE_SLIDE_DOWN;
+            cancelLongPress();
+            requestDisallowInterceptTouchEvent(true);
+
+            int activeIndex = mSwipeGestureType == GESTURE_SLIDE_DOWN ? mNumActiveViews - 1
+                    : mNumActiveViews - 2;
+
+            View v = getViewAtRelativeIndex(activeIndex);
+            if (v != null) {
+                mHighlight.setImageBitmap(createOutline(v));
+                mHighlight.bringToFront();
+                v.bringToFront();
+                mStackSlider.setView(v);
+                if (mSwipeGestureType == GESTURE_SLIDE_DOWN)
+                    v.setVisibility(VISIBLE);
+            }
+        }
+    }
+
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
         int action = ev.getAction();
@@ -296,8 +324,9 @@
         }
 
         float newY = ev.getY(pointerIndex);
+        float newX = ev.getX(pointerIndex);
         float deltaY = newY - mInitialY;
-
+        float deltaX = newX - mInitialX;
         if (mVelocityTracker == null) {
             mVelocityTracker = VelocityTracker.obtain();
         }
@@ -305,48 +334,21 @@
 
         switch (action & MotionEvent.ACTION_MASK) {
             case MotionEvent.ACTION_MOVE: {
-                if ((int) Math.abs(deltaY) > mTouchSlop && mSwipeGestureType == GESTURE_NONE) {
-                    mSwipeGestureType = deltaY < 0 ? GESTURE_SLIDE_UP : GESTURE_SLIDE_DOWN;
-                    mGestureComplete = false;
-                    cancelLongPress();
-                    requestDisallowInterceptTouchEvent(true);
+                beginGestureIfNeeded(deltaY);
+
+                float rx = 0.3f*deltaX/(mViewHeight*1.0f);
+                if (mSwipeGestureType == GESTURE_SLIDE_DOWN) {
+                    float r = (deltaY-mTouchSlop*1.0f)/mViewHeight*1.0f;
+                    mStackSlider.setYProgress(1 - r);
+                    mStackSlider.setXProgress(rx);
+                    return true;
+                } else if (mSwipeGestureType == GESTURE_SLIDE_UP) {
+                    float r = -(deltaY + mTouchSlop*1.0f)/mViewHeight*1.0f;
+                    mStackSlider.setYProgress(r);
+                    mStackSlider.setXProgress(rx);
+                    return true;
                 }
 
-                if (!mGestureComplete) {
-                    if (mSwipeGestureType == GESTURE_SLIDE_DOWN) {
-                        View v = getViewAtRelativeIndex(mNumActiveViews - 1);
-                        if (v != null) {
-                            // This view is present but hidden, make sure it's visible
-                            // if they pull down
-                            v.setVisibility(VISIBLE);
-
-                            float r = (deltaY-mTouchSlop)*1.0f / (mSwipeThreshold);
-                            mYOffset = Math.min(-mViewHeight + (int)  Math.round(
-                                    r*mSwipeThreshold) - mTouchSlop, 0);
-                            LayoutParams lp = (LayoutParams) v.getLayoutParams();
-                            lp.setVerticalOffset(mYOffset);
-
-                            float alpha = Math.max(0.0f, 1.0f - (1.0f*mYOffset/-mViewHeight));
-                            alpha = Math.min(1.0f, alpha);
-                            v.setAlpha(alpha);
-                        }
-                        return true;
-                    } else if (mSwipeGestureType == GESTURE_SLIDE_UP) {
-                        View v = getViewAtRelativeIndex(mNumActiveViews - 2);
-
-                        if (v != null) {
-                            float r = -(deltaY*1.0f + mTouchSlop) / (mSwipeThreshold);
-                            mYOffset = Math.min((int) Math.round(r*-mSwipeThreshold), 0);
-                            LayoutParams lp = (LayoutParams) v.getLayoutParams();
-                            lp.setVerticalOffset(mYOffset);
-
-                            float alpha = Math.max(0.0f, 1.0f - (1.0f*mYOffset/-mViewHeight));
-                            alpha = Math.min(1.0f, alpha);
-                            v.setAlpha(alpha);
-                        }
-                        return true;
-                    }
-                }
                 break;
             }
             case MotionEvent.ACTION_UP: {
@@ -359,9 +361,7 @@
             }
             case MotionEvent.ACTION_CANCEL: {
                 mActivePointerId = INVALID_POINTER;
-                mGestureComplete = true;
                 mSwipeGestureType = GESTURE_NONE;
-                mYOffset = 0;
                 break;
             }
         }
@@ -427,56 +427,108 @@
             mVelocityTracker = null;
         }
 
-        if (deltaY > mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_DOWN &&
-                !mGestureComplete) {
+        if (deltaY > mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_DOWN) {
             // Swipe threshold exceeded, swipe down
             showNext();
-        } else if (deltaY < -mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_UP &&
-                !mGestureComplete) {
+            mHighlight.bringToFront();
+        } else if (deltaY < -mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_UP) {
             // Swipe threshold exceeded, swipe up
             showPrevious();
-        } else if (mSwipeGestureType == GESTURE_SLIDE_UP && !mGestureComplete) {
+            mHighlight.bringToFront();
+        } else if (mSwipeGestureType == GESTURE_SLIDE_UP) {
             // Didn't swipe up far enough, snap back down
-            View v = getViewAtRelativeIndex(mNumActiveViews - 2);
-            if (v != null) {
-                // Compute the animation duration based on how far they pulled it up
-                LayoutParams lp = (LayoutParams) v.getLayoutParams();
-                int duration = (int) Math.round(
-                        lp.verticalOffset*1.0f/-mViewHeight*DEFAULT_ANIMATION_DURATION);
-                duration = Math.max(MINIMUM_ANIMATION_DURATION, duration);
+            int duration = (int) Math.round(mStackSlider.getYProgress()*DEFAULT_ANIMATION_DURATION);
 
-                // Animate back down
-                PropertyAnimator slideDown = new PropertyAnimator(duration, lp,
-                        "verticalOffset", lp.verticalOffset, 0);
-                slideDown.start();
-                PropertyAnimator fadeIn = new PropertyAnimator(duration, v,
-                        "alpha",v.getAlpha(), 1.0f);
-                fadeIn.start();
-            }
-        } else if (mSwipeGestureType == GESTURE_SLIDE_DOWN && !mGestureComplete) {
+            PropertyAnimator snapBackY = new PropertyAnimator(duration, mStackSlider,
+                    "YProgress", mStackSlider.getYProgress(), 0);
+            snapBackY.start();
+            PropertyAnimator snapBackX = new PropertyAnimator(duration, mStackSlider,
+                    "XProgress", mStackSlider.getXProgress(), 0);
+            snapBackX.start();
+        } else if (mSwipeGestureType == GESTURE_SLIDE_DOWN) {
             // Didn't swipe down far enough, snap back up
-            View v = getViewAtRelativeIndex(mNumActiveViews - 1);
-            if (v != null) {
-                // Compute the animation duration based on how far they pulled it down
-                LayoutParams lp = (LayoutParams) v.getLayoutParams();
-                int duration = (int) Math.round(
-                        (1 - lp.verticalOffset*1.0f/-mViewHeight)*DEFAULT_ANIMATION_DURATION);
-                duration = Math.max(MINIMUM_ANIMATION_DURATION, duration);
-
-                // Animate back up
-                PropertyAnimator slideUp = new PropertyAnimator(duration, lp,
-                        "verticalOffset", lp.verticalOffset, -mViewHeight);
-                slideUp.start();
-                PropertyAnimator fadeOut = new PropertyAnimator(duration, v,
-                        "alpha",v.getAlpha(), 0.0f);
-                fadeOut.start();
-            }
+            int duration = (int) Math.round((1 -
+                    mStackSlider.getYProgress())*DEFAULT_ANIMATION_DURATION);
+            PropertyAnimator snapBackY = new PropertyAnimator(duration, mStackSlider,
+                    "YProgress", mStackSlider.getYProgress(), 1);
+            snapBackY.start();
+            PropertyAnimator snapBackX = new PropertyAnimator(duration, mStackSlider,
+                    "XProgress", mStackSlider.getXProgress(), 0);
+            snapBackX.start();
         }
 
         mActivePointerId = INVALID_POINTER;
-        mGestureComplete = true;
         mSwipeGestureType = GESTURE_NONE;
-        mYOffset = 0;
+    }
+
+    private class StackSlider {
+        View mView;
+        float mYProgress;
+        float mXProgress;
+
+        private float cubic(float r) {
+            return (float) (Math.pow(2*r-1, 3) + 1)/2.0f;
+        }
+
+        private float highlightAlphaInterpolator(float r) {
+            float pivot = 0.4f;
+            if (r < pivot) {
+                return 0.85f*cubic(r/pivot);
+            } else {
+                return 0.85f*cubic(1 - (r-pivot)/(1-pivot));
+            }
+        }
+
+        private float viewAlphaInterpolator(float r) {
+            float pivot = 0.3f;
+            if (r > pivot) {
+                return (r - pivot)/(1 - pivot);
+            } else {
+                return 0;
+            }
+        }
+
+        void setView(View v) {
+            mView = v;
+        }
+
+        public void setYProgress(float r) {
+            // enforce r between 0 and 1
+            r = Math.min(1.0f, r);
+            r = Math.max(0, r);
+
+            mYProgress = r;
+
+            final LayoutParams viewLp = (LayoutParams) mView.getLayoutParams();
+            final LayoutParams highlightLp = (LayoutParams) mHighlight.getLayoutParams();
+
+            viewLp.setVerticalOffset((int) Math.round(-r*mViewHeight));
+            highlightLp.setVerticalOffset((int) Math.round(-r*mViewHeight));
+            mHighlight.setAlpha(highlightAlphaInterpolator(r));
+            mView.setAlpha(viewAlphaInterpolator(1-r));
+        }
+
+        public void setXProgress(float r) {
+            // enforce r between 0 and 1
+            r = Math.min(1.0f, r);
+            r = Math.max(-1.0f, r);
+
+            mXProgress = r;
+
+            final LayoutParams viewLp = (LayoutParams) mView.getLayoutParams();
+            final LayoutParams highlightLp = (LayoutParams) mHighlight.getLayoutParams();
+
+            viewLp.setHorizontalOffset((int) Math.round(r*mViewHeight));
+            highlightLp.setHorizontalOffset((int) Math.round(r*mViewHeight));
+        }
+
+        float getYProgress() {
+            return mYProgress;
+        }
+
+        float getXProgress() {
+            return mXProgress;
+        }
     }
 
     @Override
@@ -484,4 +536,49 @@
         super.onRemoteAdapterConnected();
         setDisplayedChild(mIndex);
     }
+
+    private static final Paint sHolographicPaint = new Paint();
+    private static final Paint sErasePaint = new Paint();
+    private static boolean sPaintsInitialized = false;
+    private static final float STROKE_WIDTH = 3.0f;
+
+    static void initializePaints(Context context) {
+        sHolographicPaint.setColor(0xff6699ff);
+        sHolographicPaint.setFilterBitmap(true);
+        sErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
+        sErasePaint.setFilterBitmap(true);
+        sPaintsInitialized = true;
+    }
+
+    static Bitmap createOutline(View v) {
+        Bitmap bitmap = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(),
+                Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(bitmap);
+
+        canvas.concat(v.getMatrix());
+        v.draw(canvas);
+
+        Bitmap outlineBitmap = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(),
+                Bitmap.Config.ARGB_8888);
+        Canvas outlineCanvas = new Canvas(outlineBitmap);
+        drawOutline(outlineCanvas, v.getMeasuredWidth(), v.getMeasuredHeight(), bitmap);
+        bitmap.recycle();
+        return outlineBitmap;
+    }
+
+    static void drawOutline(Canvas dest, int destWidth, int destHeight, Bitmap src) {
+        dest.drawColor(0, PorterDuff.Mode.CLEAR);
+
+        Bitmap mask = src.extractAlpha();
+        Matrix id = new Matrix();
+
+        Matrix m = new Matrix();
+        float xScale = STROKE_WIDTH*2/(src.getWidth());
+        float yScale = STROKE_WIDTH*2/(src.getHeight());
+        m.preScale(1+xScale, 1+yScale, src.getWidth()/2, src.getHeight()/2);
+        dest.drawBitmap(mask, m, sHolographicPaint);
+
+        dest.drawBitmap(src, id, sErasePaint);
+        mask.recycle();
+    }
 }
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index dd2ad6c..75084db 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -110,6 +110,7 @@
                 com.android.internal.R.id.lower_action_context_bar);
         mAnimatorView = (ViewAnimator) decor.findViewById(
                 com.android.internal.R.id.action_bar_animator);
+        mActionView.setContextView(mUpperContextView);
         
         if (mActionView == null || mUpperContextView == null || mAnimatorView == null) {
             throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index 6a476d0..8918a8e 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -27,6 +27,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.View.MeasureSpec;
 import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -35,9 +36,6 @@
  * @hide
  */
 public class ActionBarContextView extends ViewGroup {
-    // TODO: This must be defined in the default theme
-    private static final int CONTENT_HEIGHT_DIP = 50;
-    
     private int mItemPadding;
     private int mItemMargin;
     private int mActionSpacing;
@@ -75,11 +73,15 @@
                 com.android.internal.R.styleable.Theme_actionModeCloseDrawable);
         mItemMargin = mItemPadding / 2;
 
-        mContentHeight =
-                (int) (CONTENT_HEIGHT_DIP * getResources().getDisplayMetrics().density + 0.5f);
+        mContentHeight = a.getLayoutDimension(
+                com.android.internal.R.styleable.Theme_windowActionBarSize, 0);
         a.recycle();
     }
     
+    public void setHeight(int height) {
+        mContentHeight = height;
+    }
+
     public void setCustomView(View view) {
         if (mCustomView != null) {
             removeView(mCustomView);
@@ -208,8 +210,12 @@
         final int contentWidth = MeasureSpec.getSize(widthMeasureSpec);
         final int itemMargin = mItemPadding;
 
+        int maxHeight = mContentHeight > 0 ?
+                mContentHeight : MeasureSpec.getSize(heightMeasureSpec);
+
+        final int verticalPadding = getPaddingTop() + getPaddingBottom();
         int availableWidth = contentWidth - getPaddingLeft() - getPaddingRight();
-        final int height = mContentHeight - getPaddingTop() - getPaddingBottom();
+        final int height = maxHeight - verticalPadding;
         final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
         
         if (mCloseButton != null) {
@@ -246,7 +252,20 @@
                     MeasureSpec.makeMeasureSpec(customHeight, customHeightMode));
         }
 
-        setMeasuredDimension(contentWidth, mContentHeight);
+        if (mContentHeight <= 0) {
+            int measuredHeight = 0;
+            final int count = getChildCount();
+            for (int i = 0; i < count; i++) {
+                View v = getChildAt(i);
+                int paddedViewHeight = v.getMeasuredHeight() + verticalPadding;
+                if (paddedViewHeight > measuredHeight) {
+                    measuredHeight = paddedViewHeight;
+                }
+            }
+            setMeasuredDimension(contentWidth, measuredHeight);
+        } else {
+            setMeasuredDimension(contentWidth, maxHeight);
+        }
     }
 
     @Override
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 73d3c95..c3c0db2 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -53,7 +53,6 @@
     private static final String TAG = "ActionBarView";
     
     // TODO: This must be defined in the default theme
-    private static final int CONTENT_HEIGHT_DIP = 50;
     private static final int CONTENT_PADDING_DIP = 3;
     private static final int CONTENT_SPACING_DIP = 6;
     private static final int CONTENT_ACTION_SPACING_DIP = 12;
@@ -90,12 +89,17 @@
     private LinearLayout mTabLayout;
     private View mCustomNavView;
     
+    private int mTitleStyleRes;
+    private int mSubtitleStyleRes;
+
     private boolean mShowMenu;
     private boolean mUserTitle;
 
     private MenuBuilder mOptionsMenu;
     private ActionMenuView mMenuView;
     
+    private ActionBarContextView mContextView;
+
     private ActionMenuItem mLogoNavItem;
     
     private NavigationCallback mCallback;
@@ -151,6 +155,9 @@
             setBackgroundDrawable(background);
         }
         
+        mTitleStyleRes = a.getResourceId(R.styleable.ActionBar_titleTextStyle, 0);
+        mSubtitleStyleRes = a.getResourceId(R.styleable.ActionBar_subtitleTextStyle, 0);
+
         final int customNavId = a.getResourceId(R.styleable.ActionBar_customNavigationLayout, 0);
         if (customNavId != 0) {
             LayoutInflater inflater = LayoutInflater.from(context);
@@ -159,11 +166,7 @@
             addView(mCustomNavView);
         }
 
-        final int padding = a.getDimensionPixelSize(R.styleable.ActionBar_padding,
-                (int) (CONTENT_PADDING_DIP * metrics.density + 0.5f));
-        setPadding(padding, padding, padding, padding);
-        mContentHeight = a.getDimensionPixelSize(R.styleable.ActionBar_height,
-                (int) (CONTENT_PADDING_DIP * metrics.density + 0.5f)) - padding * 2;
+        mContentHeight = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
 
         a.recycle();
 
@@ -473,13 +476,22 @@
         mTitleLayout = (LinearLayout) inflater.inflate(R.layout.action_bar_title_item, null);
         mTitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_title);
         mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_subtitle);
+
+        if (mTitleStyleRes != 0) {
+            mTitleView.setTextAppearance(mContext, mTitleStyleRes);
+        }
         if (mTitle != null) {
             mTitleView.setText(mTitle);
         }
+
+        if (mSubtitleStyleRes != 0) {
+            mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes);
+        }
         if (mSubtitle != null) {
             mSubtitleView.setText(mSubtitle);
             mSubtitleView.setVisibility(VISIBLE);
         }
+
         addView(mTitleLayout);
     }
 
@@ -491,6 +503,10 @@
         }
     }
 
+    public void setContextView(ActionBarContextView view) {
+        mContextView = view;
+    }
+
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         int widthMode = MeasureSpec.getMode(widthMeasureSpec);
@@ -506,9 +522,13 @@
         }
 
         int contentWidth = MeasureSpec.getSize(widthMeasureSpec);
+
+        int maxHeight = mContentHeight > 0 ?
+                mContentHeight : MeasureSpec.getSize(heightMeasureSpec);
         
+        final int verticalPadding = getPaddingTop() + getPaddingBottom();
         int availableWidth = contentWidth - getPaddingLeft() - getPaddingRight();
-        final int height = mContentHeight - getPaddingTop() - getPaddingBottom();
+        final int height = maxHeight - verticalPadding;
         final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
 
         if (mLogoView != null && mLogoView.getVisibility() != GONE) {
@@ -561,7 +581,24 @@
             break;
         }
 
-        setMeasuredDimension(contentWidth, mContentHeight);
+        if (mContentHeight <= 0) {
+            int measuredHeight = 0;
+            final int count = getChildCount();
+            for (int i = 0; i < count; i++) {
+                View v = getChildAt(i);
+                int paddedViewHeight = v.getMeasuredHeight() + verticalPadding;
+                if (paddedViewHeight > measuredHeight) {
+                    measuredHeight = paddedViewHeight;
+                }
+            }
+            setMeasuredDimension(contentWidth, measuredHeight);
+        } else {
+            setMeasuredDimension(contentWidth, maxHeight);
+        }
+
+        if (mContextView != null) {
+            mContextView.setHeight(getMeasuredHeight());
+        }
     }
 
     private int measureChildView(View child, int availableWidth, int childSpecHeight, int spacing) {
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
index e1a6737..facda36 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
@@ -67,8 +67,22 @@
         this(context, xmlLayoutResId, 0);
     }
 
+    public PasswordEntryKeyboard(Context context, int xmlLayoutResId, int width, int height) {
+        this(context, xmlLayoutResId, 0, width, height);
+    }
+
     public PasswordEntryKeyboard(Context context, int xmlLayoutResId, int mode) {
         super(context, xmlLayoutResId, mode);
+        init(context);
+    }
+
+    public PasswordEntryKeyboard(Context context, int xmlLayoutResId, int mode,
+            int width, int height) {
+        super(context, xmlLayoutResId, mode, width, height);
+        init(context);
+    }
+
+    private void init(Context context) {
         final Resources res = context.getResources();
         mRes = res;
         mShiftIcon = res.getDrawable(R.drawable.sym_keyboard_shift);
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
index 53720e4..384f7bc 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
@@ -54,10 +54,20 @@
     private Vibrator mVibrator;
 
     public PasswordEntryKeyboardHelper(Context context, KeyboardView keyboardView, View targetView) {
+        this(context, keyboardView, targetView, true);
+    }
+
+    public PasswordEntryKeyboardHelper(Context context, KeyboardView keyboardView, View targetView,
+            boolean useFullScreenWidth) {
         mContext = context;
         mTargetView = targetView;
         mKeyboardView = keyboardView;
-        createKeyboards();
+        if (useFullScreenWidth || mKeyboardView.getLayoutParams().width == -1) {
+            createKeyboards();
+        } else {
+            createKeyboardsWithSpecificSize(mKeyboardView.getLayoutParams().width,
+                    mKeyboardView.getLayoutParams().height);
+        }
         mKeyboardView.setOnKeyboardActionListener(this);
         mVibrator = new Vibrator();
     }
@@ -66,6 +76,29 @@
         return mKeyboardMode == KEYBOARD_MODE_ALPHA;
     }
 
+    private void createKeyboardsWithSpecificSize(int viewWidth, int viewHeight) {
+        mNumericKeyboard = new PasswordEntryKeyboard(mContext, R.xml.password_kbd_numeric,
+                viewWidth, viewHeight);
+        mQwertyKeyboard = new PasswordEntryKeyboard(mContext,
+                R.xml.password_kbd_qwerty, R.id.mode_normal, viewWidth, viewHeight);
+        mQwertyKeyboard.enableShiftLock();
+
+        mQwertyKeyboardShifted = new PasswordEntryKeyboard(mContext,
+                R.xml.password_kbd_qwerty_shifted,
+                R.id.mode_normal, viewWidth, viewHeight);
+        mQwertyKeyboardShifted.enableShiftLock();
+        mQwertyKeyboardShifted.setShifted(true); // always shifted.
+
+        mSymbolsKeyboard = new PasswordEntryKeyboard(mContext, R.xml.password_kbd_symbols,
+                viewWidth, viewHeight);
+        mSymbolsKeyboard.enableShiftLock();
+
+        mSymbolsKeyboardShifted = new PasswordEntryKeyboard(mContext,
+                R.xml.password_kbd_symbols_shift, viewWidth, viewHeight);
+        mSymbolsKeyboardShifted.enableShiftLock();
+        mSymbolsKeyboardShifted.setShifted(true); // always shifted
+    }
+
     private void createKeyboards() {
         mNumericKeyboard = new PasswordEntryKeyboard(mContext, R.xml.password_kbd_numeric);
         mQwertyKeyboard = new PasswordEntryKeyboard(mContext,
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index e4d4850..ca9f371 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -738,7 +738,7 @@
                                         (void*) SkPaintGlue::getStringBounds },
     {"nativeGetCharArrayBounds", "(I[CIILandroid/graphics/Rect;)V",
                                     (void*) SkPaintGlue::getCharArrayBounds },
-    {"setShadowLayer", "(FFFI)V", (void*)SkPaintGlue::setShadowLayer}
+    {"nSetShadowLayer", "(FFFI)V", (void*)SkPaintGlue::setShadowLayer}
 };
 
 static jfieldID req_fieldID(jfieldID id) {
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 9f94af9..4c6eced 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -259,6 +259,7 @@
         OpenGLRenderer* renderer) {
     renderer->resetShader();
     renderer->resetColorFilter();
+    renderer->resetShadow();
 }
 
 static void android_view_GLES20Canvas_setupShader(JNIEnv* env, jobject canvas,
@@ -271,6 +272,11 @@
     renderer->setupColorFilter(filter);
 }
 
+static void android_view_GLES20Canvas_setupShadow(JNIEnv* env, jobject canvas,
+        OpenGLRenderer* renderer, jfloat radius, jfloat dx, jfloat dy, jint color) {
+    renderer->setupShadow(radius, dx, dy, color);
+}
+
 // ----------------------------------------------------------------------------
 // Text
 // ----------------------------------------------------------------------------
@@ -402,6 +408,7 @@
     { "nResetModifiers",    "(I)V",            (void*) android_view_GLES20Canvas_resetModifiers },
     { "nSetupShader",       "(II)V",           (void*) android_view_GLES20Canvas_setupShader },
     { "nSetupColorFilter",  "(II)V",           (void*) android_view_GLES20Canvas_setupColorFilter },
+    { "nSetupShadow",       "(IFFFI)V",        (void*) android_view_GLES20Canvas_setupShadow },
 
     { "nDrawText",          "(I[CIIFFII)V",    (void*) android_view_GLES20Canvas_drawTextArray },
     { "nDrawText",          "(ILjava/lang/String;IIFFII)V",
diff --git a/core/res/res/anim/push_down_in_no_alpha.xml b/core/res/res/anim/push_down_in_no_alpha.xml
new file mode 100644
index 0000000..045d691
--- /dev/null
+++ b/core/res/res/anim/push_down_in_no_alpha.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+	<translate android:fromYDelta="-100%p" android:toYDelta="0"
+            android:duration="@android:integer/config_longAnimTime"/>
+</set>
diff --git a/core/res/res/anim/push_down_out_no_alpha.xml b/core/res/res/anim/push_down_out_no_alpha.xml
new file mode 100644
index 0000000..3c2474a
--- /dev/null
+++ b/core/res/res/anim/push_down_out_no_alpha.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+	<translate android:fromYDelta="0" android:toYDelta="100%p"
+            android:duration="@android:integer/config_longAnimTime"/>
+</set>
diff --git a/core/res/res/drawable-xlarge/ic_lock_idle_alarm.png b/core/res/res/drawable-xlarge/ic_lock_idle_alarm.png
new file mode 100644
index 0000000..336a820
--- /dev/null
+++ b/core/res/res/drawable-xlarge/ic_lock_idle_alarm.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge/ic_lock_idle_charging.png b/core/res/res/drawable-xlarge/ic_lock_idle_charging.png
new file mode 100644
index 0000000..ebef531
--- /dev/null
+++ b/core/res/res/drawable-xlarge/ic_lock_idle_charging.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge/ic_lock_idle_lock.png b/core/res/res/drawable-xlarge/ic_lock_idle_lock.png
new file mode 100644
index 0000000..405e218
--- /dev/null
+++ b/core/res/res/drawable-xlarge/ic_lock_idle_lock.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge/ic_lock_idle_low_battery.png b/core/res/res/drawable-xlarge/ic_lock_idle_low_battery.png
new file mode 100644
index 0000000..f349b63
--- /dev/null
+++ b/core/res/res/drawable-xlarge/ic_lock_idle_low_battery.png
Binary files differ
diff --git a/core/res/res/layout-xlarge/keyguard.xml b/core/res/res/layout-xlarge/keyguard.xml
new file mode 100644
index 0000000..ca629f8
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/layout/keyguard.xml
+**
+** Copyright 2007, 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
+    android:paddingLeft="20dip"
+    android:paddingTop="20dip"
+    android:paddingRight="20dip"
+    android:paddingBottom="20dip"
+    android:orientation="vertical" 
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:background="#ff000000">
+
+    <TextView
+        android:id="@+id/label"
+        android:textSize="16sp" 
+        android:textStyle="bold" 
+        android:textColor="#FFFFFFFF" 
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" 
+        android:text="@string/keyguard_label_text" />
+</LinearLayout>
+
diff --git a/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml b/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml
new file mode 100644
index 0000000..8a46546
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, 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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:background="@android:color/background_dark"
+        >
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="0px"
+        android:layout_weight="1"
+        android:layout_above="@+id/emergencyCall">
+        <RelativeLayout 
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+                >
+        
+            <TextView 
+                android:id="@+id/topHeader"
+                android:layout_width="match_parent"
+                android:layout_height="64dip"
+                android:layout_alignParentTop="true"
+                android:layout_marginLeft="4dip"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:gravity="center_vertical"
+                android:drawableLeft="@drawable/ic_lock_idle_lock"
+                android:drawablePadding="5dip"
+                />
+        
+            <!-- spacer below header -->
+            <View
+                android:id="@+id/spacerTop"
+                android:layout_width="match_parent"
+                android:layout_height="1dip"
+                android:layout_below="@id/topHeader"
+                android:background="@drawable/divider_horizontal_dark"/>
+        
+            <TextView
+                android:id="@+id/instructions"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_below="@+id/spacerTop"
+                android:layout_marginTop="8dip"
+                android:layout_marginLeft="9dip"
+                android:textAppearance="?android:attr/textAppearanceSmall"
+                android:text="@android:string/lockscreen_glogin_instructions"
+                />
+        
+            <EditText
+                android:id="@+id/login"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_below="@id/instructions"
+                android:layout_marginTop="8dip"
+                android:layout_marginLeft="7dip"
+                android:layout_marginRight="7dip"
+                android:hint="@android:string/lockscreen_glogin_username_hint"
+                android:inputType="textEmailAddress"
+                />
+        
+            <EditText
+                android:id="@+id/password"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_below="@id/login"
+                android:layout_marginTop="15dip"
+                android:layout_marginLeft="7dip"
+                android:layout_marginRight="7dip"
+                android:inputType="textPassword"
+                android:hint="@android:string/lockscreen_glogin_password_hint"
+                android:nextFocusRight="@+id/ok"
+                android:nextFocusDown="@+id/ok"
+                />
+        
+            <!-- ok below password, aligned to right of screen -->
+            <Button
+                android:id="@+id/ok"
+                android:layout_width="85dip"
+                android:layout_height="wrap_content"
+                android:layout_below="@id/password"
+                android:layout_marginTop="7dip"
+                android:layout_marginRight="7dip"
+                android:layout_alignParentRight="true"
+                android:text="@android:string/lockscreen_glogin_submit_button"
+                />
+        
+        </RelativeLayout>
+    </ScrollView>
+    
+    <!-- spacer above emergency call -->
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="1dip"
+        android:layout_marginBottom="4dip"
+
+        android:background="@drawable/divider_horizontal_dark"/>
+
+    <!-- emergency call button at bottom center -->
+    <Button
+        android:id="@+id/emergencyCall"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:drawableLeft="@drawable/ic_emergency"
+        android:drawablePadding="8dip"
+        android:text="@android:string/lockscreen_emergency_call"
+        />
+
+</LinearLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_lock.xml b/core/res/res/layout-xlarge/keyguard_screen_lock.xml
new file mode 100644
index 0000000..733a350
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_lock.xml
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, 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.
+*/
+-->
+        
+<!-- This is the general lock screen which shows information about the
+  state of the device, as well as instructions on how to get past it
+  depending on the state of the device.  It is the same for landscape
+  and portrait.-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:gravity="bottom"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#ff800000"
+        >
+
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:layout_marginBottom="15dip"
+        android:layout_marginLeft="15dip"
+        android:layout_marginRight="15dip"
+        android:paddingTop="20dip"
+        android:paddingBottom="20dip"
+        android:background="@android:drawable/popup_full_dark"
+        >
+
+        <!-- when sim is present -->
+        <TextView android:id="@+id/headerSimOk1"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:gravity="center"
+                  android:textSize="34sp"/>
+        <TextView android:id="@+id/headerSimOk2"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:gravity="center"
+                  android:textSize="34sp"/>
+
+        <!-- when sim is missing / locked -->
+        <TextView android:id="@+id/headerSimBad1"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:gravity="center"
+                  android:text="@android:string/lockscreen_missing_sim_message"
+                  android:textAppearance="?android:attr/textAppearanceLarge"/>
+        <TextView android:id="@+id/headerSimBad2"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:layout_marginTop="7dip"
+                  android:layout_marginBottom="7dip"
+                  android:gravity="center"
+                  android:text="@android:string/lockscreen_missing_sim_instructions"
+                  android:textAppearance="?android:attr/textAppearanceSmall"/>
+
+        <!-- spacer after carrier info / sim messages -->
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="1dip"
+            android:layout_marginTop="8dip"
+            android:background="@android:drawable/divider_horizontal_dark"/>
+
+        <!-- time and date -->
+        <TextView android:id="@+id/time"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:gravity="center"
+                  android:textSize="34sp"/>
+
+        <TextView android:id="@+id/date"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:gravity="center"
+                  android:textSize="18sp"/>
+
+        <!-- spacer after time and date -->
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="1dip"
+            android:layout_marginBottom="8dip"
+            android:background="@android:drawable/divider_horizontal_dark"
+                />
+
+        <!-- battery info -->
+        <LinearLayout android:id="@+id/batteryInfo"
+                android:orientation="horizontal"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+              >
+
+            <ImageView android:id="@+id/batteryInfoIcon"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginRight="6dip"
+                android:baselineAligned="true"
+                android:gravity="center"
+            />
+
+            <TextView android:id="@+id/batteryInfoText"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:textSize="18sp"
+                      android:gravity="center"
+            />
+
+        </LinearLayout>
+
+        <!-- spacer after battery info -->
+        <View android:id="@+id/batteryInfoSpacer"
+            android:layout_width="match_parent"
+            android:layout_height="1dip"
+            android:layout_marginTop="8dip"
+            android:layout_marginBottom="8dip"
+            android:background="@android:drawable/divider_horizontal_dark"
+                />
+
+        <!-- next alarm info -->
+
+        <LinearLayout android:id="@+id/nextAlarmInfo"
+                android:orientation="horizontal"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+              >
+
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginRight="6dip"
+                android:baselineAligned="true"
+                android:src="@android:drawable/ic_lock_idle_alarm"
+                android:gravity="center"
+            />
+
+            <TextView android:id="@+id/nextAlarmText"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:textSize="18sp"
+                      android:gravity="center"
+            />
+        </LinearLayout>
+
+        <!-- spacer after alarm info -->
+        <View android:id="@+id/nextAlarmSpacer"
+            android:layout_width="match_parent"
+            android:layout_height="1dip"
+            android:layout_marginTop="8dip"
+            android:layout_marginBottom="8dip"
+            android:background="@android:drawable/divider_horizontal_dark"/>
+
+        <!-- lock icon with 'screen locked' message
+             (shown when SIM card is present) -->
+        <LinearLayout android:id="@+id/screenLockedInfo"
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            >
+
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginRight="6dip"
+                android:baselineAligned="true"
+                android:src="@android:drawable/ic_lock_idle_lock"
+                android:gravity="center"
+            />
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="18sp"
+                android:text="@android:string/lockscreen_screen_locked"
+                android:gravity="center"
+                    />
+        </LinearLayout>
+
+        <!-- message about how to unlock
+             (shown when SIM card is present) -->
+        <TextView android:id="@+id/lockInstructions"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:layout_marginBottom="5dip"
+                  android:gravity="center"
+                  android:textSize="14sp"/>
+
+
+        <!-- emergency call button shown when sim is missing or PUKd -->
+        <Button
+            android:id="@+id/emergencyCallButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="5dip"
+            android:layout_marginTop="5dip"
+            android:layout_gravity="center_horizontal"
+            android:drawableLeft="@drawable/ic_emergency"
+            android:drawablePadding="8dip"
+            android:text="@android:string/lockscreen_emergency_call"
+           />
+
+    </LinearLayout>
+</LinearLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml b/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml
new file mode 100644
index 0000000..c2d87a2
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal"
+        >
+    
+    <!-- left side: status and emergency call button -->
+    <LinearLayout
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:layout_width="0dip"
+            android:orientation="vertical"
+            android:gravity="center_vertical"
+                >
+        <include layout="@layout/keyguard_screen_status_land" />
+    </LinearLayout>
+    
+    <!-- right side: password -->
+    <LinearLayout
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:orientation="vertical"
+        android:layout_weight="1"
+        android:gravity="center">
+
+        <!-- Password entry field -->
+        <EditText android:id="@+id/passwordEntry"
+            android:layout_height="wrap_content"
+            android:layout_width="330dip"
+            android:singleLine="true"
+            android:textStyle="normal"
+            android:inputType="textPassword"
+            android:gravity="center"
+            android:layout_gravity="center"
+            android:textSize="24sp"
+            android:layout_marginTop="120dip"
+            android:layout_marginBottom="5dip"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:background="@drawable/password_field_default"
+            android:textColor="#ffffffff"
+            />
+
+        <!-- Numeric keyboard -->
+        <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
+            android:layout_width="330dip"
+            android:layout_height="260dip"
+            android:background="#00000000"
+            android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+        />
+        <!-- Alphanumeric keyboard -->
+        <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboardAlpha"
+            android:layout_width="450dip"
+            android:layout_height="230dip"
+            android:background="#00000000"
+            android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+        />
+
+        <!-- emergency call button -->
+        <Button
+            android:id="@+id/emergencyCall"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawableLeft="@drawable/ic_emergency"
+            android:drawablePadding="8dip"
+            android:text="@string/lockscreen_emergency_call"
+            android:visibility="gone"
+            style="@style/Widget.Button.Transparent"
+        />
+
+    </LinearLayout>
+</LinearLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml b/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml
new file mode 100644
index 0000000..0927e59
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, 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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+        >
+    
+    <!-- left side: status and emergency call button -->
+    <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="0dip"
+            android:layout_weight="1"
+            android:orientation="vertical"
+            android:gravity="center_vertical"
+                >
+        <include layout="@layout/keyguard_screen_status_land" />
+    </LinearLayout>
+    
+    <!-- right side: password -->
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1"
+        android:orientation="vertical"
+        android:gravity="center">
+
+        <!-- Password entry field -->
+        <EditText android:id="@+id/passwordEntry"
+            android:layout_height="wrap_content"
+            android:layout_width="330dip"
+            android:singleLine="true"
+            android:textStyle="normal"
+            android:inputType="textPassword"
+            android:gravity="center"
+            android:layout_gravity="center"
+            android:textSize="24sp"
+            android:layout_marginTop="120dip"
+            android:layout_marginBottom="5dip"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:background="@drawable/password_field_default"
+            android:textColor="#ffffffff"
+            />
+
+        <!-- Numeric keyboard -->
+        <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
+            android:layout_width="330dip"
+            android:layout_height="260dip"
+            android:background="#00000000"
+            android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+        />
+        <!-- Alphanumeric keyboard -->
+        <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboardAlpha"
+            android:layout_width="450dip"
+            android:layout_height="230dip"
+            android:background="#00000000"
+            android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+        />
+
+        <!-- emergency call button -->
+        <Button
+            android:id="@+id/emergencyCall"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawableLeft="@drawable/ic_emergency"
+            android:drawablePadding="8dip"
+            android:text="@string/lockscreen_emergency_call"
+            android:visibility="gone"
+            style="@style/Widget.Button.Transparent"
+        />
+
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout-xlarge/keyguard_screen_sim_pin_landscape.xml b/core/res/res/layout-xlarge/keyguard_screen_sim_pin_landscape.xml
new file mode 100644
index 0000000..b8cbe51
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_sim_pin_landscape.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, 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:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@android:color/background_dark"
+        >
+
+  
+    <!-- right side -->
+    <!-- header text ('Enter Pin Code') -->
+    <TextView android:id="@+id/headerText"
+        android:layout_above="@+id/carrier"
+        android:layout_centerHorizontal="true"
+        android:layout_marginBottom="30dip"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="24sp"
+            />
+
+    <!-- Carrier info -->
+    <TextView android:id="@+id/carrier"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_above="@+id/pinDisplayGroup"
+        android:layout_marginTop="9dip"
+        android:gravity="left|bottom"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+    />
+
+    <!-- displays dots as user enters pin -->
+    <LinearLayout android:id="@+id/pinDisplayGroup"
+        android:orientation="horizontal"
+        android:layout_centerInParent="true"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:addStatesFromChildren="true"
+        android:gravity="center_vertical"
+        android:baselineAligned="false"
+        android:paddingRight="0dip"
+        android:layout_marginRight="30dip"
+        android:layout_marginLeft="30dip"
+        android:background="@android:drawable/edit_text"
+    >
+
+        <EditText android:id="@+id/pinDisplay"
+            android:layout_width="0dip"
+            android:layout_weight="1"
+            android:layout_height="match_parent"
+            android:maxLines="1"
+            android:background="@null"
+            android:textSize="32sp"
+            android:inputType="textPassword"
+            />
+
+        <ImageButton android:id="@+id/backspace"
+             android:src="@android:drawable/ic_input_delete"
+             android:layout_width="wrap_content"
+             android:layout_height="match_parent"
+             android:layout_marginTop="2dip"
+             android:layout_marginRight="2dip"
+             android:layout_marginBottom="2dip"
+             android:gravity="center"
+            />
+
+    </LinearLayout>
+        
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_alignParentBottom="true"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="8dip"
+        android:layout_marginLeft="8dip"
+        android:layout_marginRight="8dip">
+
+        <Button android:id="@+id/ok"
+            android:text="@android:string/ok"
+            android:layout_alignParentBottom="true"
+            android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1.0"
+            android:layout_marginBottom="8dip"
+            android:layout_marginRight="8dip"
+            android:textSize="18sp"
+            />
+
+        <Button android:id="@+id/emergencyCall"
+            android:text="@android:string/lockscreen_emergency_call"
+            android:layout_alignParentBottom="true"
+            android:layout_centerHorizontal="true"
+            android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1.0"
+            android:layout_marginBottom="8dip"
+            android:layout_marginLeft="8dip"
+            android:textSize="18sp"
+            android:drawableLeft="@drawable/ic_emergency"
+            android:drawablePadding="8dip"
+        />
+    </LinearLayout>
+
+</RelativeLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_sim_pin_portrait.xml b/core/res/res/layout-xlarge/keyguard_screen_sim_pin_portrait.xml
new file mode 100644
index 0000000..009148f
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_sim_pin_portrait.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, 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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:background="@android:color/background_dark"
+    android:gravity="center_horizontal">
+
+    <LinearLayout android:id="@+id/topDisplayGroup"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <!-- header text ('Enter Pin Code') -->
+        <TextView android:id="@+id/headerText"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:singleLine="true"
+            android:textAppearance="?android:attr/textAppearanceLarge"/>
+
+        <!-- Carrier info -->
+        <TextView android:id="@+id/carrier"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="9dip"
+            android:gravity="center"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:textAppearance="?android:attr/textAppearanceMedium"/>
+
+        <!-- password entry -->
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:layout_marginRight="6dip"
+            android:layout_marginLeft="6dip"
+            android:gravity="center_vertical"
+            android:background="@android:drawable/edit_text">
+
+            <!-- displays dots as user enters pin -->
+            <TextView android:id="@+id/pinDisplay"
+                android:layout_width="0dip"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:maxLines="1"
+                android:textAppearance="?android:attr/textAppearanceLargeInverse"
+                android:textStyle="bold"
+                android:inputType="textPassword"
+            />
+
+            <ImageButton android:id="@+id/backspace"
+                android:src="@android:drawable/ic_input_delete"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginRight="-3dip"
+                android:layout_marginBottom="-3dip"
+            />
+        </LinearLayout>
+
+    </LinearLayout>
+
+    <include
+        android:id="@+id/keyPad"
+        layout="@android:layout/twelve_key_entry"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/topDisplayGroup"
+        android:layout_marginTop="10dip"
+    />
+
+    <!-- spacer below keypad -->
+    <View
+        android:id="@+id/spacerBottom"
+        android:layout_width="match_parent"
+        android:layout_height="1dip"
+        android:layout_marginTop="6dip"
+        android:layout_above="@id/emergencyCall"
+        android:background="@android:drawable/divider_horizontal_dark"
+    />
+
+    <!-- The emergency button should take the rest of the space and be centered vertically -->
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1"
+        android:gravity="center"
+        android:orientation="vertical">
+
+        <!-- emergency call button -->
+        <Button
+            android:id="@+id/emergencyCall"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawableLeft="@android:drawable/ic_emergency"
+            android:drawablePadding="8dip"
+            android:text="@android:string/lockscreen_emergency_call"
+        />
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_status_land.xml b/core/res/res/layout-xlarge/keyguard_screen_status_land.xml
new file mode 100644
index 0000000..8589862
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_status_land.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 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.
+*/
+-->
+
+<!-- Status to show on the left side of lock screen -->
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="140dip"
+        android:layout_marginTop="20dip"
+        android:gravity="left"
+        >
+
+    <TextView
+        android:id="@+id/carrier"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="17sp"
+        android:drawablePadding="4dip"
+        android:layout_marginTop="32dip"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        />
+
+    <com.android.internal.widget.DigitalClock android:id="@+id/time"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentLeft="true"
+        android:layout_marginTop="8dip"
+        android:layout_marginBottom="8dip"
+        >
+
+        <TextView android:id="@+id/timeDisplay"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            android:ellipsize="none"
+            android:textSize="120sp"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:shadowColor="#C0000000"
+            android:shadowDx="0"
+            android:shadowDy="0"
+            android:shadowRadius="3.0"
+            android:layout_marginBottom="6dip"
+            />
+
+
+        <TextView android:id="@+id/am_pm"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toRightOf="@id/timeDisplay"
+            android:layout_alignBaseline="@id/timeDisplay"
+            android:singleLine="true"
+            android:ellipsize="none"
+            android:textSize="30sp"
+            android:layout_marginLeft="8dip"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:shadowColor="#C0000000"
+            android:shadowDx="0"
+            android:shadowDy="0"
+            android:shadowRadius="3.0"
+            />
+
+    </com.android.internal.widget.DigitalClock>
+
+    <TextView
+        android:id="@+id/date"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/time"
+        android:layout_marginTop="5dip"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="32sp"
+        />
+
+    <!-- used for instructions such as "draw pattern to unlock", the next alarm, and charging
+         status.  -->
+    <TextView
+        android:id="@+id/status2"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="32sp"
+        android:layout_marginTop="50dip"
+        android:drawablePadding="4dip"
+        />
+    <TextView
+        android:id="@+id/status1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="15dip"
+        android:textSize="32sp"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        />
+        
+    <TextView
+        android:id="@+id/propertyOf"
+        android:lineSpacingExtra="8dip"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="22sp"
+        android:layout_marginTop="50dip"
+        android:singleLine="false"
+        android:visibility="invisible"
+        />
+</LinearLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_status_port.xml b/core/res/res/layout-xlarge/keyguard_screen_status_port.xml
new file mode 100644
index 0000000..8589862
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_status_port.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 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.
+*/
+-->
+
+<!-- Status to show on the left side of lock screen -->
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="140dip"
+        android:layout_marginTop="20dip"
+        android:gravity="left"
+        >
+
+    <TextView
+        android:id="@+id/carrier"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="17sp"
+        android:drawablePadding="4dip"
+        android:layout_marginTop="32dip"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        />
+
+    <com.android.internal.widget.DigitalClock android:id="@+id/time"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentLeft="true"
+        android:layout_marginTop="8dip"
+        android:layout_marginBottom="8dip"
+        >
+
+        <TextView android:id="@+id/timeDisplay"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            android:ellipsize="none"
+            android:textSize="120sp"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:shadowColor="#C0000000"
+            android:shadowDx="0"
+            android:shadowDy="0"
+            android:shadowRadius="3.0"
+            android:layout_marginBottom="6dip"
+            />
+
+
+        <TextView android:id="@+id/am_pm"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toRightOf="@id/timeDisplay"
+            android:layout_alignBaseline="@id/timeDisplay"
+            android:singleLine="true"
+            android:ellipsize="none"
+            android:textSize="30sp"
+            android:layout_marginLeft="8dip"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:shadowColor="#C0000000"
+            android:shadowDx="0"
+            android:shadowDy="0"
+            android:shadowRadius="3.0"
+            />
+
+    </com.android.internal.widget.DigitalClock>
+
+    <TextView
+        android:id="@+id/date"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/time"
+        android:layout_marginTop="5dip"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="32sp"
+        />
+
+    <!-- used for instructions such as "draw pattern to unlock", the next alarm, and charging
+         status.  -->
+    <TextView
+        android:id="@+id/status2"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="32sp"
+        android:layout_marginTop="50dip"
+        android:drawablePadding="4dip"
+        />
+    <TextView
+        android:id="@+id/status1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="15dip"
+        android:textSize="32sp"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        />
+        
+    <TextView
+        android:id="@+id/propertyOf"
+        android:lineSpacingExtra="8dip"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="22sp"
+        android:layout_marginTop="50dip"
+        android:singleLine="false"
+        android:visibility="invisible"
+        />
+</LinearLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_tab_unlock.xml b/core/res/res/layout-xlarge/keyguard_screen_tab_unlock.xml
new file mode 100644
index 0000000..4761800
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_tab_unlock.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** 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.
+*/
+-->
+
+<!-- This is the general lock screen which shows information about the
+  state of the device, as well as instructions on how to get past it
+  depending on the state of the device.  It is the same for landscape
+  and portrait.-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tabunlock="http://schemas.android.com/apk/res/com.android.tabunlock"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#70000000"
+    android:gravity="center_horizontal"
+    android:id="@+id/root">
+
+    <!-- left side: status and emergency call button -->
+    <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="0dip"
+            android:layout_weight="1"
+            android:orientation="vertical"
+            android:gravity="center_vertical"
+                >
+        <include layout="@layout/keyguard_screen_status_land" />
+    </LinearLayout>
+
+    <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="0dip"
+            android:layout_weight="1"
+            android:orientation="vertical"
+                >
+        <TextView
+            android:id="@+id/screenLocked"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/status2"
+            android:layout_marginLeft="24dip"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:layout_marginTop="12dip"
+            android:drawablePadding="4dip"
+            />
+
+        <com.android.internal.widget.SlidingTab
+            android:id="@+id/tab_selector"
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            android:layout_marginBottom="80dip"
+            />
+
+        <!-- "emergency calls only" shown when sim is missing or PUKd -->
+        <TextView
+            android:id="@+id/emergencyCallText"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/carrier"
+            android:layout_alignParentRight="true"
+            android:layout_marginTop="0dip"
+            android:layout_marginRight="8dip"
+            android:text="@string/emergency_calls_only"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textColor="@color/white"
+           />
+
+        <!-- emergency call button shown when sim is PUKd and tab_selector is
+             hidden -->
+        <Button
+            android:id="@+id/emergencyCallButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawableLeft="@drawable/ic_emergency"
+            android:layout_centerInParent="true"
+            android:layout_alignParentBottom="true"
+            android:layout_marginBottom="80dip"
+            style="@style/Widget.Button.Transparent"
+            android:drawablePadding="8dip"
+            android:visibility="gone"
+            />
+    </LinearLayout>
+
+</RelativeLayout>
+
diff --git a/core/res/res/layout-xlarge/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout-xlarge/keyguard_screen_tab_unlock_land.xml
new file mode 100644
index 0000000..bb398f6
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_tab_unlock_land.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** 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.
+*/
+-->
+
+<!-- This is the general lock screen which shows information about the
+  state of the device, as well as instructions on how to get past it
+  depending on the state of the device.-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tabunlock="http://schemas.android.com/apk/res/com.android.tabunlock"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal"
+    android:background="#70000000"
+    android:id="@+id/root">
+
+    <!-- left side: status and emergency call button -->
+    <LinearLayout
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:layout_width="0dip"
+            android:orientation="vertical"
+            android:gravity="center_vertical"
+                >
+        <include layout="@layout/keyguard_screen_status_land" />
+    </LinearLayout>
+
+    <!-- right side -->
+    <LinearLayout
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:layout_width="0dip"
+            android:orientation="horizontal"
+            android:gravity="center_horizontal"
+                >
+        <TextView
+                android:id="@+id/screenLocked"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_below="@id/status2"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:gravity="center"
+                android:layout_marginTop="12dip"
+                android:drawablePadding="4dip"
+                />
+
+        <com.android.internal.widget.SlidingTab
+            android:id="@+id/tab_selector"
+            android:orientation="vertical"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_marginRight="0dip"
+            android:layout_weight="1.0"
+            />
+            
+        <!-- "emergency calls only" shown when sim is missing or PUKd -->
+        <TextView
+            android:id="@+id/emergencyCallText"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentTop="true"
+            android:layout_marginTop="20dip"
+            android:text="@string/emergency_calls_only"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textColor="@color/white"
+               />
+
+        <!-- emergency call button shown when sim is PUKd and tab_selector is
+             hidden -->
+        <Button
+            android:id="@+id/emergencyCallButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawableLeft="@drawable/ic_emergency"
+            style="@style/Widget.Button.Transparent"
+            android:drawablePadding="8dip"
+            android:layout_marginRight="80dip"
+            android:visibility="gone"
+            />
+
+    </LinearLayout>
+</LinearLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_unlock_landscape.xml b/core/res/res/layout-xlarge/keyguard_screen_unlock_landscape.xml
new file mode 100644
index 0000000..42636ad
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_unlock_landscape.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<!-- This is the screen that shows the 9 circle unlock widget and instructs
+     the user how to unlock their device, or make an emergency call.  This
+     is the portrait layout.  -->
+
+<com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+        >
+
+    <!-- left side: status and emergency call button -->
+    <LinearLayout
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:layout_width="0dip"
+            android:orientation="vertical"
+            android:gravity="center_vertical"
+                >
+        
+        <include layout="@layout/keyguard_screen_status_land" />
+
+        <!-- footer -->
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="140dip"
+            >
+
+            <!-- option 1: a single emergency call button -->
+            <RelativeLayout android:id="@+id/footerNormal"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="left"
+                >
+                <Button android:id="@+id/emergencyCallAlone"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/lockscreen_emergency_call"
+                    style="@style/Widget.Button.Transparent"
+                    android:drawableLeft="@drawable/ic_emergency"
+                    android:drawablePadding="8dip"
+                    android:visibility="gone"
+                    />
+            </RelativeLayout>
+
+            <!-- option 2: an emergency call button, and a 'forgot pattern?' button -->
+            <LinearLayout android:id="@+id/footerForgotPattern"
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="left"
+                >
+                <Button android:id="@+id/forgotPattern"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    style="@style/Widget.Button.Transparent"
+                    />
+                <Button android:id="@+id/emergencyCallTogether"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/lockscreen_emergency_call"
+                    style="@style/Widget.Button.Transparent"
+                    android:drawableLeft="@drawable/ic_emergency"
+                    android:drawablePadding="8dip"
+                    android:visibility="gone"
+                    />
+            </LinearLayout>
+        </FrameLayout>
+    </LinearLayout>
+
+    <!-- right side: lock pattern -->
+    <LinearLayout
+        android:layout_weight="1"
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        >
+        <com.android.internal.widget.LockPatternView android:id="@+id/lockPattern"
+            android:layout_width="350dip"
+            android:layout_height="350dip"
+            android:layout_marginTop="90dip"
+            android:layout_marginRight="90dip"
+          />
+    </LinearLayout>
+
+</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_unlock_portrait.xml b/core/res/res/layout-xlarge/keyguard_screen_unlock_portrait.xml
new file mode 100644
index 0000000..aeed79b
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_unlock_portrait.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+        >
+
+    <!-- left side: status and emergency call button -->
+    <LinearLayout
+            android:layout_height="0dip"
+            android:layout_weight="1"
+            android:layout_width="match_parent"
+            android:orientation="vertical"
+            android:gravity="center_vertical"
+                >
+        
+        <include layout="@layout/keyguard_screen_status_port" />
+
+        <!-- footer -->
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="140dip"
+            >
+
+            <!-- option 1: a single emergency call button -->
+            <RelativeLayout android:id="@+id/footerNormal"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="left"
+                >
+                <Button android:id="@+id/emergencyCallAlone"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/lockscreen_emergency_call"
+                    style="@style/Widget.Button.Transparent"
+                    android:drawableLeft="@drawable/ic_emergency"
+                    android:drawablePadding="8dip"
+                    android:visibility="gone"
+                    />
+            </RelativeLayout>
+
+            <!-- option 2: an emergency call button, and a 'forgot pattern?' button -->
+            <LinearLayout android:id="@+id/footerForgotPattern"
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="left"
+                >
+                <Button android:id="@+id/forgotPattern"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    style="@style/Widget.Button.Transparent"
+                    />
+                <Button android:id="@+id/emergencyCallTogether"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/lockscreen_emergency_call"
+                    style="@style/Widget.Button.Transparent"
+                    android:drawableLeft="@drawable/ic_emergency"
+                    android:drawablePadding="8dip"
+                    android:visibility="gone"
+                    />
+            </LinearLayout>
+        </FrameLayout>
+    </LinearLayout>
+
+    <!-- right side: lock pattern -->
+    <LinearLayout
+        android:layout_weight="1"
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:gravity="center"
+        >
+        <com.android.internal.widget.LockPatternView android:id="@+id/lockPattern"
+            android:layout_width="350dip"
+            android:layout_height="350dip"
+            android:layout_marginTop="50dip"
+          />
+    </LinearLayout>
+
+</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>
+
diff --git a/core/res/res/layout-xlarge/screen_action_bar.xml b/core/res/res/layout-xlarge/screen_action_bar.xml
index 41ce8e4..30a73184 100644
--- a/core/res/res/layout-xlarge/screen_action_bar.xml
+++ b/core/res/res/layout-xlarge/screen_action_bar.xml
@@ -24,8 +24,8 @@
     <ViewAnimator android:id="@+id/action_bar_animator"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:inAnimation="@anim/push_down_in"
-        android:outAnimation="@anim/push_down_out">
+        android:inAnimation="@anim/push_down_in_no_alpha"
+        android:outAnimation="@anim/push_down_out_no_alpha">
         <com.android.internal.widget.ActionBarView
             android:id="@+id/action_bar"
             android:layout_width="match_parent"
diff --git a/core/res/res/layout-xlarge/screen_action_bar_overlay.xml b/core/res/res/layout-xlarge/screen_action_bar_overlay.xml
index d0277f0..cb35ac1 100644
--- a/core/res/res/layout-xlarge/screen_action_bar_overlay.xml
+++ b/core/res/res/layout-xlarge/screen_action_bar_overlay.xml
@@ -28,8 +28,8 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:gravity="top"
-        android:inAnimation="@anim/push_down_in"
-        android:outAnimation="@anim/push_down_out">
+        android:inAnimation="@anim/push_down_in_no_alpha"
+        android:outAnimation="@anim/push_down_out_no_alpha">
         <com.android.internal.widget.ActionBarView
             android:id="@+id/action_bar"
             android:layout_width="match_parent"
@@ -41,6 +41,7 @@
             android:layout_height="wrap_content" />
     </ViewAnimator>
     <ImageView android:src="?android:attr/windowContentOverlay"
+               android:scaleType="fitXY"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/action_bar_animator" />
diff --git a/core/res/res/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml
index ab675c7..3d52f71 100644
--- a/core/res/res/layout/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_password_landscape.xml
@@ -28,7 +28,7 @@
         android:layout_height="wrap_content"
         android:orientation="horizontal">
         <!-- "Enter PIN(Password) to unlock" -->
-        <TextView android:id="@+id/enter_password_label"
+        <TextView android:id="@+id/status1"
             android:layout_width="0dip"
             android:layout_height="wrap_content"
             android:layout_weight="1"
diff --git a/core/res/res/layout/keyguard_screen_password_portrait.xml b/core/res/res/layout/keyguard_screen_password_portrait.xml
index 9ee8781..af8a3ef 100644
--- a/core/res/res/layout/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_password_portrait.xml
@@ -24,7 +24,7 @@
     android:gravity="center_horizontal">
 
     <!-- "Enter PIN(Password) to unlock" -->
-    <TextView android:id="@+id/enter_password_label"
+    <TextView android:id="@+id/status1"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal"
diff --git a/core/res/res/layout/screen_action_bar.xml b/core/res/res/layout/screen_action_bar.xml
index f39852b..3c44b8c 100644
--- a/core/res/res/layout/screen_action_bar.xml
+++ b/core/res/res/layout/screen_action_bar.xml
@@ -24,8 +24,8 @@
     <ViewAnimator android:id="@+id/action_bar_animator"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:inAnimation="@anim/push_down_in"
-        android:outAnimation="@anim/push_down_out">
+        android:inAnimation="@anim/push_down_in_no_alpha"
+        android:outAnimation="@anim/push_down_out_no_alpha">
         <com.android.internal.widget.ActionBarView
             android:id="@+id/action_bar"
             android:layout_width="match_parent"
diff --git a/core/res/res/layout/screen_action_bar_overlay.xml b/core/res/res/layout/screen_action_bar_overlay.xml
index cb1ffc5..c854c6f 100644
--- a/core/res/res/layout/screen_action_bar_overlay.xml
+++ b/core/res/res/layout/screen_action_bar_overlay.xml
@@ -28,8 +28,8 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:gravity="top"
-        android:inAnimation="@anim/push_down_in"
-        android:outAnimation="@anim/push_down_out">
+        android:inAnimation="@anim/push_down_in_no_alpha"
+        android:outAnimation="@anim/push_down_out_no_alpha">
         <com.android.internal.widget.ActionBarView
             android:id="@+id/action_bar"
             android:layout_width="match_parent"
@@ -41,6 +41,7 @@
             android:layout_height="wrap_content" />
     </ViewAnimator>
     <ImageView android:src="?android:attr/windowContentOverlay"
+               android:scaleType="fitXY"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/action_bar_animator" />
diff --git a/core/res/res/values-xlarge/config.xml b/core/res/res/values-xlarge/config.xml
index c5a53b2..e92ed11 100644
--- a/core/res/res/values-xlarge/config.xml
+++ b/core/res/res/values-xlarge/config.xml
@@ -24,5 +24,10 @@
          interface.  This name is in the ComponentName flattened format (package/class)  -->
     <string name="config_statusBarComponent">com.android.systemui/com.android.systemui.statusbar.tablet.TabletStatusBarService</string>
     <bool name="config_statusBarCanHide">false</bool>
+
+    <!-- Show sliding tab before lockscreen -->
+    <bool name="config_enableSlidingTabFirst">false</bool>
+    <!-- Enable lockscreen rotation -->
+    <bool name="config_enableLockScreenRotation">true</bool>
 </resources>
 
diff --git a/core/res/res/values-xlarge/dimens.xml b/core/res/res/values-xlarge/dimens.xml
index b3fdf46..bc1ae58 100644
--- a/core/res/res/values-xlarge/dimens.xml
+++ b/core/res/res/values-xlarge/dimens.xml
@@ -22,5 +22,10 @@
     <!-- Height of the status bar -->
     <dimen name="status_bar_icon_size">50dip</dimen>
     <!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
+    
+    <!-- Default height of a key in the password keyboard for alpha -->
+    <dimen name="password_keyboard_key_height_alpha">0.35in</dimen>
+    <!-- Default height of a key in the password keyboard for numeric -->
+    <dimen name="password_keyboard_key_height_numeric">0.47in</dimen>
 </resources>
 
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index a75f1a6..e0608f9 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -256,6 +256,12 @@
         <!-- Reference to a style for the Action Bar -->
         <attr name="windowActionBarStyle" format="reference" />
 
+        <!-- Size of the Action Bar, including the contextual
+             bar used to present Action Modes. -->
+        <attr name="windowActionBarSize" format="dimension" >
+            <enum name="wrap_content" value="0" />
+        </attr>
+
         <!-- Flag indicating whether action modes should overlay window content
              when there is not reserved space for their UI (such as an Action Bar). -->
         <attr name="windowActionModeOverlay" format="boolean" />
@@ -1005,6 +1011,7 @@
         <attr name="windowActionBarStyle" />
         <attr name="windowActionModeOverlay" />
         <attr name="windowActionBarOverlay" />
+        <attr name="windowActionBarSize" />
     </declare-styleable>
 
     <!-- The set of attributes that describe a AlertDialog's theme. -->
@@ -4003,8 +4010,6 @@
         <attr name="customNavigationLayout" format="reference" />
         <!-- Specifies a fixed height. -->
         <attr name="height" />
-        <!-- Specifies padding around all sides. -->
-        <attr name="padding" />
     </declare-styleable>
 
 </resources>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index b6af6b2..a2316e0 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -18,8 +18,8 @@
 */
 -->
 <resources>
-	<drawable name="screen_background_light">#ffffffff</drawable>
-	<drawable name="screen_background_dark">#ff000000</drawable>
+	<drawable name="screen_background_light">#ffefefef</drawable>
+	<drawable name="screen_background_dark">#ff101010</drawable>
     <drawable name="status_bar_closed_default_background">#ff000000</drawable>
     <drawable name="status_bar_opened_default_background">#ff000000</drawable>
     <drawable name="search_bar_default_color">#ff000000</drawable>
@@ -36,18 +36,18 @@
     <color name="white">#ffffffff</color>
     <color name="black">#ff000000</color>
     <color name="transparent">#00000000</color>
-    <color name="background_dark">#ff000000</color>
-    <color name="bright_foreground_dark">#ffffffff</color>
+    <color name="background_dark">#ff101010</color>
+    <color name="bright_foreground_dark">#ffefefef</color>
     <color name="bright_foreground_dark_disabled">#80ffffff</color>
-    <color name="bright_foreground_dark_inverse">#ff000000</color>
+    <color name="bright_foreground_dark_inverse">@android:color/background_dark</color>
     <color name="dim_foreground_dark">#bebebe</color>
     <color name="dim_foreground_dark_disabled">#80bebebe</color>
     <color name="dim_foreground_dark_inverse">#323232</color>
     <color name="dim_foreground_dark_inverse_disabled">#80323232</color>
     <color name="hint_foreground_dark">#808080</color>
-    <color name="background_light">#ffffffff</color>
-    <color name="bright_foreground_light">#ff000000</color>
-    <color name="bright_foreground_light_inverse">#ffffffff</color>
+    <color name="background_light">@android:color/bright_foreground_dark</color>
+    <color name="bright_foreground_light">@android:color/background_dark</color>
+    <color name="bright_foreground_light_inverse">@android:color/bright_foreground_dark</color>
     <color name="bright_foreground_light_disabled">#80000000</color>
     <color name="dim_foreground_light">#323232</color>
     <color name="dim_foreground_light_disabled">#80323232</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index cf2b423..91e9a92 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -272,6 +272,12 @@
     <!-- Allow the menu hard key to be disabled in LockScreen on some devices -->
     <bool name="config_disableMenuKeyInLockScreen">false</bool>
 
+    <!-- Show sliding tab before lockscreen -->
+    <bool name="config_enableSlidingTabFirst">true</bool>
+
+    <!-- Diable lockscreen rotation by default -->
+    <bool name="config_enableLockScreenRotation">false</bool>
+
     <!-- Array of light sensor LUX values to define our levels for auto backlight brightness support.
          The N entries of this array define N + 1 zones as follows:
 
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 679e642..fdafaf1 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -41,8 +41,10 @@
     <dimen name="fastscroll_thumb_width">64dp</dimen>
     <!-- Height of the fastscroll thumb -->
     <dimen name="fastscroll_thumb_height">52dp</dimen>
-    <!-- Default height of a key in the password keyboard -->
-    <dimen name="password_keyboard_key_height">56dip</dimen>
+    <!-- Default height of a key in the password keyboard for alpha -->
+    <dimen name="password_keyboard_key_height_alpha">56dip</dimen>
+    <!-- Default height of a key in the password keyboard for numeric -->
+    <dimen name="password_keyboard_key_height_numeric">56dip</dimen>
     <!-- Default correction for the space key in the password keyboard -->
     <dimen name="password_keyboard_spacebar_vertical_correction">4dip</dimen>
     <!-- Distance between the text base line and virtual finger position used to position cursor -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 539f1c0..b84a613 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1320,6 +1320,8 @@
   <public type="attr" name="fragmentOpenExitAnimation" />
   <public type="attr" name="fragmentCloseEnterAnimation" />
   <public type="attr" name="fragmentCloseExitAnimation" />
+  <public type="attr" name="windowActionBarSize" />
+
   <public type="anim" name="animator_fade_in" />
   <public type="anim" name="animator_fade_out" />
 
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 7e52ebd..2ae3ccd 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -893,8 +893,11 @@
         <item name="android:background">@android:drawable/action_bar_background</item>
         <item name="android:displayOptions">useLogo</item>
         <item name="android:divider">@android:drawable/action_bar_divider</item>
-        <item name="android:height">56dip</item>
-        <item name="android:padding">3dip</item>
+        <item name="android:height">?android:attr/windowActionBarSize</item>
+        <item name="android:paddingLeft">3dip</item>
+        <item name="android:paddingTop">3dip</item>
+        <item name="android:paddingRight">3dip</item>
+        <item name="android:paddingBottom">3dip</item>
     </style>
 
     <style name="Widget.ActionButton">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 3348b4e..f9e20f7 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -118,6 +118,7 @@
         <item name="windowActionBar">false</item>
         <item name="windowActionModeOverlay">false</item>
         <item name="windowActionBarStyle">@android:style/ActionBar</item>
+        <item name="windowActionBarSize">50dip</item>
 
         <!-- Dialog attributes -->
         <item name="alertDialogStyle">@android:style/AlertDialog</item>
diff --git a/core/res/res/xml-land/password_kbd_qwerty.xml b/core/res/res/xml-land/password_kbd_qwerty.xml
index 700c527..fd8bd49 100755
--- a/core/res/res/xml-land/password_kbd_qwerty.xml
+++ b/core/res/res/xml-land/password_kbd_qwerty.xml
@@ -22,7 +22,7 @@
     android:keyWidth="10%p"
     android:horizontalGap="0px"
     android:verticalGap="0px"
-    android:keyHeight="@dimen/password_keyboard_key_height"
+    android:keyHeight="@dimen/password_keyboard_key_height_alpha"
     >
 
     <Row>
diff --git a/core/res/res/xml-land/password_kbd_qwerty_shifted.xml b/core/res/res/xml-land/password_kbd_qwerty_shifted.xml
index 1e37b6c..9ff6fd7 100755
--- a/core/res/res/xml-land/password_kbd_qwerty_shifted.xml
+++ b/core/res/res/xml-land/password_kbd_qwerty_shifted.xml
@@ -22,7 +22,7 @@
     android:keyWidth="10%p"
     android:horizontalGap="0px"
     android:verticalGap="0px"
-    android:keyHeight="@dimen/password_keyboard_key_height"
+    android:keyHeight="@dimen/password_keyboard_key_height_alpha"
     >
 
     <Row>
diff --git a/core/res/res/xml-mdpi/password_kbd_qwerty.xml b/core/res/res/xml-mdpi/password_kbd_qwerty.xml
index bae1b42..82a7c75 100755
--- a/core/res/res/xml-mdpi/password_kbd_qwerty.xml
+++ b/core/res/res/xml-mdpi/password_kbd_qwerty.xml
@@ -22,7 +22,7 @@
     android:keyWidth="10%p"
     android:horizontalGap="0px"
     android:verticalGap="0px"
-    android:keyHeight="@dimen/password_keyboard_key_height"
+    android:keyHeight="@dimen/password_keyboard_key_height_alpha"
     >
 
     <Row>
diff --git a/core/res/res/xml-mdpi/password_kbd_qwerty_shifted.xml b/core/res/res/xml-mdpi/password_kbd_qwerty_shifted.xml
index 612df9c..9fff3cc 100755
--- a/core/res/res/xml-mdpi/password_kbd_qwerty_shifted.xml
+++ b/core/res/res/xml-mdpi/password_kbd_qwerty_shifted.xml
@@ -22,7 +22,7 @@
     android:keyWidth="10%p"
     android:horizontalGap="0px"
     android:verticalGap="0px"
-    android:keyHeight="@dimen/password_keyboard_key_height"
+    android:keyHeight="@dimen/password_keyboard_key_height_alpha"
     >
 
     <Row>
diff --git a/core/res/res/xml-xlarge/password_kbd_qwerty.xml b/core/res/res/xml-xlarge/password_kbd_qwerty.xml
new file mode 100755
index 0000000..0a35040
--- /dev/null
+++ b/core/res/res/xml-xlarge/password_kbd_qwerty.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
+    android:keyWidth="10%p"
+    android:horizontalGap="0px"
+    android:verticalGap="0px"
+    android:keyHeight="@dimen/password_keyboard_key_height_alpha"
+    >
+
+    <Row android:rowEdgeFlags="top">
+        <Key android:keyLabel="1" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="2"/>
+        <Key android:keyLabel="3"/>
+        <Key android:keyLabel="4"/>
+        <Key android:keyLabel="5"/>
+        <Key android:keyLabel="6"/>
+        <Key android:keyLabel="7"/>
+        <Key android:keyLabel="8"/>
+        <Key android:keyLabel="9"/>
+        <Key android:keyLabel="0" android:keyEdgeFlags="right"/>
+    </Row>
+
+    <Row>
+        <Key android:keyLabel="q" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="w"/>
+        <Key android:keyLabel="e"/>
+        <Key android:keyLabel="r"/>
+        <Key android:keyLabel="t"/>
+        <Key android:keyLabel="y"/>
+        <Key android:keyLabel="u"/>
+        <Key android:keyLabel="i"/>
+        <Key android:keyLabel="o"/>
+        <Key android:keyLabel="p" android:keyEdgeFlags="right"/>
+    </Row>
+
+    <Row>
+        <Key android:keyLabel="a" android:horizontalGap="5%p"
+            android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="s"/>
+        <Key android:keyLabel="d"/>
+        <Key android:keyLabel="f"/>
+        <Key android:keyLabel="g"/>
+        <Key android:keyLabel="h"/>
+        <Key android:keyLabel="j"/>
+        <Key android:keyLabel="k"/>
+        <Key android:keyLabel="l" android:keyEdgeFlags="right"/>
+    </Row>
+
+    <Row>
+        <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
+            android:keyWidth="15%p" android:isModifier="true"
+            android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+            android:isSticky="true" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="z"/>
+        <Key android:keyLabel="x"/>
+        <Key android:keyLabel="c"/>
+        <Key android:keyLabel="v"/>
+        <Key android:keyLabel="b"/>
+        <Key android:keyLabel="n"/>
+        <Key android:keyLabel="m"/>
+        <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
+            android:keyWidth="15%p" android:keyEdgeFlags="right"
+            android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+            android:isRepeatable="true"/>
+    </Row>
+
+    <Row android:keyboardMode="@+id/mode_normal" android:rowEdgeFlags="bottom">
+        <Key android:codes="-2" android:keyLabel="@string/password_keyboard_label_symbol_key"
+            android:keyWidth="20%p" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="," />
+        <Key android:keyLabel="-" />
+        <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
+            android:iconPreview="@drawable/sym_keyboard_feedback_space"
+            android:keyWidth="20%p"/>
+        <Key android:keyLabel="=" />
+        <Key android:keyLabel="."
+            android:keyWidth="10%p"/>
+        <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
+            android:iconPreview="@drawable/sym_keyboard_feedback_ok"
+            android:keyWidth="20%p" android:keyEdgeFlags="right"/>
+    </Row>
+
+</Keyboard>
+
diff --git a/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml b/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml
new file mode 100755
index 0000000..9e9db81
--- /dev/null
+++ b/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
+    android:keyWidth="10%p"
+    android:horizontalGap="0px"
+    android:verticalGap="0px"
+    android:keyHeight="@dimen/password_keyboard_key_height_alpha"
+    >
+
+    <Row android:rowEdgeFlags="top">
+        <Key android:keyLabel="\@" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="\#"/>
+        <Key android:keyLabel="$"/>
+        <Key android:keyLabel="%"/>
+        <Key android:keyLabel="&amp;"/>
+        <Key android:keyLabel="*"/>
+        <Key android:keyLabel="-"/>
+        <Key android:keyLabel="+"/>
+        <Key android:keyLabel="("/>
+        <Key android:keyLabel=")" android:keyEdgeFlags="right"/>
+    </Row>
+
+    <Row>
+        <Key android:keyLabel="q" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="w"/>
+        <Key android:keyLabel="e"/>
+        <Key android:keyLabel="r"/>
+        <Key android:keyLabel="t"/>
+        <Key android:keyLabel="y"/>
+        <Key android:keyLabel="u"/>
+        <Key android:keyLabel="i"/>
+        <Key android:keyLabel="o"/>
+        <Key android:keyLabel="p" android:keyEdgeFlags="right"/>
+    </Row>
+
+    <Row>
+        <Key android:keyLabel="a" android:horizontalGap="5%p"
+            android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="s"/>
+        <Key android:keyLabel="d"/>
+        <Key android:keyLabel="f"/>
+        <Key android:keyLabel="g"/>
+        <Key android:keyLabel="h"/>
+        <Key android:keyLabel="j"/>
+        <Key android:keyLabel="k"/>
+        <Key android:keyLabel="l" android:keyEdgeFlags="right"/>
+    </Row>
+
+    <Row>
+        <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
+            android:keyWidth="15%p" android:isModifier="true"
+            android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+            android:isSticky="true" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="z"/>
+        <Key android:keyLabel="x"/>
+        <Key android:keyLabel="c"/>
+        <Key android:keyLabel="v"/>
+        <Key android:keyLabel="b"/>
+        <Key android:keyLabel="n"/>
+        <Key android:keyLabel="m"/>
+        <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
+            android:keyWidth="15%p" android:keyEdgeFlags="right"
+            android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+            android:isRepeatable="true"/>
+    </Row>
+
+    <Row android:keyboardMode="@+id/mode_normal" android:rowEdgeFlags="bottom">
+        <Key android:codes="-2" android:keyLabel="@string/password_keyboard_label_symbol_key"
+            android:keyWidth="20%p" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="," />
+        <Key android:keyLabel="_" />
+        <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
+            android:iconPreview="@drawable/sym_keyboard_feedback_space"
+            android:keyWidth="20%p"/>
+        <Key android:keyLabel="+" />
+        <Key android:keyLabel="."/>
+        <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
+            android:iconPreview="@drawable/sym_keyboard_feedback_ok"
+            android:keyWidth="20%p" android:keyEdgeFlags="right"/>
+    </Row>
+
+</Keyboard>
+
diff --git a/core/res/res/xml/password_kbd_extension.xml b/core/res/res/xml/password_kbd_extension.xml
index 28b7efe..f3fa57b 100755
--- a/core/res/res/xml/password_kbd_extension.xml
+++ b/core/res/res/xml/password_kbd_extension.xml
@@ -22,7 +22,7 @@
     android:keyWidth="10%p"
     android:horizontalGap="0px"
     android:verticalGap="0px"
-    android:keyHeight="@dimen/password_keyboard_key_height"
+    android:keyHeight="@dimen/password_keyboard_key_height_alpha"
     >
 
     <Row android:rowEdgeFlags="top">
diff --git a/core/res/res/xml/password_kbd_numeric.xml b/core/res/res/xml/password_kbd_numeric.xml
index bdd8afb..2270b8a 100755
--- a/core/res/res/xml/password_kbd_numeric.xml
+++ b/core/res/res/xml/password_kbd_numeric.xml
@@ -19,9 +19,8 @@
 -->
 <Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
     android:keyWidth="33.33%p"
-    android:horizontalGap="2px"
     android:verticalGap="0px"
-    android:keyHeight="@dimen/password_keyboard_key_height"
+    android:keyHeight="@dimen/password_keyboard_key_height_numeric"
     >
 
     <Row android:rowEdgeFlags="top">
diff --git a/core/res/res/xml/password_kbd_popup_template.xml b/core/res/res/xml/password_kbd_popup_template.xml
index 5ddfd3e..9b853e2 100644
--- a/core/res/res/xml/password_kbd_popup_template.xml
+++ b/core/res/res/xml/password_kbd_popup_template.xml
@@ -22,6 +22,6 @@
     android:keyWidth="10%p"
     android:horizontalGap="0px"
     android:verticalGap="0px"
-    android:keyHeight="@dimen/password_keyboard_key_height"
+    android:keyHeight="@dimen/password_keyboard_key_height_alpha"
     >
 </Keyboard>
diff --git a/core/res/res/xml/password_kbd_qwerty.xml b/core/res/res/xml/password_kbd_qwerty.xml
index 5fa9b8a..0a35040 100755
--- a/core/res/res/xml/password_kbd_qwerty.xml
+++ b/core/res/res/xml/password_kbd_qwerty.xml
@@ -22,7 +22,7 @@
     android:keyWidth="10%p"
     android:horizontalGap="0px"
     android:verticalGap="0px"
-    android:keyHeight="@dimen/password_keyboard_key_height"
+    android:keyHeight="@dimen/password_keyboard_key_height_alpha"
     >
 
     <Row android:rowEdgeFlags="top">
diff --git a/core/res/res/xml/password_kbd_qwerty_shifted.xml b/core/res/res/xml/password_kbd_qwerty_shifted.xml
index e491aff..9e9db81 100755
--- a/core/res/res/xml/password_kbd_qwerty_shifted.xml
+++ b/core/res/res/xml/password_kbd_qwerty_shifted.xml
@@ -22,7 +22,7 @@
     android:keyWidth="10%p"
     android:horizontalGap="0px"
     android:verticalGap="0px"
-    android:keyHeight="@dimen/password_keyboard_key_height"
+    android:keyHeight="@dimen/password_keyboard_key_height_alpha"
     >
 
     <Row android:rowEdgeFlags="top">
diff --git a/core/res/res/xml/password_kbd_symbols.xml b/core/res/res/xml/password_kbd_symbols.xml
index 9901526..9a94930 100755
--- a/core/res/res/xml/password_kbd_symbols.xml
+++ b/core/res/res/xml/password_kbd_symbols.xml
@@ -22,7 +22,7 @@
     android:keyWidth="10%p"
     android:horizontalGap="0px"
     android:verticalGap="0px"
-    android:keyHeight="@dimen/password_keyboard_key_height"
+    android:keyHeight="@dimen/password_keyboard_key_height_alpha"
     >
 
     <Row android:rowEdgeFlags="top">
diff --git a/core/res/res/xml/password_kbd_symbols_shift.xml b/core/res/res/xml/password_kbd_symbols_shift.xml
index 5b73914..a972eb2 100755
--- a/core/res/res/xml/password_kbd_symbols_shift.xml
+++ b/core/res/res/xml/password_kbd_symbols_shift.xml
@@ -22,7 +22,7 @@
     android:keyWidth="10%p"
     android:horizontalGap="0px"
     android:verticalGap="0px"
-    android:keyHeight="@dimen/password_keyboard_key_height"
+    android:keyHeight="@dimen/password_keyboard_key_height_alpha"
     >
 
     <Row android:rowEdgeFlags="top">
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 6349cb3..62fbfb4 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -43,6 +43,28 @@
     private boolean     mHasCompatScaling;
     private float       mCompatScaling;
     private float       mInvCompatScaling;
+
+    /**
+     * @hide
+     */
+    public boolean hasShadow;
+    /**
+     * @hide
+     */
+    public float shadowDx;
+    /**
+     * @hide
+     */
+    public float shadowDy;
+    /**
+     * @hide
+     */
+    public float shadowRadius;
+    /**
+     * @hide
+     */
+    public int shadowColor;
+
     /**
      * @hide
      */
@@ -935,13 +957,23 @@
      * offset and color, and blur radius. If radius is 0, then the shadow
      * layer is removed.
      */
-    public native void setShadowLayer(float radius, float dx, float dy, int color);
+    public void setShadowLayer(float radius, float dx, float dy, int color) {
+        hasShadow = radius > 0.0f;
+        shadowRadius = radius;
+        shadowDx = dx;
+        shadowDy = dy;
+        shadowColor = color;
+        nSetShadowLayer(radius, dx, dy, color);
+    }
+    
+    private native void nSetShadowLayer(float radius, float dx, float dy, int color);
 
     /**
      * Clear the shadow layer.
      */
     public void clearShadowLayer() {
-        setShadowLayer(0, 0, 0, 0);
+        hasShadow = false;
+        nSetShadowLayer(0, 0, 0, 0);
     }
 
     /**
diff --git a/graphics/java/android/renderscript/Float2.java b/graphics/java/android/renderscript/Float2.java
index 8fea91f..889bf7b 100644
--- a/graphics/java/android/renderscript/Float2.java
+++ b/graphics/java/android/renderscript/Float2.java
@@ -28,6 +28,11 @@
     public Float2() {
     }
 
+    public Float2(float initX, float initY) {
+        x = initX;
+        y = initY;
+    }
+
     public float x;
     public float y;
 }
diff --git a/graphics/java/android/renderscript/Float3.java b/graphics/java/android/renderscript/Float3.java
index 9d9e406..ebe140d 100644
--- a/graphics/java/android/renderscript/Float3.java
+++ b/graphics/java/android/renderscript/Float3.java
@@ -27,6 +27,11 @@
 public class Float3 {
     public Float3() {
     }
+    public Float3(float initX, float initY, float initZ) {
+        x = initX;
+        y = initY;
+        z = initZ;
+    }
 
     public float x;
     public float y;
diff --git a/graphics/java/android/renderscript/Float4.java b/graphics/java/android/renderscript/Float4.java
index a703e80..847732f 100644
--- a/graphics/java/android/renderscript/Float4.java
+++ b/graphics/java/android/renderscript/Float4.java
@@ -28,6 +28,13 @@
     public Float4() {
     }
 
+    public Float4(float initX, float initY, float initZ, float initW) {
+        x = initX;
+        y = initY;
+        z = initZ;
+        w = initW;
+    }
+
     public float x;
     public float y;
     public float z;
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 1efe6b5..8ed3d7b 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -17,7 +17,8 @@
 		ProgramCache.cpp \
 		SkiaColorFilter.cpp \
 		SkiaShader.cpp \
-		TextureCache.cpp
+		TextureCache.cpp \
+		TextDropShadowCache.cpp
 	
 	LOCAL_C_INCLUDES += \
 		$(JNI_H_INCLUDE) \
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index e807aba..ccc92eb 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -128,8 +128,11 @@
 }
 
 Font::CachedGlyphInfo* Font::getCachedUTFChar(SkPaint* paint, int32_t utfChar) {
-    CachedGlyphInfo* cachedGlyph = mCachedGlyphs.valueFor(utfChar);
-    if (cachedGlyph == NULL) {
+    CachedGlyphInfo* cachedGlyph = NULL;
+    ssize_t index = mCachedGlyphs.indexOfKey(utfChar);
+    if (index >= 0) {
+        cachedGlyph = mCachedGlyphs.valueAt(index);
+    } else {
         cachedGlyph = cacheGlyph(paint, utfChar);
     }
 
@@ -510,10 +513,10 @@
             uint32_t yOffset = cl->mCurrentRow;
             uint32_t width   = mCacheWidth;
             uint32_t height  = cl->mMaxHeight;
-            void*    textureData = mTextTexture + yOffset*width;
+            void* textureData = mTextTexture + yOffset*width;
 
             glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height,
-                             GL_ALPHA, GL_UNSIGNED_BYTE, textureData);
+                    GL_ALPHA, GL_UNSIGNED_BYTE, textureData);
 
             cl->mDirty = false;
         }
@@ -617,21 +620,33 @@
     }
 }
 FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const char *text,
-                                uint32_t startIndex, uint32_t len, int numGlyphs, uint32_t radius) {
+        uint32_t startIndex, uint32_t len, int numGlyphs, uint32_t radius) {
+    checkInit();
+
+    if (!mCurrentFont) {
+        DropShadow image;
+        image.width = 0;
+        image.height = 0;
+        image.image = NULL;
+        image.penX = 0;
+        image.penY = 0;
+        return image;
+    }
 
     Rect bounds;
     mCurrentFont->measureUTF(paint, text, startIndex, len, numGlyphs, &bounds);
-    uint32_t paddedWidth = (uint32_t)(bounds.right - bounds.left) + 2*radius;
-    uint32_t paddedHeight = (uint32_t)(bounds.top - bounds.bottom) + 2*radius;
+    uint32_t paddedWidth = (uint32_t) (bounds.right - bounds.left) + 2 * radius;
+    uint32_t paddedHeight = (uint32_t) (bounds.top - bounds.bottom) + 2 * radius;
     uint8_t* dataBuffer = new uint8_t[paddedWidth * paddedHeight];
-    for(uint32_t i = 0; i < paddedWidth * paddedHeight; i ++) {
+    for (uint32_t i = 0; i < paddedWidth * paddedHeight; i++) {
         dataBuffer[i] = 0;
     }
+
     int penX = radius - bounds.left;
     int penY = radius - bounds.bottom;
 
     mCurrentFont->renderUTF(paint, text, startIndex, len, numGlyphs, penX, penY,
-                              dataBuffer, paddedWidth, paddedHeight);
+            dataBuffer, paddedWidth, paddedHeight);
     blurImage(dataBuffer, paddedWidth, paddedHeight, radius);
 
     DropShadow image;
@@ -699,8 +714,7 @@
 }
 
 void FontRenderer::horizontalBlur(float* weights, int32_t radius,
-                                    const uint8_t* source, uint8_t* dest,
-                                    int32_t width, int32_t height) {
+        const uint8_t* source, uint8_t* dest, int32_t width, int32_t height) {
     float blurredPixel = 0.0f;
     float currentPixel = 0.0f;
 
@@ -744,8 +758,7 @@
 }
 
 void FontRenderer::verticalBlur(float* weights, int32_t radius,
-                                  const uint8_t* source, uint8_t* dest,
-                                  int32_t width, int32_t height) {
+        const uint8_t* source, uint8_t* dest, int32_t width, int32_t height) {
     float blurredPixel = 0.0f;
     float currentPixel = 0.0f;
 
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 6346ded..96c92d5 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -129,6 +129,14 @@
             uint32_t len, int numGlyphs, int x, int y);
 
     struct DropShadow {
+        DropShadow() { };
+
+        DropShadow(const DropShadow& dropShadow):
+            width(dropShadow.width), height(dropShadow.height),
+            image(dropShadow.image), penX(dropShadow.penX),
+            penY(dropShadow.penY) {
+        }
+
         uint32_t width;
         uint32_t height;
         uint8_t* image;
@@ -139,7 +147,7 @@
     // After renderDropShadow returns, the called owns the memory in DropShadow.image
     // and is responsible for releasing it when it's done with it
     DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex,
-                                   uint32_t len, int numGlyphs, uint32_t radius);
+            uint32_t len, int numGlyphs, uint32_t radius);
 
     GLuint getTexture() {
         checkInit();
@@ -154,7 +162,7 @@
         uint16_t mMaxWidth;
         uint32_t mCurrentRow;
         uint32_t mCurrentCol;
-        bool     mDirty;
+        bool mDirty;
 
         CacheTextureLine(uint16_t maxWidth, uint16_t maxHeight, uint32_t currentRow,
                 uint32_t currentCol):
@@ -237,9 +245,9 @@
 
     void computeGaussianWeights(float* weights, int32_t radius);
     void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
-                         int32_t width, int32_t height);
+            int32_t width, int32_t height);
     void verticalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
-                         int32_t width, int32_t height);
+            int32_t width, int32_t height);
     void blurImage(uint8_t* image, int32_t width, int32_t height, int32_t radius);
 };
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 3c1fe2a..da5b9dd 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -41,6 +41,7 @@
 #define DEFAULT_PATH_CACHE_SIZE 6.0f
 #define DEFAULT_PATCH_CACHE_SIZE 100
 #define DEFAULT_GRADIENT_CACHE_SIZE 0.5f
+#define DEFAULT_DROP_SHADOW_CACHE_SIZE 1.0f
 
 #define REQUIRED_TEXTURE_UNITS_COUNT 3
 
@@ -107,7 +108,8 @@
         mLayerCache(MB(DEFAULT_LAYER_CACHE_SIZE)),
         mGradientCache(MB(DEFAULT_GRADIENT_CACHE_SIZE)),
         mPathCache(MB(DEFAULT_PATH_CACHE_SIZE)),
-        mPatchCache(DEFAULT_PATCH_CACHE_SIZE) {
+        mPatchCache(DEFAULT_PATCH_CACHE_SIZE),
+        mDropShadowCache(MB(DEFAULT_DROP_SHADOW_CACHE_SIZE)) {
     LOGD("Create OpenGLRenderer");
 
     char property[PROPERTY_VALUE_MAX];
@@ -139,9 +141,18 @@
         LOGD("  Using default path cache size of %.2fMB", DEFAULT_PATH_CACHE_SIZE);
     }
 
+    if (property_get(PROPERTY_DROP_SHADOW_CACHE_SIZE, property, NULL) > 0) {
+        LOGD("  Setting drop shadow cache size to %sMB", property);
+        mDropShadowCache.setMaxSize(MB(atof(property)));
+    } else {
+        LOGD("  Using default drop shadow cache size of %.2fMB", DEFAULT_DROP_SHADOW_CACHE_SIZE);
+    }
+    mDropShadowCache.setFontRenderer(mFontRenderer);
+
     mCurrentProgram = NULL;
     mShader = NULL;
     mColorFilter = NULL;
+    mHasShadow = false;
 
     memcpy(mMeshVertices, gMeshVertices, sizeof(gMeshVertices));
 
@@ -163,6 +174,7 @@
     mPathCache.clear();
     mPatchCache.clear();
     mProgramCache.clear();
+    mDropShadowCache.clear();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -550,6 +562,78 @@
     drawColorRect(left, top, right, bottom, color, mode);
 }
 
+void OpenGLRenderer::renderShadow(const ShadowTexture* texture, float x, float y,
+        SkXfermode::Mode mode) {
+    const float sx = x - texture->left + mShadowDx;
+    const float sy = y - texture->top + mShadowDy;
+
+    const GLfloat a = ((mShadowColor >> 24) & 0xFF) / 255.0f;
+    const GLfloat r = a * ((mShadowColor >> 16) & 0xFF) / 255.0f;
+    const GLfloat g = a * ((mShadowColor >>  8) & 0xFF) / 255.0f;
+    const GLfloat b = a * ((mShadowColor      ) & 0xFF) / 255.0f;
+
+    GLuint textureUnit = 0;
+    renderTextureAlpha8(texture, textureUnit, sx, sy, r, g, b, a, mode, false);
+}
+
+void OpenGLRenderer::renderTextureAlpha8(const Texture* texture, GLuint& textureUnit,
+        float x, float y, float r, float g, float b, float a, SkXfermode::Mode mode,
+        bool applyFilters) {
+     // Describe the required shaders
+     ProgramDescription description;
+     description.hasTexture = true;
+     description.hasAlpha8Texture = true;
+
+     if (applyFilters) {
+         if (mShader) {
+             mShader->describe(description, mExtensions);
+         }
+         if (mColorFilter) {
+             mColorFilter->describe(description, mExtensions);
+         }
+     }
+
+     // Build and use the appropriate shader
+     useProgram(mProgramCache.get(description));
+
+     // Setup the blending mode
+     chooseBlending(true, mode);
+     bindTexture(texture->id, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, textureUnit);
+     glUniform1i(mCurrentProgram->getUniform("sampler"), textureUnit);
+
+     int texCoordsSlot = mCurrentProgram->getAttrib("texCoords");
+     glEnableVertexAttribArray(texCoordsSlot);
+
+     // Setup attributes
+     glVertexAttribPointer(mCurrentProgram->position, 2, GL_FLOAT, GL_FALSE,
+             gMeshStride, &mMeshVertices[0].position[0]);
+     glVertexAttribPointer(texCoordsSlot, 2, GL_FLOAT, GL_FALSE,
+             gMeshStride, &mMeshVertices[0].texture[0]);
+
+     // Setup uniforms
+     mModelView.loadTranslate(x, y, 0.0f);
+     mModelView.scale(texture->width, texture->height, 1.0f);
+     mCurrentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform);
+
+     glUniform4f(mCurrentProgram->color, r, g, b, a);
+
+     textureUnit++;
+     if (applyFilters) {
+         // Setup attributes and uniforms required by the shaders
+         if (mShader) {
+             mShader->setupProgram(mCurrentProgram, mModelView, *mSnapshot, &textureUnit);
+         }
+         if (mColorFilter) {
+             mColorFilter->setupProgram(mCurrentProgram);
+         }
+     }
+
+     // Draw the mesh
+     glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
+
+     glDisableVertexAttribArray(texCoordsSlot);
+}
+
 #define kStdStrikeThru_Offset   (-6.0f / 21.0f)
 #define kStdUnderline_Offset    (1.0f / 9.0f)
 #define kStdUnderline_Thickness (1.0f / 18.0f)
@@ -578,6 +662,15 @@
     SkXfermode::Mode mode;
     getAlphaAndMode(paint, &alpha, &mode);
 
+    mFontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()), paint->getTextSize());
+    if (mHasShadow) {
+        glActiveTexture(gTextureUnits[0]);
+        const ShadowTexture* shadow = mDropShadowCache.get(paint, text, bytesCount,
+                count, mShadowRadius);
+        const AutoTexture autoCleanup(shadow);
+        renderShadow(shadow, x, y, mode);
+    }
+
     uint32_t color = paint->getColor();
     const GLfloat a = alpha / 255.0f;
     const GLfloat r = a * ((color >> 16) & 0xFF) / 255.0f;
@@ -624,7 +717,6 @@
     }
 
     const Rect& clip = mSnapshot->getLocalClip();
-    mFontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()), paint->getTextSize());
     mFontRenderer.renderText(paint, &clip, text, 0, bytesCount, count, x, y);
 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
@@ -693,55 +785,9 @@
     const GLfloat g = a * ((color >>  8) & 0xFF) / 255.0f;
     const GLfloat b = a * ((color      ) & 0xFF) / 255.0f;
 
-    // Describe the required shaders
-    ProgramDescription description;
-    description.hasTexture = true;
-    description.hasAlpha8Texture = true;
-    if (mShader) {
-        mShader->describe(description, mExtensions);
-    }
-    if (mColorFilter) {
-        mColorFilter->describe(description, mExtensions);
-    }
-
-    // Build and use the appropriate shader
-    useProgram(mProgramCache.get(description));
-
-    // Setup the blending mode
-    chooseBlending(true, mode);
-    bindTexture(texture->id, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, textureUnit);
-    glUniform1i(mCurrentProgram->getUniform("sampler"), textureUnit);
-
-    int texCoordsSlot = mCurrentProgram->getAttrib("texCoords");
-    glEnableVertexAttribArray(texCoordsSlot);
-
-    // Setup attributes
-    glVertexAttribPointer(mCurrentProgram->position, 2, GL_FLOAT, GL_FALSE,
-            gMeshStride, &mMeshVertices[0].position[0]);
-    glVertexAttribPointer(texCoordsSlot, 2, GL_FLOAT, GL_FALSE,
-            gMeshStride, &mMeshVertices[0].texture[0]);
-
-    // Setup uniforms
-    mModelView.loadTranslate(texture->left - texture->offset,
-            texture->top - texture->offset, 0.0f);
-    mModelView.scale(texture->width, texture->height, 1.0f);
-    mCurrentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform);
-
-    glUniform4f(mCurrentProgram->color, r, g, b, a);
-
-    textureUnit++;
-    // Setup attributes and uniforms required by the shaders
-    if (mShader) {
-        mShader->setupProgram(mCurrentProgram, mModelView, *mSnapshot, &textureUnit);
-    }
-    if (mColorFilter) {
-        mColorFilter->setupProgram(mCurrentProgram);
-    }
-
-    // Draw the mesh
-    glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
-
-    glDisableVertexAttribArray(texCoordsSlot);
+    const float x = texture->left - texture->offset;
+    const float y = texture->top - texture->offset;
+    renderTextureAlpha8(texture, textureUnit, x, y, r, g, b, a, mode, true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -772,6 +818,22 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+// Drop shadow
+///////////////////////////////////////////////////////////////////////////////
+
+void OpenGLRenderer::resetShadow() {
+    mHasShadow = false;
+}
+
+void OpenGLRenderer::setupShadow(float radius, float dx, float dy, int color) {
+    mHasShadow = true;
+    mShadowRadius = radius;
+    mShadowDx = dx;
+    mShadowDy = dy;
+    mShadowColor = color;
+}
+
+///////////////////////////////////////////////////////////////////////////////
 // Drawing implementation
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 76783e9..948ff13 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -45,6 +45,7 @@
 #include "SkiaShader.h"
 #include "SkiaColorFilter.h"
 #include "PathCache.h"
+#include "TextDropShadowCache.h"
 
 namespace android {
 namespace uirenderer {
@@ -101,6 +102,9 @@
     void resetColorFilter();
     void setupColorFilter(SkiaColorFilter* filter);
 
+    void resetShadow();
+    void setupShadow(float radius, float dx, float dy, int color);
+
     void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
 
 private:
@@ -222,6 +226,34 @@
             GLvoid* vertices, GLvoid* texCoords, GLvoid* indices, GLsizei elementsCount = 0);
 
     /**
+     * Renders the specified shadow.
+     *
+     * @param texture The shadow texture
+     * @param x The x coordinate of the shadow
+     * @param y The y coordinate of the shadow
+     * @param mode The blending mode
+     */
+    void renderShadow(const ShadowTexture* texture, float x, float y, SkXfermode::Mode mode);
+
+    /**
+     * Renders the specified Alpha8 texture as a rectangle.
+     *
+     * @param texture The texture to render with
+     * @param textureUnit The texture unit to use, may be modified
+     * @param x The x coordinate of the rectangle to draw
+     * @param y The y coordinate of the rectangle to draw
+     * @param r The red component of the color
+     * @param g The green component of the color
+     * @param b The blue component of the color
+     * @param a The alpha component of the color
+     * @param mode The blending mode
+     * @param applyFilters Whether or not to take color filters and
+     *        shaders into account
+     */
+    void renderTextureAlpha8(const Texture* texture, GLuint& textureUnit, float x, float y,
+            float r, float g, float b, float a, SkXfermode::Mode mode, bool applyFilters);
+
+    /**
      * Resets the texture coordinates stored in mMeshVertices. Setting the values
      * back to default is achieved by calling:
      *
@@ -304,6 +336,13 @@
     // Font renderer
     FontRenderer mFontRenderer;
 
+    // Drop shadow
+    bool mHasShadow;
+    float mShadowRadius;
+    float mShadowDx;
+    float mShadowDy;
+    int mShadowColor;
+
     // Various caches
     TextureCache mTextureCache;
     LayerCache mLayerCache;
@@ -311,6 +350,7 @@
     ProgramCache mProgramCache;
     PathCache mPathCache;
     PatchCache mPatchCache;
+    TextDropShadowCache mDropShadowCache;
 }; // class OpenGLRenderer
 
 }; // namespace uirenderer
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index 9a22dc0..10440ea 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -166,7 +166,7 @@
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
     texture->blend = true;
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, bitmap.rowBytesAsPixels(), texture->height, 0,
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texture->width, texture->height, 0,
             GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.getPixels());
 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 915b0be..7514b6f 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -27,6 +27,7 @@
 #define PROPERTY_LAYER_CACHE_SIZE "ro.hwui.layer_cache_size"
 #define PROPERTY_GRADIENT_CACHE_SIZE "ro.hwui.gradient_cache_size"
 #define PROPERTY_PATH_CACHE_SIZE "ro.hwui.path_cache_size"
+#define PROPERTY_DROP_SHADOW_CACHE_SIZE "ro.hwui.drop_shadow_cache_size"
 
 // These properties are defined in pixels
 #define PROPERTY_TEXT_CACHE_WIDTH "ro.hwui.text_cache_width"
diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp
new file mode 100644
index 0000000..aab5bd4
--- /dev/null
+++ b/libs/hwui/TextDropShadowCache.cpp
@@ -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.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include "TextDropShadowCache.h"
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Constructors/destructor
+///////////////////////////////////////////////////////////////////////////////
+
+TextDropShadowCache::TextDropShadowCache(uint32_t maxByteSize):
+        mCache(GenerationCache<ShadowText, ShadowTexture*>::kUnlimitedCapacity),
+        mSize(0), mMaxSize(maxByteSize) {
+    mCache.setOnEntryRemovedListener(this);
+}
+
+TextDropShadowCache::~TextDropShadowCache() {
+    mCache.clear();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Size management
+///////////////////////////////////////////////////////////////////////////////
+
+uint32_t TextDropShadowCache::getSize() {
+    return mSize;
+}
+
+uint32_t TextDropShadowCache::getMaxSize() {
+    return mMaxSize;
+}
+
+void TextDropShadowCache::setMaxSize(uint32_t maxSize) {
+    mMaxSize = maxSize;
+    while (mSize > mMaxSize) {
+        mCache.removeOldest();
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Callbacks
+///////////////////////////////////////////////////////////////////////////////
+
+void TextDropShadowCache::operator()(ShadowText& text, ShadowTexture*& texture) {
+    const uint32_t size = texture->width * texture->height;
+    mSize -= size;
+
+    if (texture) {
+        glDeleteTextures(1, &texture->id);
+        delete texture;
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Caching
+///////////////////////////////////////////////////////////////////////////////
+
+void TextDropShadowCache::clear() {
+    mCache.clear();
+}
+
+ShadowTexture* TextDropShadowCache::get(SkPaint* paint, const char* text, uint32_t len,
+        int numGlyphs, uint32_t radius) {
+    ShadowText entry(paint, radius, len, text);
+    ShadowTexture* texture = mCache.get(entry);
+
+    if (!texture) {
+        FontRenderer::DropShadow shadow = mRenderer->renderDropShadow(paint, text, 0,
+                len, numGlyphs, radius);
+
+        texture = new ShadowTexture;
+        texture->left = shadow.penX;
+        texture->top = shadow.penY;
+        texture->width = shadow.width;
+        texture->height = shadow.height;
+        texture->generation = 0;
+        texture->blend = true;
+
+        const uint32_t size = shadow.width * shadow.height;
+        // Don't even try to cache a bitmap that's bigger than the cache
+        if (size < mMaxSize) {
+            while (mSize + size > mMaxSize) {
+                mCache.removeOldest();
+            }
+        }
+
+        glGenTextures(1, &texture->id);
+
+        glBindTexture(GL_TEXTURE_2D, texture->id);
+        // Textures are Alpha8
+        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texture->width, texture->height, 0,
+                GL_ALPHA, GL_UNSIGNED_BYTE, shadow.image);
+
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+        if (size < mMaxSize) {
+            mSize += size;
+            mCache.put(entry, texture);
+        } else {
+            texture->cleanup = true;
+        }
+
+        // Cleanup shadow
+        delete[] shadow.image;
+    }
+
+    return texture;
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h
new file mode 100644
index 0000000..9c86187
--- /dev/null
+++ b/libs/hwui/TextDropShadowCache.h
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_UI_TEXT_DROP_SHADOW_CACHE_H
+#define ANDROID_UI_TEXT_DROP_SHADOW_CACHE_H
+
+#include <GLES2/gl2.h>
+
+#include <SkPaint.h>
+
+#include "GenerationCache.h"
+#include "FontRenderer.h"
+#include "Texture.h"
+
+namespace android {
+namespace uirenderer {
+
+struct ShadowText {
+    ShadowText() { }
+
+    ShadowText(SkPaint* paint, uint32_t radius, uint32_t len, const char* srcText):
+            paint(paint), radius(radius), len(len) {
+        text = new char[len];
+        memcpy(text, srcText, len);
+
+        hash = 0;
+        uint32_t multiplier = 1;
+        for (uint32_t i = 0; i < len; i++) {
+            hash += text[i] * multiplier;
+            uint32_t shifted = multiplier << 5;
+            multiplier = shifted - multiplier;
+        }
+    }
+
+    ShadowText(const ShadowText& shadow):
+            paint(shadow.paint), radius(shadow.radius), len(shadow.len), hash(shadow.hash) {
+        text = new char[len];
+        memcpy(text, shadow.text, shadow.len);
+    }
+
+    ~ShadowText() {
+        delete[] text;
+    }
+
+    SkPaint* paint;
+    uint32_t radius;
+    uint32_t len;
+    uint32_t hash;
+    char *text;
+
+    bool operator<(const ShadowText& rhs) const {
+        if (len < rhs.len) return true;
+        else if (len == rhs.len) {
+            if (radius < rhs.radius) return true;
+            else if (radius == rhs.radius) {
+                if (paint < rhs.paint) return true;
+                else if (paint == rhs.paint) {
+                    if (hash < rhs.hash) return true;
+                    if (hash == rhs.hash) {
+                        return strncmp(text, rhs.text, len) < 0;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+}; // struct ShadowText
+
+/**
+ * Alpha texture used to represent a shadow.
+ */
+struct ShadowTexture: public Texture {
+    ShadowTexture(): Texture() {
+    }
+
+    float left;
+    float top;
+}; // struct ShadowTexture
+
+class TextDropShadowCache: public OnEntryRemoved<ShadowText, ShadowTexture*> {
+public:
+    TextDropShadowCache(uint32_t maxByteSize);
+    ~TextDropShadowCache();
+
+    /**
+     * Used as a callback when an entry is removed from the cache.
+     * Do not invoke directly.
+     */
+    void operator()(ShadowText& text, ShadowTexture*& texture);
+
+    ShadowTexture* get(SkPaint* paint, const char* text, uint32_t len,
+            int numGlyphs, uint32_t radius);
+
+    /**
+     * Clears the cache. This causes all textures to be deleted.
+     */
+    void clear();
+
+    void setFontRenderer(FontRenderer& fontRenderer) {
+        mRenderer = &fontRenderer;
+    }
+
+    /**
+     * Sets the maximum size of the cache in bytes.
+     */
+    void setMaxSize(uint32_t maxSize);
+    /**
+     * Returns the maximum size of the cache in bytes.
+     */
+    uint32_t getMaxSize();
+    /**
+     * Returns the current size of the cache in bytes.
+     */
+    uint32_t getSize();
+
+private:
+    GenerationCache<ShadowText, ShadowTexture*> mCache;
+
+    uint32_t mSize;
+    uint32_t mMaxSize;
+    FontRenderer* mRenderer;
+}; // class TextDropShadowCache
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_UI_TEXT_DROP_SHADOW_CACHE_H
diff --git a/libs/rs/java/SceneGraph/Android.mk b/libs/rs/java/SceneGraph/Android.mk
new file mode 100644
index 0000000..5520446
--- /dev/null
+++ b/libs/rs/java/SceneGraph/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2008 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.
+#
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
+
+LOCAL_PACKAGE_NAME := SceneGraph
+
+include $(BUILD_PACKAGE)
+
+endif
diff --git a/libs/rs/java/SceneGraph/AndroidManifest.xml b/libs/rs/java/SceneGraph/AndroidManifest.xml
new file mode 100644
index 0000000..8a8f87a
--- /dev/null
+++ b/libs/rs/java/SceneGraph/AndroidManifest.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.scenegraph">
+    <application android:label="SceneGraph">
+        <activity android:name="SceneGraph"
+                  android:theme="@android:style/Theme.Black.NoTitleBar">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/libs/rs/java/SceneGraph/res/drawable/robot.png b/libs/rs/java/SceneGraph/res/drawable/robot.png
new file mode 100644
index 0000000..f7353fd
--- /dev/null
+++ b/libs/rs/java/SceneGraph/res/drawable/robot.png
Binary files differ
diff --git a/libs/rs/java/SceneGraph/res/raw/robot.a3d b/libs/rs/java/SceneGraph/res/raw/robot.a3d
new file mode 100644
index 0000000..2d7d32b
--- /dev/null
+++ b/libs/rs/java/SceneGraph/res/raw/robot.a3d
Binary files differ
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraph.java b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraph.java
new file mode 100644
index 0000000..5daa4ac
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraph.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008 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.scenegraph;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings.System;
+import android.util.Config;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.ListView;
+
+import java.lang.Runtime;
+
+public class SceneGraph extends Activity {
+
+    private SceneGraphView mView;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        // Create our Preview view and set it as the content of our
+        // Activity
+        mView = new SceneGraphView(this);
+        setContentView(mView);
+    }
+
+    @Override
+    protected void onResume() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onResume();
+        mView.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onPause();
+        mView.onPause();
+    }
+
+}
+
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphRS.java b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphRS.java
new file mode 100644
index 0000000..3db4a2b6
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphRS.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2008 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.scenegraph;
+
+import java.io.Writer;
+import java.util.Map;
+import java.util.Vector;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.Element.Builder;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.util.Log;
+
+
+public class SceneGraphRS {
+
+    private final int STATE_LAST_FOCUS = 1;
+
+    int mWidth;
+    int mHeight;
+    int mRotation;
+
+    public SceneGraphRS() {
+    }
+
+    public void init(RenderScriptGL rs, Resources res, int width, int height) {
+        mRS = rs;
+        mRes = res;
+        mWidth = width;
+        mHeight = height;
+        mRotation = 0;
+        initRS();
+    }
+
+    private Resources mRes;
+    private RenderScriptGL mRS;
+    private Sampler mSampler;
+    private ProgramStore mPSBackground;
+    private ProgramFragment mPFBackground;
+    private ProgramVertex mPVBackground;
+    private ProgramVertex.MatrixAllocation mPVA;
+
+    private Allocation mGridImage;
+    private Allocation mAllocPV;
+
+    private Mesh mMesh;
+
+    private Font mItalic;
+    private Allocation mTextAlloc;
+
+    private ScriptC_Scenegraph mScript;
+    private ScriptC_Transform mTransformScript;
+
+    int mLastX;
+    int mLastY;
+
+    public void touchEvent(int x, int y) {
+        int dx = mLastX - x;
+        if(Math.abs(dx) > 50 || Math.abs(dx) < 3) {
+            dx = 0;
+        }
+
+        mRotation -= dx;
+        if(mRotation > 360) {
+            mRotation -= 360;
+        }
+        if(mRotation < 0) {
+            mRotation += 360;
+        }
+
+        mScript.set_gRotate(-(float)mRotation);
+
+        mLastX = x;
+        mLastY = y;
+    }
+
+    private void initPFS() {
+        ProgramStore.Builder b = new ProgramStore.Builder(mRS, null, null);
+
+        b.setDepthFunc(ProgramStore.DepthFunc.LESS);
+        b.setDitherEnable(false);
+        b.setDepthMask(true);
+        mPSBackground = b.create();
+
+        mScript.set_gPFSBackground(mPSBackground);
+    }
+
+    private void initPF() {
+        Sampler.Builder bs = new Sampler.Builder(mRS);
+        bs.setMin(Sampler.Value.LINEAR);
+        bs.setMag(Sampler.Value.LINEAR);
+        bs.setWrapS(Sampler.Value.CLAMP);
+        bs.setWrapT(Sampler.Value.WRAP);
+        mSampler = bs.create();
+
+        ProgramFragment.Builder b = new ProgramFragment.Builder(mRS);
+        b.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
+                     ProgramFragment.Builder.Format.RGBA, 0);
+        mPFBackground = b.create();
+        mPFBackground.bindSampler(mSampler, 0);
+
+        mScript.set_gPFBackground(mPFBackground);
+    }
+
+    private void initPV() {
+        ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null);
+        mPVBackground = pvb.create();
+
+        mPVA = new ProgramVertex.MatrixAllocation(mRS);
+        mPVBackground.bindAllocation(mPVA);
+        mPVA.setupProjectionNormalized(mWidth, mHeight);
+
+        mScript.set_gPVBackground(mPVBackground);
+    }
+
+    private void loadImage() {
+        mGridImage = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.robot, Element.RGB_565(mRS), true);
+        mGridImage.uploadToTexture(0);
+
+        mScript.set_gTGrid(mGridImage);
+    }
+
+    private void initTextAllocation() {
+        String allocString = "Displaying file: R.raw.robot";
+        mTextAlloc = Allocation.createFromString(mRS, allocString);
+        mScript.set_gTextAlloc(mTextAlloc);
+    }
+
+    SgTransform mRootTransform;
+    SgTransform mGroup1;
+
+    SgTransform mRobot1;
+    SgTransform mRobot2;
+
+    void initTransformHierarchy() {
+        mRootTransform = new SgTransform(mRS);
+
+        mGroup1 = new SgTransform(mRS);
+        mRootTransform.addChild(mGroup1);
+
+        mRobot1 = new SgTransform(mRS);
+        mRobot2 = new SgTransform(mRS);
+
+        mGroup1.addChild(mRobot1);
+        mGroup1.addChild(mRobot2);
+
+        mGroup1.setTransform(0, new Float4(0.0f, 0.0f, 5.0f, 0.0f), TransformType.TRANSLATE);
+        mGroup1.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, 15.0f), TransformType.ROTATE);
+
+        mRobot1.setTransform(0, new Float4(-2.0f, -0.5f, 0.0f, 0.0f), TransformType.TRANSLATE);
+        mRobot1.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, 20.0f), TransformType.ROTATE);
+        mRobot1.setTransform(2, new Float4(0.2f, 0.2f, 0.2f, 0.0f), TransformType.SCALE);
+
+        mRobot2.setTransform(0, new Float4(2.0f, 0.0f, 0.0f, 0.0f), TransformType.TRANSLATE);
+        mRobot2.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, -20.0f), TransformType.ROTATE);
+        mRobot2.setTransform(2, new Float4(0.3f, 0.3f, 0.3f, 0.0f), TransformType.SCALE);
+    }
+
+    private void initRS() {
+
+        mScript = new ScriptC_Scenegraph(mRS, mRes, R.raw.scenegraph, true);
+        mTransformScript = new ScriptC_Transform(mRS, mRes, R.raw.transform, false);
+        mTransformScript.set_transformScript(mTransformScript);
+
+        mScript.set_gTransformRS(mTransformScript);
+
+        initPFS();
+        initPF();
+        initPV();
+
+        loadImage();
+
+        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
+        FileA3D.IndexEntry entry = model.getIndexEntry(0);
+        if(entry == null || entry.getClassID() != FileA3D.ClassID.MESH) {
+            Log.e("rs", "could not load model");
+        }
+        else {
+            mMesh = (Mesh)entry.getObject();
+            mScript.set_gTestMesh(mMesh);
+        }
+
+        mItalic = Font.create(mRS, mRes, "DroidSerif-Italic.ttf", 8);
+        mScript.set_gItalic(mItalic);
+
+        initTextAllocation();
+
+        initTransformHierarchy();
+
+        Log.v("========SceneGraph========", "transform hierarchy initialized");
+
+        mScript.bind_gRootNode(mRootTransform.getField());
+
+        mScript.bind_gGroup(mGroup1.mParent.mChildField);
+        mScript.bind_gRobot1(mRobot1.mParent.mChildField);
+        mScript.set_gRobot1Index(mRobot1.mIndexInParentGroup);
+        mScript.bind_gRobot2(mRobot2.mParent.mChildField);
+        mScript.set_gRobot2Index(mRobot2.mIndexInParentGroup);
+
+        mRS.contextBindRootScript(mScript);
+    }
+}
+
+
+
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphView.java b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphView.java
new file mode 100644
index 0000000..ae94869
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphView.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008 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.scenegraph;
+
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.concurrent.Semaphore;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+import android.renderscript.RenderScriptGL;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+public class SceneGraphView extends RSSurfaceView {
+
+    public SceneGraphView(Context context) {
+        super(context);
+        //setFocusable(true);
+    }
+
+    private RenderScriptGL mRS;
+    private SceneGraphRS mRender;
+
+
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        super.surfaceChanged(holder, format, w, h);
+        if (mRS == null) {
+            mRS = createRenderScript(true);
+            mRS.contextSetSurface(w, h, holder.getSurface());
+            mRender = new SceneGraphRS();
+            mRender.init(mRS, getResources(), w, h);
+        }
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        if(mRS != null) {
+            mRS = null;
+            destroyRenderScript();
+        }
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event)
+    {
+        // break point at here
+        // this method doesn't work when 'extends View' include 'extends ScrollView'.
+        return super.onKeyDown(keyCode, event);
+    }
+
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev)
+    {
+        boolean ret = true;
+        int act = ev.getAction();
+        if (act == ev.ACTION_UP) {
+            ret = false;
+        }
+
+        mRender.touchEvent((int)ev.getX(), (int)ev.getY());
+        return ret;
+    }
+}
+
+
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/SgTransform.java b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SgTransform.java
new file mode 100644
index 0000000..e81f1a7
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SgTransform.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2008 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.scenegraph;
+
+import java.io.Writer;
+import java.util.Map;
+import java.util.Vector;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.Element.Builder;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.util.Log;
+
+enum TransformType {
+
+    NONE(0),
+    TRANSLATE(1),
+    ROTATE(2),
+    SCALE(3);
+
+    int mID;
+    TransformType(int id) {
+        mID = id;
+    }
+}
+
+public class SgTransform {
+
+
+    ScriptField_SgTransform mTransformField;
+    ScriptField_SgTransform mChildField;
+    public ScriptField_SgTransform.Item mTransformData;
+
+    Float4[] mTransforms;
+    TransformType[] mTransformTypes;
+
+    RenderScript mRS;
+
+    Vector mChildren;
+    SgTransform mParent;
+    int mIndexInParentGroup;
+
+    public void setParent(SgTransform parent, int parentIndex) {
+        mParent = parent;
+        mIndexInParentGroup = parentIndex;
+    }
+
+    public void addChild(SgTransform child) {
+        mChildren.add(child);
+        child.setParent(this, mChildren.size() - 1);
+    }
+
+    public void setTransform(int index, Float4 value, TransformType type) {
+        mTransforms[index] = value;
+        mTransformTypes[index] = type;
+    }
+
+    void initData() {
+        int numTransforms = 16;
+        mTransforms = new Float4[numTransforms];
+        mTransformTypes = new TransformType[numTransforms];
+        for(int i = 0; i < numTransforms; i ++) {
+            mTransforms[i] = new Float4(0, 0, 0, 0);
+            mTransformTypes[i] = TransformType.NONE;
+        }
+    }
+
+    void setData() {
+
+        mTransformData.globalMat_Row0 = new Float4(1, 0, 0, 0);
+        mTransformData.globalMat_Row1 = new Float4(0, 1, 0, 0);
+        mTransformData.globalMat_Row2 = new Float4(0, 0, 1, 0);
+        mTransformData.globalMat_Row3 = new Float4(0, 0, 0, 1);
+
+        mTransformData.localMat_Row0 = new Float4(1, 0, 0, 0);
+        mTransformData.localMat_Row1 = new Float4(0, 1, 0, 0);
+        mTransformData.localMat_Row2 = new Float4(0, 0, 1, 0);
+        mTransformData.localMat_Row3 = new Float4(0, 0, 0, 1);
+
+        mTransformData.transforms0 = mTransforms[0];
+        mTransformData.transforms1 = mTransforms[1];
+        mTransformData.transforms2 = mTransforms[2];
+        mTransformData.transforms3 = mTransforms[3];
+        mTransformData.transforms4 = mTransforms[4];
+        mTransformData.transforms5 = mTransforms[5];
+        mTransformData.transforms6 = mTransforms[6];
+        mTransformData.transforms7 = mTransforms[7];
+        mTransformData.transforms8 = mTransforms[8];
+        mTransformData.transforms9 = mTransforms[9];
+        mTransformData.transforms10 = mTransforms[10];
+        mTransformData.transforms11 = mTransforms[11];
+        mTransformData.transforms12 = mTransforms[12];
+        mTransformData.transforms13 = mTransforms[13];
+        mTransformData.transforms14 = mTransforms[14];
+        mTransformData.transforms15 = mTransforms[15];
+
+        mTransformData.transformType0 = mTransformTypes[0].mID;
+        mTransformData.transformType1 = mTransformTypes[1].mID;
+        mTransformData.transformType2 = mTransformTypes[2].mID;
+        mTransformData.transformType3 = mTransformTypes[3].mID;
+        mTransformData.transformType4 = mTransformTypes[4].mID;
+        mTransformData.transformType5 = mTransformTypes[5].mID;
+        mTransformData.transformType6 = mTransformTypes[6].mID;
+        mTransformData.transformType7 = mTransformTypes[7].mID;
+        mTransformData.transformType8 = mTransformTypes[8].mID;
+        mTransformData.transformType9 = mTransformTypes[9].mID;
+        mTransformData.transformType10 = mTransformTypes[10].mID;
+        mTransformData.transformType11 = mTransformTypes[11].mID;
+        mTransformData.transformType12 = mTransformTypes[12].mID;
+        mTransformData.transformType13 = mTransformTypes[13].mID;
+        mTransformData.transformType14 = mTransformTypes[14].mID;
+        mTransformData.transformType15 = mTransformTypes[15].mID;
+
+        mTransformData.isDirty = 1;
+        mTransformData.children = null;
+
+    }
+
+    public SgTransform(RenderScript rs) {
+        mRS = rs;
+        mTransformData = new ScriptField_SgTransform.Item();
+        mChildren = new Vector();
+        initData();
+    }
+
+    public ScriptField_SgTransform.Item getData() {
+        setData();
+        if(mChildren.size() != 0) {
+            mChildField = new ScriptField_SgTransform(mRS, mChildren.size());
+            mTransformData.children = mChildField.getAllocation();
+
+            for(int i = 0; i < mChildren.size(); i ++) {
+                SgTransform child = (SgTransform)mChildren.get(i);
+                mChildField.set(child.getData(), i, false);
+            }
+            mChildField.copyAll();
+        }
+
+        return mTransformData;
+    }
+
+    public ScriptField_SgTransform getField() {
+        mTransformField = new ScriptField_SgTransform(mRS, 1);
+        mTransformField.set(getData(), 0, true);
+        return mTransformField;
+    }
+}
+
+
+
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/scenegraph.rs b/libs/rs/java/SceneGraph/src/com/android/scenegraph/scenegraph.rs
new file mode 100644
index 0000000..e6ae6df
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/scenegraph.rs
@@ -0,0 +1,92 @@
+// Copyright (C) 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.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.scenegraph)
+
+#include "rs_graphics.rsh"
+#include "transform_def.rsh"
+
+rs_program_vertex gPVBackground;
+rs_program_fragment gPFBackground;
+
+rs_allocation gTGrid;
+rs_mesh gTestMesh;
+
+rs_program_store gPFSBackground;
+
+float gRotate;
+
+rs_font gItalic;
+rs_allocation gTextAlloc;
+
+rs_script gTransformRS;
+
+SgTransform *gGroup;
+SgTransform *gRobot1;
+int gRobot1Index;
+SgTransform *gRobot2;
+int gRobot2Index;
+
+SgTransform *gRootNode;
+
+#pragma rs export_var(gPVBackground, gPFBackground, gTGrid, gTestMesh, gPFSBackground, gRotate, gItalic, gTextAlloc, gTransformRS, gGroup, gRobot1, gRobot1Index, gRobot2, gRobot2Index, gRootNode)
+
+float gDT;
+int64_t gLastTime;
+
+void init() {
+    gRotate = 0.0f;
+}
+
+int root(int launchID) {
+
+    gGroup->transforms1.w += 0.5f;
+    gGroup->isDirty = 1;
+
+    SgTransform *robot1Ptr = gRobot1 + gRobot1Index;
+
+    robot1Ptr->transforms1.w -= 1.5f;
+    robot1Ptr->isDirty = 1;
+
+    SgTransform *robot2Ptr = gRobot2 + gRobot2Index;
+    robot2Ptr->transforms1.w += 2.5f;
+    robot2Ptr->isDirty = 1;
+
+    rsForEach(gTransformRS, gRootNode->children, gRootNode->children, 0);
+
+    rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgClearDepth(1.0f);
+
+    rsgBindProgramVertex(gPVBackground);
+
+    rsgBindProgramFragment(gPFBackground);
+    rsgBindProgramStore(gPFSBackground);
+    rsgBindTexture(gPFBackground, 0, gTGrid);
+
+    rsgProgramVertexLoadModelMatrix((rs_matrix4x4 *)&robot1Ptr->globalMat_Row0);
+    rsgDrawMesh(gTestMesh);
+
+    rsgProgramVertexLoadModelMatrix((rs_matrix4x4 *)&robot2Ptr->globalMat_Row0);
+    rsgDrawMesh(gTestMesh);
+
+    color(0.3f, 0.3f, 0.3f, 1.0f);
+    rsgDrawText("Renderscript transform test", 30, 695);
+
+    rsgBindFont(gItalic);
+    rsgDrawText(gTextAlloc, 30, 730);
+
+    return 10;
+}
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform.rs b/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform.rs
new file mode 100644
index 0000000..a62d12b
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform.rs
@@ -0,0 +1,102 @@
+// Copyright (C) 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.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.scenegraph)
+
+#include "transform_def.rsh"
+
+rs_script transformScript;
+
+#pragma rs export_var(transformScript)
+
+typedef struct {
+    int changed;
+    rs_matrix4x4 *mat;
+} ParentData;
+
+void appendTransformation(int type, float4 data, rs_matrix4x4 *mat) {
+    rs_matrix4x4 temp;
+
+    switch(type) {
+    case TRANSFORM_TRANSLATE:
+        rsMatrixLoadTranslate(&temp, data.x, data.y, data.z);
+        break;
+    case TRANSFORM_ROTATE:
+        rsMatrixLoadRotate(&temp, data.w, data.x, data.y, data.z);
+        break;
+    case TRANSFORM_SCALE:
+        rsMatrixLoadScale(&temp, data.x, data.y, data.z);
+        break;
+    }
+    rsMatrixMultiply(mat, &temp);
+}
+
+void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) {
+
+    SgTransform *data = (SgTransform *)v_out;
+    const ParentData *parent = (const ParentData *)usrData;
+
+    //rsDebug("Transform data", (int)data);
+    //rsDebug("Entering parent", (int)parent);
+
+    rs_matrix4x4 *localMat = (rs_matrix4x4*)&data->localMat_Row0;
+    rs_matrix4x4 *globalMat = (rs_matrix4x4*)&data->globalMat_Row0;
+
+    ParentData toChild;
+    toChild.changed = 0;
+    toChild.mat = globalMat;
+
+    //rsDebug("Transform is dirty", data->isDirty);
+
+    // Refresh matrices if dirty
+    if(data->isDirty) {
+        data->isDirty = 0;
+        toChild.changed = 1;
+
+        // Reset our local matrix
+        rsMatrixLoadIdentity(localMat);
+
+        float4 *transformSource = &data->transforms0;
+        int *transformTypes = &data->transformType0;
+
+        for(int i = 0; i < 16; i ++) {
+            if(transformTypes[i] == TRANSFORM_NONE) {
+                break;
+            }
+            //rsDebug("Transform adding transformation", transformTypes[i]);
+            appendTransformation(transformTypes[i], transformSource[i], localMat);
+        }
+    }
+
+    //rsDebug("Transform checking parent", (int)0);
+
+    if(parent) {
+        if(parent->changed) {
+            toChild.changed = 1;
+
+            rsMatrixLoad(globalMat, parent->mat);
+            rsMatrixMultiply(globalMat, localMat);
+        }
+    }
+    else {
+        rsMatrixLoad(globalMat, localMat);
+    }
+
+    //rsDebug("Transform calling self with child ", (int)data->children.p);
+    if(data->children.p) {
+        rsForEach(transformScript, data->children, data->children, (void*)&toChild);
+    }
+}
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform_def.rsh b/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform_def.rsh
new file mode 100644
index 0000000..10aac37
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform_def.rsh
@@ -0,0 +1,73 @@
+// Copyright (C) 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.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.scenegraph)
+
+#define TRANSFORM_NONE 0
+#define TRANSFORM_TRANSLATE 1
+#define TRANSFORM_ROTATE 2
+#define TRANSFORM_SCALE 3
+
+typedef struct {
+    float4 globalMat_Row0;
+    float4 globalMat_Row1;
+    float4 globalMat_Row2;
+    float4 globalMat_Row3;
+
+    float4 localMat_Row0;
+    float4 localMat_Row1;
+    float4 localMat_Row2;
+    float4 localMat_Row3;
+
+    float4 transforms0;
+    float4 transforms1;
+    float4 transforms2;
+    float4 transforms3;
+    float4 transforms4;
+    float4 transforms5;
+    float4 transforms6;
+    float4 transforms7;
+    float4 transforms8;
+    float4 transforms9;
+    float4 transforms10;
+    float4 transforms11;
+    float4 transforms12;
+    float4 transforms13;
+    float4 transforms14;
+    float4 transforms15;
+
+    int transformType0;
+    int transformType1;
+    int transformType2;
+    int transformType3;
+    int transformType4;
+    int transformType5;
+    int transformType6;
+    int transformType7;
+    int transformType8;
+    int transformType9;
+    int transformType10;
+    int transformType11;
+    int transformType12;
+    int transformType13;
+    int transformType14;
+    int transformType15;
+
+    int isDirty;
+
+    rs_allocation children;
+
+} SgTransform;
diff --git a/libs/rs/rsMesh.cpp b/libs/rs/rsMesh.cpp
index 9026578..810e4ff 100644
--- a/libs/rs/rsMesh.cpp
+++ b/libs/rs/rsMesh.cpp
@@ -224,6 +224,49 @@
     return mesh;
 }
 
+void Mesh::computeBBox() {
+    float *posPtr = NULL;
+    uint32_t vectorSize = 0;
+    uint32_t stride = 0;
+    uint32_t numVerts = 0;
+    // First we need to find the position ptr and stride
+    for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
+        const Type *bufferType = mVertexBuffers[ct]->getType();
+        const Element *bufferElem = bufferType->getElement();
+
+        for (uint32_t ct=0; ct < bufferElem->getFieldCount(); ct++) {
+            if(strcmp(bufferElem->getFieldName(ct), "position") == 0) {
+                vectorSize = bufferElem->getField(ct)->getComponent().getVectorSize();
+                stride = bufferElem->getSizeBytes() / sizeof(float);
+                uint32_t offset = bufferElem->getFieldOffsetBytes(ct);
+                posPtr = (float*)((uint8_t*)mVertexBuffers[ct]->getPtr() + offset);
+                numVerts = bufferType->getDimX();
+                break;
+            }
+        }
+        if(posPtr) {
+            break;
+        }
+    }
+
+    mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 1e6;
+    mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = -1e6;
+    if(!posPtr) {
+        LOGE("Unable to compute bounding box");
+        mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 0.0f;
+        mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = 0.0f;
+        return;
+    }
+
+    for(uint32_t i = 0; i < numVerts; i ++) {
+        for(uint32_t v = 0; v < vectorSize; v ++) {
+            mBBoxMin[v] = rsMin(mBBoxMin[v], posPtr[v]);
+            mBBoxMax[v] = rsMax(mBBoxMax[v], posPtr[v]);
+        }
+        posPtr += stride;
+    }
+}
+
 
 MeshContext::MeshContext()
 {
diff --git a/libs/rs/rsMesh.h b/libs/rs/rsMesh.h
index 765a971..ed01c38 100644
--- a/libs/rs/rsMesh.h
+++ b/libs/rs/rsMesh.h
@@ -61,6 +61,11 @@
     virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_MESH; }
     static Mesh *createFromStream(Context *rsc, IStream *stream);
 
+    // Bounding volumes
+    float mBBoxMin[3];
+    float mBBoxMax[3];
+    void computeBBox();
+
 protected:
 };
 
diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp
index f5e59534..4b8de76 100644
--- a/libs/rs/rsScriptC_LibGL.cpp
+++ b/libs/rs/rsScriptC_LibGL.cpp
@@ -251,6 +251,20 @@
     sm->renderPrimitiveRange(rsc, primIndex, start, len);
 }
 
+static void SC_meshComputeBoundingBox(RsMesh vsm, float *minX, float *minY, float *minZ,
+                                                     float *maxX, float *maxY, float *maxZ)
+{
+    GET_TLS();
+    Mesh *sm = static_cast<Mesh *>(vsm);
+    sm->computeBBox();
+    *minX = sm->mBBoxMin[0];
+    *minY = sm->mBBoxMin[1];
+    *minZ = sm->mBBoxMin[2];
+    *maxX = sm->mBBoxMax[0];
+    *maxY = sm->mBBoxMax[1];
+    *maxZ = sm->mBBoxMax[2];
+}
+
 
 //////////////////////////////////////////////////////////////////////////////
 //
@@ -390,6 +404,7 @@
     { "_Z11rsgDrawMesh7rs_mesh", (void *)&SC_drawMesh },
     { "_Z11rsgDrawMesh7rs_meshj", (void *)&SC_drawMeshPrimitive },
     { "_Z11rsgDrawMesh7rs_meshjjj", (void *)&SC_drawMeshPrimitiveRange },
+    { "_Z25rsgMeshComputeBoundingBox7rs_meshPfS0_S0_S0_S0_S0_", (void *)&SC_meshComputeBoundingBox },
 
     { "_Z13rsgClearColorffff", (void *)&SC_ClearColor },
     { "_Z13rsgClearDepthf", (void *)&SC_ClearDepth },
diff --git a/libs/rs/scriptc/rs_graphics.rsh b/libs/rs/scriptc/rs_graphics.rsh
index fd0491c..63bd9d7 100644
--- a/libs/rs/scriptc/rs_graphics.rsh
+++ b/libs/rs/scriptc/rs_graphics.rsh
@@ -77,6 +77,23 @@
 extern void __attribute__((overloadable))
     rsgFontColor(float, float, float, float);
 
+extern void __attribute__((overloadable))
+    rsgMeshComputeBoundingBox(rs_mesh mesh, float *minX, float *minY, float *minZ,
+                                                float *maxX, float *maxY, float *maxZ);
+void __attribute__((overloadable))
+rsgMeshComputeBoundingBox(rs_mesh mesh, float3 *bBoxMin, float3 *bBoxMax) {
+    float x1, y1, z1, x2, y2, z2;
+    rsgMeshComputeBoundingBox(mesh, &x1, &y1, &z1, &x2, &y2, &z2);
+    bBoxMin->x = x1;
+    bBoxMin->y = y1;
+    bBoxMin->z = z1;
+    bBoxMax->x = x2;
+    bBoxMax->y = y2;
+    bBoxMax->z = z2;
+}
+
+
+
 ///////////////////////////////////////////////////////
 // misc
 
diff --git a/packages/SystemUI/res/drawable-hdpi/battery_0.png b/packages/SystemUI/res/drawable-hdpi/battery_0.png
new file mode 100644
index 0000000..f4103a8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/battery_100.png b/packages/SystemUI/res/drawable-hdpi/battery_100.png
new file mode 100644
index 0000000..061cbe5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/battery_20.png b/packages/SystemUI/res/drawable-hdpi/battery_20.png
new file mode 100644
index 0000000..0064027
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/battery_20.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/battery_40.png b/packages/SystemUI/res/drawable-hdpi/battery_40.png
new file mode 100644
index 0000000..10de0e7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/battery_40.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/battery_60.png b/packages/SystemUI/res/drawable-hdpi/battery_60.png
new file mode 100644
index 0000000..aa2b8ef
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/battery_60.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/battery_80.png b/packages/SystemUI/res/drawable-hdpi/battery_80.png
new file mode 100644
index 0000000..fe231f0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/battery_80.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/signal_0.png b/packages/SystemUI/res/drawable-hdpi/signal_0.png
new file mode 100644
index 0000000..00e36c4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/signal_100.png b/packages/SystemUI/res/drawable-hdpi/signal_100.png
new file mode 100644
index 0000000..96e52ff
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/signal_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/signal_20.png b/packages/SystemUI/res/drawable-hdpi/signal_20.png
new file mode 100644
index 0000000..c0f652a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/signal_20.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/signal_40.png b/packages/SystemUI/res/drawable-hdpi/signal_40.png
new file mode 100644
index 0000000..995dd8e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/signal_40.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/signal_60.png b/packages/SystemUI/res/drawable-hdpi/signal_60.png
new file mode 100644
index 0000000..51e31ba
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/signal_60.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/signal_80.png b/packages/SystemUI/res/drawable-hdpi/signal_80.png
new file mode 100644
index 0000000..afa656e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/signal_80.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_0.png b/packages/SystemUI/res/drawable-mdpi/battery_0.png
new file mode 100644
index 0000000..b5d36cc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_100.png b/packages/SystemUI/res/drawable-mdpi/battery_100.png
new file mode 100644
index 0000000..75cc409
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_20.png b/packages/SystemUI/res/drawable-mdpi/battery_20.png
new file mode 100644
index 0000000..c0d0030
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/battery_20.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_40.png b/packages/SystemUI/res/drawable-mdpi/battery_40.png
new file mode 100644
index 0000000..e301c08
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/battery_40.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_60.png b/packages/SystemUI/res/drawable-mdpi/battery_60.png
new file mode 100644
index 0000000..0fde1fa
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/battery_60.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_80.png b/packages/SystemUI/res/drawable-mdpi/battery_80.png
new file mode 100644
index 0000000..15c4e1c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/battery_80.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_0.png b/packages/SystemUI/res/drawable-mdpi/signal_0.png
new file mode 100644
index 0000000..6533677
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_100.png b/packages/SystemUI/res/drawable-mdpi/signal_100.png
new file mode 100644
index 0000000..e8976a2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/signal_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_20.png b/packages/SystemUI/res/drawable-mdpi/signal_20.png
new file mode 100644
index 0000000..651e2a9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/signal_20.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_40.png b/packages/SystemUI/res/drawable-mdpi/signal_40.png
new file mode 100644
index 0000000..6ba7906
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/signal_40.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_60.png b/packages/SystemUI/res/drawable-mdpi/signal_60.png
new file mode 100644
index 0000000..6d2e812
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/signal_60.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_80.png b/packages/SystemUI/res/drawable-mdpi/signal_80.png
new file mode 100644
index 0000000..a152623
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/signal_80.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/battery.xml b/packages/SystemUI/res/drawable/battery.xml
new file mode 100644
index 0000000..c2294d1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/battery.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/stat_sys_battery.xml
+**
+** Copyright 2007, 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.
+*/
+-->
+
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:maxLevel="1" android:drawable="@drawable/battery_0" />
+    <item android:maxLevel="5">
+        <animation-list android:oneshot="false">
+            <item android:drawable="@drawable/battery_0" android:duration="250" />
+            <item android:drawable="@drawable/battery_20" android:duration="250" />
+        </animation-list>
+    </item>
+    <item android:maxLevel="20" android:drawable="@drawable/battery_20" />
+    <item android:maxLevel="40" android:drawable="@drawable/battery_40" />
+    <item android:maxLevel="60" android:drawable="@drawable/battery_60" />
+    <item android:maxLevel="80" android:drawable="@drawable/battery_80" />
+    <item android:maxLevel="101" android:drawable="@drawable/battery_100" />
+</level-list>
+
diff --git a/packages/SystemUI/res/drawable/battery_charging.xml b/packages/SystemUI/res/drawable/battery_charging.xml
new file mode 100644
index 0000000..2fd0c6d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/battery_charging.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/stat_sys_battery.xml
+**
+** Copyright 2007, 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.
+*/
+-->
+
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:maxLevel="20">
+        <animation-list android:oneshot="false">
+            <item android:drawable="@drawable/battery_0" android:duration="1000" />
+            <item android:drawable="@drawable/battery_20" android:duration="1000" />
+        </animation-list>
+    </item>
+    <item android:maxLevel="40">
+        <animation-list android:oneshot="false">
+            <item android:drawable="@drawable/battery_20" android:duration="1000" />
+            <item android:drawable="@drawable/battery_40" android:duration="1000" />
+        </animation-list>
+    </item>
+    <item android:maxLevel="60">
+        <animation-list android:oneshot="false">
+            <item android:drawable="@drawable/battery_40" android:duration="1000" />
+            <item android:drawable="@drawable/battery_60" android:duration="1000" />
+        </animation-list>
+    </item>
+    <item android:maxLevel="80">
+        <animation-list android:oneshot="false">
+            <item android:drawable="@drawable/battery_60" android:duration="1000" />
+            <item android:drawable="@drawable/battery_80" android:duration="1000" />
+        </animation-list>
+    </item>
+    <item android:maxLevel="92">
+        <animation-list android:oneshot="false">
+            <item android:drawable="@drawable/battery_80" android:duration="1000" />
+            <item android:drawable="@drawable/battery_100" android:duration="1000" />
+        </animation-list>
+    </item>
+    <item android:maxLevel="101" android:drawable="@drawable/battery_100" />
+</level-list>
+
diff --git a/packages/SystemUI/res/drawable/signal.xml b/packages/SystemUI/res/drawable/signal.xml
new file mode 100644
index 0000000..8b4f56b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/signal.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/stat_sys_battery.xml
+**
+** Copyright 2007, 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.
+*/
+-->
+
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:maxLevel="01" android:drawable="@drawable/signal_0" />
+    <item android:maxLevel="20" android:drawable="@drawable/signal_20" />
+    <item android:maxLevel="40" android:drawable="@drawable/signal_40" />
+    <item android:maxLevel="60" android:drawable="@drawable/signal_60" />
+    <item android:maxLevel="80" android:drawable="@drawable/signal_80" />
+    <item android:maxLevel="101" android:drawable="@drawable/signal_100" />
+
+</level-list>
+
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_center.xml b/packages/SystemUI/res/layout-xlarge/status_bar_center.xml
index c32e997..775fea0 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_center.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_center.xml
@@ -36,18 +36,20 @@
         android:padding="2dip"
         />
     <ImageView
-        android:layout_width="wrap_content"
+        android:id="@+id/battery"
+        android:layout_width="50dip"
         android:layout_height="wrap_content"
         android:layout_alignParentLeft="true"
         android:layout_below="@id/clock"
-        android:src="@drawable/dots_empty"
+        android:src="@drawable/battery"
         />
     <ImageView
-        android:layout_width="wrap_content"
+        android:id="@+id/signal"
+        android:layout_width="50dip"
         android:layout_height="wrap_content"
         android:layout_alignParentRight="true"
         android:layout_below="@id/clock"
-        android:src="@drawable/dots_full"
+        android:src="@drawable/signal"
         />
 </RelativeLayout>
 
diff --git a/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml b/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml
index fc37900..e5b2f53 100644
--- a/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml
+++ b/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml
@@ -96,6 +96,7 @@
         <TextView android:id="@+id/battery_info"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:gravity="center"
             android:layout_below="@id/battery_meter"
             />
 
@@ -121,12 +122,13 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_alignParentRight="true"
-            android:src="@drawable/dots_full"
+            android:src="@drawable/signal"
             />
 
         <TextView android:id="@+id/signal_info"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:gravity="center"
             android:layout_below="@id/signal_meter"
             />
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
index 236b521..c864daa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
@@ -78,14 +78,25 @@
     private ImageButton mOrientationButton;
     private ImageButton mAirplaneButton;
 
+    private ImageView mBatteryMeter;
+    private ImageView mSignalMeter;
+
+    private TextView mBatteryText;
+    private TextView mSignalText;
+
     private final AudioManager mAudioManager;
 
 
     private BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
+            final String action = intent.getAction();
+            if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
                 mSoundButton.setAlpha(getSilentMode() ? 0x7F : 0xFF);
+            } else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
+                // hack for now
+                mBar.updateBatteryDisplay(intent.getIntExtra("level", 0), 
+                        (intent.getIntExtra("plugged", 0) != 0));
             }
         }
     };
@@ -93,6 +104,12 @@
     public void setBar(TabletStatusBarService bar) {
         mBar = bar;
     }
+
+    public void setBatteryLevel(int level, boolean plugged) {
+        mBatteryMeter.setImageResource(plugged ? R.drawable.battery_charging : R.drawable.battery);
+        mBatteryMeter.setImageLevel(level);
+        mBatteryText.setText(String.format("Battery: %d%%", level));
+    }
     
     public SystemPanel(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
@@ -151,8 +168,21 @@
             }
         });
 
-        IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
+        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+        filter.addAction(Intent.ACTION_POWER_CONNECTED);
         getContext().registerReceiver(mReceiver, filter);
+
+        mBatteryMeter = (ImageView)findViewById(R.id.battery_meter);
+        mBatteryMeter.setImageResource(R.drawable.battery);
+        mBatteryMeter.setImageLevel(0);
+        mSignalMeter = (ImageView)findViewById(R.id.signal_meter);
+        mBatteryMeter.setImageResource(R.drawable.signal);
+        mBatteryMeter.setImageLevel(0);
+
+        mBatteryText = (TextView)findViewById(R.id.battery_info);
+        mSignalText = (TextView)findViewById(R.id.signal_info);
     }
 
     public void onDetachedFromWindow() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
index 9c86f2d..b0ffaa5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
@@ -75,6 +75,9 @@
     ViewGroup mPile;
     TextView mClearButton;
 
+    ImageView mBatteryMeter;
+    ImageView mSignalMeter;
+
     NotificationIconArea.IconLayout mIconLayout;
 
     KickerController mKicker;
@@ -151,6 +154,10 @@
 
         mKicker = new KickerController((Context)this, mStatusBarView);
 
+        // System info (center)
+        mBatteryMeter = (ImageView) sb.findViewById(R.id.battery);
+        mSignalMeter = (ImageView) sb.findViewById(R.id.signal);
+
         // Add the windows
         addPanelWindows();
 
@@ -198,18 +205,27 @@
             }
         }
     }
+    
+    StatusBarIcon mBatterySBI;
+    StatusBarIcon mSignalSBI;
+    public void updateBatteryDisplay(int level, boolean plugged) {
+        if (DEBUG) Slog.d(TAG, "battery=" + level + (plugged ? " - plugged" : " - unplugged"));
+        mBatteryMeter.setImageResource(plugged ? R.drawable.battery_charging : R.drawable.battery);
+        mBatteryMeter.setImageLevel(level);
+        mSystemPanel.setBatteryLevel(level, plugged);
+    }
 
     public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
-        // TODO
+        if (DEBUG) Slog.d(TAG, "addIcon(" + slot + ") -> " + icon);
     }
 
     public void updateIcon(String slot, int index, int viewIndex,
             StatusBarIcon old, StatusBarIcon icon) {
-        // TODO
+        if (DEBUG) Slog.d(TAG, "updateIcon(" + slot + ") -> " + icon);
     }
 
     public void removeIcon(String slot, int index, int viewIndex) {
-        // TODO
+        if (DEBUG) Slog.d(TAG, "removeIcon(" + slot + ")");
     }
 
     public void addNotification(IBinder key, StatusBarNotification notification) {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
index ba1d7f5..70a4b20 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -113,7 +113,15 @@
                     flags, PixelFormat.TRANSLUCENT);
             lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
             lp.windowAnimations = com.android.internal.R.style.Animation_LockScreen;
-            lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+
+            if (mContext.getResources().getBoolean(R.bool.config_enableLockScreenRotation)) {
+                Log.d(TAG, "Rotation sensor for lock screen On!");
+                lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;
+            } else {
+                Log.d(TAG, "Rotation sensor for lock screen Off!");
+                lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+            }
+
             lp.setTitle("Keyguard");
             mWindowLayoutParams = lp;
 
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 8693294..822be46 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -645,7 +645,9 @@
             // Show LockScreen first for any screen other than Pattern unlock.
             final boolean usingLockPattern = mLockPatternUtils.getKeyguardStoredPasswordQuality()
                     == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
-            if (isSecure() && usingLockPattern) {
+
+            boolean showSlidingTab = getResources().getBoolean(R.bool.config_enableSlidingTabFirst);
+            if (isSecure() && (usingLockPattern || !showSlidingTab)) {
                 return Mode.UnlockScreen;
             } else {
                 return Mode.LockScreen;
@@ -688,7 +690,7 @@
 
     private void showTimeoutDialog() {
         int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
-        int messageId = R.string.lockscreen_too_many_failed_attempts_dialog_message;;
+        int messageId = R.string.lockscreen_too_many_failed_attempts_dialog_message;
         if(getUnlockMode() == UnlockMode.Password) {
             if(mLockPatternUtils.getKeyguardStoredPasswordQuality() ==
                 DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) {
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index b3707b0..f8c0aba 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -59,12 +59,7 @@
     private final KeyguardUpdateMonitor mUpdateMonitor;
     private final KeyguardScreenCallback mCallback;
 
-    private TextView mCarrier;
     private SlidingTab mSelector;
-    private TextView mTime;
-    private TextView mDate;
-    private TextView mStatus1;
-    private TextView mStatus2;
     private TextView mScreenLocked;
     private TextView mEmergencyCallText;
     private Button mEmergencyCallButton;
@@ -93,6 +88,8 @@
     private java.text.DateFormat mTimeFormat;
     private boolean mEnableMenuKeyInLockScreen;
 
+    private StatusView mStatusView;
+
     /**
      * The status of this lock screen.
      */
@@ -195,14 +192,7 @@
             inflater.inflate(R.layout.keyguard_screen_tab_unlock_land, this, true);
         }
 
-        mCarrier = (TextView) findViewById(R.id.carrier);
-        // Required for Marquee to work
-        mCarrier.setSelected(true);
-        mCarrier.setTextColor(0xffffffff);
-
-        mDate = (TextView) findViewById(R.id.date);
-        mStatus1 = (TextView) findViewById(R.id.status1);
-        mStatus2 = (TextView) findViewById(R.id.status2);
+        mStatusView = new StatusView(this, mUpdateMonitor, mLockPatternUtils);
 
         mScreenLocked = (TextView) findViewById(R.id.screenLocked);
         mSelector = (SlidingTab) findViewById(R.id.tab_selector);
@@ -427,38 +417,11 @@
     }
 
     private void refreshTimeAndDateDisplay() {
-        mDate.setText(DateFormat.format(mDateFormatString, new Date()));
+        mStatusView.refreshTimeAndDateDisplay();
     }
 
     private void updateStatusLines() {
-        if (!mStatus.showStatusLines()
-                || (mCharging == null && mNextAlarm == null)) {
-            mStatus1.setVisibility(View.INVISIBLE);
-            mStatus2.setVisibility(View.INVISIBLE);
-        } else if (mCharging != null && mNextAlarm == null) {
-            // charging only
-            mStatus1.setVisibility(View.VISIBLE);
-            mStatus2.setVisibility(View.INVISIBLE);
-
-            mStatus1.setText(mCharging);
-            mStatus1.setCompoundDrawablesWithIntrinsicBounds(mChargingIcon, null, null, null);
-        } else if (mNextAlarm != null && mCharging == null) {
-            // next alarm only
-            mStatus1.setVisibility(View.VISIBLE);
-            mStatus2.setVisibility(View.INVISIBLE);
-
-            mStatus1.setText(mNextAlarm);
-            mStatus1.setCompoundDrawablesWithIntrinsicBounds(mAlarmIcon, null, null, null);
-        } else if (mCharging != null && mNextAlarm != null) {
-            // both charging and next alarm
-            mStatus1.setVisibility(View.VISIBLE);
-            mStatus2.setVisibility(View.VISIBLE);
-
-            mStatus1.setText(mCharging);
-            mStatus1.setCompoundDrawablesWithIntrinsicBounds(mChargingIcon, null, null, null);
-            mStatus2.setText(mNextAlarm);
-            mStatus2.setCompoundDrawablesWithIntrinsicBounds(mAlarmIcon, null, null, null);
-        }
+        mStatusView.updateStatusLines(mStatus.showStatusLines(), mCharging, mChargingIcon, mAlarmIcon);
     }
 
     /** {@inheritDoc} */
@@ -508,7 +471,7 @@
         switch (status) {
             case Normal:
                 // text
-                mCarrier.setText(
+                mStatusView.setCarrierText(
                         getCarrierString(
                                 mUpdateMonitor.getTelephonyPlmn(),
                                 mUpdateMonitor.getTelephonySpn()));
@@ -524,7 +487,7 @@
             case NetworkLocked:
                 // The carrier string shows both sim card status (i.e. No Sim Card) and
                 // carrier's name and/or "Emergency Calls Only" status
-                mCarrier.setText(
+                mStatusView.setCarrierText(
                         getCarrierString(
                                 mUpdateMonitor.getTelephonyPlmn(),
                                 getContext().getText(R.string.lockscreen_network_locked_message)));
@@ -537,7 +500,7 @@
                 break;
             case SimMissing:
                 // text
-                mCarrier.setText(R.string.lockscreen_missing_sim_message_short);
+                mStatusView.setCarrierText(R.string.lockscreen_missing_sim_message_short);
                 mScreenLocked.setText(R.string.lockscreen_missing_sim_instructions);
 
                 // layout
@@ -548,7 +511,7 @@
                 break;
             case SimMissingLocked:
                 // text
-                mCarrier.setText(
+                mStatusView.setCarrierText(
                         getCarrierString(
                                 mUpdateMonitor.getTelephonyPlmn(),
                                 getContext().getText(R.string.lockscreen_missing_sim_message_short)));
@@ -562,7 +525,7 @@
                 break;
             case SimLocked:
                 // text
-                mCarrier.setText(
+                mStatusView.setCarrierText(
                         getCarrierString(
                                 mUpdateMonitor.getTelephonyPlmn(),
                                 getContext().getText(R.string.lockscreen_sim_locked_message)));
@@ -574,7 +537,7 @@
                 break;
             case SimPukLocked:
                 // text
-                mCarrier.setText(
+                mStatusView.setCarrierText(
                         getCarrierString(
                                 mUpdateMonitor.getTelephonyPlmn(),
                                 getContext().getText(R.string.lockscreen_sim_puk_locked_message)));
diff --git a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
index 60cd56c..9db86aa 100644
--- a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
@@ -30,6 +30,7 @@
 import android.telephony.TelephonyManager;
 import android.text.method.DigitsKeyListener;
 import android.text.method.TextKeyListener;
+import android.util.Log;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -50,6 +51,7 @@
 public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen,
         View.OnClickListener, KeyguardUpdateMonitor.InfoCallback, OnEditorActionListener {
 
+    private static final String TAG = "PasswordUnlockScreen";
     private final KeyguardUpdateMonitor mUpdateMonitor;
     private final KeyguardScreenCallback mCallback;
 
@@ -59,12 +61,15 @@
     private Button mEmergencyCallButton;
     private LockPatternUtils mLockPatternUtils;
     private PasswordEntryKeyboardView mKeyboardView;
+    private PasswordEntryKeyboardView mKeyboardViewAlpha;
     private PasswordEntryKeyboardHelper mKeyboardHelper;
+    private PasswordEntryKeyboardHelper mKeyboardHelperAlpha;
 
     private int mCreationOrientation;
     private int mCreationHardKeyboardHidden;
     private CountDownTimer mCountdownTimer;
-    private TextView mTitle;
+
+    private StatusView mStatusView;
 
     // To avoid accidental lockout due to events while the device in in the pocket, ignore
     // any passwords with length less than or equal to this length.
@@ -88,25 +93,43 @@
             layoutInflater.inflate(R.layout.keyguard_screen_password_landscape, this, true);
         }
 
+        mStatusView = new StatusView(this, mUpdateMonitor, mLockPatternUtils);
+
         final int quality = lockPatternUtils.getKeyguardStoredPasswordQuality();
         mIsAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == quality
                 || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == quality
                 || DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == quality;
 
         mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard);
+        mKeyboardViewAlpha = (PasswordEntryKeyboardView) findViewById(R.id.keyboardAlpha);
         mPasswordEntry = (EditText) findViewById(R.id.passwordEntry);
         mPasswordEntry.setOnEditorActionListener(this);
         mEmergencyCallButton = (Button) findViewById(R.id.emergencyCall);
         mEmergencyCallButton.setOnClickListener(this);
         mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
-        mTitle = (TextView) findViewById(R.id.enter_password_label);
 
-        mKeyboardHelper = new PasswordEntryKeyboardHelper(context, mKeyboardView, this);
-        mKeyboardHelper.setKeyboardMode(mIsAlpha ? PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA
-                : PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
+        mKeyboardHelper = new PasswordEntryKeyboardHelper(context, mKeyboardView, this, false);
+        if (mKeyboardViewAlpha == null || !mIsAlpha) {
+            mKeyboardHelper.setKeyboardMode(mIsAlpha ?
+                    PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA
+                    : PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
+            mKeyboardView.setVisibility(
+                    mCreationHardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO
+                    ? View.INVISIBLE : View.VISIBLE);
+        } else {
+            mKeyboardHelperAlpha = new PasswordEntryKeyboardHelper(context, mKeyboardViewAlpha,
+                    this, false);
+            mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
+            mKeyboardHelperAlpha.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA);
+            mKeyboardView.setVisibility(View.GONE);
+            mKeyboardViewAlpha.setVisibility(
+                    mCreationHardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO
+                    ? View.INVISIBLE : View.VISIBLE);
+            mPasswordEntry.setWidth(mKeyboardViewAlpha.getLayoutParams().width);
+        }
 
-        mKeyboardView.setVisibility(mCreationHardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO
-                ? View.INVISIBLE : View.VISIBLE);
+        mPasswordEntry.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_lock, 0,
+                0, 0);
         mPasswordEntry.requestFocus();
 
         // This allows keyboards with overlapping qwerty/numeric keys to choose just the
@@ -115,11 +138,20 @@
             mPasswordEntry.setKeyListener(TextKeyListener.getInstance());
         } else {
             mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
-            mTitle.setText(R.string.keyguard_password_enter_pin_password_code);
+            mStatusView.setInstructionText(R.string.keyguard_password_enter_pin_password_code);
         }
 
         mKeyboardHelper.setVibratePattern(mLockPatternUtils.isTactileFeedbackEnabled() ?
                 com.android.internal.R.array.config_virtualKeyVibePattern : 0);
+        if (mKeyboardHelperAlpha != null) {
+            mKeyboardHelperAlpha.setVibratePattern(mLockPatternUtils.isTactileFeedbackEnabled() ?
+                    com.android.internal.R.array.config_virtualKeyVibePattern : 0);
+        }
+
+        // until we get an update...
+        mStatusView.setCarrierText(LockScreen.getCarrierString(
+                        mUpdateMonitor.getTelephonyPlmn(),
+                        mUpdateMonitor.getTelephonySpn()));
     }
 
     @Override
@@ -140,6 +172,9 @@
 
     /** {@inheritDoc} */
     public void onResume() {
+        // reset status
+        mStatusView.resetStatusInfo(mUpdateMonitor, mLockPatternUtils);
+
         // start fresh
         mPasswordEntry.setText("");
         resetStatusInfo();
@@ -179,9 +214,9 @@
                 long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
                 handleAttemptLockout(deadline);
             }
-            mTitle.setText(R.string.lockscreen_password_wrong);
+            mStatusView.setInstructionText(R.string.lockscreen_password_wrong);
         } else if (entry.length() > 0) {
-            mTitle.setText(R.string.lockscreen_password_wrong);
+            mStatusView.setInstructionText(R.string.lockscreen_password_wrong);
         }
         mPasswordEntry.setText("");
     }
@@ -199,7 +234,7 @@
                 String instructions = getContext().getString(
                         R.string.lockscreen_too_many_failed_attempts_countdown,
                         secondsRemaining);
-                mTitle.setText(instructions);
+                mStatusView.setInstructionText(instructions);
             }
 
             @Override
@@ -252,31 +287,40 @@
         return false;
     }
 
+    // ---------- InfoCallback
+
+    /** {@inheritDoc} */
+    public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) {
+        mStatusView.onRefreshBatteryInfo(showBatteryInfo, pluggedIn, batteryLevel);
+    }
+
+    /** {@inheritDoc} */
+    public void onTimeChanged() {
+        mStatusView.onTimeChanged();
+    }
+
+    /** {@inheritDoc} */
+    public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
+        mStatusView.onRefreshCarrierInfo(plmn, spn);
+    }
+
+    /** {@inheritDoc} */
+    public void onRingerModeChanged(int state) {
+        // not currently used
+    }
+
+    // ---------- SimStateCallback
+
+    /** {@inheritDoc} */
     public void onPhoneStateChanged(String newState) {
         mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
     }
 
-    public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) {
-
-    }
-
-    public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
-
-    }
-
-    public void onRingerModeChanged(int state) {
-
-    }
-
-    public void onTimeChanged() {
-
-    }
-
     private void resetStatusInfo() {
         if(mIsAlpha) {
-            mTitle.setText(R.string.keyguard_password_enter_password_code);
+            mStatusView.setInstructionText(R.string.keyguard_password_enter_password_code);
         } else {
-            mTitle.setText(R.string.keyguard_password_enter_pin_password_code);
+            mStatusView.setInstructionText(R.string.keyguard_password_enter_pin_password_code);
         }
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
index 418e243..35fa3e5 100644
--- a/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
@@ -25,9 +25,6 @@
 import android.view.ViewGroup;
 import android.view.MotionEvent;
 import android.widget.Button;
-import android.widget.TextView;
-import android.text.format.DateFormat;
-import android.text.TextUtils;
 import android.util.Log;
 import com.android.internal.R;
 import com.android.internal.telephony.IccCard;
@@ -37,7 +34,6 @@
 import com.android.internal.widget.LockPatternView.Cell;
 
 import java.util.List;
-import java.util.Date;
 
 /**
  * This is the screen that shows the 9 circle unlock widget and instructs
@@ -75,27 +71,7 @@
      */
     private boolean mEnableFallback;
 
-    private String mDateFormatString;
-
-    private TextView mCarrier;
-    private TextView mDate;
-
-    // are we showing battery information?
-    private boolean mShowingBatteryInfo = false;
-
-    // last known plugged in state
-    private boolean mPluggedIn = false;
-
-    // last known battery level
-    private int mBatteryLevel = 100;
-
-    private String mNextAlarm = null;
-
-    private String mInstructions = null;
-    private TextView mStatus1;
-    private TextView mStatusSep;
-    private TextView mStatus2;
-
+    private StatusView mStatusView;
 
     private LockPatternView mLockPatternView;
 
@@ -133,15 +109,18 @@
     private void updateFooter(FooterMode mode) {
         switch (mode) {
             case Normal:
+                Log.d(TAG, "mode normal");
                 mFooterNormal.setVisibility(View.VISIBLE);
                 mFooterForgotPattern.setVisibility(View.GONE);
                 break;
             case ForgotLockPattern:
+                Log.d(TAG, "mode ForgotLockPattern");
                 mFooterNormal.setVisibility(View.GONE);
                 mFooterForgotPattern.setVisibility(View.VISIBLE);
                 mForgotPatternButton.setVisibility(View.VISIBLE);
                 break;
             case VerifyUnlocked:
+                Log.d(TAG, "mode VerifyUnlocked");
                 mFooterNormal.setVisibility(View.GONE);
                 mFooterForgotPattern.setVisibility(View.GONE);
         }
@@ -180,24 +159,16 @@
         mCreationOrientation = configuration.orientation;
 
         LayoutInflater inflater = LayoutInflater.from(context);
+
         if (mCreationOrientation != Configuration.ORIENTATION_LANDSCAPE) {
+            Log.d(TAG, "portrait mode");
             inflater.inflate(R.layout.keyguard_screen_unlock_portrait, this, true);
         } else {
+            Log.d(TAG, "landscape mode");
             inflater.inflate(R.layout.keyguard_screen_unlock_landscape, this, true);
         }
 
-        mCarrier = (TextView) findViewById(R.id.carrier);
-        mDate = (TextView) findViewById(R.id.date);
-
-        mDateFormatString = getContext().getString(R.string.full_wday_month_day_no_year);
-        refreshTimeAndDateDisplay();
-
-        mStatus1 = (TextView) findViewById(R.id.status1);
-        mStatusSep = (TextView) findViewById(R.id.statusSep);
-        mStatus2 = (TextView) findViewById(R.id.status2);
-
-        resetStatusInfo();
-
+        mStatusView = new StatusView(this, mUpdateMonitor, mLockPatternUtils);
 
         mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern);
 
@@ -249,15 +220,11 @@
         updateMonitor.registerSimStateCallback(this);
         setFocusableInTouchMode(true);
 
-        // Required to get Marquee to work.
-        mCarrier.setSelected(true);
-        mCarrier.setTextColor(0xffffffff);
-
         // until we get an update...
-        mCarrier.setText(
-                LockScreen.getCarrierString(
+        mStatusView.setCarrierText(LockScreen.getCarrierString(
                         mUpdateMonitor.getTelephonyPlmn(),
                         mUpdateMonitor.getTelephonySpn()));
+
     }
 
     private void refreshEmergencyButtonText() {
@@ -270,88 +237,6 @@
         mEnableFallback = state;
     }
 
-    private void resetStatusInfo() {
-        mInstructions = null;
-        mShowingBatteryInfo = mUpdateMonitor.shouldShowBatteryInfo();
-        mPluggedIn = mUpdateMonitor.isDevicePluggedIn();
-        mBatteryLevel = mUpdateMonitor.getBatteryLevel();
-        mNextAlarm = mLockPatternUtils.getNextAlarm();
-        updateStatusLines();
-    }
-
-    private void updateStatusLines() {
-        if (mInstructions != null) {
-            // instructions only
-            mStatus1.setText(mInstructions);
-            if (TextUtils.isEmpty(mInstructions)) {
-                mStatus1.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
-            } else {
-                mStatus1.setCompoundDrawablesWithIntrinsicBounds(
-                        R.drawable.ic_lock_idle_lock, 0, 0, 0);
-            }
-
-            mStatus1.setVisibility(View.VISIBLE);
-            mStatusSep.setVisibility(View.GONE);
-            mStatus2.setVisibility(View.GONE);
-        } else if (mShowingBatteryInfo && mNextAlarm == null) {
-            // battery only
-            if (mPluggedIn) {
-              if (mBatteryLevel >= 100) {
-                mStatus1.setText(getContext().getString(R.string.lockscreen_charged));
-              } else {
-                  mStatus1.setText(getContext().getString(R.string.lockscreen_plugged_in, mBatteryLevel));
-              }
-            } else {
-                mStatus1.setText(getContext().getString(R.string.lockscreen_low_battery));
-            }
-            mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_charging, 0, 0, 0);
-
-            mStatus1.setVisibility(View.VISIBLE);
-            mStatusSep.setVisibility(View.GONE);
-            mStatus2.setVisibility(View.GONE);
-
-        } else if (mNextAlarm != null && !mShowingBatteryInfo) {
-            // alarm only
-            mStatus1.setText(mNextAlarm);
-            mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_alarm, 0, 0, 0);
-
-            mStatus1.setVisibility(View.VISIBLE);
-            mStatusSep.setVisibility(View.GONE);
-            mStatus2.setVisibility(View.GONE);
-        } else if (mNextAlarm != null && mShowingBatteryInfo) {
-            // both battery and next alarm
-            mStatus1.setText(mNextAlarm);
-            mStatusSep.setText("|");
-            mStatus2.setText(getContext().getString(
-                    R.string.lockscreen_battery_short,
-                    Math.min(100, mBatteryLevel)));
-            mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_alarm, 0, 0, 0);
-            if (mPluggedIn) {
-                mStatus2.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_charging, 0, 0, 0);
-            } else {
-                mStatus2.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
-            }
-
-            mStatus1.setVisibility(View.VISIBLE);
-            mStatusSep.setVisibility(View.VISIBLE);
-            mStatus2.setVisibility(View.VISIBLE);
-        } else {
-            // nothing specific to show; show general instructions
-            mStatus1.setText(R.string.lockscreen_pattern_instructions);
-            mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_lock, 0, 0, 0);
-
-            mStatus1.setVisibility(View.VISIBLE);
-            mStatusSep.setVisibility(View.GONE);
-            mStatus2.setVisibility(View.GONE);
-        }
-    }
-
-
-    private void refreshTimeAndDateDisplay() {
-        mDate.setText(DateFormat.format(mDateFormatString, new Date()));
-    }
-
-
     @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
         // as long as the user is entering a pattern (i.e sending a touch
@@ -366,25 +251,21 @@
         return result;
     }
 
-
     // ---------- InfoCallback
 
     /** {@inheritDoc} */
     public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) {
-        mShowingBatteryInfo = showBatteryInfo;
-        mPluggedIn = pluggedIn;
-        mBatteryLevel = batteryLevel;
-        updateStatusLines();
+        mStatusView.onRefreshBatteryInfo(showBatteryInfo, pluggedIn, batteryLevel);
     }
 
     /** {@inheritDoc} */
     public void onTimeChanged() {
-        refreshTimeAndDateDisplay();
+        mStatusView.onTimeChanged();
     }
 
     /** {@inheritDoc} */
     public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
-        mCarrier.setText(LockScreen.getCarrierString(plmn, spn));
+        mStatusView.onRefreshCarrierInfo(plmn, spn);
     }
 
     /** {@inheritDoc} */
@@ -444,8 +325,8 @@
 
     /** {@inheritDoc} */
     public void onResume() {
-        // reset header
-        resetStatusInfo();
+        // reset status
+        mStatusView.resetStatusInfo(mUpdateMonitor, mLockPatternUtils);
 
         // reset lock pattern
         mLockPatternView.enableInput();
@@ -514,8 +395,8 @@
             if (mLockPatternUtils.checkPattern(pattern)) {
                 mLockPatternView
                         .setDisplayMode(LockPatternView.DisplayMode.Correct);
-                mInstructions = "";
-                updateStatusLines();
+                mStatusView.setInstructions("");
+                mStatusView.updateStatusLines();
                 mCallback.keyguardDone(true);
                 mCallback.reportSuccessfulUnlockAttempt();
             } else {
@@ -533,8 +414,9 @@
                     handleAttemptLockout(deadline);
                 } else {
                     // TODO mUnlockIcon.setVisibility(View.VISIBLE);
-                    mInstructions = getContext().getString(R.string.lockscreen_pattern_wrong);
-                    updateStatusLines();
+                    mStatusView.setInstructions(
+                            getContext().getString(R.string.lockscreen_pattern_wrong));
+                    mStatusView.updateStatusLines();
                     mLockPatternView.postDelayed(
                             mCancelPatternRunnable,
                             PATTERN_CLEAR_TIMEOUT_MS);
@@ -552,17 +434,18 @@
             @Override
             public void onTick(long millisUntilFinished) {
                 int secondsRemaining = (int) (millisUntilFinished / 1000);
-                mInstructions = getContext().getString(
+                mStatusView.setInstructions(getContext().getString(
                         R.string.lockscreen_too_many_failed_attempts_countdown,
-                        secondsRemaining);
-                updateStatusLines();
+                        secondsRemaining));
+                mStatusView.updateStatusLines();
             }
 
             @Override
             public void onFinish() {
                 mLockPatternView.setEnabled(true);
-                mInstructions = getContext().getString(R.string.lockscreen_pattern_instructions);
-                updateStatusLines();
+                mStatusView.setInstructions(getContext().getString(
+                        R.string.lockscreen_pattern_instructions));
+                mStatusView.updateStatusLines();
                 // TODO mUnlockIcon.setVisibility(View.VISIBLE);
                 mFailedPatternAttemptsSinceLastTimeout = 0;
                 if (mEnableFallback) {
diff --git a/policy/src/com/android/internal/policy/impl/StatusView.java b/policy/src/com/android/internal/policy/impl/StatusView.java
new file mode 100644
index 0000000..3f08cfd
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/StatusView.java
@@ -0,0 +1,255 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+
+package com.android.internal.policy.impl;
+
+import com.android.internal.R;
+import com.android.internal.widget.LockPatternUtils;
+
+import java.util.Date;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.text.format.DateFormat;
+import android.util.Log;
+import android.view.View;
+import android.widget.TextView;
+
+class StatusView {
+    private String mDateFormatString;
+
+    private TextView mCarrier;
+    private TextView mDate;
+
+    // are we showing battery information?
+    private boolean mShowingBatteryInfo = false;
+
+    // last known plugged in state
+    private boolean mPluggedIn = false;
+
+    // last known battery level
+    private int mBatteryLevel = 100;
+
+    private String mNextAlarm = null;
+
+    private String mInstructions = null;
+    private TextView mStatus1;
+    private TextView mStatus2;
+    private TextView mPropertyOf;
+
+    private boolean mHasStatus2;
+    private boolean mHasCarrier;
+    private boolean mHasDate;
+    private boolean mHasProperty;
+
+    private View mView;
+
+    private View findViewById(int id) {
+        return mView.findViewById(id);
+    }
+
+    private Context getContext() {
+        return mView.getContext();
+    }
+
+    void setInstructions(String instructions) {
+        mInstructions = instructions;
+    }
+
+    void setCarrierText(CharSequence carrierText) {
+        if (mCarrier != null) {
+            mCarrier.setText(carrierText);
+        }
+    }
+
+    void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) {
+        mShowingBatteryInfo = showBatteryInfo;
+        mPluggedIn = pluggedIn;
+        mBatteryLevel = batteryLevel;
+        updateStatusLines();
+    }
+
+    void onTimeChanged() {
+        refreshTimeAndDateDisplay();
+    }
+
+    public void onRingerModeChanged(int state) {
+    }
+
+    void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
+        setCarrierText(LockScreen.getCarrierString(plmn, spn));
+    }
+
+    public StatusView(View view, KeyguardUpdateMonitor updateMonitor,
+                  LockPatternUtils lockPatternUtils) {
+        mView = view;
+        mCarrier = (TextView) findViewById(R.id.carrier);
+        mHasCarrier = (mCarrier != null);
+        mDate = (TextView) findViewById(R.id.date);
+        mHasDate = (mDate != null);
+        mDateFormatString = getContext().getString(R.string.full_wday_month_day_no_year);
+
+        refreshTimeAndDateDisplay();
+
+        mStatus1 = (TextView) findViewById(R.id.status1);
+        mStatus2 = (TextView) findViewById(R.id.status2);
+        mHasStatus2 = (mStatus2 != null);
+        mPropertyOf = (TextView) findViewById(R.id.propertyOf);
+        mHasProperty = (mPropertyOf != null);
+
+        resetStatusInfo(updateMonitor, lockPatternUtils);
+
+        // Required to get Marquee to work.
+        if (mHasCarrier) {
+            mCarrier.setSelected(true);
+            mCarrier.setTextColor(0xffffffff);
+        }
+
+    }
+
+    void resetStatusInfo(KeyguardUpdateMonitor updateMonitor, LockPatternUtils lockPatternUtils) {
+        mInstructions = null;
+        mShowingBatteryInfo = updateMonitor.shouldShowBatteryInfo();
+        mPluggedIn = updateMonitor.isDevicePluggedIn();
+        mBatteryLevel = updateMonitor.getBatteryLevel();
+        mNextAlarm = lockPatternUtils.getNextAlarm();
+        updateStatusLines();
+    }
+
+    void setInstructionText(int stringId) {
+        mStatus1.setText(stringId);
+        mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_lock, 0, 0, 0);
+        mStatus1.setVisibility(View.VISIBLE);
+    }
+
+    void setInstructionText(String string) {
+        mStatus1.setText(string);
+        mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_lock, 0, 0, 0);
+        mStatus1.setVisibility(View.VISIBLE);
+    }
+
+    void setCarrierText(int stringId) {
+        mCarrier.setText(stringId);
+    }
+    void setCarrierText(String string) {
+        mCarrier.setText(string);
+    }
+
+    /** Originated from PatternUnlockScreen **/
+    void updateStatusLines() {
+        if (mHasProperty) {
+            // TODO Get actual name & email
+            String name = "John Smith";
+            String email = "jsmith@gmail.com";
+            mPropertyOf.setText("Property of:\n" + name + "\n" + email);
+            mPropertyOf.setVisibility(View.VISIBLE);
+        }
+
+        if (!mHasStatus2) return;
+
+        if (mInstructions != null) {
+            // instructions only
+            mStatus1.setText(mInstructions);
+            if (TextUtils.isEmpty(mInstructions)) {
+                mStatus1.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+            } else {
+                mStatus1.setCompoundDrawablesWithIntrinsicBounds(
+                        R.drawable.ic_lock_idle_lock, 0, 0, 0);
+            }
+
+            mStatus1.setVisibility(View.VISIBLE);
+            mStatus2.setVisibility(View.INVISIBLE);
+        } else if (mShowingBatteryInfo && mNextAlarm == null) {
+            // battery only
+            if (mPluggedIn) {
+              if (mBatteryLevel >= 100) {
+                mStatus1.setText(getContext().getString(R.string.lockscreen_charged));
+              } else {
+                  mStatus1.setText(getContext().getString(R.string.lockscreen_plugged_in,
+                          mBatteryLevel));
+              }
+            } else {
+                mStatus1.setText(getContext().getString(R.string.lockscreen_low_battery));
+            }
+            mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_charging, 0,
+                    0, 0);
+
+            mStatus1.setVisibility(View.VISIBLE);
+            mStatus2.setVisibility(View.INVISIBLE);
+
+        } else if (mNextAlarm != null && !mShowingBatteryInfo) {
+            // alarm only
+            mStatus1.setText(mNextAlarm);
+            mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_alarm, 0,
+                    0, 0);
+
+            mStatus1.setVisibility(View.VISIBLE);
+            mStatus2.setVisibility(View.INVISIBLE);
+        } else if (mNextAlarm != null && mShowingBatteryInfo) {
+            // both battery and next alarm
+            mStatus1.setText(mNextAlarm);
+            mStatus2.setText(getContext().getString(
+                    R.string.lockscreen_battery_short,
+                    Math.min(100, mBatteryLevel)));
+            mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_alarm, 0,
+                    0, 0);
+            if (mPluggedIn) {
+                mStatus2.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_charging,
+                        0, 0, 0);
+            } else {
+                mStatus2.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+            }
+
+            mStatus1.setVisibility(View.VISIBLE);
+            mStatus2.setVisibility(View.VISIBLE);
+        } else {
+            // nothing specific to show; show general instructions
+            mStatus1.setText(R.string.lockscreen_pattern_instructions);
+            mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_lock, 0,
+                    0, 0);
+
+            mStatus1.setVisibility(View.VISIBLE);
+            mStatus2.setVisibility(View.INVISIBLE);
+        }
+    }
+
+    /** Originated from LockScreen **/
+    // TODO Merge with function above
+    void updateStatusLines(boolean showStatusLines, String charging, Drawable chargingIcon,
+            Drawable alarmIcon) {
+        if (!showStatusLines || (charging == null && mNextAlarm == null)) {
+            mStatus1.setVisibility(View.INVISIBLE);
+            mStatus2.setVisibility(View.INVISIBLE);
+        } else if (charging != null && mNextAlarm == null) {
+            // charging only
+            mStatus1.setVisibility(View.VISIBLE);
+            mStatus2.setVisibility(View.INVISIBLE);
+
+            mStatus1.setText(charging);
+            mStatus1.setCompoundDrawablesWithIntrinsicBounds(chargingIcon, null, null, null);
+        } else if (mNextAlarm != null && charging == null) {
+            // next alarm only
+            mStatus1.setVisibility(View.VISIBLE);
+            mStatus2.setVisibility(View.INVISIBLE);
+
+            mStatus1.setText(mNextAlarm);
+            mStatus1.setCompoundDrawablesWithIntrinsicBounds(alarmIcon, null, null, null);
+        } else if (charging != null && mNextAlarm != null) {
+            // both charging and next alarm
+            mStatus1.setVisibility(View.VISIBLE);
+            mStatus2.setVisibility(View.VISIBLE);
+
+            mStatus1.setText(charging);
+            mStatus1.setCompoundDrawablesWithIntrinsicBounds(chargingIcon, null, null, null);
+            mStatus2.setText(mNextAlarm);
+            mStatus2.setCompoundDrawablesWithIntrinsicBounds(alarmIcon, null, null, null);
+        }
+    }
+
+    void refreshTimeAndDateDisplay() {
+        if (mHasDate) {
+            mDate.setText(DateFormat.format(mDateFormatString, new Date()));
+        }
+    }
+
+}
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 1c7faa4..6e7633e 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1675,6 +1675,9 @@
     float masterVolume = mMasterVolume;
     bool  masterMute = mMasterMute;
 
+    if (masterMute) {
+        masterVolume = 0;
+    }
 #ifdef LVMX
     bool tracksConnectedChanged = false;
     bool stateChanged = false;
@@ -1696,10 +1699,7 @@
     // Delegate master volume control to effect in output mix effect chain if needed
     sp<EffectChain> chain = getEffectChain_l(AudioSystem::SESSION_OUTPUT_MIX);
     if (chain != 0) {
-        uint32_t v = 0;
-        if (!masterMute) {
-            v = (uint32_t)(masterVolume * (1 << 24));
-        }
+        uint32_t v = (uint32_t)(masterVolume * (1 << 24));
         chain->setVolume_l(&v, &v);
         masterVolume = (float)((v + (1 << 23)) >> 24);
         chain.clear();
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 8b0a9de..b0fa0f5 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1385,7 +1385,7 @@
      * Normalize a phone number by removing the characters other than digits. If
      * the given number has keypad letters, the letters will be converted to
      * digits first.
-     * 
+     *
      * @param phoneNumber
      *            the number to be normalized.
      * @return the normalized number.
@@ -1397,9 +1397,9 @@
         int len = phoneNumber.length();
         for (int i = 0; i < len; i++) {
             char c = phoneNumber.charAt(i);
-            if (PhoneNumberUtils.isISODigit(c)) {
+            if ((i == 0 && c == '+') || PhoneNumberUtils.isISODigit(c)) {
                 sb.append(c);
-            } else if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') {
+            } else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
                 return normalizeNumber(PhoneNumberUtils.convertKeypadLettersToDigits(phoneNumber));
             }
         }
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
index 5ef1c69..88aa78ef 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
@@ -524,6 +524,7 @@
         assertEquals("6502910000", PhoneNumberUtils.normalizeNumber("650 2910000"));
         assertEquals("1234567", PhoneNumberUtils.normalizeNumber("12,3#4*567"));
         assertEquals("8004664114", PhoneNumberUtils.normalizeNumber("800-GOOG-114"));
+        assertEquals("+16502910000", PhoneNumberUtils.normalizeNumber("+1 650 2910000"));
     }
 
 }
diff --git a/tests/DumpRenderTree2/Android.mk b/tests/DumpRenderTree2/Android.mk
index eddbb4b..81fc633 100644
--- a/tests/DumpRenderTree2/Android.mk
+++ b/tests/DumpRenderTree2/Android.mk
@@ -1,3 +1,18 @@
+#
+# 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.
+#
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
diff --git a/tests/DumpRenderTree2/assets/run-apache2.py b/tests/DumpRenderTree2/assets/run-apache2.py
index d7590ee..cffbe37 100644
--- a/tests/DumpRenderTree2/assets/run-apache2.py
+++ b/tests/DumpRenderTree2/assets/run-apache2.py
@@ -1,5 +1,19 @@
 #!/usr/bin/python
-
+#
+# 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.
+#
 """Start, stop, or restart apache2 server.
 
   Apache2 must be installed with mod_php!
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/TextActivity.java b/tests/HwAccelerationTest/src/com/google/android/test/hwui/TextActivity.java
index 59f665c..8af1b7b 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/TextActivity.java
+++ b/tests/HwAccelerationTest/src/com/google/android/test/hwui/TextActivity.java
@@ -65,8 +65,16 @@
             canvas.drawText("Hello OpenGL renderer!", 100, 60, mMediumPaint);
             mMediumPaint.setTextAlign(Paint.Align.LEFT);
             canvas.drawText("Hello OpenGL renderer!", 100, 100, mMediumPaint);
+            mMediumPaint.setShadowLayer(2.5f, 0.0f, 0.0f, 0xff000000);
+            canvas.drawText("Hello OpenGL renderer!", 100, 150, mMediumPaint);
+            mMediumPaint.clearShadowLayer();
             canvas.drawText("Hello OpenGL renderer!", 100, 200, mLargePaint);
-            
+
+            mLargePaint.setShadowLayer(2.5f, 3.0f, 3.0f, 0xff000000);
+            canvas.drawText("Hello OpenGL renderer!", 100, 400, mLargePaint);
+            mLargePaint.setShadowLayer(3.0f, 3.0f, 3.0f, 0xff00ff00);
+            canvas.drawText("Hello OpenGL renderer!", 100, 500, mLargePaint);
+            mLargePaint.clearShadowLayer();
             
             canvas.drawText("Hello OpenGL renderer!", 500, 40, mStrikePaint);
             mStrikePaint.setStrikeThruText(true);
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index d6cfb12..e4f447e 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -1830,6 +1830,16 @@
             continue;
         }
 
+        if (bundle->getMaxResVersion() != NULL && group.version.length() != 0) {
+            int maxResInt = atoi(bundle->getMaxResVersion());
+            const char *verString = group.version.string();
+            int dirVersionInt = atoi(verString + 1); // skip 'v' in version name
+            if (dirVersionInt > maxResInt) {
+              fprintf(stderr, "max res %d, skipping %s\n", maxResInt, entry->d_name);
+              continue;
+            }
+        }
+
         FileType type = getFileType(subdirName.string());
 
         if (type == kFileTypeDirectory) {
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 3308a35..6a1f2d5 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -45,6 +45,7 @@
           mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),
           mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
           mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL),
+          mMaxResVersion(NULL),
           mArgc(0), mArgv(NULL)
         {}
     ~Bundle(void) {}
@@ -134,6 +135,8 @@
     void setVersionName(const char* val) { mVersionName = val; }
     const char* getCustomPackage() const { return mCustomPackage; }
     void setCustomPackage(const char* val) { mCustomPackage = val; }
+    const char* getMaxResVersion() const { return mMaxResVersion; }
+    void setMaxResVersion(const char * val) { mMaxResVersion = val; }
 
     /*
      * Set and get the file specification.
@@ -230,6 +233,7 @@
     const char* mVersionCode;
     const char* mVersionName;
     const char* mCustomPackage;
+    const char* mMaxResVersion;
 
     /* file specification */
     int         mArgc;
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index b0c6e39..f457cc8 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -62,6 +62,7 @@
         "        [--rename-manifest-package PACKAGE] \\\n"
         "        [--rename-instrumentation-target-package PACKAGE] \\\n"
         "        [--utf16] [--auto-add-overlay] \\\n"
+        "        [--max-res-version VAL] \\\n"
         "        [-I base-package [-I base-package ...]] \\\n"
         "        [-A asset-source-dir]  [-G class-list-file] [-P public-definitions-file] \\\n"
         "        [-S resource-sources [-S resource-sources ...]] "
@@ -128,6 +129,8 @@
         "       higher, the default encoding for resources will be in UTF-8.\n"
         "   --target-sdk-version\n"
         "       inserts android:targetSdkVersion in to manifest.\n"
+        "   --max-res-version\n"
+        "       ignores versioned resource directories above the given value.\n"
         "   --values\n"
         "       when used with \"dump resources\" also includes resource values.\n"
         "   --version-code\n"
@@ -416,6 +419,15 @@
                         goto bail;
                     }
                     bundle.setMaxSdkVersion(argv[0]);
+                } else if (strcmp(cp, "-max-res-version") == 0) {
+                    argc--;
+                    argv++;
+                    if (!argc) {
+                        fprintf(stderr, "ERROR: No argument supplied for '--max-res-version' option\n");
+                        wantUsage = true;
+                        goto bail;
+                    }
+                    bundle.setMaxResVersion(argv[0]);
                 } else if (strcmp(cp, "-version-code") == 0) {
                     argc--;
                     argv++;