am 841ce670: Merge commit \'81af21e67cd842d16d4b45e8a2d1ec56ff8d764f\' into jb-mr1-dev

* commit '841ce670b29180a157a084a9c0e803b13e92020c': (26 commits)
  hide the correct text, and more text, on bounce
  Improve PIN key layouts.
  Obscure speech for PIN password keys when no headset plugged in.
  Initial changes to allow dropping on delete target to remove widget.
  hide multiuser selector when IME is up.
  Block swipe up gesture if challenge non-interactive.
  Properly disable challenge handle.
  Disable disable back if using an alternate back icon.
  Disable security handle when swiping into camera widget.
  Import translations. DO NOT MERGE
  Fix small issue with previous CL
  Widget size policy, size callbacks
  Don't show security method until we actually return from the camera
  Fix whitespace problem and sync with prototype.
  PUK support.
  Fix build.
  SIM PIN support.
  Use clock's widget as the default keyguard widget
  Add configurable em-dash separator for all concatenated keyguard strings
  Cleaning up keyguard persistence threads when the pager is detached. (Bug 7460991)
  ...
diff --git a/api/current.txt b/api/current.txt
index 6b893d5..345b862 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23429,6 +23429,17 @@
     method public void set(T, V);
   }
 
+  public class PropertyValueModel extends android.util.ValueModel {
+    method public T get();
+    method public H getHost();
+    method public android.util.Property<H, T> getProperty();
+    method public java.lang.Class<T> getType();
+    method public static android.util.PropertyValueModel<H, T> of(H, android.util.Property<H, T>);
+    method public static android.util.PropertyValueModel<H, T> of(H, java.lang.Class<T>, java.lang.String);
+    method public static android.util.PropertyValueModel of(java.lang.Object, java.lang.String);
+    method public void set(T);
+  }
+
   public class SparseArray implements java.lang.Cloneable {
     ctor public SparseArray();
     ctor public SparseArray(int);
@@ -23577,6 +23588,14 @@
     field public int type;
   }
 
+  public abstract class ValueModel {
+    ctor protected ValueModel();
+    method public abstract T get();
+    method public abstract java.lang.Class<T> getType();
+    method public abstract void set(T);
+    field public static final android.util.ValueModel EMPTY;
+  }
+
   public class Xml {
     method public static android.util.AttributeSet asAttributeSet(org.xmlpull.v1.XmlPullParser);
     method public static android.util.Xml.Encoding findEncodingByName(java.lang.String) throws java.io.UnsupportedEncodingException;
@@ -27967,10 +27986,12 @@
     method public abstract void onSelectedDayChange(android.widget.CalendarView, int, int, int);
   }
 
