Merge "Import translations. DO NOT MERGE"
diff --git a/api/current.txt b/api/current.txt
index a6bdf5a..6fdd161 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23119,6 +23119,7 @@
     method public void addOnLayoutChangeListener(android.view.View.OnLayoutChangeListener);
     method public void addTouchables(java.util.ArrayList<android.view.View>);
     method public android.view.ViewPropertyAnimator animate();
+    method public void announceForAccessibility(java.lang.CharSequence);
     method protected boolean awakenScrollBars();
     method protected boolean awakenScrollBars(int);
     method protected boolean awakenScrollBars(int, boolean);
@@ -24343,6 +24344,7 @@
     field public static final int INVALID_POSITION = -1; // 0xffffffff
     field public static final deprecated int MAX_TEXT_LENGTH = 500; // 0x1f4
     field public static final int TYPES_ALL_MASK = -1; // 0xffffffff
+    field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000
     field public static final int TYPE_NOTIFICATION_STATE_CHANGED = 64; // 0x40
     field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1024; // 0x400
     field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 512; // 0x200
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a651362..7ab79ff 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3952,6 +3952,24 @@
     }
 
     /**
+     * Convenience method for sending a {@link AccessibilityEvent#TYPE_ANNOUNCEMENT}
+     * {@link AccessibilityEvent} to make an announcement which is related to some
+     * sort of a context change for which none of the events representing UI transitions
+     * is a good fit. For example, announcing a new page in a book. If accessibility
+     * is not enabled this method does nothing.
+     *
+     * @param text The announcement text.
+     */
+    public void announceForAccessibility(CharSequence text) {
+        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+            AccessibilityEvent event = AccessibilityEvent.obtain(
+                    AccessibilityEvent.TYPE_ANNOUNCEMENT);
+            event.getText().add(text);
+            sendAccessibilityEventUnchecked(event);
+        }
+    }
+
+    /**
      * @see #sendAccessibilityEvent(int)
      *
      * Note: Called from the default {@link AccessibilityDelegate}.
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 75b875a..58844fc 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -429,6 +429,26 @@
  * view.</br>
  * </p>
  * <p>
+ * <b>MISCELLANEOUS TYPES</b></br>
+ * </p>
+ * <p>
+ * <b>Announcement</b> - represents the event of an application making an
+ * announcement. Usually this announcement is related to some sort of a context
+ * change for which none of the events representing UI transitions is a good fit.
+ * For example, announcing a new page in a book.</br>
+ * <em>Type:</em> {@link #TYPE_ANNOUNCEMENT}</br>
+ * <em>Properties:</em></br>
+ * <ul>
+ *   <li>{@link #getEventType()} - The type of the event.</li>
+ *   <li>{@link #getSource()} - The source info (for registered clients).</li>
+ *   <li>{@link #getClassName()} - The class name of the source.</li>
+ *   <li>{@link #getPackageName()} - The package name of the source.</li>
+ *   <li>{@link #getEventTime()}  - The event time.</li>
+ *   <li>{@link #getText()} - The text of the announcement.</li>
+ *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
+ * </ul>
+ * </p>
+ * <p>
  * <b>Security note</b>
  * <p>
  * Since an event contains the text of its source privacy can be compromised by leaking
@@ -538,6 +558,11 @@
     public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 0x00002000;
 
     /**
+     * Represents the event of an application making an announcement.
+     */
+    public static final int TYPE_ANNOUNCEMENT = 0x00004000;
+
+    /**
      * Mask for {@link AccessibilityEvent} all types.
      *
      * @see #TYPE_VIEW_CLICKED
@@ -554,6 +579,7 @@
      * @see #TYPE_WINDOW_CONTENT_CHANGED
      * @see #TYPE_VIEW_SCROLLED
      * @see #TYPE_VIEW_TEXT_SELECTION_CHANGED
+     * @see #TYPE_ANNOUNCEMENT
      */
     public static final int TYPES_ALL_MASK = 0xFFFFFFFF;
 
@@ -984,6 +1010,8 @@
                 return "TYPE_VIEW_TEXT_SELECTION_CHANGED";
             case TYPE_VIEW_SCROLLED:
                 return "TYPE_VIEW_SCROLLED";
+            case TYPE_ANNOUNCEMENT:
+                return "TYPE_ANNOUNCEMENT";
             default:
                 return null;
         }
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 2afb841..800ebc8 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -76,6 +76,8 @@
     private volatile WebBackForwardListClient mWebBackForwardListClient;
     // Used to call startActivity during url override.
     private final Context mContext;
+    // block messages flag for destroy
+    private boolean mBlockMessages;
 
     // Message IDs
     private static final int PAGE_STARTED                         = 100;
@@ -155,10 +157,18 @@
         mBackForwardList = new WebBackForwardList(this);
     }
 
