Fix 2402303: Split Keyboard widget from LatinIME into reusable PasswordEntryKeyboardView

- Added new PasswordEntryKeyboardView to internal/widgets.  Widget supports:
	- alpha mode with symbols (latin-1 only).
	- a numeric keyboard
	- IME emulation that applies keyboard input to arbitrary top-level view widget.
- Added new transparent assets to framework resources.
- Modified Keyguard and Keyguard layouts to use new PasswordEntryKeyboardView.
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
old mode 100755
new mode 100644
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
new file mode 100644
index 0000000..51f7f69
--- /dev/null
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * 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.internal.widget;
+
+import java.util.Locale;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.Paint.Align;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.inputmethodservice.Keyboard;
+import android.inputmethodservice.KeyboardView;
+import android.util.Log;
+import com.android.internal.R;
+
+/**
+ * A basic, embed-able keyboard designed for password entry. Allows entry of all Latin-1 characters.
+ *
+ * It has two modes: alpha and numeric. In alpha mode, it allows all Latin-1 characters and enables
+ * an additional keyboard with symbols.  In numeric mode, it shows a 12-key DTMF dialer-like
+ * keypad with alpha characters hints.
+ */
+public class PasswordEntryKeyboard extends Keyboard {
+    private static final String TAG = "PasswordEntryKeyboard";
+    private static final int SHIFT_OFF = 0;
+    private static final int SHIFT_ON = 1;
+    private static final int SHIFT_LOCKED = 2;
+    public static final int KEYCODE_SPACE = ' ';
+
+    private Drawable mShiftIcon;
+    private Drawable mShiftLockIcon;
+    private Drawable mShiftLockPreviewIcon;
+    private Drawable mOldShiftIcon;
+    private Drawable mOldShiftPreviewIcon;
+    private Drawable mSpaceIcon;
+    private Key mShiftKey;
+    private Key mEnterKey;
+    private Key mF1Key;
+    private Key mSpaceKey;
+    private Locale mLocale;
+    private Resources mRes;
+    private int mExtensionResId;
+    private int mShiftState = SHIFT_OFF;
+
+    static int sSpacebarVerticalCorrection;
+
+    public PasswordEntryKeyboard(Context context, int xmlLayoutResId) {
+        this(context, xmlLayoutResId, 0);
+    }
+
+    public PasswordEntryKeyboard(Context context, int xmlLayoutResId, int mode) {
+        super(context, xmlLayoutResId, mode);
+        final Resources res = context.getResources();
+        mRes = res;
+        mShiftIcon = res.getDrawable(R.drawable.sym_keyboard_shift);
+        mShiftLockIcon = res.getDrawable(R.drawable.sym_keyboard_shift_locked);
+        mShiftLockPreviewIcon = res.getDrawable(R.drawable.sym_keyboard_feedback_shift_locked);
+        mShiftLockPreviewIcon.setBounds(0, 0,
+                mShiftLockPreviewIcon.getIntrinsicWidth(),
+                mShiftLockPreviewIcon.getIntrinsicHeight());
+        mSpaceIcon = res.getDrawable(R.drawable.sym_keyboard_space);
+        sSpacebarVerticalCorrection = res.getDimensionPixelOffset(
+                R.dimen.password_keyboard_spacebar_vertical_correction);
+    }
+
+    public PasswordEntryKeyboard(Context context, int layoutTemplateResId,
+            CharSequence characters, int columns, int horizontalPadding) {
+        super(context, layoutTemplateResId, characters, columns, horizontalPadding);
+    }
+
+    @Override
+    protected Key createKeyFromXml(Resources res, Row parent, int x, int y,
+            XmlResourceParser parser) {
+        LatinKey key = new LatinKey(res, parent, x, y, parser);
+        final int code = key.codes[0];
+        if (code >=0 && code != '\n' && (code < 32 || code > 127)) {
+            Log.w(TAG, "Key code for " + key.label + " is not latin-1");
+            key.label = " ";
+            key.setEnabled(false);
+        }
+        switch (key.codes[0]) {
+            case 10:
+                mEnterKey = key;
+                break;
+            case PasswordEntryKeyboardView.KEYCODE_F1:
+                mF1Key = key;
+                break;
+            case 32:
+                mSpaceKey = key;
+                break;
+        }
+        return key;
+    }
+
+    /**
+     * Allows enter key resources to be overridden
+     * @param res resources to grab given items from
+     * @param previewId preview drawable shown on enter key
+     * @param iconId normal drawable shown on enter key
+     * @param labelId string shown on enter key
+     */
+    void setEnterKeyResources(Resources res, int previewId, int iconId, int labelId) {
+        if (mEnterKey != null) {
+            // Reset some of the rarely used attributes.
+            mEnterKey.popupCharacters = null;
+            mEnterKey.popupResId = 0;
+            mEnterKey.text = null;
+
+            mEnterKey.iconPreview = res.getDrawable(previewId);
+            mEnterKey.icon = res.getDrawable(iconId);
+            mEnterKey.label = res.getText(labelId);
+
+            // Set the initial size of the preview icon
+            if (mEnterKey.iconPreview != null) {
+                mEnterKey.iconPreview.setBounds(0, 0,
+                        mEnterKey.iconPreview.getIntrinsicWidth(),
+                        mEnterKey.iconPreview.getIntrinsicHeight());
+            }
+        }
+    }
+
+    /**
+     * Allows shiftlock to be turned on.  See {@link #setShiftLocked(boolean)}
+     *
+     */
+    void enableShiftLock() {
+        int index = getShiftKeyIndex();
+        if (index >= 0) {
+            mShiftKey = getKeys().get(index);
+            if (mShiftKey instanceof LatinKey) {
+                ((LatinKey)mShiftKey).enableShiftLock();
+            }
+            mOldShiftIcon = mShiftKey.icon;
+            mOldShiftPreviewIcon = mShiftKey.iconPreview;
+        }
+    }
+
+    /**
+     * Turn on shift lock. This turns on the LED for this key, if it has one.
+     * It should be followed by a call to {@link KeyboardView#invalidateKey(int)}
+     * or {@link KeyboardView#invalidateAllKeys()}
+     *
+     * @param shiftLocked
+     */
+    void setShiftLocked(boolean shiftLocked) {
+        if (mShiftKey != null) {
+            if (shiftLocked) {
+                mShiftKey.on = true;
+                mShiftKey.icon = mShiftLockIcon;
+                mShiftState = SHIFT_LOCKED;
+            } else {
+                mShiftKey.on = false;
+                mShiftKey.icon = mShiftLockIcon;
+                mShiftState = SHIFT_ON;
+            }
+        }
+    }
+
+    /**
+     * Turn on shift mode. Sets shift mode and turns on icon for shift key.
+     * It should be followed by a call to {@link KeyboardView#invalidateKey(int)}
+     * or {@link KeyboardView#invalidateAllKeys()}
+     *
+     * @param shiftLocked
+     */
+    @Override
+    public boolean setShifted(boolean shiftState) {
+        boolean shiftChanged = false;
+        if (mShiftKey != null) {
+            if (shiftState == false) {
+                shiftChanged = mShiftState != SHIFT_OFF;
+                mShiftState = SHIFT_OFF;
+                mShiftKey.on = false;
+                mShiftKey.icon = mOldShiftIcon;
+            } else if (mShiftState == SHIFT_OFF) {
+                shiftChanged = mShiftState == SHIFT_OFF;
+                mShiftState = SHIFT_ON;
+                mShiftKey.on = false;
+                mShiftKey.icon = mShiftIcon;
+            }
+        } else {
+            return super.setShifted(shiftState);
+        }
+        return shiftChanged;
+    }
+
+    /**
+     * Whether or not keyboard is shifted.
+     * @return true if keyboard state is shifted.
+     */
+    @Override
+    public boolean isShifted() {
+        if (mShiftKey != null) {
+            return mShiftState != SHIFT_OFF;
+        } else {
+            return super.isShifted();
+        }
+    }
+
+    /**
+     * Sets keyboard extension. Keyboard extension is shown when input is detected above keyboard
+     * while keyboard has focus.
+     *
+     * @param resId
+     */
+    public void setExtension(int resId) {
+        mExtensionResId = resId;
+    }
+
+    /**
+     * Get current extesion resource id.
+     *
+     * @return resource id, 0 if not set.
+     */
+    public int getExtension() {
+        return mExtensionResId;
+    }
+
+    private void updateSpaceBarForLocale() {
+        if (mLocale != null) {
+            // Create the graphic for spacebar
+            Bitmap buffer = Bitmap.createBitmap(mSpaceKey.width, mSpaceIcon.getIntrinsicHeight(),
+                    Bitmap.Config.ARGB_8888);
+            Canvas canvas = new Canvas(buffer);
+            canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
+            Paint paint = new Paint();
+            paint.setAntiAlias(true);
+            // TODO: Make the text size a customizable attribute
+            paint.setTextSize(22);
+            paint.setTextAlign(Align.CENTER);
+            // Draw a drop shadow for the text
+            paint.setShadowLayer(1f, 0, 0, 0xFF000000);
+            paint.setColor(0x80C0C0C0);
+            canvas.drawText(mLocale.getDisplayLanguage(mLocale),
+                    buffer.getWidth() / 2, - paint.ascent() + 2, paint);
+            int x = (buffer.getWidth() - mSpaceIcon.getIntrinsicWidth()) / 2;
+            int y = buffer.getHeight() - mSpaceIcon.getIntrinsicHeight();
+            mSpaceIcon.setBounds(x, y,
+                    x + mSpaceIcon.getIntrinsicWidth(), y + mSpaceIcon.getIntrinsicHeight());
+            mSpaceIcon.draw(canvas);
+            mSpaceKey.icon = new BitmapDrawable(mRes, buffer);
+            mSpaceKey.repeatable = false;
+        } else {
+            mSpaceKey.icon = mRes.getDrawable(R.drawable.sym_keyboard_space);
+            mSpaceKey.repeatable = true;
+        }
+    }
+
+    public void setLanguage(Locale locale) {
+        if (mLocale != null && mLocale.equals(locale)) return;
+        mLocale = locale;
+        updateSpaceBarForLocale();
+    }
+
+    static class LatinKey extends Keyboard.Key {
+        private boolean mShiftLockEnabled;
+        private boolean mEnabled = true;
+
+        public LatinKey(Resources res, Keyboard.Row parent, int x, int y,
+                XmlResourceParser parser) {
+            super(res, parent, x, y, parser);
+            if (popupCharacters != null && popupCharacters.length() == 0) {
+                // If there is a keyboard with no keys specified in popupCharacters
+                popupResId = 0;
+            }
+        }
+
+        void setEnabled(boolean enabled) {
+            mEnabled = enabled;
+        }
+
+        void enableShiftLock() {
+            mShiftLockEnabled = true;
+        }
+
+        @Override
+        public void onReleased(boolean inside) {
+            if (!mShiftLockEnabled) {
+                super.onReleased(inside);
+            } else {
+                pressed = !pressed;
+            }
+        }
+
+        /**
+         * Overriding this method so that we can reduce the target area for certain keys.
+         */
+        @Override
+        public boolean isInside(int x, int y) {
+            if (!mEnabled) {
+                return false;
+            }
+            final int code = codes[0];
+            if (code == KEYCODE_SHIFT || code == KEYCODE_DELETE) {
+                y -= height / 10;
+                if (code == KEYCODE_SHIFT) x += width / 6;
+                if (code == KEYCODE_DELETE) x -= width / 6;
+            } else if (code == KEYCODE_SPACE) {
+                y += PasswordEntryKeyboard.sSpacebarVerticalCorrection;
+            }
+            return super.isInside(x, y);
+        }
+    }
+}
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
new file mode 100644
index 0000000..b809afc
--- /dev/null
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * 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.internal.widget;
+
+import android.content.Context;
+import android.inputmethodservice.Keyboard;
+import android.inputmethodservice.KeyboardView;
+import android.inputmethodservice.KeyboardView.OnKeyboardActionListener;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.text.Editable;
+import android.text.Selection;
+import android.util.Log;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewRoot;
+import android.view.inputmethod.InputConnection;
+import android.widget.EditText;
+import com.android.internal.R;
+
+public class PasswordEntryKeyboardHelper implements OnKeyboardActionListener {
+
+    public static final int KEYBOARD_MODE_ALPHA = 0;
+    public static final int KEYBOARD_MODE_NUMERIC = 1;
+    private static final int KEYBOARD_STATE_NORMAL = 0;
+    private static final int KEYBOARD_STATE_SHIFTED = 1;
+    private static final int KEYBOARD_STATE_CAPSLOCK = 2;
+    private static final String TAG = "PasswordEntryKeyboardHelper";
+    private int mKeyboardMode = KEYBOARD_MODE_ALPHA;
+    private int mKeyboardState = KEYBOARD_STATE_NORMAL;
+    private PasswordEntryKeyboard mQwertyKeyboard;
+    private PasswordEntryKeyboard mQwertyKeyboardShifted;
+    private PasswordEntryKeyboard mSymbolsKeyboard;
+    private PasswordEntryKeyboard mSymbolsKeyboardShifted;
+    private PasswordEntryKeyboard mNumericKeyboard;
+    private Context mContext;
+    private View mTargetView;
+    private KeyboardView mKeyboardView;
+
+    public PasswordEntryKeyboardHelper(Context context, KeyboardView keyboardView, View targetView) {
+        mContext = context;
+        mTargetView = targetView;
+        mKeyboardView = keyboardView;
+        createKeyboards();
+        mKeyboardView.setOnKeyboardActionListener(this);
+    }
+
+    public boolean isAlpha() {
+        return mKeyboardMode == KEYBOARD_MODE_ALPHA;
+    }
+
+    private void createKeyboards() {
+        mNumericKeyboard = new PasswordEntryKeyboard(mContext, R.xml.password_kbd_numeric);
+        mQwertyKeyboard = new PasswordEntryKeyboard(mContext,
+                R.xml.password_kbd_qwerty, R.id.mode_normal);
+        mQwertyKeyboard.enableShiftLock();
+
+        mQwertyKeyboardShifted = new PasswordEntryKeyboard(mContext,
+                R.xml.password_kbd_qwerty_shifted,
+                R.id.mode_normal);
+        mQwertyKeyboardShifted.enableShiftLock();
+        mQwertyKeyboardShifted.setShifted(true); // always shifted.
+
+        mSymbolsKeyboard = new PasswordEntryKeyboard(mContext, R.xml.password_kbd_symbols);
+        mSymbolsKeyboard.enableShiftLock();
+
+        mSymbolsKeyboardShifted = new PasswordEntryKeyboard(mContext,
+                R.xml.password_kbd_symbols_shift);
+        mSymbolsKeyboardShifted.enableShiftLock();
+        mSymbolsKeyboardShifted.setShifted(true); // always shifted
+    }
+
+    public void setKeyboardMode(int mode) {
+        switch (mode) {
+            case KEYBOARD_MODE_ALPHA:
+                mKeyboardView.setKeyboard(mQwertyKeyboard);
+                mKeyboardState = KEYBOARD_STATE_NORMAL;
+                break;
+            case KEYBOARD_MODE_NUMERIC:
+                mKeyboardView.setKeyboard(mNumericKeyboard);
+                mKeyboardState = KEYBOARD_STATE_NORMAL;
+                break;
+        }
+        mKeyboardMode = mode;
+    }
+
+    private void sendKeyEventsToTarget(int keyEventCode) {
+        Handler handler = mTargetView.getHandler();
+        KeyEvent[] events = KeyCharacterMap.load(KeyCharacterMap.ALPHA).getEvents(
+                new char[] { (char) keyEventCode });
+        if (events != null) {
+            for (KeyEvent event : events) {
+                handler.sendMessage(handler.obtainMessage(ViewRoot.DISPATCH_KEY, event));
+            }
+        }
+    }
+
+    public void sendDownUpKeyEvents(int keyEventCode) {
+        long eventTime = SystemClock.uptimeMillis();
+        Handler handler = mTargetView.getHandler();
+        handler.sendMessage(handler.obtainMessage(ViewRoot.DISPATCH_KEY_FROM_IME,
+                new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN, keyEventCode, 0, 0, 0, 0,
+                    KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE)));
+        handler.sendMessage(handler.obtainMessage(ViewRoot.DISPATCH_KEY_FROM_IME,
+                new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_UP, keyEventCode, 0, 0, 0, 0,
+                        KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE)));
+    }
+
+    public void onKey(int primaryCode, int[] keyCodes) {
+        Log.v(TAG, "Key code = " + Integer.toHexString(primaryCode));
+        if (primaryCode == Keyboard.KEYCODE_DELETE) {
+            handleBackspace();
+        } else if (primaryCode == Keyboard.KEYCODE_SHIFT) {
+            handleShift();
+        } else if (primaryCode == Keyboard.KEYCODE_CANCEL) {
+            handleClose();
+            return;
+        } else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE && mKeyboardView != null) {
+            handleModeChange();
+        } else {
+            handleCharacter(primaryCode, keyCodes);
+            // Switch back to old keyboard if we're not in capslock mode
+            if (mKeyboardState == KEYBOARD_STATE_SHIFTED) {
+                // skip to the unlocked state
+                mKeyboardState = KEYBOARD_STATE_CAPSLOCK;
+                handleShift();
+            }
+        }
+    }
+
+    private void handleModeChange() {
+        final Keyboard current = mKeyboardView.getKeyboard();
+        Keyboard next = null;
+        if (current == mQwertyKeyboard || current == mQwertyKeyboardShifted) {
+            next = mSymbolsKeyboard;
+        } else if (current == mSymbolsKeyboard || current == mSymbolsKeyboardShifted) {
+            next = mQwertyKeyboard;
+        }
+        if (next != null) {
+            mKeyboardView.setKeyboard(next);
+            mKeyboardState = KEYBOARD_STATE_NORMAL;
+        }
+    }
+
+    private void handleBackspace() {
+        sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
+    }
+
+    private void handleShift() {
+        if (mKeyboardView == null) {
+            return;
+        }
+        Keyboard current = mKeyboardView.getKeyboard();
+        PasswordEntryKeyboard next = null;
+        final boolean isAlphaMode = current == mQwertyKeyboard
+                || current == mQwertyKeyboardShifted;
+        if (mKeyboardState == KEYBOARD_STATE_NORMAL) {
+            mKeyboardState = isAlphaMode ? KEYBOARD_STATE_SHIFTED : KEYBOARD_STATE_CAPSLOCK;
+            next = isAlphaMode ? mQwertyKeyboardShifted : mSymbolsKeyboardShifted;
+        } else if (mKeyboardState == KEYBOARD_STATE_SHIFTED) {
+            mKeyboardState = KEYBOARD_STATE_CAPSLOCK;
+            next = isAlphaMode ? mQwertyKeyboardShifted : mSymbolsKeyboardShifted;
+        } else if (mKeyboardState == KEYBOARD_STATE_CAPSLOCK) {
+            mKeyboardState = KEYBOARD_STATE_NORMAL;
+            next = isAlphaMode ? mQwertyKeyboard : mSymbolsKeyboard;
+        }
+        if (next != null) {
+            if (next != current) {
+                mKeyboardView.setKeyboard(next);
+            }
+            next.setShiftLocked(mKeyboardState == KEYBOARD_STATE_CAPSLOCK);
+            mKeyboardView.setShifted(mKeyboardState != KEYBOARD_STATE_NORMAL);
+        }
+    }
+
+    private void handleCharacter(int primaryCode, int[] keyCodes) {
+        // Maybe turn off shift if not in capslock mode.
+        if (mKeyboardView.isShifted() && primaryCode != ' ' && primaryCode != '\n') {
+            primaryCode = Character.toUpperCase(primaryCode);
+        }
+        sendKeyEventsToTarget(primaryCode);
+    }
+
+    private void handleClose() {
+
+    }
+
+    public void onPress(int primaryCode) {
+
+    }
+
+    public void onRelease(int primaryCode) {
+
+    }
+
+    public void onText(CharSequence text) {
+
+    }
+
+    public void swipeDown() {
+
+    }
+
+    public void swipeLeft() {
+
+    }
+
+    public void swipeRight() {
+
+    }
+
+    public void swipeUp() {
+
+    }
+};
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java
new file mode 100644
index 0000000..9b93fc2
--- /dev/null
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * 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.internal.widget;
+
+import android.content.Context;
+import android.inputmethodservice.Keyboard;
+import android.inputmethodservice.KeyboardView;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.widget.PopupWindow;
+import com.android.internal.R;
+
+public class PasswordEntryKeyboardView extends KeyboardView {
+
+    public static final int KEYCODE_OPTIONS = -100;
+    static final int KEYCODE_SHIFT_LONGPRESS = -101;
+    static final int KEYCODE_VOICE = -102;
+    static final int KEYCODE_F1 = -103;
+    static final int KEYCODE_NEXT_LANGUAGE = -104;
+
+    private boolean mExtensionVisible;
+    private PasswordEntryKeyboardView mExtension;
+    private PopupWindow mExtensionPopup;
+    private boolean mFirstEvent;
+
+    public PasswordEntryKeyboardView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public PasswordEntryKeyboardView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent me) {
+        if (((PasswordEntryKeyboard) getKeyboard()).getExtension() == 0) {
+            return super.onTouchEvent(me);
+        }
+        if (me.getY() < 0) {
+            if (mExtensionVisible) {
+                int action = me.getAction();
+                if (mFirstEvent) action = MotionEvent.ACTION_DOWN;
+                mFirstEvent = false;
+                MotionEvent translated = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
+                        action,
+                        me.getX(), me.getY() + mExtension.getHeight(), me.getMetaState());
+                boolean result = mExtension.onTouchEvent(translated);
+                translated.recycle();
+                if (me.getAction() == MotionEvent.ACTION_UP
+                        || me.getAction() == MotionEvent.ACTION_CANCEL) {
+                    closeExtension();
+                }
+                return result;
+            } else {
+                if (openExtension()) {
+                    MotionEvent cancel = MotionEvent.obtain(me.getDownTime(), me.getEventTime(),
+                            MotionEvent.ACTION_CANCEL, me.getX() - 100, me.getY() - 100, 0);
+                    super.onTouchEvent(cancel);
+                    cancel.recycle();
+                    if (mExtension.getHeight() > 0) {
+                        MotionEvent translated = MotionEvent.obtain(me.getEventTime(),
+                                me.getEventTime(),
+                                MotionEvent.ACTION_DOWN,
+                                me.getX(), me.getY() + mExtension.getHeight(),
+                                me.getMetaState());
+                        mExtension.onTouchEvent(translated);
+                        translated.recycle();
+                    } else {
+                        mFirstEvent = true;
+                    }
+                }
+                return true;
+            }
+        } else if (mExtensionVisible) {
+            closeExtension();
+            // Send a down event into the main keyboard first
+            MotionEvent down = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
+                    MotionEvent.ACTION_DOWN, me.getX(), me.getY(), me.getMetaState());
+            super.onTouchEvent(down);
+            down.recycle();
+            // Send the actual event
+            return super.onTouchEvent(me);
+        } else {
+            return super.onTouchEvent(me);
+        }
+    }
+
+    private boolean openExtension() {
+        if (((PasswordEntryKeyboard) getKeyboard()).getExtension() == 0) return false;
+        makePopupWindow();
+        mExtensionVisible = true;
+        return true;
+    }
+
+    private void makePopupWindow() {
+        if (mExtensionPopup == null) {
+            int[] windowLocation = new int[2];
+            mExtensionPopup = new PopupWindow(getContext());
+            mExtensionPopup.setBackgroundDrawable(null);
+            LayoutInflater li = (LayoutInflater) getContext().getSystemService(
+                    Context.LAYOUT_INFLATER_SERVICE);
+            mExtension = (PasswordEntryKeyboardView) li.inflate(
+                    R.layout.password_keyboard_input, null);
+            mExtension.setOnKeyboardActionListener(getOnKeyboardActionListener());
+            mExtension.setPopupParent(this);
+            mExtension.setPopupOffset(0, -windowLocation[1]);
+            Keyboard keyboard;
+            mExtension.setKeyboard(keyboard = new PasswordEntryKeyboard(getContext(),
+                    ((PasswordEntryKeyboard) getKeyboard()).getExtension()));
+            mExtensionPopup.setContentView(mExtension);
+            mExtensionPopup.setWidth(getWidth());
+            mExtensionPopup.setHeight(keyboard.getHeight());
+            getLocationInWindow(windowLocation);
+            // TODO: Fix the "- 30".
+            mExtension.setPopupOffset(0, -windowLocation[1] - 30);
+            mExtensionPopup.showAtLocation(this, 0, 0, -keyboard.getHeight()
+                    + windowLocation[1]);
+        } else {
+            mExtension.setVisibility(VISIBLE);
+        }
+    }
+
+    @Override
+    public void closing() {
+        super.closing();
+        if (mExtensionPopup != null && mExtensionPopup.isShowing()) {
+            mExtensionPopup.dismiss();
+            mExtensionPopup = null;
+        }
+    }
+
+    private void closeExtension() {
+        mExtension.setVisibility(INVISIBLE);
+        mExtension.closing();
+        mExtensionVisible = false;
+    }
+}
diff --git a/core/res/res/drawable-en-hdpi/sym_keyboard_delete.png b/core/res/res/drawable-en-hdpi/sym_keyboard_delete.png
new file mode 100755
index 0000000..569369e
--- /dev/null
+++ b/core/res/res/drawable-en-hdpi/sym_keyboard_delete.png
Binary files differ
diff --git a/core/res/res/drawable-en-hdpi/sym_keyboard_feedback_delete.png b/core/res/res/drawable-en-hdpi/sym_keyboard_feedback_delete.png
new file mode 100755
index 0000000..ca76375
--- /dev/null
+++ b/core/res/res/drawable-en-hdpi/sym_keyboard_feedback_delete.png
Binary files differ
diff --git a/core/res/res/drawable-en-mdpi/sym_keyboard_delete.png b/core/res/res/drawable-en-mdpi/sym_keyboard_delete.png
new file mode 100644
index 0000000..f1f7c58c
--- /dev/null
+++ b/core/res/res/drawable-en-mdpi/sym_keyboard_delete.png
Binary files differ
diff --git a/core/res/res/drawable-en-mdpi/sym_keyboard_feedback_delete.png b/core/res/res/drawable-en-mdpi/sym_keyboard_feedback_delete.png
new file mode 100644
index 0000000..3c90839
--- /dev/null
+++ b/core/res/res/drawable-en-mdpi/sym_keyboard_feedback_delete.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png
new file mode 100644
index 0000000..b6c234c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal_off.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal_off.9.png
new file mode 100644
index 0000000..9f3c087
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal_on.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal_on.9.png
new file mode 100644
index 0000000..4041342
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png
new file mode 100644
index 0000000..73a8cd1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed_off.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed_off.9.png
new file mode 100644
index 0000000..8473e8e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed_on.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed_on.9.png
new file mode 100644
index 0000000..f4f59c0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_trans_normal_off.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_trans_normal_off.9.png
new file mode 100644
index 0000000..1508653
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_trans_normal_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_trans_normal_on.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_trans_normal_on.9.png
new file mode 100644
index 0000000..66c231a
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_trans_normal_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_trans_pressed_off.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_trans_pressed_off.9.png
new file mode 100644
index 0000000..cdad182
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_trans_pressed_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_trans_pressed_on.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_trans_pressed_on.9.png
new file mode 100644
index 0000000..e95f4cf
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_trans_pressed_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/password_field_default.9.png b/core/res/res/drawable-hdpi/password_field_default.9.png
new file mode 100644
index 0000000..2c424f0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/password_field_default.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_delete.png b/core/res/res/drawable-hdpi/sym_keyboard_delete.png
new file mode 100755
index 0000000..59d78be
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_delete.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_delete_dim.png b/core/res/res/drawable-hdpi/sym_keyboard_delete_dim.png
new file mode 100644
index 0000000..34b6d1f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_delete_dim.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_feedback_delete.png b/core/res/res/drawable-hdpi/sym_keyboard_feedback_delete.png
new file mode 100755
index 0000000..ca76375
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_feedback_delete.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_feedback_ok.png b/core/res/res/drawable-hdpi/sym_keyboard_feedback_ok.png
new file mode 100644
index 0000000..2d144ec
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_feedback_ok.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_feedback_return.png b/core/res/res/drawable-hdpi/sym_keyboard_feedback_return.png
new file mode 100755
index 0000000..ae57299
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_feedback_return.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_feedback_shift.png b/core/res/res/drawable-hdpi/sym_keyboard_feedback_shift.png
new file mode 100755
index 0000000..4db31c8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_feedback_shift.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.png b/core/res/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.png
new file mode 100755
index 0000000..3fd5659
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_feedback_space.png b/core/res/res/drawable-hdpi/sym_keyboard_feedback_space.png
new file mode 100755
index 0000000..98266ee
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_feedback_space.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_num0_no_plus.png b/core/res/res/drawable-hdpi/sym_keyboard_num0_no_plus.png
new file mode 100644
index 0000000..2aad23c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_num0_no_plus.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_num1.png b/core/res/res/drawable-hdpi/sym_keyboard_num1.png
new file mode 100755
index 0000000..0fc03ef
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_num1.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_num2.png b/core/res/res/drawable-hdpi/sym_keyboard_num2.png
new file mode 100755
index 0000000..283560b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_num2.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_num3.png b/core/res/res/drawable-hdpi/sym_keyboard_num3.png
new file mode 100755
index 0000000..9a3b329
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_num3.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_num4.png b/core/res/res/drawable-hdpi/sym_keyboard_num4.png
new file mode 100755
index 0000000..f13ff1a
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_num4.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_num5.png b/core/res/res/drawable-hdpi/sym_keyboard_num5.png
new file mode 100755
index 0000000..c251329
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_num5.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_num6.png b/core/res/res/drawable-hdpi/sym_keyboard_num6.png
new file mode 100755
index 0000000..4acba4c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_num6.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_num7.png b/core/res/res/drawable-hdpi/sym_keyboard_num7.png
new file mode 100755
index 0000000..14931c1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_num7.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_num8.png b/core/res/res/drawable-hdpi/sym_keyboard_num8.png
new file mode 100755
index 0000000..d4973fd
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_num8.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_num9.png b/core/res/res/drawable-hdpi/sym_keyboard_num9.png
new file mode 100755
index 0000000..49cec66
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_num9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_ok.png b/core/res/res/drawable-hdpi/sym_keyboard_ok.png
new file mode 100644
index 0000000..9105da2
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_ok.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_ok_dim.png b/core/res/res/drawable-hdpi/sym_keyboard_ok_dim.png
new file mode 100644
index 0000000..bd419de
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_ok_dim.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_return.png b/core/res/res/drawable-hdpi/sym_keyboard_return.png
new file mode 100755
index 0000000..58505c5
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_return.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_shift.png b/core/res/res/drawable-hdpi/sym_keyboard_shift.png
new file mode 100755
index 0000000..8149081
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_shift.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_shift_locked.png b/core/res/res/drawable-hdpi/sym_keyboard_shift_locked.png
new file mode 100755
index 0000000..31ca277
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_shift_locked.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_space.png b/core/res/res/drawable-hdpi/sym_keyboard_space.png
new file mode 100755
index 0000000..3e98b30
--- /dev/null
+++ b/core/res/res/drawable-hdpi/sym_keyboard_space.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png
new file mode 100644
index 0000000..20f3d50
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal_off.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal_off.9.png
new file mode 100644
index 0000000..d09ce53
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal_on.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal_on.9.png
new file mode 100644
index 0000000..a9e008c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png
new file mode 100644
index 0000000..1ed3065
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed_off.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed_off.9.png
new file mode 100644
index 0000000..5710ebf
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed_on.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed_on.9.png
new file mode 100644
index 0000000..dd7d89e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_trans_normal_off.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_trans_normal_off.9.png
new file mode 100644
index 0000000..77426ef
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_trans_normal_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_trans_normal_on.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_trans_normal_on.9.png
new file mode 100644
index 0000000..e4c9bd5
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_trans_normal_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_trans_pressed_off.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_trans_pressed_off.9.png
new file mode 100644
index 0000000..bb98b01
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_trans_pressed_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_trans_pressed_on.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_trans_pressed_on.9.png
new file mode 100644
index 0000000..3c7dcc80
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_trans_pressed_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/password_field_default.9.png b/core/res/res/drawable-mdpi/password_field_default.9.png
new file mode 100644
index 0000000..3193275
--- /dev/null
+++ b/core/res/res/drawable-mdpi/password_field_default.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_delete.png b/core/res/res/drawable-mdpi/sym_keyboard_delete.png
new file mode 100644
index 0000000..43a033ea
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_delete.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_delete_dim.png b/core/res/res/drawable-mdpi/sym_keyboard_delete_dim.png
new file mode 100644
index 0000000..25460d8
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_delete_dim.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_feedback_delete.png b/core/res/res/drawable-mdpi/sym_keyboard_feedback_delete.png
new file mode 100644
index 0000000..1edb10b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_feedback_delete.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_feedback_ok.png b/core/res/res/drawable-mdpi/sym_keyboard_feedback_ok.png
new file mode 100644
index 0000000..3148836
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_feedback_ok.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_feedback_return.png b/core/res/res/drawable-mdpi/sym_keyboard_feedback_return.png
new file mode 100644
index 0000000..03d9c9b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_feedback_return.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_feedback_shift.png b/core/res/res/drawable-mdpi/sym_keyboard_feedback_shift.png
new file mode 100644
index 0000000..97f4661f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_feedback_shift.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_feedback_shift_locked.png b/core/res/res/drawable-mdpi/sym_keyboard_feedback_shift_locked.png
new file mode 100755
index 0000000..7194b30
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_feedback_shift_locked.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_feedback_space.png b/core/res/res/drawable-mdpi/sym_keyboard_feedback_space.png
new file mode 100644
index 0000000..739db68
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_feedback_space.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_num0_no_plus.png b/core/res/res/drawable-mdpi/sym_keyboard_num0_no_plus.png
new file mode 100644
index 0000000..91332b1
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_num0_no_plus.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_num1.png b/core/res/res/drawable-mdpi/sym_keyboard_num1.png
new file mode 100644
index 0000000..aaac11b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_num1.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_num2.png b/core/res/res/drawable-mdpi/sym_keyboard_num2.png
new file mode 100644
index 0000000..4372eb8
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_num2.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_num3.png b/core/res/res/drawable-mdpi/sym_keyboard_num3.png
new file mode 100644
index 0000000..6f54c85
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_num3.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_num4.png b/core/res/res/drawable-mdpi/sym_keyboard_num4.png
new file mode 100644
index 0000000..3e50bb9
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_num4.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_num5.png b/core/res/res/drawable-mdpi/sym_keyboard_num5.png
new file mode 100644
index 0000000..c39ef44
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_num5.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_num6.png b/core/res/res/drawable-mdpi/sym_keyboard_num6.png
new file mode 100644
index 0000000..ea88ceb
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_num6.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_num7.png b/core/res/res/drawable-mdpi/sym_keyboard_num7.png
new file mode 100644
index 0000000..ce800ba
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_num7.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_num8.png b/core/res/res/drawable-mdpi/sym_keyboard_num8.png
new file mode 100644
index 0000000..1a8ff94
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_num8.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_num9.png b/core/res/res/drawable-mdpi/sym_keyboard_num9.png
new file mode 100644
index 0000000..8b344c0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_num9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_ok.png b/core/res/res/drawable-mdpi/sym_keyboard_ok.png
new file mode 100644
index 0000000..b8b5292
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_ok.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_ok_dim.png b/core/res/res/drawable-mdpi/sym_keyboard_ok_dim.png
new file mode 100644
index 0000000..33ecff5
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_ok_dim.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_return.png b/core/res/res/drawable-mdpi/sym_keyboard_return.png
new file mode 100644
index 0000000..17f2574
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_return.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_shift.png b/core/res/res/drawable-mdpi/sym_keyboard_shift.png
new file mode 100644
index 0000000..0566e5a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_shift.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_shift_locked.png b/core/res/res/drawable-mdpi/sym_keyboard_shift_locked.png
new file mode 100755
index 0000000..ccaf05d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_shift_locked.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_space.png b/core/res/res/drawable-mdpi/sym_keyboard_space.png
new file mode 100644
index 0000000..4e6273b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/sym_keyboard_space.png
Binary files differ
diff --git a/core/res/res/drawable/btn_keyboard_key_fulltrans.xml b/core/res/res/drawable/btn_keyboard_key_fulltrans.xml
new file mode 100644
index 0000000..cfad6e3
--- /dev/null
+++ b/core/res/res/drawable/btn_keyboard_key_fulltrans.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <!-- Toggle keys. Use checkable/checked state. -->
+
+    <item android:state_checkable="true" android:state_checked="true"
+          android:state_pressed="true"
+          android:drawable="@drawable/btn_keyboard_key_fulltrans_pressed_on" />
+    <item android:state_checkable="true" android:state_pressed="true"
+          android:drawable="@drawable/btn_keyboard_key_fulltrans_pressed_off" />
+    <item android:state_checkable="true" android:state_checked="true"
+          android:drawable="@drawable/btn_keyboard_key_fulltrans_normal_on" />
+    <item android:state_checkable="true"
+          android:drawable="@drawable/btn_keyboard_key_fulltrans_normal_off" />
+
+    <!-- Normal keys -->
+    <item android:state_pressed="true"
+          android:drawable="@drawable/btn_keyboard_key_fulltrans_pressed" />
+    <item android:drawable="@drawable/btn_keyboard_key_fulltrans_normal" />
+
+</selector>
diff --git a/core/res/res/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml
index 5bc034b..b089df6 100644
--- a/core/res/res/layout/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_password_landscape.xml
@@ -16,105 +16,68 @@
 ** limitations under the License.
 */
 -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
     android:orientation="vertical"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    android:background="@android:color/background_dark">