-  public class CheckBox extends android.widget.CompoundButton {
+  public class CheckBox extends android.widget.CompoundButton implements android.widget.ValueEditor {
     ctor public CheckBox(android.content.Context);
     ctor public CheckBox(android.content.Context, android.util.AttributeSet);
     ctor public CheckBox(android.content.Context, android.util.AttributeSet, int);
+    method public android.util.ValueModel<java.lang.Boolean> getValueModel();
+    method public void setValueModel(android.util.ValueModel<java.lang.Boolean>);
   }
 
   public abstract interface Checkable {
@@ -28143,14 +28164,16 @@
     method public void setSize(int, int);
   }
 
-  public class EditText extends android.widget.TextView {
+  public class EditText extends android.widget.TextView implements android.widget.ValueEditor {
     ctor public EditText(android.content.Context);
     ctor public EditText(android.content.Context, android.util.AttributeSet);
     ctor public EditText(android.content.Context, android.util.AttributeSet, int);
     method public void extendSelection(int);
+    method public android.util.ValueModel<java.lang.CharSequence> getValueModel();
     method public void selectAll();
     method public void setSelection(int, int);
     method public void setSelection(int);
+    method public void setValueModel(android.util.ValueModel<java.lang.CharSequence>);
   }
 
   public abstract interface ExpandableListAdapter {
@@ -29175,11 +29198,13 @@
     method public abstract java.lang.Object[] getSections();
   }
 
-  public class SeekBar extends android.widget.AbsSeekBar {
+  public class SeekBar extends android.widget.AbsSeekBar implements android.widget.ValueEditor {
     ctor public SeekBar(android.content.Context);
     ctor public SeekBar(android.content.Context, android.util.AttributeSet);
     ctor public SeekBar(android.content.Context, android.util.AttributeSet, int);
+    method public android.util.ValueModel<java.lang.Integer> getValueModel();
     method public void setOnSeekBarChangeListener(android.widget.SeekBar.OnSeekBarChangeListener);
+    method public void setValueModel(android.util.ValueModel<java.lang.Integer>);
   }
 
   public static abstract interface SeekBar.OnSeekBarChangeListener {
@@ -29767,6 +29792,11 @@
     method public android.widget.TextView getText2();
   }
 
+  public abstract interface ValueEditor {
+    method public abstract android.util.ValueModel<T> getValueModel();
+    method public abstract void setValueModel(android.util.ValueModel<T>);
+  }
+
   public class VideoView extends android.view.SurfaceView implements android.widget.MediaController.MediaPlayerControl {
     ctor public VideoView(android.content.Context);
     ctor public VideoView(android.content.Context, android.util.AttributeSet);
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 3314dc3..71e840e 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -31,6 +31,7 @@
     { AID_MEDIA, "media.player" },
     { AID_MEDIA, "media.camera" },
     { AID_MEDIA, "media.audio_policy" },
+    { AID_MEDIA, "android.media.IAAHMetaDataService" },
     { AID_DRM,   "drm.drmManager" },
     { AID_NFC,   "nfc" },
     { AID_BLUETOOTH, "bluetooth" },
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 456d757..c136a4d 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -113,7 +113,6 @@
 import java.util.regex.Pattern;
 
 import libcore.io.DropBox;
-import libcore.io.EventLogger;
 import libcore.io.IoUtils;
 
 import dalvik.system.CloseGuard;
@@ -4979,13 +4978,6 @@
         }
     }
 
-    private static class EventLoggingReporter implements EventLogger.Reporter {
-        @Override
-        public void report (int code, Object... list) {
-            EventLog.writeEvent(code, list);
-        }
-    }
-
     private class DropBoxReporter implements DropBox.Reporter {
 
         private DropBoxManager dropBox;
@@ -5015,9 +5007,6 @@
 
         Environment.initForCurrentUser();
 
-        // Set the reporter for event logging in libcore
-        EventLogger.setReporter(new EventLoggingReporter());
-
         Process.setArgV0("<pre-initialized>");
 
         Looper.prepareMainLooper();
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 336960e..e343e83 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -939,8 +939,9 @@
      * @param preferenceScreen A {@link PreferenceScreen} whose hierarchy click
      *            listener should be called in the proper order (between other
      *            processing). May be null.
+     * @hide
      */
-    void performClick(PreferenceScreen preferenceScreen) {
+    public void performClick(PreferenceScreen preferenceScreen) {
         
         if (!isEnabled()) {
             return;
diff --git a/core/java/android/preference/PreferenceManager.java b/core/java/android/preference/PreferenceManager.java
index 5ca7d79..17f88f1 100644
--- a/core/java/android/preference/PreferenceManager.java
+++ b/core/java/android/preference/PreferenceManager.java
@@ -138,7 +138,10 @@
     
     private OnPreferenceTreeClickListener mOnPreferenceTreeClickListener;
     
-    PreferenceManager(Activity activity, int firstRequestCode) {
+    /**
+     * @hide
+     */
+    public PreferenceManager(Activity activity, int firstRequestCode) {
         mActivity = activity;
         mNextRequestCode = firstRequestCode;
         
diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java
index 5ef86b1..200b57b 100644
--- a/core/java/android/text/format/Time.java
+++ b/core/java/android/text/format/Time.java
@@ -411,9 +411,6 @@
      * @throws android.util.TimeFormatException if s cannot be parsed.
      */
     public boolean parse(String s) {
-        if (s == null) {
-            throw new NullPointerException("time string is null");
-        }
         if (nativeParse(s)) {
             timezone = TIMEZONE_UTC;
             return true;
diff --git a/core/java/android/util/PropertyValueModel.java b/core/java/android/util/PropertyValueModel.java
new file mode 100755
index 0000000..eb9c47d
--- /dev/null
+++ b/core/java/android/util/PropertyValueModel.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ * A value model for a {@link Property property} of a host object. This class can be used for
+ * both reflective and non-reflective property implementations.
+ *
+ * @param <H> the host type, where the host is the object that holds this property
+ * @param <T> the value type
+ *
+ * @see Property
+ * @see ValueModel
+ */
+public class PropertyValueModel<H, T> extends ValueModel<T> {
+    private final H mHost;
+    private final Property<H, T> mProperty;
+
+    private PropertyValueModel(H host, Property<H, T> property) {
+        mProperty = property;
+        mHost = host;
+    }
+
+    /**
+     * Returns the host.
+     *
+     * @return the host
+     */
+    public H getHost() {
+        return mHost;
+    }
+
+    /**
+     * Returns the property.
+     *
+     * @return the property
+     */
+    public Property<H, T> getProperty() {
+        return mProperty;
+    }
+
+    @Override
+    public Class<T> getType() {
+        return mProperty.getType();
+    }
+
+    @Override
+    public T get() {
+        return mProperty.get(mHost);
+    }
+
+    @Override
+    public void set(T value) {
+        mProperty.set(mHost, value);
+    }
+
+    /**
+     * Return an appropriate PropertyValueModel for this host and property.
+     *
+     * @param host the host
+     * @param property the property
+     * @return the value model
+     */
+    public static <H, T> PropertyValueModel<H, T> of(H host, Property<H, T> property) {
+        return new PropertyValueModel<H, T>(host, property);
+    }
+
+    /**
+     * Return a PropertyValueModel for this {@code host} and a
+     * reflective property, constructed from this {@code propertyType} and {@code propertyName}.
+     *
+     * @param host
+     * @param propertyType the property type
+     * @param propertyName the property name
+     * @return a value model with this host and a reflective property with this type and name
+     *
+     * @see Property#of
+     */
+    public static <H, T> PropertyValueModel<H, T> of(H host, Class<T> propertyType,
+            String propertyName) {
+        return of(host, Property.of((Class<H>) host.getClass(), propertyType, propertyName));
+    }
+
+    private static Class getNullaryMethodReturnType(Class c, String name) {
+        try {
+            return c.getMethod(name).getReturnType();
+        } catch (NoSuchMethodException e) {
+            return null;
+        }
+    }
+
+    private static Class getFieldType(Class c, String name) {
+        try {
+            return c.getField(name).getType();
+        } catch (NoSuchFieldException e) {
+            return null;
+        }
+    }
+
+    private static String capitalize(String name) {
+        if (name.isEmpty()) {
+            return name;
+        }
+        return Character.toUpperCase(name.charAt(0)) + name.substring(1);
+    }
+
+    /**
+     * Return a PropertyValueModel for this {@code host} and and {@code propertyName}.
+     *
+     * @param host the host
+     * @param propertyName the property name
+     * @return a value model with this host and a reflective property with this name
+     */
+    public static PropertyValueModel of(Object host, String propertyName) {
+        Class clazz = host.getClass();
+        String suffix = capitalize(propertyName);
+        Class propertyType = getNullaryMethodReturnType(clazz, "get" + suffix);
+        if (propertyType == null) {
+            propertyType = getNullaryMethodReturnType(clazz, "is" + suffix);
+        } 
+        if (propertyType == null) {
+            propertyType = getFieldType(clazz, propertyName); 
+        }         
+        if (propertyType == null) {
+            throw new NoSuchPropertyException(propertyName); 
+        }
+        return of(host, propertyType, propertyName);
+    }
+}
diff --git a/core/java/android/util/ValueModel.java b/core/java/android/util/ValueModel.java
new file mode 100755
index 0000000..4789682
--- /dev/null
+++ b/core/java/android/util/ValueModel.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+/**
+ * A ValueModel is an abstraction for a 'slot' or place in memory in which a value
+ * may be stored and retrieved. A common implementation of ValueModel is a regular property of
+ * an object, whose value may be retrieved by calling the appropriate <em>getter</em>
+ * method and set by calling the corresponding <em>setter</em> method.
+ *
+ * @param <T> the value type
+ *
+ * @see PropertyValueModel
+ */
+public abstract class ValueModel<T> {
+    /**
+     * The empty model should be used in place of {@code null} to indicate that a
+     * model has not been set. The empty model has no value and does nothing when it is set.
+     */
+    public static final ValueModel EMPTY = new ValueModel() {
+        @Override
+        public Class getType() {
+            return Object.class;
+        }
+
+        @Override
+        public Object get() {
+            return null;
+        }
+
+        @Override
+        public void set(Object value) {
+
+        }
+    };
+
+    protected ValueModel() {
+    }
+
+    /**
+     * Returns the type of this property.
+     *
+     * @return the property type
+     */
+    public abstract Class<T> getType();
+
+    /**
+     * Returns the value of this property.
+     *
+     * @return the property value
+     */
+    public abstract T get();
+
+    /**
+     * Sets the value of this property.
+     *
+     * @param value the new value for this property
+     */
+    public abstract void set(T value);
+}
\ No newline at end of file
diff --git a/core/java/android/view/SimulatedTrackball.java b/core/java/android/view/SimulatedTrackball.java
new file mode 100644
index 0000000..1878e28
--- /dev/null
+++ b/core/java/android/view/SimulatedTrackball.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.os.Handler;
+import android.os.Handler.Callback;
+import android.os.Message;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+
+/**
+ * This class creates trackball events from touchpad events.
+ * 
+ * @see ViewRootImpl
+ */
+class SimulatedTrackball {
+
+    // Maximum difference in milliseconds between the down and up of a touch
+    // event for it to be considered a tap
+    // TODO:Read this value from a configuration file
+    private static final int MAX_TAP_TIME = 250;
+    private static final int FLICK_MSG_ID = 313;
+
+    // The position of the previous touchpad event
+    private float mLastTouchpadXPosition;
+    private float mLastTouchpadYPosition;
+    // Where the touchpad was initially pressed
+    private float mTouchpadEnterXPosition;
+    private float mTouchpadEnterYPosition;
+    // When the most recent ACTION_HOVER_ENTER occurred
+    private long mLastTouchPadStartTimeMs = 0;
+    // When the most recent direction key was sent
+    private long mLastTouchPadKeySendTimeMs = 0;
+    // When the most recent touch event of any type occurred
+    private long mLastTouchPadEventTimeMs = 0;
+
+    // How quickly keys were sent;
+    private int mKeySendRateMs = 0;
+    private int mLastKeySent;
+    // Last movement in device screen pixels
+    private float mLastMoveX = 0;
+    private float mLastMoveY = 0;
+    // Offset from the initial touch. Gets reset as direction keys are sent.
+    private float mAccumulatedX;
+    private float mAccumulatedY;
+
+    // Change in position allowed during tap events
+    private float mTouchSlop;
+    private float mTouchSlopSquared;
+    // Has the TouchSlop constraint been invalidated
+    private boolean mAlwaysInTapRegion = true;
+
+    // Most recent event. Used to determine what device sent the event.
+    private MotionEvent mRecentEvent;
+
+    // TODO: Currently using screen dimensions tuned to a Galaxy Nexus, need to
+    // read this from a config file instead
+    private int mDistancePerTick;
+    private int mDistancePerTickSquared;
+    // Highest rate that the flinged events can occur at before dying out
+    private int mMaxRepeatDelay;
+    // The square of the minimum distance needed for a flick to register
+    private int mMinFlickDistanceSquared;
+    // How quickly the repeated events die off
+    private float mFlickDecay;
+
+    public SimulatedTrackball() {
+        mDistancePerTick = SystemProperties.getInt("persist.vr_dist_tick", 64);
+        mDistancePerTickSquared = mDistancePerTick * mDistancePerTick;
+        mMaxRepeatDelay = SystemProperties.getInt("persist.vr_repeat_delay", 300);
+        mMinFlickDistanceSquared = SystemProperties.getInt("persist.vr_min_flick", 20);
+        mMinFlickDistanceSquared *= mMinFlickDistanceSquared;
+        mFlickDecay = Float.parseFloat(SystemProperties.get(
+                "persist.sys.vr_flick_decay", "1.3"));
+        mTouchSlop = ViewConfiguration.getTouchSlop();
+        mTouchSlopSquared = mTouchSlop * mTouchSlop;
+    }
+
+    private final Handler mHandler = new Handler(new Callback() {
+            @Override
+        public boolean handleMessage(Message msg) {
+            if (msg.what != FLICK_MSG_ID)
+                return false;
+
+            final long time = SystemClock.uptimeMillis();
+            ViewRootImpl viewroot = (ViewRootImpl) msg.obj;
+            // Send the key
+            viewroot.enqueueInputEvent(new KeyEvent(time, time,
+                    KeyEvent.ACTION_DOWN, msg.arg2, 0, mRecentEvent.getMetaState(),
+                    mRecentEvent.getDeviceId(), 0,
+                    KeyEvent.FLAG_FALLBACK, mRecentEvent.getSource()));
+            viewroot.enqueueInputEvent(new KeyEvent(time, time,
+                    KeyEvent.ACTION_UP, msg.arg2, 0, mRecentEvent.getMetaState(),
+                    mRecentEvent.getDeviceId(), 0,
+                    KeyEvent.FLAG_FALLBACK, mRecentEvent.getSource()));
+            Message msgCopy = Message.obtain(msg);
+            // Increase the delay by the decay factor
+            msgCopy.arg1 = (int) Math.ceil(mFlickDecay * msgCopy.arg1);
+            if (msgCopy.arg1 <= mMaxRepeatDelay) {
+                // Send the key again in arg1 milliseconds
+                mHandler.sendMessageDelayed(msgCopy, msgCopy.arg1);
+            }
+            return false;
+        }
+    });
+
+    public void updateTrackballDirection(ViewRootImpl viewroot, MotionEvent event) {
+        // Store what time the touchpad event occurred
+        final long time = SystemClock.uptimeMillis();
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_HOVER_ENTER:
+                mLastTouchPadStartTimeMs = time;
+                mAlwaysInTapRegion = true;
+                mTouchpadEnterXPosition = event.getX();
+                mTouchpadEnterYPosition = event.getY();
+                mAccumulatedX = 0;
+                mAccumulatedY = 0;
+                mLastMoveX = 0;
+                mLastMoveY = 0;
+                // Clear any flings
+                mHandler.removeMessages(FLICK_MSG_ID);
+                break;
+            case MotionEvent.ACTION_HOVER_MOVE:
+                // Determine whether the move is slop or an intentional move
+                float deltaX = event.getX() - mTouchpadEnterXPosition;
+                float deltaY = event.getY() - mTouchpadEnterYPosition;
+                if (mTouchSlopSquared < deltaX * deltaX + deltaY * deltaY) {
+                    mAlwaysInTapRegion = false;
+                }
+
+                // Find the difference in position between the two most recent
+                // touchpad events
+                mLastMoveX = event.getX() - mLastTouchpadXPosition;
+                mLastMoveY = event.getY() - mLastTouchpadYPosition;
+                mAccumulatedX += mLastMoveX;
+                mAccumulatedY += mLastMoveY;
+                float mAccumulatedXSquared = mAccumulatedX * mAccumulatedX;
+                float mAccumulatedYSquared = mAccumulatedY * mAccumulatedY;
+                // Determine if we've moved far enough to send a key press
+                if (mAccumulatedXSquared > mDistancePerTickSquared ||
+                        mAccumulatedYSquared > mDistancePerTickSquared) {
+                    float dominantAxis;
+                    float sign;
+                    boolean isXAxis;
+                    int key;
+                    int repeatCount = 0;
+                    // Determine dominant axis
+                    if (mAccumulatedXSquared > mAccumulatedYSquared) {
+                        dominantAxis = mAccumulatedX;
+                        isXAxis = true;
+                    } else {
+                        dominantAxis = mAccumulatedY;
+                        isXAxis = false;
+                    }
+                    // Determine sign of axis
+                    sign = (dominantAxis > 0) ? 1 : -1;
+                    // Determine key to send
+                    if (isXAxis) {
+                        key = (sign == 1) ? KeyEvent.KEYCODE_DPAD_RIGHT :
+                                KeyEvent.KEYCODE_DPAD_LEFT;
+                    } else {
+                        key = (sign == 1) ? KeyEvent.KEYCODE_DPAD_DOWN : KeyEvent.KEYCODE_DPAD_UP;
+                    }
+                    // Send key until maximum distance constraint is satisfied
+                    while (dominantAxis * dominantAxis > mDistancePerTickSquared) {
+                        repeatCount++;
+                        dominantAxis -= sign * mDistancePerTick;
+                        viewroot.enqueueInputEvent(new KeyEvent(time, time,
+                                KeyEvent.ACTION_DOWN, key, 0, event.getMetaState(),
+                                event.getDeviceId(), 0, KeyEvent.FLAG_FALLBACK, event.getSource()));
+                        viewroot.enqueueInputEvent(new KeyEvent(time, time,
+                                KeyEvent.ACTION_UP, key, 0, event.getMetaState(),
+                                event.getDeviceId(), 0, KeyEvent.FLAG_FALLBACK, event.getSource()));
+                    }
+                    // Save new axis values
+                    mAccumulatedX = isXAxis ? dominantAxis : 0;
+                    mAccumulatedY = isXAxis ? 0 : dominantAxis;
+
+                    mLastKeySent = key;
+                    mKeySendRateMs = (int) ((time - mLastTouchPadKeySendTimeMs) / repeatCount);
+                    mLastTouchPadKeySendTimeMs = time;
+                }
+                break;
+            case MotionEvent.ACTION_HOVER_EXIT:
+                if (time - mLastTouchPadStartTimeMs < MAX_TAP_TIME && mAlwaysInTapRegion) {
+                    // Trackball Down
+                    MotionEvent trackballEvent = MotionEvent.obtain(mLastTouchPadStartTimeMs, time,
+                            MotionEvent.ACTION_DOWN, 0, 0, 0, 0, event.getMetaState(),
+                            10f, 10f, event.getDeviceId(), 0);
+                    trackballEvent.setSource(InputDevice.SOURCE_CLASS_TRACKBALL);
+                    viewroot.enqueueInputEvent(trackballEvent);
+                    // Trackball Release
+                    trackballEvent = MotionEvent.obtain(mLastTouchPadStartTimeMs, time,
+                            MotionEvent.ACTION_UP, 0, 0, 0, 0, event.getMetaState(),
+                            10f, 10f, event.getDeviceId(), 0);
+                    trackballEvent.setSource(InputDevice.SOURCE_CLASS_TRACKBALL);
+                    viewroot.enqueueInputEvent(trackballEvent);
+                } else {
+                    float xMoveSquared = mLastMoveX * mLastMoveX;
+                    float yMoveSquared = mLastMoveY * mLastMoveY;
+                    // Determine whether the last gesture was a fling.
+                    if (mMinFlickDistanceSquared <= xMoveSquared + yMoveSquared &&
+                            time - mLastTouchPadEventTimeMs <= MAX_TAP_TIME &&
+                            mKeySendRateMs <= mMaxRepeatDelay && mKeySendRateMs > 0) {
+                        Message message = Message.obtain(mHandler, FLICK_MSG_ID,
+                                mKeySendRateMs, mLastKeySent, viewroot);
+                        mRecentEvent = event;
+                        mHandler.sendMessageDelayed(message, mKeySendRateMs);
+                    }
+                }
+                break;
+        }
+        // Store touch event position and time
+        mLastTouchPadEventTimeMs = time;
+        mLastTouchpadXPosition = event.getX();
+        mLastTouchpadYPosition = event.getY();
+    }
+}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index b6016e9..27d770b 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -144,6 +144,8 @@
     final TrackballAxis mTrackballAxisX = new TrackballAxis();
     final TrackballAxis mTrackballAxisY = new TrackballAxis();
 
+    final SimulatedTrackball mSimulatedTrackball = new SimulatedTrackball();
+
     int mLastJoystickXDirection;
     int mLastJoystickYDirection;
     int mLastJoystickXKeyCode;
@@ -3395,7 +3397,6 @@
         if (mInputEventConsistencyVerifier != null) {
             mInputEventConsistencyVerifier.onGenericMotionEvent(event, 0);
         }
-
         if (mView != null && mAdded && (q.mFlags & QueuedInputEvent.FLAG_DELIVER_POST_IME) == 0) {
             if (LOCAL_LOGV)
                 Log.v(TAG, "Dispatching generic motion " + event + " to " + mView);
@@ -3422,12 +3423,17 @@
 
     private void deliverGenericMotionEventPostIme(QueuedInputEvent q) {
         final MotionEvent event = (MotionEvent) q.mEvent;
-        final boolean isJoystick = (event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0;
+        final int source = event.getSource();
+        final boolean isJoystick = (source & InputDevice.SOURCE_CLASS_JOYSTICK) != 0;
+        final boolean isTouchPad = (source & InputDevice.SOURCE_CLASS_POSITION) != 0;
 
         // If there is no view, then the event will not be handled.
         if (mView == null || !mAdded) {
             if (isJoystick) {
                 updateJoystickDirection(event, false);
+            } else if (isTouchPad) {
+              //Convert TouchPad motion into a TrackBall event
+              mSimulatedTrackball.updateTrackballDirection(this, event);
             }
             finishInputEvent(q, false);
             return;
@@ -3437,6 +3443,9 @@
         if (mView.dispatchGenericMotionEvent(event)) {
             if (isJoystick) {
                 updateJoystickDirection(event, false);
+            } else if (isTouchPad) {
+              //Convert TouchPad motion into a TrackBall event
+              mSimulatedTrackball.updateTrackballDirection(this, event);
             }
             finishInputEvent(q, true);
             return;
@@ -3447,6 +3456,10 @@
             // those.
             updateJoystickDirection(event, true);
             finishInputEvent(q, true);
+        } else if (isTouchPad) {
+            //Convert TouchPad motion into a TrackBall event
+            mSimulatedTrackball.updateTrackballDirection(this, event);
+            finishInputEvent(q, true);
         } else {
             finishInputEvent(q, false);
         }
diff --git a/core/java/android/widget/CheckBox.java b/core/java/android/widget/CheckBox.java
index f1804f8..41ab5f2 100644
--- a/core/java/android/widget/CheckBox.java
+++ b/core/java/android/widget/CheckBox.java
@@ -20,6 +20,7 @@
 import android.util.AttributeSet;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.util.ValueModel;
 
 
 /**
@@ -55,7 +56,9 @@
  * {@link android.R.styleable#View View Attributes}
  * </p>
  */
-public class CheckBox extends CompoundButton {
+public class CheckBox extends CompoundButton implements ValueEditor<Boolean> {
+    private ValueModel<Boolean> mValueModel = ValueModel.EMPTY;
+
     public CheckBox(Context context) {
         this(context, null);
     }
@@ -79,4 +82,22 @@
         super.onInitializeAccessibilityNodeInfo(info);
         info.setClassName(CheckBox.class.getName());
     }
+
+    @Override
+    public ValueModel<Boolean> getValueModel() {
+        return mValueModel;
+    }
+
+    @Override
+    public void setValueModel(ValueModel<Boolean> valueModel) {
+        mValueModel = valueModel;
+        setChecked(mValueModel.get());
+    }
+
+    @Override
+    public boolean performClick() {
+        boolean handled = super.performClick();
+        mValueModel.set(isChecked());
+        return handled;
+    }
 }
diff --git a/core/java/android/widget/EditText.java b/core/java/android/widget/EditText.java
index 57e51c2..ec81214 100644
--- a/core/java/android/widget/EditText.java
+++ b/core/java/android/widget/EditText.java
@@ -17,6 +17,7 @@
 package android.widget;
 
 import android.content.Context;
+import android.graphics.Rect;
 import android.text.Editable;
 import android.text.Selection;
 import android.text.Spannable;
@@ -24,6 +25,7 @@
 import android.text.method.ArrowKeyMovementMethod;
 import android.text.method.MovementMethod;
 import android.util.AttributeSet;
+import android.util.ValueModel;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 
@@ -47,7 +49,9 @@
  * {@link android.R.styleable#TextView TextView Attributes},
  * {@link android.R.styleable#View View Attributes}
  */
-public class EditText extends TextView {
+public class EditText extends TextView implements ValueEditor<CharSequence> {
+    private ValueModel<CharSequence> mValueModel = ValueModel.EMPTY;
+
     public EditText(Context context) {
         this(context, null);
     }
@@ -128,4 +132,21 @@
         super.onInitializeAccessibilityNodeInfo(info);
         info.setClassName(EditText.class.getName());
     }
+
+    @Override
+    public ValueModel<CharSequence> getValueModel() {
+        return mValueModel;
+    }
+
+    @Override
+    public void setValueModel(ValueModel<CharSequence> valueModel) {
+        mValueModel = valueModel;
+        setText(mValueModel.get());
+    }
+
+    @Override
+    void sendAfterTextChanged(Editable text) {
+        super.sendAfterTextChanged(text);
+        mValueModel.set(text);
+    }
 }
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 4918e48..6cfeb15 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -470,6 +470,11 @@
     private final PressedStateHelper mPressedStateHelper;
 
     /**
+     * The keycode of the last handled DPAD down event.
+     */
+    private int mLastHandledDownDpadKeyCode = -1;
+
+    /**
      * Interface to listen for changes of the current value.
      */
     public interface OnValueChangeListener {
@@ -936,6 +941,31 @@
             case KeyEvent.KEYCODE_ENTER:
                 removeAllCallbacks();
                 break;
+            case KeyEvent.KEYCODE_DPAD_DOWN:
+            case KeyEvent.KEYCODE_DPAD_UP:
+                if (!mHasSelectorWheel) {
+                    break;
+                }
+                switch (event.getAction()) {
+                    case KeyEvent.ACTION_DOWN:
+                        if (mWrapSelectorWheel || (keyCode == KeyEvent.KEYCODE_DPAD_DOWN)
+                                ? getValue() < getMaxValue() : getValue() > getMinValue()) {
+                            requestFocus();
+                            mLastHandledDownDpadKeyCode = keyCode;
+                            removeAllCallbacks();
+                            if (mFlingScroller.isFinished()) {
+                                changeValueByOne(keyCode == KeyEvent.KEYCODE_DPAD_DOWN);
+                            }
+                            return true;
+                        }
+                        break;
+                    case KeyEvent.ACTION_UP:
+                        if (mLastHandledDownDpadKeyCode == keyCode) {
+                            mLastHandledDownDpadKeyCode = -1;
+                            return true;
+                        }
+                        break;
+                }
         }
         return super.dispatchKeyEvent(event);
     }
diff --git a/core/java/android/widget/SeekBar.java b/core/java/android/widget/SeekBar.java
index 2737f94..a6486a8 100644
--- a/core/java/android/widget/SeekBar.java
+++ b/core/java/android/widget/SeekBar.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.util.AttributeSet;
+import android.util.ValueModel;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 
@@ -33,7 +34,7 @@
  *
  * @attr ref android.R.styleable#SeekBar_thumb
  */
-public class SeekBar extends AbsSeekBar {
+public class SeekBar extends AbsSeekBar implements ValueEditor<Integer> {
 
     /**
      * A callback that notifies clients when the progress level has been
@@ -69,8 +70,9 @@
         void onStopTrackingTouch(SeekBar seekBar);
     }
 
+    private ValueModel<Integer> mValueModel = ValueModel.EMPTY;
     private OnSeekBarChangeListener mOnSeekBarChangeListener;
-    
+
     public SeekBar(Context context) {
         this(context, null);
     }
@@ -89,9 +91,23 @@
 
         if (mOnSeekBarChangeListener != null) {
             mOnSeekBarChangeListener.onProgressChanged(this, getProgress(), fromUser);
+            if (fromUser) {
+                mValueModel.set(getProgress());
+            }
         }
     }
 
+    @Override
+    public ValueModel<Integer> getValueModel() {
+        return mValueModel;
+    }
+
+    @Override
+    public void setValueModel(ValueModel<Integer> valueModel) {
+        mValueModel = valueModel;
+        setProgress(mValueModel.get());
+    }
+
     /**
      * Sets a listener to receive notifications of changes to the SeekBar's progress level. Also
      * provides notifications of when the user starts and stops a touch gesture within the SeekBar.
diff --git a/core/java/android/widget/ValueEditor.java b/core/java/android/widget/ValueEditor.java
new file mode 100755
index 0000000..2b91abf
--- /dev/null
+++ b/core/java/android/widget/ValueEditor.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget;
+
+import android.util.ValueModel;
+
+/**
+ * An interface for editors of simple values. Classes implementing this interface are normally
+ * UI controls (subclasses of {@link android.view.View View}) that can provide a suitable
+ * user interface to display and edit values of the specified type. This interface is
+ * intended to describe editors for simple types, like {@code boolean}, {@code int} or
+ * {@code String}, where the values themselves are immutable.
+ * <p>
+ * For example, {@link android.widget.CheckBox CheckBox} implements
+ * this interface for the Boolean type as it is capable of providing an appropriate
+ * mechanism for displaying and changing the value of a Boolean property.
+ *
+ * @param <T> the value type that this editor supports
+ */
+public interface ValueEditor<T> {
+    /**
+     * Return the last value model that was set. If no value model has been set, the editor
+     * should return the value {@link android.util.ValueModel#EMPTY}.
+     *
+     * @return the value model
+     */
+    public ValueModel<T> getValueModel();
+
+    /**
+     * Sets the value model for this editor. When the value model is set, the editor should
+     * retrieve the value from the value model, using {@link android.util.ValueModel#get()},
+     * and set its internal state accordingly. Likewise, when the editor's internal state changes
+     * it should update the value model by calling  {@link android.util.ValueModel#set(T)}
+     * with the appropriate value.
+     *
+     * @param valueModel the new value model for this editor.
+     */
+    public void setValueModel(ValueModel<T> valueModel);
+}
diff --git a/core/jni/android_text_format_Time.cpp b/core/jni/android_text_format_Time.cpp
index aa2c5f39..0a59ae7 100644
--- a/core/jni/android_text_format_Time.cpp
+++ b/core/jni/android_text_format_Time.cpp
@@ -23,7 +23,6 @@
 #include "jni.h"
 #include "utils/misc.h"
 #include "android_runtime/AndroidRuntime.h"
-#include "ScopedStringChars.h"
 #include "TimeUtils.h"
 #include <nativehelper/JNIHelp.h>
 #include <cutils/tztime.h>
@@ -72,10 +71,11 @@
     t->t.tm_gmtoff = env->GetLongField(o, g_gmtoffField);
     bool allDay = env->GetBooleanField(o, g_allDayField);
     if (allDay &&
-       ((t->t.tm_sec !=0) || (t->t.tm_min != 0) || (t->t.tm_hour != 0))) {
-        jniThrowException(env, "java/lang/IllegalArgumentException",
-                          "allDay is true but sec, min, hour are not 0.");
-        return false;
+	((t->t.tm_sec !=0) || (t->t.tm_min != 0) || (t->t.tm_hour != 0))) {
+        char msg[100];
+	sprintf(msg, "allDay is true but sec, min, hour are not 0.");
+	jniThrowException(env, "java/lang/IllegalArgumentException", msg);
+	return false;
     }
     return true;
 }
@@ -313,7 +313,7 @@
 static jstring android_text_format_Time_toString(JNIEnv* env, jobject This)
 {
     Time t;
-    if (!java2time(env, &t, This)) return env->NewStringUTF("");
+    if (!java2time(env, &t, This)) return env->NewStringUTF("");;
     ACQUIRE_TIMEZONE(This, t)
 
     String8 r = t.toString();
@@ -365,30 +365,32 @@
 // ============================================================================
 // Just do this here because it's not worth recreating the strings
 
-static int get_char(JNIEnv* env, const ScopedStringChars& s, int spos, int mul,
-                    bool* thrown)
+static int get_char(JNIEnv* env, const jchar *s, int spos, int mul,
+                    bool *thrown)
 {
     jchar c = s[spos];
     if (c >= '0' && c <= '9') {
         return (c - '0') * mul;
     } else {
         if (!*thrown) {
-            jniThrowExceptionFmt(env, "android/util/TimeFormatException",
-                                 "Parse error at pos=%d", spos);
+            char msg[100];
+            sprintf(msg, "Parse error at pos=%d", spos);
+            jniThrowException(env, "android/util/TimeFormatException", msg);
             *thrown = true;
         }
         return 0;
     }
 }
 
-static bool check_char(JNIEnv* env, const ScopedStringChars& s, int spos, jchar expected)
+static bool check_char(JNIEnv* env, const jchar *s, int spos, jchar expected)
 {
     jchar c = s[spos];
     if (c != expected) {
-        jniThrowExceptionFmt(env, "android/util/TimeFormatException",
-                             "Unexpected character 0x%02x at pos=%d.  Expected %c.",
-                             c, spos, expected);
-        return false;
+        char msg[100];
+	sprintf(msg, "Unexpected character 0x%02x at pos=%d.  Expected %c.", c, spos,
+		expected);
+	jniThrowException(env, "android/util/TimeFormatException", msg);
+	return false;
     }
     return true;
 }
@@ -397,19 +399,20 @@
 static jboolean android_text_format_Time_parse(JNIEnv* env, jobject This, jstring strObj)
 {
     jsize len = env->GetStringLength(strObj);
-    if (len < 8) {
-        jniThrowException(env, "android/util/TimeFormatException",
-                          "String too short -- expected at least 8 characters.");
-        return false;
-    }
+    const jchar *s = env->GetStringChars(strObj, NULL);
 
+    bool thrown = false;
+    int n;
     jboolean inUtc = false;
 
-    ScopedStringChars s(env, strObj);
+    if (len < 8) {
+        char msg[100];
+        sprintf(msg, "String too short -- expected at least 8 characters.");
+	jniThrowException(env, "android/util/TimeFormatException", msg);
+	return false;
+    }
 
     // year
-    int n;
-    bool thrown = false;
     n = get_char(env, s, 0, 1000, &thrown);
     n += get_char(env, s, 1, 100, &thrown);
     n += get_char(env, s, 2, 10, &thrown);
@@ -456,7 +459,7 @@
         if (len > 15) {
             // Z
             if (!check_char(env, s, 15, 'Z')) return false;
-            inUtc = true;
+	    inUtc = true;
         }
     } else {
         env->SetBooleanField(This, g_allDayField, JNI_TRUE);
@@ -469,7 +472,8 @@
     env->SetIntField(This, g_ydayField, 0);
     env->SetIntField(This, g_isdstField, -1);
     env->SetLongField(This, g_gmtoffField, 0);
-
+    
+    env->ReleaseStringChars(strObj, s);
     return inUtc;
 }
 
@@ -478,19 +482,19 @@
                                            jstring strObj)
 {
     jsize len = env->GetStringLength(strObj);
+    const jchar *s = env->GetStringChars(strObj, NULL);
+
+    bool thrown = false;
+    int n;
+    jboolean inUtc = false;
+
     if (len < 10) {
         jniThrowException(env, "android/util/TimeFormatException",
-                          "String too short --- expected at least 10 characters.");
+                "Time input is too short; must be at least 10 characters");
         return false;
     }
 
-    jboolean inUtc = false;
-
-    ScopedStringChars s(env, strObj);
-
     // year
-    int n;
-    bool thrown = false;
     n = get_char(env, s, 0, 1000, &thrown);    
     n += get_char(env, s, 1, 100, &thrown);
     n += get_char(env, s, 2, 10, &thrown);
@@ -521,28 +525,28 @@
         // T
         if (!check_char(env, s, 10, 'T')) return false;
 
-        env->SetBooleanField(This, g_allDayField, JNI_FALSE);
+	env->SetBooleanField(This, g_allDayField, JNI_FALSE);
         // hour
         n = get_char(env, s, 11, 10, &thrown);
         n += get_char(env, s, 12, 1, &thrown);
         if (thrown) return false;
-        int hour = n;
+	int hour = n;
         // env->SetIntField(This, g_hourField, n);
+	
+	// :
+	if (!check_char(env, s, 13, ':')) return false;
 
-        // :
-        if (!check_char(env, s, 13, ':')) return false;
-
-        // minute
+	// minute
         n = get_char(env, s, 14, 10, &thrown);
         n += get_char(env, s, 15, 1, &thrown);
         if (thrown) return false;
-        int minute = n;
+	int minute = n;
         // env->SetIntField(This, g_minField, n);
 
-        // :
-        if (!check_char(env, s, 16, ':')) return false;
+	// :
+	if (!check_char(env, s, 16, ':')) return false;
 
-        // second
+	// second
         n = get_char(env, s, 17, 10, &thrown);
         n += get_char(env, s, 18, 1, &thrown);
         if (thrown) return false;
@@ -562,63 +566,64 @@
         if (len > tz_index) {
             char c = s[tz_index];
 
-            // NOTE: the offset is meant to be subtracted to get from local time
-            // to UTC.  we therefore use 1 for '-' and -1 for '+'.
-            switch (c) {
-            case 'Z':
-                // Zulu time -- UTC
-                offset = 0;
-                break;
-            case '-': 
+	    // NOTE: the offset is meant to be subtracted to get from local time
+	    // to UTC.  we therefore use 1 for '-' and -1 for '+'.
+	    switch (c) {
+	    case 'Z':
+	        // Zulu time -- UTC
+	        offset = 0;
+		break;
+	    case '-': 
                 offset = 1;
-                break;
-            case '+': 
+	        break;
+	    case '+': 
                 offset = -1;
-                break;
-            default:
-                jniThrowExceptionFmt(env, "android/util/TimeFormatException",
-                                     "Unexpected character 0x%02x at position %d.  Expected + or -",
-                                     c, tz_index);
-                return false;
-            }
+	        break;
+	    default:
+	        char msg[100];
+	        sprintf(msg, "Unexpected character 0x%02x at position %d.  Expected + or -",
+			c, tz_index);
+	        jniThrowException(env, "android/util/TimeFormatException", msg);
+	        return false;
+	    }
             inUtc = true;
 
-            if (offset != 0) {
-                if (len < tz_index + 6) {
-                    jniThrowExceptionFmt(env, "android/util/TimeFormatException",
-                                         "Unexpected length; should be %d characters",
-                                         tz_index + 6);
-                    return false;
-                }
+	    if (offset != 0) {
+	        if (len < tz_index + 6) {
+	            char msg[100];
+	            sprintf(msg, "Unexpected length; should be %d characters", tz_index + 6);
+	            jniThrowException(env, "android/util/TimeFormatException", msg);
+	            return false;
+	        }
 
-                // hour
-                n = get_char(env, s, tz_index + 1, 10, &thrown);
-                n += get_char(env, s, tz_index + 2, 1, &thrown);
-                if (thrown) return false;
-                n *= offset;
-                hour += n;
+	        // hour
+	        n = get_char(env, s, tz_index + 1, 10, &thrown);
+		n += get_char(env, s, tz_index + 2, 1, &thrown);
+		if (thrown) return false;
+		n *= offset;
+		hour += n;
 
-                // :
-                if (!check_char(env, s, tz_index + 3, ':')) return false;
-            
-                // minute
-                n = get_char(env, s, tz_index + 4, 10, &thrown);
-                n += get_char(env, s, tz_index + 5, 1, &thrown);
-                if (thrown) return false;
-                n *= offset;
-                minute += n;
-            }
-        }
-        env->SetIntField(This, g_hourField, hour);
+		// :
+		if (!check_char(env, s, tz_index + 3, ':')) return false;
+	    
+		// minute
+		n = get_char(env, s, tz_index + 4, 10, &thrown);
+		n += get_char(env, s, tz_index + 5, 1, &thrown);
+		if (thrown) return false;
+		n *= offset;
+		minute += n;
+	    }
+	}
+	env->SetIntField(This, g_hourField, hour);
         env->SetIntField(This, g_minField, minute);
 
-        if (offset != 0) {
-            // we need to normalize after applying the hour and minute offsets
-            android_text_format_Time_normalize(env, This, false /* use isdst */);
-            // The timezone is set to UTC in the calling Java code.
-        }
+	if (offset != 0) {
+	    // we need to normalize after applying the hour and minute offsets
+	    android_text_format_Time_normalize(env, This, false /* use isdst */);
+	    // The timezone is set to UTC in the calling Java code.
+	}
     } else {
-        env->SetBooleanField(This, g_allDayField, JNI_TRUE);
+	env->SetBooleanField(This, g_allDayField, JNI_TRUE);
         env->SetIntField(This, g_hourField, 0);
         env->SetIntField(This, g_minField, 0);
         env->SetIntField(This, g_secField, 0);
@@ -628,7 +633,8 @@
     env->SetIntField(This, g_ydayField, 0);
     env->SetIntField(This, g_isdstField, -1);
     env->SetLongField(This, g_gmtoffField, 0);
-
+    
+    env->ReleaseStringChars(strObj, s);
     return inUtc;
 }
 
diff --git a/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java b/services/java/com/android/server/updatable/ConfigUpdateInstallReceiver.java
similarity index 100%
rename from services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
rename to services/java/com/android/server/updatable/ConfigUpdateInstallReceiver.java
diff --git a/services/java/com/android/server/updates/CertPinInstallReceiver.java b/services/java/com/android/server/updates/CertPinInstallReceiver.java
deleted file mode 100644
index c03fbc3..0000000
--- a/services/java/com/android/server/updates/CertPinInstallReceiver.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.updates;
-
-public class CertPinInstallReceiver extends ConfigUpdateInstallReceiver {
-
-    public CertPinInstallReceiver() {
-        super("/data/misc/keychain/", "pins", "metadata/", "version");
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/updates/CertPinInstallReceiverTest.java b/services/tests/servicestests/src/com/android/server/updates/CertPinInstallReceiverTest.java
deleted file mode 100644
index b6742a1..0000000
--- a/services/tests/servicestests/src/com/android/server/updates/CertPinInstallReceiverTest.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.updates;
-
-import android.content.Context;
-import android.content.Intent;
-import android.test.AndroidTestCase;
-import android.provider.Settings;
-import android.util.Base64;
-import android.util.Log;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.cert.CertificateFactory;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.Signature;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.KeyFactory;
-import java.util.HashSet;
-import java.io.*;
-import libcore.io.IoUtils;
-
-/**
- * Tests for {@link com.android.server.CertPinInstallReceiver}
- */
-public class CertPinInstallReceiverTest extends AndroidTestCase {
-
-    private static final String TAG = "CertPinInstallReceiverTest";
-
-    private static final String PINLIST_ROOT = System.getenv("ANDROID_DATA") + "/misc/keychain/";
-
-    public static final String PINLIST_CONTENT_PATH = PINLIST_ROOT + "pins";
-    public static final String PINLIST_METADATA_PATH = PINLIST_CONTENT_PATH + "metadata";
-
-    public static final String PINLIST_CONTENT_URL_KEY = "pinlist_content_url";
-    public static final String PINLIST_METADATA_URL_KEY = "pinlist_metadata_url";
-    public static final String PINLIST_CERTIFICATE_KEY = "config_update_certificate";
-    public static final String PINLIST_VERSION_KEY = "pinlist_version";
-
-    private static final String EXTRA_CONTENT_PATH = "CONTENT_PATH";
-    private static final String EXTRA_REQUIRED_HASH = "REQUIRED_HASH";
-    private static final String EXTRA_SIGNATURE = "SIGNATURE";
-    private static final String EXTRA_VERSION_NUMBER = "VERSION";
-
-    public static final String TEST_CERT = "" +
-                    "MIIDsjCCAxugAwIBAgIJAPLf2gS0zYGUMA0GCSqGSIb3DQEBBQUAMIGYMQswCQYDVQQGEwJVUzET" +
-                    "MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEPMA0GA1UEChMGR29v" +
-                    "Z2xlMRAwDgYDVQQLEwd0ZXN0aW5nMRYwFAYDVQQDEw1HZXJlbXkgQ29uZHJhMSEwHwYJKoZIhvcN" +
-                    "AQkBFhJnY29uZHJhQGdvb2dsZS5jb20wHhcNMTIwNzE0MTc1MjIxWhcNMTIwODEzMTc1MjIxWjCB" +
-                    "mDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZp" +
-                    "ZXcxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHdGVzdGluZzEWMBQGA1UEAxMNR2VyZW15IENv" +
-                    "bmRyYTEhMB8GCSqGSIb3DQEJARYSZ2NvbmRyYUBnb29nbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUA" +
-                    "A4GNADCBiQKBgQCjGGHATBYlmas+0sEECkno8LZ1KPglb/mfe6VpCT3GhSr+7br7NG/ZwGZnEhLq" +
-                    "E7YIH4fxltHmQC3Tz+jM1YN+kMaQgRRjo/LBCJdOKaMwUbkVynAH6OYsKevjrOPk8lfM5SFQzJMG" +
-                    "sA9+Tfopr5xg0BwZ1vA/+E3mE7Tr3M2UvwIDAQABo4IBADCB/TAdBgNVHQ4EFgQUhzkS9E6G+x8W" +
-                    "L4EsmRjDxu28tHUwgc0GA1UdIwSBxTCBwoAUhzkS9E6G+x8WL4EsmRjDxu28tHWhgZ6kgZswgZgx" +
-                    "CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3" +
-                    "MQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB3Rlc3RpbmcxFjAUBgNVBAMTDUdlcmVteSBDb25k" +
-                    "cmExITAfBgkqhkiG9w0BCQEWEmdjb25kcmFAZ29vZ2xlLmNvbYIJAPLf2gS0zYGUMAwGA1UdEwQF" +
-                    "MAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAYiugFDmbDOQ2U/+mqNt7o8ftlEo9SJrns6O8uTtK6AvR" +
-                    "orDrR1AXTXkuxwLSbmVfedMGOZy7Awh7iZa8hw5x9XmUudfNxvmrKVEwGQY2DZ9PXbrnta/dwbhK" +
-                    "mWfoepESVbo7CKIhJp8gRW0h1Z55ETXD57aGJRvQS4pxkP8ANhM=";
-
-
-    public static final String TEST_KEY = "" +
-                    "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKMYYcBMFiWZqz7SwQQKSejwtnUo" +
-                    "+CVv+Z97pWkJPcaFKv7tuvs0b9nAZmcSEuoTtggfh/GW0eZALdPP6MzVg36QxpCBFGOj8sEIl04p" +
-                    "ozBRuRXKcAfo5iwp6+Os4+TyV8zlIVDMkwawD35N+imvnGDQHBnW8D/4TeYTtOvczZS/AgMBAAEC" +
-                    "gYBxwFalNSwZK3WJipq+g6KLCiBn1JxGGDQlLKrweFaSuFyFky9fd3IvkIabirqQchD612sMb+GT" +
-                    "0t1jptW6z4w2w6++IW0A3apDOCwoD+uvDBXrbFqI0VbyAWUNqHVdaFFIRk2IHGEE6463mGRdmILX" +
-                    "IlCd/85RTHReg4rl/GFqWQJBANgLAIR4pWbl5Gm+DtY18wp6Q3pJAAMkmP/lISCBIidu1zcqYIKt" +
-                    "PoDW4Knq9xnhxPbXrXKv4YzZWHBK8GkKhQ0CQQDBQnXufQcMew+PwiS0oJvS+eQ6YJwynuqG2ejg" +
-                    "WE+T7489jKtscRATpUXpZUYmDLGg9bLt7L62hFvFSj2LO2X7AkBcdrD9AWnBFWlh/G77LVHczSEu" +
-                    "KCoyLiqxcs5vy/TjLaQ8vw1ZQG580/qJnr+tOxyCjSJ18GK3VppsTRaBznfNAkB3nuCKNp9HTWCL" +
-                    "dfrsRsFMrFpk++mSt6SoxXaMbn0LL2u1CD4PCEiQMGt+lK3/3TmRTKNs+23sYS7Ahjxj0udDAkEA" +
-                    "p57Nj65WNaWeYiOfTwKXkLj8l29H5NbaGWxPT0XkWr4PvBOFZVH/wj0/qc3CMVGnv11+DyO+QUCN" +
-                    "SqBB5aRe8g==";
-
-    private void overrideSettings(String key, String value) throws Exception {
-        assertTrue(Settings.Secure.putString(mContext.getContentResolver(), key, value));
-        Thread.sleep(1000);
-    }
-
-    private void overrideCert(String value) throws Exception {
-        overrideSettings(PINLIST_CERTIFICATE_KEY, value);
-    }
-
-    private String readPins() throws Exception {
-        return IoUtils.readFileAsString(PINLIST_CONTENT_PATH);
-    }
-
-    private String readCurrentVersion() throws Exception {
-        return IoUtils.readFileAsString("/data/misc/keychain/metadata/version");
-    }
-
-    private String getNextVersion() throws Exception {
-        int currentVersion = Integer.parseInt(readCurrentVersion());
-        return Integer.toString(currentVersion + 1);
-    }
-
-    private static String getCurrentHash(String content) throws Exception {
-        if (content == null) {
-            return "0";
-        }
-        MessageDigest dgst = MessageDigest.getInstance("SHA512");
-        byte[] encoded = content.getBytes();
-        byte[] fingerprint = dgst.digest(encoded);
-        return IntegralToString.bytesToHexString(fingerprint, false);
-    }
-
-    private static String getHashOfCurrentContent() throws Exception {
-        String content = IoUtils.readFileAsString("/data/misc/keychain/pins");
-        return getCurrentHash(content);
-    }
-
-    private PrivateKey createKey() throws Exception {
-        byte[] derKey = Base64.decode(TEST_KEY.getBytes(), Base64.DEFAULT);
-        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(derKey);
-        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
-        return (PrivateKey) keyFactory.generatePrivate(keySpec);
-    }
-
-    private X509Certificate createCertificate() throws Exception {
-        byte[] derCert = Base64.decode(TEST_CERT.getBytes(), Base64.DEFAULT);
-        InputStream istream = new ByteArrayInputStream(derCert);
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-        return (X509Certificate) cf.generateCertificate(istream);
-    }
-
-    private String makeTemporaryContentFile(String content) throws Exception {
-        FileOutputStream fw = mContext.openFileOutput("content.txt", mContext.MODE_WORLD_READABLE);
-        fw.write(content.getBytes(), 0, content.length());
-        fw.close();
-        return mContext.getFilesDir() + "/content.txt";
-    }
-
-    private String createSignature(String content, String version, String requiredHash)
-                                   throws Exception {
-        Signature signer = Signature.getInstance("SHA512withRSA");
-        signer.initSign(createKey());
-        signer.update(content.trim().getBytes());
-        signer.update(version.trim().getBytes());
-        signer.update(requiredHash.getBytes());
-        String sig = new String(Base64.encode(signer.sign(), Base64.DEFAULT));
-        assertEquals(true,
-                     verifySignature(content, version, requiredHash, sig, createCertificate()));
-        return sig;
-    }
-
-    public boolean verifySignature(String content, String version, String requiredPrevious,
-                                   String signature, X509Certificate cert) throws Exception {
-        Signature signer = Signature.getInstance("SHA512withRSA");
-        signer.initVerify(cert);
-        signer.update(content.trim().getBytes());
-        signer.update(version.trim().getBytes());
-        signer.update(requiredPrevious.trim().getBytes());
-        return signer.verify(Base64.decode(signature.getBytes(), Base64.DEFAULT));
-    }
-
-    private void sendIntent(String contentPath, String version, String required, String sig) {
-        Intent i = new Intent();
-        i.setAction("android.intent.action.UPDATE_PINS");
-        i.putExtra(EXTRA_CONTENT_PATH, contentPath);
-        i.putExtra(EXTRA_VERSION_NUMBER, version);
-        i.putExtra(EXTRA_REQUIRED_HASH, required);
-        i.putExtra(EXTRA_SIGNATURE, sig);
-        mContext.sendBroadcast(i);
-    }
-
-    private String runTest(String cert, String content, String version, String required, String sig)
-                           throws Exception {
-        Log.e(TAG, "started test");
-        overrideCert(cert);
-        String contentPath = makeTemporaryContentFile(content);
-        sendIntent(contentPath, version, required, sig);
-        Thread.sleep(1000);
-        return readPins();
-    }
-
-    private String runTestWithoutSig(String cert, String content, String version, String required)
-                                     throws Exception {
-        String sig = createSignature(content, version, required);
-        return runTest(cert, content, version, required, sig);
-    }
-
-    public void testOverwritePinlist() throws Exception {
-        Log.e(TAG, "started testOverwritePinList");
-        assertEquals("abcde", runTestWithoutSig(TEST_CERT, "abcde", getNextVersion(), getHashOfCurrentContent()));
-        Log.e(TAG, "started testOverwritePinList");
-    }
-
-   public void testBadSignatureFails() throws Exception {
-        Log.e(TAG, "started testOverwritePinList");
-        String text = "blahblah";
-        runTestWithoutSig(TEST_CERT, text, getNextVersion(), getHashOfCurrentContent());
-        assertEquals(text, runTest(TEST_CERT, "bcdef", getNextVersion(), getCurrentHash(text), ""));
-        Log.e(TAG, "started testOverwritePinList");
-    }
-
-    public void testBadRequiredHashFails() throws Exception {
-        runTestWithoutSig(TEST_CERT, "blahblahblah", getNextVersion(), getHashOfCurrentContent());
-        assertEquals("blahblahblah", runTestWithoutSig(TEST_CERT, "cdefg", getNextVersion(), "0"));
-        Log.e(TAG, "started testOverwritePinList");
-    }
-
-    public void testBadVersionFails() throws Exception {
-        String text = "blahblahblahblah";
-        String version = getNextVersion();
-        runTestWithoutSig(TEST_CERT, text, version, getHashOfCurrentContent());
-        assertEquals(text, runTestWithoutSig(TEST_CERT, "defgh", version, getCurrentHash(text)));
-        Log.e(TAG, "started testOverwritePinList");
-    }
-
-    public void testOverrideRequiredHash() throws Exception {
-        runTestWithoutSig(TEST_CERT, "blahblahblah", getNextVersion(), getHashOfCurrentContent());
-        assertEquals("blahblahblah", runTestWithoutSig(TEST_CERT, "cdefg", "NONE", "0"));
-        Log.e(TAG, "started testOverwritePinList");
-    }
-
-}
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 77168f9..9c2e1b9 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -1946,7 +1946,7 @@
                 const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
 
                 fprintf(fp,
-                        "int styleable %s_%s %d\n",
+                        "int styleable.%s_%s %d\n",
                         nclassName.string(),
                         String8(name).string(), (int)pos);
             }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 039319d..4a4320c 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -30,6 +30,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.net.IConnectivityManager;
 import android.net.ConnectivityManager;
@@ -68,6 +69,7 @@
 import android.text.TextUtils;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -1949,6 +1951,26 @@
                 break;
         }
 
+        if ((r.getConfiguration().uiMode & Configuration.UI_MODE_TYPE_APPLIANCE) ==
+                Configuration.UI_MODE_TYPE_APPLIANCE) {
+            // For appliance devices, add a key listener which accepts.
+            dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
+
+                @Override
+                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
+                    // TODO: make the actual key come from a config value.
+                    if (keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
+                        sendMessage(PEER_CONNECTION_USER_ACCEPT);
+                        dialog.dismiss();
+                        return true;
+                    }
+                    return false;
+                }
+            });
+            // TODO: add timeout for this dialog.
+            // TODO: update UI in appliance mode to tell user what to do.
+        }
+
         dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
         dialog.show();
     }