+    protected synchronized void blockMessages() {
+        mBlockMessages = true;
+    }
+
+    protected synchronized boolean messagesBlocked() {
+        return mBlockMessages;
+    }
+
     protected void shutdown() {
+        removeCallbacksAndMessages(null);
         setWebViewClient(null);
         setWebChromeClient(null);
-        removeCallbacksAndMessages(null);
     }
 
     /**
@@ -265,6 +275,7 @@
         // in the UI thread. The WebViewClient and WebChromeClient functions
         // that check for a non-null callback are ok because java ensures atomic
         // 32-bit reads and writes.
+        if (messagesBlocked()) return;
         switch (msg.what) {
             case PAGE_STARTED:
                 String startedUrl = msg.getData().getString("url");
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index af011a1b..5db2431 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -2070,6 +2070,7 @@
     }
 
     private void destroyImpl() {
+        mCallbackProxy.blockMessages();
         clearHelpers();
         if (mListBoxDialog != null) {
             mListBoxDialog.dismiss();
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 09aa286..de30755 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -1244,6 +1244,23 @@
                                 + " arg1=" + msg.arg1 + " arg2=" + msg.arg2
                                 + " obj=" + msg.obj);
                     }
+                    switch (msg.what) {
+                    case PAUSE_TIMERS:
+                        mSavedPriority = Process.getThreadPriority(mTid);
+                        Process.setThreadPriority(mTid,
+                            Process.THREAD_PRIORITY_BACKGROUND);
+                        pauseTimers();
+                        if (mNativeClass != 0) {
+                            nativeCloseIdleConnections(mNativeClass);
+                        }
+                        return;
+
+                    case RESUME_TIMERS:
+                        Process.setThreadPriority(mTid, mSavedPriority);
+                        resumeTimers();
+                        return;
+                    }
+
                     if (mWebView == null || mNativeClass == 0) {
                         if (DebugFlags.WEB_VIEW_CORE) {
                             Log.w(LOGTAG, "Rejecting message " + msg.what
@@ -1252,8 +1269,6 @@
                         return;
                     }
                     if (mDestroying == true
-                            && msg.what != EventHub.RESUME_TIMERS
-                            && msg.what != EventHub.PAUSE_TIMERS
                             && msg.what != EventHub.DESTROY) {
                         if (DebugFlags.WEB_VIEW_CORE) {
                             Log.v(LOGTAG, "Rejecting message " + msg.what
@@ -1419,18 +1434,6 @@
                             restoreState(msg.arg1);
                             break;
 
-                        case PAUSE_TIMERS:
-                            mSavedPriority = Process.getThreadPriority(mTid);
-                            Process.setThreadPriority(mTid,
-                                    Process.THREAD_PRIORITY_BACKGROUND);
-                            pauseTimers();
-                            nativeCloseIdleConnections(mNativeClass);
-                            break;
-
-                        case RESUME_TIMERS:
-                            Process.setThreadPriority(mTid, mSavedPriority);
-                            resumeTimers();
-                            break;
 
                         case ON_PAUSE:
                             nativePause(mNativeClass);
@@ -1961,12 +1964,10 @@
      */
     void destroy() {
         synchronized (mEventHub) {
-            // Do not call removeMessages as then we risk removing PAUSE_TIMERS
-            // or RESUME_TIMERS messages, which we must still handle as they
-            // are per process. DESTROY will instead trigger a white list in
-            // mEventHub, skipping any remaining messages in the queue
+            // send DESTROY to front of queue
+            // PAUSE/RESUME timers will still be processed even if they get handled later
             mEventHub.mDestroying = true;
-            mEventHub.sendMessage(
+            mEventHub.sendMessageAtFrontOfQueue(
                     Message.obtain(null, EventHub.DESTROY));
             mEventHub.blockMessages();
         }
diff --git a/core/res/res/anim/screen_rotate_180_enter.xml b/core/res/res/anim/screen_rotate_180_enter.xml
index 688a8d5..e2f3ce2 100644
--- a/core/res/res/anim/screen_rotate_180_enter.xml
+++ b/core/res/res/anim/screen_rotate_180_enter.xml
@@ -24,5 +24,5 @@
             android:interpolator="@interpolator/decelerate_quint"
             android:fillEnabled="true"
             android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
+            android:duration="@android:integer/config_longAnimTime" />
 </set>
diff --git a/core/res/res/anim/screen_rotate_180_exit.xml b/core/res/res/anim/screen_rotate_180_exit.xml
index 58a1868..fe4a950 100644
--- a/core/res/res/anim/screen_rotate_180_exit.xml
+++ b/core/res/res/anim/screen_rotate_180_exit.xml
@@ -24,5 +24,5 @@
             android:interpolator="@interpolator/decelerate_quint"
             android:fillEnabled="true"
             android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
+            android:duration="@android:integer/config_longAnimTime" />
 </set>
\ No newline at end of file
diff --git a/core/res/res/anim/screen_rotate_180_frame.xml b/core/res/res/anim/screen_rotate_180_frame.xml
index 19dade1..1a3ee67 100644
--- a/core/res/res/anim/screen_rotate_180_frame.xml
+++ b/core/res/res/anim/screen_rotate_180_frame.xml
@@ -24,5 +24,5 @@
             android:interpolator="@interpolator/decelerate_quint"
             android:fillEnabled="true"
             android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
+            android:duration="@android:integer/config_longAnimTime" />
 </set>
diff --git a/core/res/res/anim/screen_rotate_finish_enter.xml b/core/res/res/anim/screen_rotate_finish_enter.xml
index 9d731e6..f12a1aec 100644
--- a/core/res/res/anim/screen_rotate_finish_enter.xml
+++ b/core/res/res/anim/screen_rotate_finish_enter.xml
@@ -26,7 +26,6 @@
             android:fillEnabled="true"
             android:fillBefore="true" android:fillAfter="true"
             android:duration="@android:integer/config_shortAnimTime"/>
-    <!--
     <scale android:fromXScale="100%p" android:toXScale="100%"
             android:fromYScale="100%p" android:toYScale="100%"
             android:pivotX="50%" android:pivotY="50%"
@@ -34,5 +33,4 @@
             android:fillEnabled="true"
             android:fillBefore="true" android:fillAfter="true"
             android:duration="@android:integer/config_mediumAnimTime" />
-    -->
 </set>
diff --git a/core/res/res/anim/screen_rotate_finish_exit.xml b/core/res/res/anim/screen_rotate_finish_exit.xml
index 60daa18..3d9c569 100644
--- a/core/res/res/anim/screen_rotate_finish_exit.xml
+++ b/core/res/res/anim/screen_rotate_finish_exit.xml
@@ -19,8 +19,8 @@
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:shareInterpolator="false">
-    <scale android:fromXScale="1.0" android:toXScale="1.0"
-            android:fromYScale="1.0" android:toYScale="1.0"
+    <scale android:fromXScale="1.0" android:toXScale="1.1111111111111"
+            android:fromYScale="1.0" android:toYScale="1.1111111111111"
             android:pivotX="50%" android:pivotY="50%"
             android:interpolator="@interpolator/accelerate_decelerate"
             android:fillEnabled="true"
diff --git a/core/res/res/anim/screen_rotate_minus_90_enter.xml b/core/res/res/anim/screen_rotate_minus_90_enter.xml
index d2aebc9..38a674d 100644
--- a/core/res/res/anim/screen_rotate_minus_90_enter.xml
+++ b/core/res/res/anim/screen_rotate_minus_90_enter.xml
@@ -19,44 +19,10 @@
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:shareInterpolator="false">
-    <!--
-    <scale android:fromXScale="1.0" android:toXScale="0.565"
-            android:fromYScale="1.0" android:toYScale="0.565"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="false" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime"/>
-    <scale android:fromXScale="1.0" android:toXScale="1.777777777"
-            android:fromYScale="1.0" android:toYScale="1.777777777"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="false" android:fillAfter="true"
-            android:startOffset="@android:integer/config_longAnimTime"
-            android:duration="@android:integer/config_mediumAnimTime"/>
-    <scale android:fromXScale="100%p" android:toXScale="100%"
-            android:fromYScale="100%p" android:toYScale="100%"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="true" android:fillAfter="true"
-            android:startOffset="@android:integer/config_longAnimTime"
-            android:duration="@android:integer/config_mediumAnimTime" />
-    -->
-    <!--
-    <scale android:fromXScale="100%p" android:toXScale="100%"
-            android:fromYScale="100%p" android:toYScale="100%"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
-    -->
     <rotate android:fromDegrees="-90" android:toDegrees="0"
             android:pivotX="50%" android:pivotY="50%"
             android:interpolator="@interpolator/decelerate_quint"
             android:fillEnabled="true"
             android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
+            android:duration="@android:integer/config_longAnimTime" />
 </set>
diff --git a/core/res/res/anim/screen_rotate_minus_90_exit.xml b/core/res/res/anim/screen_rotate_minus_90_exit.xml
index c7c38cd..a75aca7 100644
--- a/core/res/res/anim/screen_rotate_minus_90_exit.xml
+++ b/core/res/res/anim/screen_rotate_minus_90_exit.xml
@@ -19,51 +19,10 @@
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:shareInterpolator="false">
-    <!--
-    <scale android:fromXScale="1.0" android:toXScale="0.565"
-            android:fromYScale="1.0" android:toYScale="0.565"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="false" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime"/>
-    <scale android:fromXScale="1.0" android:toXScale="1.777777777"
-            android:fromYScale="1.0" android:toYScale="1.777777777"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="false" android:fillAfter="true"
-            android:startOffset="@android:integer/config_longAnimTime"
-            android:duration="@android:integer/config_mediumAnimTime"/>
-    <scale android:fromXScale="100%" android:toXScale="100%p"
-            android:fromYScale="100%" android:toYScale="100%p"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:startOffset="@android:integer/config_longAnimTime"
-            android:duration="@android:integer/config_mediumAnimTime" />
-    <alpha android:fromAlpha="1.0" android:toAlpha="0"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="false" android:fillAfter="true"
-            android:startOffset="@android:integer/config_longAnimTime"
-            android:duration="@android:integer/config_mediumAnimTime" />
-    -->
-    <!--
-    <scale android:fromXScale="100%" android:toXScale="100%p"
-            android:fromYScale="100%" android:toYScale="100%p"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:duration="@android:integer/config_mediumAnimTime" />
-    <alpha android:fromAlpha="1.0" android:toAlpha="0"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="false" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
-    -->
     <rotate android:fromDegrees="0" android:toDegrees="90"
             android:pivotX="50%" android:pivotY="50%"
             android:interpolator="@interpolator/decelerate_quint"
             android:fillEnabled="true"
             android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
+            android:duration="@android:integer/config_longAnimTime" />
 </set>
diff --git a/core/res/res/anim/screen_rotate_minus_90_frame.xml b/core/res/res/anim/screen_rotate_minus_90_frame.xml
index 874f2e9..2d198f3 100644
--- a/core/res/res/anim/screen_rotate_minus_90_frame.xml
+++ b/core/res/res/anim/screen_rotate_minus_90_frame.xml
@@ -24,5 +24,5 @@
             android:interpolator="@interpolator/decelerate_quint"
             android:fillEnabled="true"
             android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
+            android:duration="@android:integer/config_longAnimTime" />
 </set>
diff --git a/core/res/res/anim/screen_rotate_plus_90_enter.xml b/core/res/res/anim/screen_rotate_plus_90_enter.xml
index 63d7043..583d2ba 100644
--- a/core/res/res/anim/screen_rotate_plus_90_enter.xml
+++ b/core/res/res/anim/screen_rotate_plus_90_enter.xml
@@ -19,44 +19,10 @@
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:shareInterpolator="false">
-    <!--
-    <scale android:fromXScale="1.0" android:toXScale="0.565"
-            android:fromYScale="1.0" android:toYScale="0.565"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="false" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime"/>
-    <scale android:fromXScale="1.0" android:toXScale="1.777777777"
-            android:fromYScale="1.0" android:toYScale="1.777777777"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="false" android:fillAfter="true"
-            android:startOffset="75"
-            android:duration="@android:integer/config_mediumAnimTime"/>
-    <scale android:fromXScale="100%p" android:toXScale="100%"
-            android:fromYScale="100%p" android:toYScale="100%"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="true" android:fillAfter="true"
-            android:startOffset="75"
-            android:duration="@android:integer/config_mediumAnimTime" />
-    -->
-    <!--
-    <scale android:fromXScale="100%p" android:toXScale="100%"
-            android:fromYScale="100%p" android:toYScale="100%"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
-    -->
     <rotate android:fromDegrees="90" android:toDegrees="0"
             android:pivotX="50%" android:pivotY="50%"
             android:interpolator="@interpolator/decelerate_quint"
             android:fillEnabled="true"
             android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
+            android:duration="@android:integer/config_longAnimTime" />
 </set>
diff --git a/core/res/res/anim/screen_rotate_plus_90_exit.xml b/core/res/res/anim/screen_rotate_plus_90_exit.xml
index ea48c81..a2bef41 100644
--- a/core/res/res/anim/screen_rotate_plus_90_exit.xml
+++ b/core/res/res/anim/screen_rotate_plus_90_exit.xml
@@ -19,51 +19,10 @@
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:shareInterpolator="false">
-    <!--
-    <scale android:fromXScale="1.0" android:toXScale="0.565"
-            android:fromYScale="1.0" android:toYScale="0.565"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="false" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime"/>
-    <scale android:fromXScale="1.0" android:toXScale="1.777777777"
-            android:fromYScale="1.0" android:toYScale="1.777777777"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="false" android:fillAfter="true"
-            android:startOffset="75"
-            android:duration="@android:integer/config_mediumAnimTime"/>
-    <scale android:fromXScale="100%" android:toXScale="100%p"
-            android:fromYScale="100%" android:toYScale="100%p"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:startOffset="75"
-            android:duration="@android:integer/config_mediumAnimTime" />
-    <alpha android:fromAlpha="1.0" android:toAlpha="0"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="false" android:fillAfter="true"
-            android:startOffset="75"
-            android:duration="@android:integer/config_mediumAnimTime" />
-    -->
-    <!--
-    <scale android:fromXScale="100%" android:toXScale="100%p"
-            android:fromYScale="100%" android:toYScale="100%p"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:duration="@android:integer/config_mediumAnimTime" />
-    <alpha android:fromAlpha="1.0" android:toAlpha="0"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="false" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
-    -->
     <rotate android:fromDegrees="0" android:toDegrees="-90"
             android:pivotX="50%" android:pivotY="50%"
             android:interpolator="@interpolator/decelerate_quint"
             android:fillEnabled="true"
             android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
+            android:duration="@android:integer/config_longAnimTime" />
 </set>
diff --git a/core/res/res/anim/screen_rotate_plus_90_frame.xml b/core/res/res/anim/screen_rotate_plus_90_frame.xml
index 03c6aa6..cd20050 100644
--- a/core/res/res/anim/screen_rotate_plus_90_frame.xml
+++ b/core/res/res/anim/screen_rotate_plus_90_frame.xml
@@ -24,5 +24,5 @@
             android:interpolator="@interpolator/decelerate_quint"
             android:fillEnabled="true"
             android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
+            android:duration="@android:integer/config_longAnimTime" />
 </set>
diff --git a/core/res/res/layout/action_bar_title_item.xml b/core/res/res/layout/action_bar_title_item.xml
index 4c74f6a..2e21383 100644
--- a/core/res/res/layout/action_bar_title_item.xml
+++ b/core/res/res/layout/action_bar_title_item.xml
@@ -18,7 +18,7 @@
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:orientation="horizontal"
-              android:paddingRight="16dip"
+              android:paddingRight="8dip"
               android:background="?android:attr/actionBarItemBackground"
               android:enabled="false">
 
diff --git a/graphics/java/android/graphics/RectF.java b/graphics/java/android/graphics/RectF.java
index 293dfcc..c633d84 100644
--- a/graphics/java/android/graphics/RectF.java
+++ b/graphics/java/android/graphics/RectF.java
@@ -84,7 +84,7 @@
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
 
-        Rect r = (Rect) o;
+        RectF r = (RectF) o;
         return left == r.left && top == r.top && right == r.right && bottom == r.bottom;
     }
 
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 07f3b16..f3a1d9a 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -1687,7 +1687,9 @@
             // The configuration closest to the actual size is best.
             // We assume that larger configs have already been filtered
             // out at this point.  That means we just want the largest one.
-            return smallestScreenWidthDp >= o.smallestScreenWidthDp;
+            if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
+                return smallestScreenWidthDp > o.smallestScreenWidthDp;
+            }
         }
 
         if (screenSizeDp || o.screenSizeDp) {
@@ -1711,7 +1713,9 @@
             //ALOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d",
             //    screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp,
             //    requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta);
-            return (myDelta <= otherDelta);
+            if (myDelta != otherDelta) {
+                return myDelta < otherDelta;
+            }
         }
 
         if (screenLayout || o.screenLayout) {
@@ -1738,7 +1742,9 @@
                     if (mySL == 0) return false;
                     return true;
                 }