-
-    <!-- displays dots as user enters pin -->
-    <LinearLayout android:id="@+id/pinDisplayGroup"
-        android:orientation="horizontal"
-        android:layout_centerInParent="true"
-        android:layout_width="fill_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:layout_marginTop="6dip"
-        android:background="@android:drawable/edit_text">
-
-        <EditText android:id="@+id/pinDisplay"
-            android:layout_width="0dip"
-            android:layout_weight="1"
-            android:layout_height="fill_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="fill_parent"
-             android:layout_marginTop="2dip"
-             android:layout_marginRight="2dip"
-             android:layout_marginBottom="2dip"
-             android:gravity="center"
-        />
-
-    </LinearLayout>
-
-    <!-- header text ('Enter Pin Code') -->
-    <TextView android:id="@+id/headerText"
-        android:layout_above="@id/pinDisplayGroup"
-        android:layout_centerHorizontal="true"
-        android:layout_marginBottom="30dip"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:textSize="24sp"
-    />
+    android:background="#70000000"
+    android:gravity="center_horizontal">
 
     <LinearLayout
-        android:orientation="horizontal"
-        android:layout_alignParentBottom="true"
-        android:layout_width="fill_parent"
+        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:orientation="horizontal">
+        <!-- "Enter PIN(Password) to unlock" -->
+        <TextView android:id="@+id/enter_password_label"
             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"
-            />
+            android:layout_weight="1"
+            android:orientation="horizontal"
+            android:layout_marginRight="6dip"
+            android:layout_marginLeft="6dip"
+            android:layout_marginTop="10dip"
+            android:layout_marginBottom="10dip"
+            android:gravity="center"
+            android:ellipsize="marquee"
+            android:text="@android:string/keyguard_password_enter_password_code"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+        />
 
-        <Button android:id="@+id/emergencyCall"
-            android:text="@android:string/lockscreen_emergency_call"
-            android:layout_alignParentBottom="true"
-            android:layout_centerHorizontal="true"
+        <!-- Password entry field -->
+        <EditText android:id="@+id/passwordEntry"
             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"
+            android:layout_weight="1"
+            android:singleLine="true"
+            android:textStyle="bold"
+            android:inputType="textPassword"
+            android:gravity="center"
+            android:layout_gravity="center"
+            android:textSize="32sp"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:background="@drawable/password_field_default"
+            android:textColor="#ffffffff"
         />
     </LinearLayout>
 
-    <!-- Not currently visible on this screen -->
-    <TextView
-        android:id="@+id/carrier"
-        android:layout_width="wrap_content"
+    <!-- Alphanumeric keyboard -->
+    <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
+        android:layout_alignParentBottom="true"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_alignParentTop="true"
-        android:layout_marginTop="6dip"
-        android:layout_alignParentRight="true"
-        android:layout_marginRight="8dip"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:visibility="gone"
+        android:background="#00000000"
+        android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
     />
 