-                return fixedMySL >= fixedOSL;
+                if (fixedMySL != fixedOSL) {
+                    return fixedMySL > fixedOSL;
+                }
             }
             if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0
                     && (requested->screenLayout & MASK_SCREENLONG)) {
@@ -1857,7 +1863,9 @@
                 myDelta += requested->screenHeight - screenHeight;
                 otherDelta += requested->screenHeight - o.screenHeight;
             }
-            return (myDelta <= otherDelta);
+            if (myDelta != otherDelta) {
+                return myDelta < otherDelta;
+            }
         }
 
         if (version || o.version) {
@@ -2150,7 +2158,7 @@
                 res.append("nodpi");
                 break;
             default:
-                res.appendFormat("density=%d", dtohs(density));
+                res.appendFormat("%ddpi", dtohs(density));
                 break;
         }
     }
@@ -2440,7 +2448,7 @@
     uint32_t bagTypeSpecFlags = 0;
     mTable.lock();
     const ssize_t N = mTable.getBagLocked(resID, &bag, &bagTypeSpecFlags);
-    TABLE_NOISY(LOGV("Applying style 0x%08x to theme %p, count=%d", resID, this, N));
+    TABLE_NOISY(ALOGV("Applying style 0x%08x to theme %p, count=%d", resID, this, N));
     if (N < 0) {
         mTable.unlock();
         return N;
@@ -2506,7 +2514,7 @@
             continue;
         }
         theme_entry* curEntry = curEntries + e;