-</RelativeLayout>
+    <!-- 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"
+        style="@style/Widget.Button.Transparent"
+    />
+
+</LinearLayout>
diff --git a/core/res/res/layout/keyguard_screen_password_portrait.xml b/core/res/res/layout/keyguard_screen_password_portrait.xml
index a7814af..9ee8781 100644
--- a/core/res/res/layout/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_password_portrait.xml
@@ -17,142 +17,77 @@
 */
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
     android:orientation="vertical"
     android:background="#70000000"
     android:gravity="center_horizontal">
 
-    <LinearLayout android:id="@+id/topDisplayGroup"
-        android:layout_width="fill_parent"
+    <!-- "Enter PIN(Password) to unlock" -->
+    <TextView android:id="@+id/enter_password_label"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:orientation="vertical">
-
-        <RelativeLayout
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content">
-
-            <com.android.internal.widget.DigitalClock android:id="@+id/time"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="6dip"
-                android:layout_marginLeft="6dip"
-                android:layout_alignParentTop="true"
-                android:layout_alignParentLeft="true">
-
-                <TextView android:id="@+id/timeDisplay"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:gravity="bottom"
-                    android:singleLine="true"
-                    android:ellipsize="none"
-                    android:textSize="56sp"
-                    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="fill_parent"
-                    android:gravity="bottom"
-                    android:singleLine="true"
-                    android:ellipsize="none"
-                    android:textSize="18sp"
-                    android:layout_marginLeft="4dip"
-                    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/carrier"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignParentTop="true"
-                android:layout_marginTop="6dip"
-                android:layout_alignParentRight="true"
-                android:layout_marginRight="8dip"
-                android:textAppearance="?android:attr/textAppearanceMedium"
-            />
-
-        </RelativeLayout>
-
-        <!-- password entry -->
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:layout_marginRight="6dip"
-            android:layout_marginLeft="6dip"
-            android:gravity="center_vertical"
-            android:hint="@android:string/keyguard_password_enter_password_code"
-            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:orientation="horizontal"
+        android:layout_marginRight="6dip"
+        android:layout_marginLeft="6dip"
         android:layout_marginTop="10dip"
+        android:layout_marginBottom="10dip"
+        android:gravity="center"
+        android:text="@android:string/keyguard_password_enter_password_code"
+        android:textAppearance="?android:attr/textAppearanceLarge"
     />
 
-    <!-- spacer below keypad -->
+    <!-- spacer above text entry field -->
     <View
         android:id="@+id/spacerBottom"
         android:layout_width="fill_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="fill_parent"
-        android:layout_height="0dip"
-        android:layout_weight="1"
+    <!-- Password entry field -->
+    <EditText android:id="@+id/passwordEntry"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:singleLine="true"
+        android:textStyle="bold"
+        android:inputType="textPassword"
         android:gravity="center"
-        android:orientation="vertical">
+        android:layout_gravity="center"
+        android:textSize="32sp"
+        android:layout_marginTop="15dip"
+        android:layout_marginLeft="30dip"
+        android:layout_marginRight="30dip"
+        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:background="@drawable/password_field_default"
+        android:textColor="#ffffffff"
+    />
 
-        <!-- 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>
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1" />
 
+    <!-- Alphanumeric keyboard -->
+    <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
+        android:layout_alignParentBottom="true"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        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:layout_marginTop="20dip"
+        android:layout_marginBottom="20dip"
+        android:text="@string/lockscreen_emergency_call"
+        style="@style/Widget.Button.Transparent"
+    />
 </LinearLayout>