-        TABLE_NOISY(LOGV("Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x",
+        TABLE_NOISY(ALOGV("Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x",
                    attrRes, bag->map.value.dataType, bag->map.value.data,
              curEntry->value.dataType));
         if (force || curEntry->value.dataType == Res_value::TYPE_NULL) {
@@ -2577,22 +2585,22 @@
         const uint32_t t = Res_GETTYPE(resID);
         const uint32_t e = Res_GETENTRY(resID);
 
-        TABLE_THEME(LOGI("Looking up attr 0x%08x in theme %p", resID, this));
+        TABLE_THEME(ALOGI("Looking up attr 0x%08x in theme %p", resID, this));
 
         if (p >= 0) {
             const package_info* const pi = mPackages[p];
-            TABLE_THEME(LOGI("Found package: %p", pi));
+            TABLE_THEME(ALOGI("Found package: %p", pi));
             if (pi != NULL) {
-                TABLE_THEME(LOGI("Desired type index is %ld in avail %d", t, pi->numTypes));
+                TABLE_THEME(ALOGI("Desired type index is %ld in avail %d", t, pi->numTypes));
                 if (t < pi->numTypes) {
                     const type_info& ti = pi->types[t];
-                    TABLE_THEME(LOGI("Desired entry index is %ld in avail %d", e, ti.numEntries));
+                    TABLE_THEME(ALOGI("Desired entry index is %ld in avail %d", e, ti.numEntries));
                     if (e < ti.numEntries) {
                         const theme_entry& te = ti.entries[e];
                         if (outTypeSpecFlags != NULL) {
                             *outTypeSpecFlags |= te.typeSpecFlags;
                         }
-                        TABLE_THEME(LOGI("Theme value: type=0x%x, data=0x%08x",
+                        TABLE_THEME(ALOGI("Theme value: type=0x%x, data=0x%08x",
                                 te.value.dataType, te.value.data));
                         const uint8_t type = te.value.dataType;
                         if (type == Res_value::TYPE_ATTRIBUTE) {
@@ -2627,7 +2635,7 @@
     if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) {
         uint32_t newTypeSpecFlags;
         blockIndex = getAttribute(inOutValue->data, inOutValue, &newTypeSpecFlags);
-        TABLE_THEME(LOGI("Resolving attr reference: blockIndex=%d, type=0x%x, data=%p\n",
+        TABLE_THEME(ALOGI("Resolving attr reference: blockIndex=%d, type=0x%x, data=%p\n",
              (int)blockIndex, (int)inOutValue->dataType, (void*)inOutValue->data));
         if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newTypeSpecFlags;
         //printf("Retrieved attribute new type=0x%x\n", inOutValue->dataType);
@@ -2772,7 +2780,7 @@
     header->size = dtohl(header->header->header.size);
     //ALOGI("Got size 0x%x, again size 0x%x, raw size 0x%x\n", header->size,
     //     dtohl(header->header->header.size), header->header->header.size);
-    LOAD_TABLE_NOISY(LOGV("Loading ResTable @%p:\n", header->header));
+    LOAD_TABLE_NOISY(ALOGV("Loading ResTable @%p:\n", header->header));
     LOAD_TABLE_NOISY(printHexData(2, header->header, header->size < 256 ? header->size : 256,
                                   16, 16, 0, false, printToLogFunc));
     if (dtohs(header->header->header.headerSize) > header->size
@@ -2802,7 +2810,7 @@
         if (err != NO_ERROR) {
             return (mError=err);
         }
-        TABLE_NOISY(LOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
+        TABLE_NOISY(ALOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
                      dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
                      (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
         const size_t csize = dtohl(chunk->size);
@@ -2856,7 +2864,7 @@
         ALOGW("No string values found in resource table!");
     }
 
-    TABLE_NOISY(LOGV("Returning from add with mError=%d\n", mError));
+    TABLE_NOISY(ALOGV("Returning from add with mError=%d\n", mError));
     return mError;
 }
 
@@ -3127,7 +3135,7 @@
         if (newIndex == BAD_INDEX) {
             return BAD_INDEX;
         }
-        TABLE_THEME(LOGI("Resolving reference %p: newIndex=%d, type=0x%x, data=%p\n",
+        TABLE_THEME(ALOGI("Resolving reference %p: newIndex=%d, type=0x%x, data=%p\n",
              (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data));
         //printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex);
         if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newFlags;
@@ -3268,7 +3276,7 @@
     // This is what we are building.
     bag_set* set = NULL;
 
-    TABLE_NOISY(LOGI("Building bag: %p\n", (void*)resID));
+    TABLE_NOISY(ALOGI("Building bag: %p\n", (void*)resID));
     
     ResTable_config bestConfig;
     memset(&bestConfig, 0, sizeof(bestConfig));
@@ -3338,7 +3346,7 @@
         
         size_t N = count;
 
-        TABLE_NOISY(LOGI("Found map: size=%p parent=%p count=%d\n",
+        TABLE_NOISY(ALOGI("Found map: size=%p parent=%p count=%d\n",
                          entrySize, parent, count));
 
         // If this map inherits from another, we need to start
@@ -3357,9 +3365,9 @@
             if (NP > 0) {
                 memcpy(set+1, parentBag, NP*sizeof(bag_entry));
                 set->numAttrs = NP;
-                TABLE_NOISY(LOGI("Initialized new bag with %d inherited attributes.\n", NP));
+                TABLE_NOISY(ALOGI("Initialized new bag with %d inherited attributes.\n", NP));
             } else {
-                TABLE_NOISY(LOGI("Initialized new bag with no inherited attributes.\n"));
+                TABLE_NOISY(ALOGI("Initialized new bag with no inherited attributes.\n"));
                 set->numAttrs = 0;
             }
             set->availAttrs = NT;
@@ -3386,7 +3394,7 @@
         bag_entry* entries = (bag_entry*)(set+1);
         size_t curEntry = 0;
         uint32_t pos = 0;
-        TABLE_NOISY(LOGI("Starting with set %p, entries=%p, avail=%d\n",
+        TABLE_NOISY(ALOGI("Starting with set %p, entries=%p, avail=%d\n",
                      set, entries, set->availAttrs));
         while (pos < count) {
             TABLE_NOISY(printf("Now at %p\n", (void*)curOff));
@@ -3465,7 +3473,7 @@
             *outTypeSpecFlags = set->typeSpecFlags;
         }
         *outBag = (bag_entry*)(set+1);
-        TABLE_NOISY(LOGI("Returning %d attrs\n", set->numAttrs));
+        TABLE_NOISY(ALOGI("Returning %d attrs\n", set->numAttrs));
         return set->numAttrs;
     }
     return BAD_INDEX;
@@ -3474,27 +3482,10 @@
 void ResTable::setParameters(const ResTable_config* params)
 {
     mLock.lock();
-    TABLE_GETENTRY(LOGI("Setting parameters: imsi:%d/%d lang:%c%c cnt:%c%c "
-                        "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d sw%ddp w%ddp h%ddp\n",
-                       params->mcc, params->mnc,
-                       params->language[0] ? params->language[0] : '-',
-                       params->language[1] ? params->language[1] : '-',
-                       params->country[0] ? params->country[0] : '-',
-                       params->country[1] ? params->country[1] : '-',
-                       params->orientation,
-                       params->touchscreen,
-                       params->density,
-                       params->keyboard,
-                       params->inputFlags,
-                       params->navigation,
-                       params->screenWidth,
-                       params->screenHeight,
-                       params->smallestScreenWidthDp,
-                       params->screenWidthDp,
-                       params->screenHeightDp));
+    TABLE_GETENTRY(ALOGI("Setting parameters: %s\n", params->toString().string()));
     mParams = *params;
     for (size_t i=0; i<mPackageGroups.size(); i++) {
-        TABLE_NOISY(LOGI("CLEARING BAGS FOR GROUP %d!", i));
+        TABLE_NOISY(ALOGI("CLEARING BAGS FOR GROUP %d!", i));
         mPackageGroups[i]->clearBagCache();
     }
     mLock.unlock();
@@ -4840,13 +4831,13 @@
         ResTable_config thisConfig;
         thisConfig.copyFromDtoH(thisType->config);
 
-        TABLE_GETENTRY(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): %s\n",
+        TABLE_GETENTRY(ALOGI("Match entry 0x%x in type 0x%x (sz 0x%x): %s\n",
                            entryIndex, typeIndex+1, dtohl(thisType->config.size),
                            thisConfig.toString().string()));
         
         // Check to make sure this one is valid for the current parameters.
         if (config && !thisConfig.match(*config)) {
-            TABLE_GETENTRY(LOGI("Does not match config!\n"));
+            TABLE_GETENTRY(ALOGI("Does not match config!\n"));
             continue;
         }
         
@@ -4859,7 +4850,7 @@
         
         uint32_t thisOffset = dtohl(eindex[entryIndex]);
         if (thisOffset == ResTable_type::NO_ENTRY) {
-            TABLE_GETENTRY(LOGI("Skipping because it is not defined!\n"));
+            TABLE_GETENTRY(ALOGI("Skipping because it is not defined!\n"));
             continue;
         }
         
@@ -4868,7 +4859,7 @@
             // we will skip it.  We check starting with things we most care
             // about to those we least care about.
             if (!thisConfig.isBetterThan(bestConfig, config)) {
-                TABLE_GETENTRY(LOGI("This config is worse than last!\n"));
+                TABLE_GETENTRY(ALOGI("This config is worse than last!\n"));
                 continue;
             }
         }
@@ -4876,12 +4867,12 @@
         type = thisType;
         offset = thisOffset;
         bestConfig = thisConfig;
-        TABLE_GETENTRY(LOGI("Best entry so far -- using it!\n"));
+        TABLE_GETENTRY(ALOGI("Best entry so far -- using it!\n"));
         if (!config) break;
     }
     
     if (type == NULL) {
-        TABLE_GETENTRY(LOGI("No value found for requested entry!\n"));
+        TABLE_GETENTRY(ALOGI("No value found for requested entry!\n"));
         return BAD_INDEX;
     }
     
@@ -5024,7 +5015,7 @@
     const uint8_t* endPos = ((const uint8_t*)pkg) + dtohs(pkg->header.size);
     while (((const uint8_t*)chunk) <= (endPos-sizeof(ResChunk_header)) &&
            ((const uint8_t*)chunk) <= (endPos-dtohl(chunk->size))) {
-        TABLE_NOISY(LOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
+        TABLE_NOISY(ALOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
                          dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
                          (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
         const size_t csize = dtohl(chunk->size);
diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp
index 63bf7cc..fae602c 100644
--- a/libs/rs/driver/rsdGL.cpp
+++ b/libs/rs/driver/rsdGL.cpp
@@ -37,6 +37,7 @@
 
 #include <malloc.h>
 #include "rsContext.h"
+#include "rsDevice.h"
 #include "rsdShaderCache.h"
 #include "rsdVertexArray.h"
 #include "rsdFrameBufferObj.h"
diff --git a/libs/rs/rs.h b/libs/rs/rs.h
index fbcaf4a..825b9b8 100644
--- a/libs/rs/rs.h
+++ b/libs/rs/rs.h
@@ -20,10 +20,6 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #include "rsDefines.h"
 
 //
@@ -61,10 +57,6 @@
 
 #include "rsgApiFuncDecl.h"
 
-#ifdef __cplusplus
-};
-#endif
-
 #endif // RENDER_SCRIPT_H
 
 
diff --git a/libs/rs/rsAdapter.cpp b/libs/rs/rsAdapter.cpp
index 177fb60..41811ae 100644
--- a/libs/rs/rsAdapter.cpp
+++ b/libs/rs/rsAdapter.cpp
@@ -16,6 +16,7 @@
  */
 
 #include "rsContext.h"
+#include "rsAdapter.h"
 
 using namespace android;
 using namespace android::renderscript;
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index 83c88fd..a404c49 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -15,6 +15,8 @@
  */
 
 #include "rsContext.h"
+#include "rsAllocation.h"
+#include "rsAdapter.h"
 #include "rs_hal.h"
 
 #include "system/window.h"
diff --git a/libs/rs/rsAnimation.h b/libs/rs/rsAnimation.h
index bff8d6f..526a081 100644
--- a/libs/rs/rsAnimation.h
+++ b/libs/rs/rsAnimation.h
@@ -19,7 +19,7 @@
 
 #include "rsUtils.h"
 #include "rsObjectBase.h"
-
+#include "rsDefines.h"
 // ---------------------------------------------------------------------------
 namespace android {
 namespace renderscript {
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 748b72a..1b51872 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -18,6 +18,7 @@
 #include "rsDevice.h"
 #include "rsContext.h"
 #include "rsThreadIO.h"
+#include "rsMesh.h"
 #include <ui/FramebufferNativeWindow.h>
 #include <gui/DisplayEventReceiver.h>
 
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 05c799e..0f44267 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -18,18 +18,10 @@
 #define ANDROID_RS_CONTEXT_H
 
 #include "rsUtils.h"
-#include "rsType.h"
-#include "rsAllocation.h"
-#include "rsMesh.h"
-
 #include "rs_hal.h"
 
-#include "rsMutex.h"
 #include "rsThreadIO.h"
-#include "rsMatrix4x4.h"
-#include "rsDevice.h"
 #include "rsScriptC.h"
-#include "rsAdapter.h"
 #include "rsSampler.h"
 #include "rsFont.h"
 #include "rsPath.h"
@@ -39,13 +31,13 @@
 #include "rsProgramVertex.h"
 #include "rsFBOCache.h"
 
-#include "rsgApiStructs.h"
-
 // ---------------------------------------------------------------------------
 namespace android {
 
 namespace renderscript {
 
+class Device;
+
 #if 0
 #define CHECK_OBJ(o) { \
     GET_TLS(); \
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index 2bf9a75..1f53c79 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -19,6 +19,7 @@
 #include "rs.h"
 #include "rsFont.h"
 #include "rsProgramFragment.h"
+#include "rsMesh.h"
 #include <cutils/properties.h>
 
 #ifndef ANDROID_RS_SERIALIZE
diff --git a/libs/rs/rsMesh.cpp b/libs/rs/rsMesh.cpp
index f9dbc33..399a52b 100644
--- a/libs/rs/rsMesh.cpp
+++ b/libs/rs/rsMesh.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "rsContext.h"
+#include "rsMesh.h"
 #include "rs.h"
 
 using namespace android;
diff --git a/libs/rs/rsPath.cpp b/libs/rs/rsPath.cpp
index c4f4978..055bb86 100644
--- a/libs/rs/rsPath.cpp
+++ b/libs/rs/rsPath.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "rsContext.h"
+#include "rs.h"
 
 using namespace android;
 using namespace android::renderscript;
diff --git a/libs/rs/rsPath.h b/libs/rs/rsPath.h
index 7c05503..1abfc9a 100644
--- a/libs/rs/rsPath.h
+++ b/libs/rs/rsPath.h
@@ -18,7 +18,7 @@
 #define ANDROID_RS_PATH_H
 
 
-#include "rs.h"
+#include "rsObjectBase.h"
 
 // ---------------------------------------------------------------------------
 namespace android {
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index c8a53ea..23fcbe7 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -16,6 +16,7 @@
 
 #include "rsContext.h"
 #include "rsProgramVertex.h"
+#include "rsMatrix4x4.h"
 
 using namespace android;
 using namespace android::renderscript;
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index a5a0fae..749495d 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -19,6 +19,7 @@
 #include "rsMatrix4x4.h"
 #include "rsMatrix3x3.h"
 #include "rsMatrix2x2.h"
+#include "rsgApiStructs.h"
 
 #include "utils/Timers.h"
 
diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp
index bda18fd..21b1c42 100644
--- a/libs/rs/rsScriptC_LibGL.cpp
+++ b/libs/rs/rsScriptC_LibGL.cpp
@@ -19,6 +19,8 @@
 #include "rsMatrix4x4.h"
 #include "rsMatrix3x3.h"
 #include "rsMatrix2x2.h"
+#include "rsMesh.h"
+#include "rsgApiStructs.h"
 
 #include "utils/Timers.h"
 #include "driver/rsdVertexArray.h"
diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp
index 7182f53..8a0a5dc 100644
--- a/libs/rs/rsThreadIO.cpp
+++ b/libs/rs/rsThreadIO.cpp
@@ -15,8 +15,8 @@
  */
 
 #include "rsContext.h"
-
 #include "rsThreadIO.h"
+#include "rsgApiStructs.h"
 
 #include <unistd.h>
 #include <sys/types.h>
diff --git a/libs/rs/rsg_generator.c b/libs/rs/rsg_generator.c
index 99c305e..c0f82dc 100644
--- a/libs/rs/rsg_generator.c
+++ b/libs/rs/rsg_generator.c
@@ -187,7 +187,7 @@
     fprintf(f, "#include \"rsDevice.h\"\n");
     fprintf(f, "#include \"rsContext.h\"\n");
     fprintf(f, "#include \"rsThreadIO.h\"\n");
-    //fprintf(f, "#include \"rsgApiStructs.h\"\n");
+    fprintf(f, "#include \"rsgApiStructs.h\"\n");
     fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
     fprintf(f, "#include \"rsFifo.h\"\n");
     fprintf(f, "\n");
@@ -408,6 +408,7 @@
     fprintf(f, "#include \"rsDevice.h\"\n");
     fprintf(f, "#include \"rsContext.h\"\n");
     fprintf(f, "#include \"rsThreadIO.h\"\n");
+    fprintf(f, "#include \"rsgApiStructs.h\"\n");
     fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
     fprintf(f, "\n");
     fprintf(f, "namespace android {\n");
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index 650b6c4..2b3cb1a 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -437,8 +437,11 @@
                         kKeyTime, &mPositionTimeMediaUs));
 
             mPositionTimeRealUs =
-                ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
+                -mLatencyUs + ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
                     / mSampleRate;
+            if (mPositionTimeRealUs < 0) {
+                mPositionTimeRealUs = 0;
+            }
 
             ALOGV("buffer->size() = %d, "
                  "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
@@ -493,7 +496,9 @@
 int64_t AudioPlayer::getRealTimeUsLocked() const {
     CHECK(mStarted);
     CHECK_NE(mSampleRate, 0);
-    return -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate;
+    int64_t t = -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate;
+    if (t < 0) return 0;
+    return t;
 }
 
 int64_t AudioPlayer::getMediaTimeUs() {
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar.xml b/packages/SystemUI/res/layout-sw600dp/status_bar.xml
index b96c357..2308bf0 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar.xml
@@ -54,7 +54,7 @@
                 android:clipToPadding="false"
                 >
                 <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
-                    android:layout_width="80dip"
+                    android:layout_width="@dimen/navigation_key_width"
                     android:layout_height="match_parent"
                     android:src="@drawable/ic_sysbar_back"
                     systemui:keyCode="4"
@@ -62,7 +62,7 @@
                     systemui:glowBackground="@drawable/ic_sysbar_highlight"
                     />
                 <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
-                    android:layout_width="80dip"
+                    android:layout_width="@dimen/navigation_key_width"
                     android:layout_height="match_parent"
                     android:src="@drawable/ic_sysbar_home"
                     systemui:keyCode="3"
@@ -70,14 +70,14 @@
                     systemui:glowBackground="@drawable/ic_sysbar_highlight"
                     />
                 <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
-                    android:layout_width="80dip"
+                    android:layout_width="@dimen/navigation_key_width"
                     android:layout_height="match_parent"
                     android:src="@drawable/ic_sysbar_recent"
                     android:contentDescription="@string/accessibility_recent"
                     systemui:glowBackground="@drawable/ic_sysbar_highlight"
                     />
                 <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
-                    android:layout_width="80dip"
+                    android:layout_width="@dimen/navigation_menu_key_width"
                     android:layout_height="match_parent"
                     android:src="@drawable/ic_sysbar_menu"
                     systemui:keyCode="82"
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index 82fcc88..bb80098 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -49,7 +49,7 @@
                 android:visibility="invisible"
                 />
             <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
-                android:layout_width="80dp"
+                android:layout_width="@dimen/navigation_key_width"
                 android:layout_height="match_parent"
                 android:src="@drawable/ic_sysbar_back"
                 systemui:keyCode="4"
@@ -64,7 +64,7 @@
                 android:visibility="invisible"
                 />
             <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
-                android:layout_width="80dp"
+                android:layout_width="@dimen/navigation_key_width"
                 android:layout_height="match_parent"
                 android:src="@drawable/ic_sysbar_home"
                 systemui:keyCode="3"
@@ -80,7 +80,7 @@
                 android:visibility="invisible"
                 />
             <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
-                android:layout_width="80dp"
+                android:layout_width="@dimen/navigation_key_width"
                 android:layout_height="match_parent"
                 android:src="@drawable/ic_sysbar_recent"
                 android:layout_weight="0"
@@ -88,7 +88,7 @@
                 android:contentDescription="@string/accessibility_recent"
                 />
             <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
-                android:layout_width="40dp"
+                android:layout_width="@dimen/navigation_menu_key_width"
                 android:layout_height="match_parent"
                 android:src="@drawable/ic_sysbar_menu"
                 systemui:keyCode="82"
diff --git a/packages/SystemUI/res/values-sw600dp-port/dimens.xml b/packages/SystemUI/res/values-sw600dp-port/dimens.xml
index b8a6cfe..39eade6 100644
--- a/packages/SystemUI/res/values-sw600dp-port/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-port/dimens.xml
@@ -18,5 +18,11 @@
 <resources>
     <!-- gap on either side of status bar notification icons -->
     <dimen name="status_bar_icon_padding">0dp</dimen>
+
+    <!-- The width of the view containing non-menu status bar icons -->
+    <dimen name="navigation_key_width">70dip</dimen>
+
+    <!-- The width of the view containing the menu status bar icon -->
+    <dimen name="navigation_menu_key_width">40dip</dimen>
 </resources>
 
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index f522285..ba1cdfa 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -67,4 +67,10 @@
 
     <!-- opacity at which Notification icons will be drawn in the status bar -->
     <item type="dimen" name="status_bar_icon_drawing_alpha">100%</item>
+
+    <!-- The width of the view containing non-menu status bar icons -->
+    <dimen name="navigation_key_width">80dip</dimen>
+
+    <!-- The width of the view containing the menu status bar icon -->
+    <dimen name="navigation_menu_key_width">40dip</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml
index 6736c1a..b16b1e8 100644
--- a/packages/SystemUI/res/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp/dimens.xml
@@ -21,5 +21,11 @@
 
     <!-- opacity at which Notification icons will be drawn in the status bar -->
     <item type="dimen" name="status_bar_icon_drawing_alpha">100%</item>
+
+    <!-- The width of the view containing non-menu status bar icons -->
+    <dimen name="navigation_key_width">80dip</dimen>
+
+    <!-- The width of the view containing the menu status bar icon -->
+    <dimen name="navigation_menu_key_width">80dip</dimen>
 </resources>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 8fba86a..2c22e3c 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -91,4 +91,9 @@
     <!-- The padding on the global screenshot background image -->
     <dimen name="global_screenshot_bg_padding">20dp</dimen>
 
+    <!-- The width of the view containing non-menu status bar icons -->
+    <dimen name="navigation_key_width">80dip</dimen>
+
+    <!-- The width of the view containing the menu status bar icon -->
+    <dimen name="navigation_menu_key_width">40dip</dimen>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index eda52fc..87eb9cc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -123,6 +123,8 @@
     int mNaturalBarHeight = -1;
     int mIconSize = -1;
     int mIconHPadding = -1;
+    int mNavIconWidth = -1;
+    int mMenuNavIconWidth = -1;
     private int mMaxNotificationIcons = 5;
 
     H mHandler = new H();
@@ -462,6 +464,26 @@
             com.android.internal.R.dimen.system_bar_icon_size);
         int newIconHPadding = res.getDimensionPixelSize(
             R.dimen.status_bar_icon_padding);
+        int newNavIconWidth = res.getDimensionPixelSize(R.dimen.navigation_key_width);
+        int newMenuNavIconWidth = res.getDimensionPixelSize(R.dimen.navigation_menu_key_width);
+
+        if (mNavigationArea != null && newNavIconWidth != mNavIconWidth) {
+            mNavIconWidth = newNavIconWidth;
+
+            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+                     mNavIconWidth, ViewGroup.LayoutParams.MATCH_PARENT);
+            mBackButton.setLayoutParams(lp);
+            mHomeButton.setLayoutParams(lp);
+            mRecentButton.setLayoutParams(lp);
+        }
+
+        if (mNavigationArea != null && newMenuNavIconWidth != mMenuNavIconWidth) {
+            mMenuNavIconWidth = newMenuNavIconWidth;
+
+            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+                     mMenuNavIconWidth, ViewGroup.LayoutParams.MATCH_PARENT);
+            mMenuButton.setLayoutParams(lp);
+        }
 
         if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
 //            Slog.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index f9b033b..37f15e2 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -5192,8 +5192,8 @@
                     reqFormat == mInput->stream->common.get_format(&mInput->stream->common) &&
                     reqFormat == AUDIO_FORMAT_PCM_16_BIT &&
                     ((int)mInput->stream->common.get_sample_rate(&mInput->stream->common) <= (2 * reqSamplingRate)) &&
-                    (popcount(mInput->stream->common.get_channels(&mInput->stream->common)) < 3) &&
-                    (reqChannelCount < 3)) {
+                    popcount(mInput->stream->common.get_channels(&mInput->stream->common)) <= FCC_2 &&
+                    (reqChannelCount <= FCC_2)) {
                     status = NO_ERROR;
                 }
                 if (status == NO_ERROR) {
@@ -5270,7 +5270,7 @@
     mFrameCount = mInputBytes / mFrameSize;
     mRsmpInBuffer = new int16_t[mFrameCount * mChannelCount];
 
-    if (mSampleRate != mReqSampleRate && mChannelCount < 3 && mReqChannelCount < 3)
+    if (mSampleRate != mReqSampleRate && mChannelCount <= FCC_2 && mReqChannelCount <= FCC_2)
     {
         int channelCount;
          // optmization: if mono to mono, use the resampler in stereo to stereo mode to avoid
@@ -5559,7 +5559,7 @@
     if (inStream == NULL && status == BAD_VALUE &&
         reqFormat == format && format == AUDIO_FORMAT_PCM_16_BIT &&
         (samplingRate <= 2 * reqSamplingRate) &&
-        (popcount(channels) < 3) && (popcount(reqChannels) < 3)) {
+        (popcount(channels) <= FCC_2) && (popcount(reqChannels) <= FCC_2)) {
         ALOGV("openInput() reopening with proposed sampling rate and channels");
         status = inHwDev->open_input_stream(inHwDev, *pDevices, &format,
                                             &channels, &samplingRate,
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 2e259c0..d9f2972 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -58,6 +58,15 @@
 
 // ----------------------------------------------------------------------------
 
+// AudioFlinger has a hard-coded upper limit of 2 channels for capture and playback.
+// There is support for > 2 channel tracks down-mixed to 2 channel output via a down-mix effect.
+// Adding full support for > 2 channel capture or playback would require more than simply changing
+// this #define.  There is an independent hard-coded upper limit in AudioMixer;
+// removing that AudioMixer limit would be necessary but insufficient to support > 2 channels.
+// The macro FCC_2 highlights some (but not all) places where there is are 2-channel assumptions.
+// Search also for "2", "left", "right", "[0]", "[1]", ">> 16", "<< 16", etc.
+#define FCC_2 2     // FCC_2 = Fixed Channel Count 2
+
 static const nsecs_t kDefaultStandbyTimeInNsecs = seconds(3);
 
 class AudioFlinger :
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 720b5fe..09d0698 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -880,7 +880,6 @@
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
             wifiFirmwareReload(wlanIface, "AP");
-            mConnector.execute("softap", "start", wlanIface);
             if (wifiConfig == null) {
                 mConnector.execute("softap", "set", wlanIface, softapIface);
             } else {
diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java
index 7ac67b6..7b5bf08 100644
--- a/services/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -372,6 +372,12 @@
                 break;
         }
 
+        // Compute partial steps between original and final sizes.  These
+        // are used for the dimensions of the exiting and entering elements,
+        // so they are never stretched too significantly.
+        final int halfWidth = (finalWidth + mOriginalWidth) / 2;
+        final int halfHeight = (finalHeight + mOriginalHeight) / 2;
+
         // Initialize the animations.  This is a hack, redefining what "parent"
         // means to allow supplying the last and next size.  In this definition
         // "%p" is the original (let's call it "previous") size, and "%" is the
@@ -379,14 +385,14 @@
         if (firstStart) {
             if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
             mStartEnterAnimation.initialize(finalWidth, finalHeight,
-                    mOriginalWidth, mOriginalHeight);
-            mStartExitAnimation.initialize(finalWidth, finalHeight,
+                    halfWidth, halfHeight);
+            mStartExitAnimation.initialize(halfWidth, halfHeight,
                     mOriginalWidth, mOriginalHeight);
             mStartFrameAnimation.initialize(finalWidth, finalHeight,
                     mOriginalWidth, mOriginalHeight);
             mFinishEnterAnimation.initialize(finalWidth, finalHeight,
-                    mOriginalWidth, mOriginalHeight);
-            mFinishExitAnimation.initialize(finalWidth, finalHeight,
+                    halfWidth, halfHeight);
+            mFinishExitAnimation.initialize(halfWidth, halfHeight,
                     mOriginalWidth, mOriginalHeight);
             mFinishFrameAnimation.initialize(finalWidth, finalHeight,
                     mOriginalWidth, mOriginalHeight);
diff --git a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
index 6f85c7d..983c349 100644
--- a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
+++ b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
@@ -39,30 +39,6 @@
  * The formatting will be restarted once the text is cleared.
  */
 public class PhoneNumberFormattingTextWatcher implements TextWatcher {
-    /**
-     * One or more characters were removed from the end.
-     */
-    private final static int STATE_REMOVE_LAST = 0;
-
-    /**
-     * One or more characters were appended.
-     */
-    private final static int STATE_APPEND = 1;
-
-    /**
-     * One or more digits were changed in the beginning or the middle of text.
-     */
-    private final static int STATE_MODIFY_DIGITS = 2;
-
-    /**
-     * The changes other than the above.
-     */
-    private final static int STATE_OTHER = 3;
-
-    /**
-     * The state of this change could be one value of the above
-     */
-    private int mState;
 
     /**
      * Indicates the change was caused by ourselves.
@@ -97,46 +73,30 @@
         mFormatter = PhoneNumberUtil.getInstance().getAsYouTypeFormatter(countryCode);
     }
 
+    @Override
     public void beforeTextChanged(CharSequence s, int start, int count,
             int after) {
         if (mSelfChange || mStopFormatting) {
             return;
         }
-        if (count == 0 && s.length() == start) {
-            // Append one or more new chars
-            mState = STATE_APPEND;
-        } else if (after == 0 && start + count == s.length() && count > 0) {
-            // Remove one or more chars from the end of string.
-            mState = STATE_REMOVE_LAST;
-        } else if (count > 0 && !hasSeparator(s, start, count)) {
-            // Remove the dialable chars in the begin or middle of text.
-            mState = STATE_MODIFY_DIGITS;
-        } else {
-            mState = STATE_OTHER;
+        // If the user manually deleted any non-dialable characters, stop formatting
+        if (count > 0 && hasSeparator(s, start, count)) {
+            stopFormatting();
         }
     }
 
+    @Override
     public void onTextChanged(CharSequence s, int start, int before, int count) {
         if (mSelfChange || mStopFormatting) {
             return;
         }
-        if (mState == STATE_OTHER) {
-            if (count > 0 && !hasSeparator(s, start, count)) {
-                // User inserted the dialable characters in the middle of text.
-                mState = STATE_MODIFY_DIGITS;
-            }
-        }
-        // Check whether we should stop formatting.
-        if (mState == STATE_APPEND && count > 0 && hasSeparator(s, start, count)) {
-            // User appended the non-dialable character, stop formatting.
-            stopFormatting();
-        } else if (mState == STATE_OTHER) {
-            // User must insert or remove the non-dialable characters in the begin or middle of
-            // number, stop formatting.
+        // If the user inserted any non-dialable characters, stop formatting
+        if (count > 0 && hasSeparator(s, start, count)) {
             stopFormatting();
         }
     }
 
+    @Override
     public synchronized void afterTextChanged(Editable s) {
         if (mStopFormatting) {
             // Restart the formatting when all texts were clear.
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
index 6f0175e..a6a0fce 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
@@ -182,14 +182,17 @@
 
     public void testTextChangedByOtherTextWatcher() {
         final TextWatcher cleanupTextWatcher = new TextWatcher() {
+            @Override
             public void afterTextChanged(Editable s) {
                 s.clear();
             }
 
+            @Override
             public void beforeTextChanged(CharSequence s, int start, int count,
                     int after) {
             }
 
+            @Override
             public void onTextChanged(CharSequence s, int start, int before,
                     int count) {
             }
@@ -208,6 +211,81 @@
         assertEquals(expected1, number.toString());
     }
 
+    /**
+     * Test the case where some other component is auto-completing what the user is typing
+     */
+    public void testAutoCompleteWithFormattedNumber() {
+        String init = "650-1";
+        String expected = "+1-650-123-4567"; // Different formatting than ours
+        testReplacement(init, expected, expected);
+    }
+
+    /**
+     * Test the case where some other component is auto-completing what the user is typing
+     */
+    public void testAutoCompleteWithFormattedNameAndNumber() {
+        String init = "650-1";
+        String expected = "Test User <650-123-4567>";
+        testReplacement(init, expected, expected);
+    }
+
+    /**
+     * Test the case where some other component is auto-completing what the user is typing
+     */
+    public void testAutoCompleteWithNumericNameAndNumber() {
+        String init = "650";
+        String expected = "2nd Test User <650-123-4567>";
+        testReplacement(init, expected, expected);
+    }
+
+    /**
+     * Test the case where some other component is auto-completing what the user is typing
+     */
+    public void testAutoCompleteWithUnformattedNumber() {
+        String init = "650-1";
+        String expected = "6501234567";
+        testReplacement(init, expected, expected);
+    }
+
+    /**
+     * Test the case where some other component is auto-completing what the user is typing, where
+     * the deleted text doesn't have any formatting and neither does the replacement text: in this
+     * case the replacement text should be formatted by the PhoneNumberFormattingTextWatcher.
+     */
+    public void testAutoCompleteUnformattedWithUnformattedNumber() {
+        String init = "650";
+        String replacement = "6501234567";
+        String expected = "(650) 123-4567";
+        testReplacement(init, replacement, expected);
+
+        String init2 = "650";
+        String replacement2 = "16501234567";
+        String expected2 = "1 650-123-4567";
+        testReplacement(init2, replacement2, expected2);
+    }
+
+    /**
+     * Helper method for testing replacing the entire string with another string
+     * @param init The initial string
+     * @param expected
+     */
+    private void testReplacement(String init, String replacement, String expected) {
+        TextWatcher textWatcher = getTextWatcher();
+
+        SpannableStringBuilder number = new SpannableStringBuilder(init);
+
+        // Replace entire text with the given values
+        textWatcher.beforeTextChanged(number, 0, init.length(), replacement.length());
+        number.replace(0, init.length(), replacement, 0, replacement.length());
+        Selection.setSelection(number, replacement.length()); // move the cursor to the end
+        textWatcher.onTextChanged(number, 0, init.length(), replacement.length());
+        textWatcher.afterTextChanged(number);
+
+        assertEquals(expected, number.toString());
+        // the cursor should be still at the end
+        assertEquals(expected.length(), Selection.getSelectionEnd(number));
+    }
+
     private TextWatcher getTextWatcher() {
         return new PhoneNumberFormattingTextWatcher("US");
     }