diff --git a/core/res/res/layout/password_keyboard_input.xml b/core/res/res/layout/password_keyboard_input.xml
new file mode 100755
index 0000000..e40b69e
--- /dev/null
+++ b/core/res/res/layout/password_keyboard_input.xml
@@ -0,0 +1,29 @@
+<?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.passwordunlockdemo.LatinKeyboardView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@android:id/keyboardView"
+        android:layout_alignParentBottom="true"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="#00000000"
+        android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+        />
diff --git a/core/res/res/values-land/dimens.xml b/core/res/res/values-land/dimens.xml
new file mode 100644
index 0000000..647a562
--- /dev/null
+++ b/core/res/res/values-land/dimens.xml
@@ -0,0 +1,24 @@
+<?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.
+*/
+-->
+
+<resources>
+    <dimen name="password_keyboard_key_height">47dip</dimen>
+    <dimen name="password_keyboard_spacebar_vertical_correction">2dip</dimen>
+</resources>
\ No newline at end of file
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 6a3538d..5cea28db 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -4,16 +4,16 @@
 **
 ** Copyright 2006, 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 
+** 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 
+**     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 
+** 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.
 */
 -->
@@ -34,4 +34,8 @@
     <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 correction for the space key in the password keyboard -->
+    <dimen name="password_keyboard_spacebar_vertical_correction">4dip</dimen>
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4df570c..89cbd08 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1536,6 +1536,14 @@
     <!-- Displayed on lock screen's right tab - turn sound off -->
     <string name="lockscreen_sound_off_label">Sound off</string>
 
+    <!-- Password keyboard strings. Used by LockScreen and Settings --><skip />
+    <!-- Label for "switch to symbols" key.  Must be short to fit on key! -->
+    <string name="password_keyboard_label_symbol_key">\?123</string>
+    <!-- Label for "switch to alphabetic" key.  Must be short to fit on key! -->
+    <string name="password_keyboard_label_alpha_key">ABC</string>
+    <!-- Label for ALT modifier key.  Must be short to fit on key! -->
+    <string name="password_keyboard_label_alt_key">ALT</string>
+
     <!-- A format string for 12-hour time of day, just the hour, not the minute, with lower-case "am" or "pm" (example: "3pm"). -->
     <string name="hour_ampm">"<xliff:g id="hour" example="3">%-l</xliff:g><xliff:g id="ampm" example="pm">%P</xliff:g>"</string>
 
diff --git a/core/res/res/xml-land/password_kbd_qwerty.xml b/core/res/res/xml-land/password_kbd_qwerty.xml
new file mode 100755
index 0000000..a3d4e88
--- /dev/null
+++ b/core/res/res/xml-land/password_kbd_qwerty.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.
+*/
+-->
+
+<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"
+    >
+
+    <Row>
+        <Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>
+        <Key android:codes="119" android:keyLabel="w"/>
+        <Key android:codes="101" android:keyLabel="e"/>
+        <Key android:codes="114" android:keyLabel="r"/>
+        <Key android:codes="116" android:keyLabel="t"/>
+        <Key android:codes="121" android:keyLabel="y"/>
+        <Key android:codes="117" android:keyLabel="u"/>
+        <Key android:codes="105" android:keyLabel="i"/>
+        <Key android:codes="111" android:keyLabel="o"/>
+        <Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/>
+    </Row>
+
+    <Row>
+        <Key android:codes="97" android:keyLabel="a" android:horizontalGap="5%p"
+            android:keyEdgeFlags="left"/>
+        <Key android:codes="115" android:keyLabel="s"/>
+        <Key android:codes="100" android:keyLabel="d"/>
+        <Key android:codes="102" android:keyLabel="f"/>
+        <Key android:codes="103" android:keyLabel="g"/>
+        <Key android:codes="104" android:keyLabel="h"/>
+        <Key android:codes="106" android:keyLabel="j"/>
+        <Key android:codes="107" android:keyLabel="k"/>
+        <Key android:codes="108" 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:codes="122" android:keyLabel="z"/>
+        <Key android:codes="120" android:keyLabel="x"/>
+        <Key android:codes="99" android:keyLabel="c"/>
+        <Key android:codes="118" android:keyLabel="v"/>
+        <Key android:codes="98" android:keyLabel="b"/>
+        <Key android:codes="110" android:keyLabel="n"/>
+        <Key android:codes="109" 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" android:isRepeatable="true"/>
+        <Key android:keyLabel="=" />
+        <Key android:codes="46" android:keyLabel="."
+            android:keyWidth="10%p"/>
+        <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
+            android:iconPreview="@drawable/sym_keyboard_feedback_return"
+            android:keyWidth="20%p" android:keyEdgeFlags="right"/>
+    </Row>
+
+</Keyboard>
+
diff --git a/core/res/res/xml-land/password_kbd_qwerty_shifted.xml b/core/res/res/xml-land/password_kbd_qwerty_shifted.xml
new file mode 100755
index 0000000..2285d91
--- /dev/null
+++ b/core/res/res/xml-land/password_kbd_qwerty_shifted.xml
@@ -0,0 +1,88 @@
+<?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"
+    >
+
+    <Row>
+        <Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>
+        <Key android:codes="119" android:keyLabel="w"/>
+        <Key android:codes="101" android:keyLabel="e"/>
+        <Key android:codes="114" android:keyLabel="r"/>
+        <Key android:codes="116" android:keyLabel="t"/>
+        <Key android:codes="121" android:keyLabel="y"/>
+        <Key android:codes="117" android:keyLabel="u"/>
+        <Key android:codes="105" android:keyLabel="i"/>
+        <Key android:codes="111" android:keyLabel="o"/>
+        <Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/>
+    </Row>
+
+    <Row>
+        <Key android:codes="97" android:keyLabel="a" android:horizontalGap="5%p"
+            android:keyEdgeFlags="left"/>
+        <Key android:codes="115" android:keyLabel="s"/>
+        <Key android:codes="100" android:keyLabel="d"/>
+        <Key android:codes="102" android:keyLabel="f"/>
+        <Key android:codes="103" android:keyLabel="g"/>
+        <Key android:codes="104" android:keyLabel="h"/>
+        <Key android:codes="106" android:keyLabel="j"/>
+        <Key android:codes="107" android:keyLabel="k"/>
+        <Key android:codes="108" 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:codes="122" android:keyLabel="z"/>
+        <Key android:codes="120" android:keyLabel="x"/>
+        <Key android:codes="99" android:keyLabel="c"/>
+        <Key android:codes="118" android:keyLabel="v"/>
+        <Key android:codes="98" android:keyLabel="b"/>
+        <Key android:codes="110" android:keyLabel="n"/>
+        <Key android:codes="109" 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" android:isRepeatable="true"/>
+        <Key android:keyLabel="+" />
+        <Key android:codes="46" android:keyLabel="."/>
+        <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
+            android:iconPreview="@drawable/sym_keyboard_feedback_return"
+            android:keyWidth="20%p" android:keyEdgeFlags="right"/>
+    </Row>
+
+</Keyboard>
+
diff --git a/core/res/res/xml-mdpi/password_kbd_qwerty.xml b/core/res/res/xml-mdpi/password_kbd_qwerty.xml
new file mode 100755
index 0000000..a3d4e88
--- /dev/null
+++ b/core/res/res/xml-mdpi/password_kbd_qwerty.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.
+*/
+-->
+
+<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"
+    >
+
+    <Row>
+        <Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>
+        <Key android:codes="119" android:keyLabel="w"/>
+        <Key android:codes="101" android:keyLabel="e"/>
+        <Key android:codes="114" android:keyLabel="r"/>
+        <Key android:codes="116" android:keyLabel="t"/>
+        <Key android:codes="121" android:keyLabel="y"/>
+        <Key android:codes="117" android:keyLabel="u"/>
+        <Key android:codes="105" android:keyLabel="i"/>
+        <Key android:codes="111" android:keyLabel="o"/>
+        <Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/>
+    </Row>
+
+    <Row>
+        <Key android:codes="97" android:keyLabel="a" android:horizontalGap="5%p"
+            android:keyEdgeFlags="left"/>
+        <Key android:codes="115" android:keyLabel="s"/>
+        <Key android:codes="100" android:keyLabel="d"/>
+        <Key android:codes="102" android:keyLabel="f"/>
+        <Key android:codes="103" android:keyLabel="g"/>
+        <Key android:codes="104" android:keyLabel="h"/>
+        <Key android:codes="106" android:keyLabel="j"/>
+        <Key android:codes="107" android:keyLabel="k"/>
+        <Key android:codes="108" 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:codes="122" android:keyLabel="z"/>
+        <Key android:codes="120" android:keyLabel="x"/>
+        <Key android:codes="99" android:keyLabel="c"/>
+        <Key android:codes="118" android:keyLabel="v"/>
+        <Key android:codes="98" android:keyLabel="b"/>
+        <Key android:codes="110" android:keyLabel="n"/>
+        <Key android:codes="109" 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" android:isRepeatable="true"/>
+        <Key android:keyLabel="=" />
+        <Key android:codes="46" android:keyLabel="."
+            android:keyWidth="10%p"/>
+        <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
+            android:iconPreview="@drawable/sym_keyboard_feedback_return"
+            android:keyWidth="20%p" android:keyEdgeFlags="right"/>
+    </Row>
+
+</Keyboard>
+
diff --git a/core/res/res/xml-mdpi/password_kbd_qwerty_shifted.xml b/core/res/res/xml-mdpi/password_kbd_qwerty_shifted.xml
new file mode 100755
index 0000000..2285d91
--- /dev/null
+++ b/core/res/res/xml-mdpi/password_kbd_qwerty_shifted.xml
@@ -0,0 +1,88 @@
+<?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"
+    >
+
+    <Row>
+        <Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>
+        <Key android:codes="119" android:keyLabel="w"/>
+        <Key android:codes="101" android:keyLabel="e"/>
+        <Key android:codes="114" android:keyLabel="r"/>
+        <Key android:codes="116" android:keyLabel="t"/>
+        <Key android:codes="121" android:keyLabel="y"/>
+        <Key android:codes="117" android:keyLabel="u"/>
+        <Key android:codes="105" android:keyLabel="i"/>
+        <Key android:codes="111" android:keyLabel="o"/>
+        <Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/>
+    </Row>
+
+    <Row>
+        <Key android:codes="97" android:keyLabel="a" android:horizontalGap="5%p"
+            android:keyEdgeFlags="left"/>
+        <Key android:codes="115" android:keyLabel="s"/>
+        <Key android:codes="100" android:keyLabel="d"/>
+        <Key android:codes="102" android:keyLabel="f"/>
+        <Key android:codes="103" android:keyLabel="g"/>
+        <Key android:codes="104" android:keyLabel="h"/>
+        <Key android:codes="106" android:keyLabel="j"/>
+        <Key android:codes="107" android:keyLabel="k"/>
+        <Key android:codes="108" 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:codes="122" android:keyLabel="z"/>
+        <Key android:codes="120" android:keyLabel="x"/>
+        <Key android:codes="99" android:keyLabel="c"/>
+        <Key android:codes="118" android:keyLabel="v"/>
+        <Key android:codes="98" android:keyLabel="b"/>
+        <Key android:codes="110" android:keyLabel="n"/>
+        <Key android:codes="109" 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" android:isRepeatable="true"/>
+        <Key android:keyLabel="+" />
+        <Key android:codes="46" android:keyLabel="."/>
+        <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
+            android:iconPreview="@drawable/sym_keyboard_feedback_return"
+            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
new file mode 100755
index 0000000..354594e
--- /dev/null
+++ b/core/res/res/xml/password_kbd_extension.xml
@@ -0,0 +1,61 @@
+<?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"
+    >
+
+    <Row android:rowEdgeFlags="top">
+        <Key android:keyLabel="!" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="\@"/>
+        <Key android:keyLabel="\#"/>
+        <Key android:keyLabel="&amp;"/>
+        <Key android:keyLabel="-"/>
+        <Key android:keyLabel="\'"/>
+        <Key android:keyLabel=":"/>
+        <Key android:keyLabel="&quot;"/>
+        <Key android:keyLabel="/"/>
+        <Key android:keyLabel="\?" android:keyEdgeFlags="right"
+        />
+    </Row>
+
+    <Row android:rowEdgeFlags="bottom">
+        <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"
+        />
+        <Key android:codes="50" android:keyLabel="2"
+        />
+        <Key android:codes="51" android:keyLabel="3"
+        />
+        <Key android:codes="52" android:keyLabel="4"
+        />
+        <Key android:codes="53" android:keyLabel="5"
+        />
+        <Key android:codes="54" android:keyLabel="6"/>
+        <Key android:codes="55" android:keyLabel="7"
+        />
+        <Key android:codes="56" android:keyLabel="8"/>
+        <Key android:codes="57" android:keyLabel="9"/>
+        <Key android:codes="48" android:keyLabel="0"
+                android:keyEdgeFlags="right"/>
+    </Row>
+</Keyboard>
diff --git a/core/res/res/xml/password_kbd_numeric.xml b/core/res/res/xml/password_kbd_numeric.xml
new file mode 100755
index 0000000..e3f1612
--- /dev/null
+++ b/core/res/res/xml/password_kbd_numeric.xml
@@ -0,0 +1,53 @@
+<?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="33.33%p"
+    android:horizontalGap="2px"
+    android:verticalGap="0px"
+    android:keyHeight="@dimen/password_keyboard_key_height"
+    >
+
+    <Row>
+        <Key android:codes="49" android:keyIcon="@drawable/sym_keyboard_num1" android:keyEdgeFlags="left"/>
+        <Key android:codes="50" android:keyIcon="@drawable/sym_keyboard_num2"/>
+        <Key android:codes="51" android:keyIcon="@drawable/sym_keyboard_num3"/>
+    </Row>
+
+    <Row>
+        <Key android:codes="52" android:keyIcon="@drawable/sym_keyboard_num4" android:keyEdgeFlags="left"/>
+        <Key android:codes="53" android:keyIcon="@drawable/sym_keyboard_num5"/>
+        <Key android:codes="54" android:keyIcon="@drawable/sym_keyboard_num6"/>
+    </Row>
+
+    <Row>
+        <Key android:codes="55" android:keyIcon="@drawable/sym_keyboard_num7" android:keyEdgeFlags="left"/>
+        <Key android:codes="56" android:keyIcon="@drawable/sym_keyboard_num8"/>
+        <Key android:codes="57" android:keyIcon="@drawable/sym_keyboard_num9"/>
+    </Row>
+
+    <Row android:rowEdgeFlags="bottom">
+        <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"/>
+        <Key android:codes="48" android:keyIcon="@drawable/sym_keyboard_num0_no_plus"/>
+        <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
+            android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+            android:isRepeatable="true" android:keyEdgeFlags="right"/>
+    </Row>
+
+</Keyboard>
diff --git a/core/res/res/xml/password_kbd_popup_template.xml b/core/res/res/xml/password_kbd_popup_template.xml
new file mode 100644
index 0000000..5ddfd3e
--- /dev/null
+++ b/core/res/res/xml/password_kbd_popup_template.xml
@@ -0,0 +1,27 @@
+<?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"
+    >
+</Keyboard>
diff --git a/core/res/res/xml/password_kbd_qwerty.xml b/core/res/res/xml/password_kbd_qwerty.xml
new file mode 100755
index 0000000..d4a454b
--- /dev/null
+++ b/core/res/res/xml/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"
+    >
+
+    <Row android:rowEdgeFlags="top">
+        <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
+        <Key android:codes="50" android:keyLabel="2"/>
+        <Key android:codes="51" android:keyLabel="3"/>
+        <Key android:codes="52" android:keyLabel="4"/>
+        <Key android:codes="53" android:keyLabel="5"/>
+        <Key android:codes="54" android:keyLabel="6"/>
+        <Key android:codes="55" android:keyLabel="7"/>
+        <Key android:codes="56" android:keyLabel="8"/>
+        <Key android:codes="57" android:keyLabel="9"/>
+        <Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/>
+    </Row>
+
+    <Row>
+        <Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>
+        <Key android:codes="119" android:keyLabel="w"/>
+        <Key android:codes="101" android:keyLabel="e"/>
+        <Key android:codes="114" android:keyLabel="r"/>
+        <Key android:codes="116" android:keyLabel="t"/>
+        <Key android:codes="121" android:keyLabel="y"/>
+        <Key android:codes="117" android:keyLabel="u"/>
+        <Key android:codes="105" android:keyLabel="i"/>
+        <Key android:codes="111" android:keyLabel="o"/>
+        <Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/>
+    </Row>
+
+    <Row>
+        <Key android:codes="97" android:keyLabel="a" android:horizontalGap="5%p"
+            android:keyEdgeFlags="left"/>
+        <Key android:codes="115" android:keyLabel="s"/>
+        <Key android:codes="100" android:keyLabel="d"/>
+        <Key android:codes="102" android:keyLabel="f"/>
+        <Key android:codes="103" android:keyLabel="g"/>
+        <Key android:codes="104" android:keyLabel="h"/>
+        <Key android:codes="106" android:keyLabel="j"/>
+        <Key android:codes="107" android:keyLabel="k"/>
+        <Key android:codes="108" 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:codes="122" android:keyLabel="z"/>
+        <Key android:codes="120" android:keyLabel="x"/>
+        <Key android:codes="99" android:keyLabel="c"/>
+        <Key android:codes="118" android:keyLabel="v"/>
+        <Key android:codes="98" android:keyLabel="b"/>
+        <Key android:codes="110" android:keyLabel="n"/>
+        <Key android:codes="109" 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" android:isRepeatable="true"/>
+        <Key android:keyLabel="=" />
+        <Key android:codes="46" 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/password_kbd_qwerty_shifted.xml b/core/res/res/xml/password_kbd_qwerty_shifted.xml
new file mode 100755
index 0000000..f341d9e
--- /dev/null
+++ b/core/res/res/xml/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"
+    >
+
+    <Row android:rowEdgeFlags="top">
+        <Key android:codes="64" android:keyLabel="\@" android:keyEdgeFlags="left"/>
+        <Key android:codes="35" android:keyLabel="\#"/>
+        <Key android:codes="36" android:keyLabel="$"/>
+        <Key android:codes="37" android:keyLabel="%"/>
+        <Key android:codes="38" android:keyLabel="&amp;"/>
+        <Key android:codes="42" android:keyLabel="*"/>
+        <Key android:codes="45" android:keyLabel="-"/>
+        <Key android:keyLabel="+"/>
+        <Key android:codes="40" android:keyLabel="("/>
+        <Key android:codes="41" android:keyLabel=")" android:keyEdgeFlags="right"/>
+    </Row>
+
+    <Row>
+        <Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>
+        <Key android:codes="119" android:keyLabel="w"/>
+        <Key android:codes="101" android:keyLabel="e"/>
+        <Key android:codes="114" android:keyLabel="r"/>
+        <Key android:codes="116" android:keyLabel="t"/>
+        <Key android:codes="121" android:keyLabel="y"/>
+        <Key android:codes="117" android:keyLabel="u"/>
+        <Key android:codes="105" android:keyLabel="i"/>
+        <Key android:codes="111" android:keyLabel="o"/>
+        <Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/>
+    </Row>
+
+    <Row>
+        <Key android:codes="97" android:keyLabel="a" android:horizontalGap="5%p"
+            android:keyEdgeFlags="left"/>
+        <Key android:codes="115" android:keyLabel="s"/>
+        <Key android:codes="100" android:keyLabel="d"/>
+        <Key android:codes="102" android:keyLabel="f"/>
+        <Key android:codes="103" android:keyLabel="g"/>
+        <Key android:codes="104" android:keyLabel="h"/>
+        <Key android:codes="106" android:keyLabel="j"/>
+        <Key android:codes="107" android:keyLabel="k"/>
+        <Key android:codes="108" 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:codes="122" android:keyLabel="z"/>
+        <Key android:codes="120" android:keyLabel="x"/>
+        <Key android:codes="99" android:keyLabel="c"/>
+        <Key android:codes="118" android:keyLabel="v"/>
+        <Key android:codes="98" android:keyLabel="b"/>
+        <Key android:codes="110" android:keyLabel="n"/>
+        <Key android:codes="109" 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" android:isRepeatable="true"/>
+        <Key android:keyLabel="+" />
+        <Key android:codes="46" 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_symbols.xml b/core/res/res/xml/password_kbd_symbols.xml
new file mode 100755
index 0000000..c97e6ae
--- /dev/null
+++ b/core/res/res/xml/password_kbd_symbols.xml
@@ -0,0 +1,91 @@
+<?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"
+    >
+
+    <Row>
+        <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
+        <Key android:codes="50" android:keyLabel="2"/>
+        <Key android:codes="51" android:keyLabel="3"/>
+        <Key android:codes="52" android:keyLabel="4"/>
+        <Key android:codes="53" android:keyLabel="5"/>
+        <Key android:codes="54" android:keyLabel="6"/>
+        <Key android:codes="55" android:keyLabel="7"/>
+        <Key android:codes="56" android:keyLabel="8"/>
+        <Key android:codes="57" android:keyLabel="9"/>
+        <Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/>
+    </Row>
+
+    <Row>
+        <Key android:codes="64" android:keyLabel="\@" android:keyEdgeFlags="left"/>
+        <Key android:codes="35" android:keyLabel="\#"/>
+        <Key android:codes="36" android:keyLabel="$"/>
+        <Key android:codes="37" android:keyLabel="%"/>
+        <Key android:codes="38" android:keyLabel="&amp;"/>
+        <Key android:codes="42" android:keyLabel="*"/>
+        <Key android:codes="45" android:keyLabel="-"/>
+        <Key android:keyLabel="+"/>
+        <Key android:codes="40" android:keyLabel="("
+                android:popupKeyboard="@xml/password_kbd_popup_template"
+                android:popupCharacters="[{&lt;"
+        />
+        <Key android:codes="41" android:keyLabel=")" android:keyEdgeFlags="right"
+                android:popupKeyboard="@xml/password_kbd_popup_template"
+                android:popupCharacters="]}&gt;"
+        />
+    </Row>
+
+    <Row>
+        <Key android:codes="-1" android:keyLabel="@string/password_keyboard_label_alt_key"
+                android:keyWidth="15%p" android:isModifier="true"
+                android:isSticky="true" android:keyEdgeFlags="left"/>
+        <Key android:codes="33" android:keyLabel="!"/>
+        <Key android:codes="34" android:keyLabel="&quot;"/>
+        <Key android:codes="39" android:keyLabel="\'"/>
+        <Key android:codes="58" android:keyLabel=":"/>
+        <Key android:codes="59" android:keyLabel=";"/>
+        <Key android:codes="47" android:keyLabel="/" />
+        <Key android:codes="63" android:keyLabel="\?"/>
+        <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:rowEdgeFlags="bottom">
+        <Key android:codes="-2" android:keyLabel="@string/password_keyboard_label_alpha_key"
+            android:keyWidth="20%p" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="," android:keyWidth="10%p"/>
+        <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
+            android:keyWidth="40%p"
+            android:iconPreview="@drawable/sym_keyboard_feedback_space"
+            android:isRepeatable="true"/>
+        <Key android:keyLabel="." android:keyWidth="10%p" />
+        <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
+            android:keyWidth="20%p" android:keyEdgeFlags="right"
+            android:iconPreview="@drawable/sym_keyboard_feedback_ok"
+        />
+    </Row>
+</Keyboard>
diff --git a/core/res/res/xml/password_kbd_symbols_shift.xml b/core/res/res/xml/password_kbd_symbols_shift.xml
new file mode 100755
index 0000000..97ec3c5f
--- /dev/null
+++ b/core/res/res/xml/password_kbd_symbols_shift.xml
@@ -0,0 +1,87 @@
+<?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"
+    >
+
+    <Row>
+        <Key android:keyLabel="~" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="`"/>
+        <Key android:keyLabel="|"/>
+        <Key android:keyLabel="•"/>
+        <Key android:keyLabel="√"/>
+        <Key android:keyLabel="π"/>
+        <Key android:keyLabel="÷"/>
+        <Key android:keyLabel="×"/>
+        <Key android:keyLabel="{"/>
+        <Key android:keyLabel="}" android:keyEdgeFlags="right"/>
+    </Row>
+
+    <Row>
+        <Key android:keyLabel="¥" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="£"/>
+        <Key android:keyLabel="¢"/>
+        <Key android:keyLabel="€"/>
+        <Key android:keyLabel="°"/>
+        <Key android:keyLabel="^"/>
+        <Key android:keyLabel="_"/>
+        <Key android:keyLabel="="/>
+        <Key android:keyLabel="["/>
+        <Key android:keyLabel="]" android:keyEdgeFlags="right"/>
+    </Row>
+
+    <Row>
+        <Key android:codes="-1" android:keyLabel="@string/password_keyboard_label_alt_key"
+            android:keyWidth="15%p" android:isModifier="true"
+            android:isSticky="true" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="™"/>
+        <Key android:keyLabel="®"/>
+        <Key android:keyLabel="©"/>
+        <Key android:keyLabel="¶"/>
+        <Key android:keyLabel="\\"/>
+        <Key android:keyLabel="&lt;"/>
+        <Key android:keyLabel="&gt;"/>
+        <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:rowEdgeFlags="bottom">
+        <Key android:codes="-2" android:keyLabel="@string/password_keyboard_label_alpha_key"
+            android:keyWidth="20%p" android:keyEdgeFlags="left"/>
+        <Key android:keyLabel="„" android:keyWidth="10%p" />
+        <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
+            android:keyWidth="40%p"
+            android:iconPreview="@drawable/sym_keyboard_feedback_space"
+            android:isRepeatable="true"/>
+        <Key android:keyLabel="…" android:keyWidth="10%p" />
+        <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
+            android:keyWidth="20%p" android:keyEdgeFlags="right"
+            android:iconPreview="@drawable/sym_keyboard_feedback_ok"
+        />
+    </Row>
+</Keyboard>