Merge "Update the error for WebView thread violations to make clear that it's not fatal"
diff --git a/CleanSpec.mk b/CleanSpec.mk
index d48904c..7bab945 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -111,6 +111,7 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/wifi/java)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/wifi/java)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/fonts/Lohit_Hindi.ttf)
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 34f0a64..a126e83 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -133,6 +133,39 @@
     }
 }
 
+static void dumpSource(const sp<MediaSource> &source, const String8 &filename) {
+    FILE *out = fopen(filename.string(), "wb");
+
+    CHECK_EQ((status_t)OK, source->start());
+
+    status_t err;
+    for (;;) {
+        MediaBuffer *mbuf;
+        err = source->read(&mbuf);
+
+        if (err == INFO_FORMAT_CHANGED) {
+            continue;
+        } else if (err != OK) {
+            break;
+        }
+
+        CHECK_EQ(
+                fwrite((const uint8_t *)mbuf->data() + mbuf->range_offset(),
+                       1,
+                       mbuf->range_length(),
+                       out),
+                (ssize_t)mbuf->range_length());
+
+        mbuf->release();
+        mbuf = NULL;
+    }
+
+    CHECK_EQ((status_t)OK, source->stop());
+
+    fclose(out);
+    out = NULL;
+}
+
 static void playSource(OMXClient *client, sp<MediaSource> &source) {
     sp<MetaData> meta = source->getFormat();
 
@@ -578,6 +611,7 @@
                     "(video only)\n");
     fprintf(stderr, "       -S allocate buffers from a surface\n");
     fprintf(stderr, "       -T allocate buffers from a surface texture\n");
+    fprintf(stderr, "       -d(ump) filename (raw stream data to a file)\n");
 }
 
 int main(int argc, char **argv) {
@@ -590,6 +624,8 @@
     bool seekTest = false;
     bool useSurfaceAlloc = false;
     bool useSurfaceTexAlloc = false;
+    bool dumpStream = false;
+    String8 dumpStreamFilename;
     gNumRepetitions = 1;
     gMaxNumFrames = 0;
     gReproduceBug = -1;
@@ -604,7 +640,7 @@
     sp<LiveSession> liveSession;
 
     int res;
-    while ((res = getopt(argc, argv, "han:lm:b:ptsrow:kxST")) >= 0) {
+    while ((res = getopt(argc, argv, "han:lm:b:ptsrow:kxSTd:")) >= 0) {
         switch (res) {
             case 'a':
             {
@@ -612,6 +648,13 @@
                 break;
             }
 
+            case 'd':
+            {
+                dumpStream = true;
+                dumpStreamFilename.setTo(optarg);
+                break;
+            }
+
             case 'l':
             {
                 listComponents = true;
@@ -1062,6 +1105,8 @@
 
         if (gWriteMP4) {
             writeSourcesToMP4(mediaSources, syncInfoPresent);
+        } else if (dumpStream) {
+            dumpSource(mediaSource, dumpStreamFilename);
         } else if (seekTest) {
             performSeekTest(mediaSource);
         } else {
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index be00aa5..51c6f3a 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -29,16 +29,29 @@
 import android.widget.SpinnerAdapter;
 
 /**
- * Acts as a replacement for the title bar in Activities.
- * The action bar provides facilities for creating toolbar actions as well as
- * methods of navigating the application.
- * <p>By default, the action bar appears at the top of every activity, with the application icon on
- * the left, followed by the activity title. Items from the activity's options menu are also
- * accessible from the action bar.</p>
+ * A window feature at the top of the activity that may display the activity title, navigation
+ * modes, and other interactive items.
+ * <p>Beginning with Android 3.0 (API level 11), the action bar appears at the top of an
+ * activity's window when the activity uses the system's {@link
+ * android.R.style#Theme_Holo Holo} theme (or one of its descendant themes), which is the default.
+ * You may otherwise add the action bar by calling {@link
+ * android.view.Window#requestFeature requestFeature(FEATURE_ACTION_BAR)} or by declaring it in a
+ * custom theme with the {@link android.R.styleable#Theme_windowActionBar windowActionBar} property.
+ * <p>By default, the action bar shows the application icon on
+ * the left, followed by the activity title. If your activity has an options menu, you can make
+ * select items accessible directly from the action bar as "action items". You can also
+ * modify various characteristics of the action bar or remove it completely.</p>
  * <p>From your activity, you can retrieve an instance of {@link ActionBar} by calling {@link
  * android.app.Activity#getActionBar getActionBar()}.</p>
- * <p>For more information, read the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action
+ * <p>For information about how to use the action bar, including how to add action items, navigation
+ * modes and more, read the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action
  * Bar</a> developer guide.</p>
+ * <p>In some cases, the action bar may be overlayed by another bar that enables contextual actions,
+ * using an {@link android.view.ActionMode}. For example, when the user selects one or more items in
+ * your activity, you can enable an action mode that offers actions specific to the selected
+ * items, with a UI that temporarily replaces the action bar. Although the UI may occupy the
+ * same space, the {@link android.view.ActionMode} APIs are distinct and independent from those for
+ * {@link ActionBar}.
  */
 public abstract class ActionBar {
     /**
@@ -423,6 +436,7 @@
      * Set the ActionBar's split background. This will appear in
      * the split action bar containing menu-provided action buttons
      * on some devices and configurations.
+     * <p>You can enable split action bar with {@link android.R.attr#uiOptions}
      *
      * @param d Background drawable for the split bar
      */
@@ -460,13 +474,6 @@
      * </ul>
      *
      * @return The current navigation mode.
-     * 
-     * @see #setStandardNavigationMode()
-     * @see #setStandardNavigationMode(CharSequence)
-     * @see #setStandardNavigationMode(CharSequence, CharSequence)
-     * @see #setDropdownNavigationMode(SpinnerAdapter)
-     * @see #setTabNavigationMode()
-     * @see #setCustomNavigationMode(View)
      */
     public abstract int getNavigationMode();
 
@@ -498,7 +505,6 @@
      * @return A new Tab
      *
      * @see #addTab(Tab)
-     * @see #insertTab(Tab, int)
      */
     public abstract Tab newTab();
 
@@ -606,7 +612,7 @@
     public abstract void show();
 
     /**
-     * Hide the ActionBar if it is not currently showing.
+     * Hide the ActionBar if it is currently showing.
      * If the window hosting the ActionBar does not have the feature
      * {@link Window#FEATURE_ACTION_BAR_OVERLAY} it will resize application
      * content to fit the new space available.
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 7799779..b4471f0 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1550,6 +1550,13 @@
             return true;
         }
 
+        case DISMISS_KEYGUARD_ON_NEXT_ACTIVITY_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            dismissKeyguardOnNextActivity();
+            reply.writeNoException();
+            return true;
+        }
+
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -3504,5 +3511,15 @@
         reply.recycle();
     }
 
+    public void dismissKeyguardOnNextActivity() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(DISMISS_KEYGUARD_ON_NEXT_ACTIVITY_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 27dd691..26813bf 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -372,6 +372,8 @@
 
     public void showBootMessage(CharSequence msg, boolean always) throws RemoteException;
 
+    public void dismissKeyguardOnNextActivity() throws RemoteException;
+
     /*
      * Private non-Binder interfaces
      */
@@ -602,4 +604,5 @@
     int UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+135;
     int GET_PROCESS_PSS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+136;
     int SHOW_BOOT_MESSAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+137;
+    int DISMISS_KEYGUARD_ON_NEXT_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+138;
 }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 72cf26a..f44d038 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -5577,24 +5577,35 @@
 
     @Override
     public String toString() {
-        StringBuilder   b = new StringBuilder(128);
+        StringBuilder b = new StringBuilder(128);
 
         b.append("Intent { ");
-        toShortString(b, true, true);
+        toShortString(b, true, true, true);
         b.append(" }");
 
         return b.toString();
     }
 
     /** @hide */
-    public String toShortString(boolean comp, boolean extras) {
-        StringBuilder   b = new StringBuilder(128);
-        toShortString(b, comp, extras);
+    public String toInsecureString() {
+        StringBuilder b = new StringBuilder(128);
+
+        b.append("Intent { ");
+        toShortString(b, false, true, true);
+        b.append(" }");
+
         return b.toString();
     }
 
     /** @hide */
-    public void toShortString(StringBuilder b, boolean comp, boolean extras) {
+    public String toShortString(boolean secure, boolean comp, boolean extras) {
+        StringBuilder b = new StringBuilder(128);
+        toShortString(b, secure, comp, extras);
+        return b.toString();
+    }
+
+    /** @hide */
+    public void toShortString(StringBuilder b, boolean secure, boolean comp, boolean extras) {
         boolean first = true;
         if (mAction != null) {
             b.append("act=").append(mAction);
@@ -5621,19 +5632,8 @@
             }
             first = false;
             b.append("dat=");
-            String scheme = mData.getScheme();
-            if (scheme != null) {
-                if (scheme.equalsIgnoreCase("tel")) {
-                    b.append("tel:xxx-xxx-xxxx");
-                } else if (scheme.equalsIgnoreCase("sip")) {
-                    b.append("sip:xxxxxxxxxx");
-                } else if (scheme.equalsIgnoreCase("sms")) {
-                    b.append("sms:xxx-xxx-xxxx");
-                } else if (scheme.equalsIgnoreCase("smsto")) {
-                    b.append("smsto:xxx-xxx-xxxx");
-                } else {
-                    b.append(mData);
-                }
+            if (secure) {
+                b.append(mData.toSafeString());
             } else {
                 b.append(mData);
             }
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index bba329d..0e6694de 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -442,7 +442,11 @@
     public int uiOptions = 0;
 
     /**
-     * Flag for use with uiOptions.
+     * Flag for use with {@link #uiOptions}.
+     * Indicates that the action bar should put all action items in a separate bar when
+     * the screen is narrow.
+     * <p>This value corresponds to "splitActionBarWhenNarrow" for the {@link #uiOptions} XML
+     * attribute.
      */
     public static final int UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW = 1;
 
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 58f7869..e40de26 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -480,6 +480,12 @@
     public final void stopPreview() {
         _stopPreview();
         mFaceDetectionRunning = false;
+
+        mShutterCallback = null;
+        mRawImageCallback = null;
+        mPostviewCallback = null;
+        mJpegCallback = null;
+        mAutoFocusCallback = null;
     }
 
     private native final void _stopPreview();
@@ -766,15 +772,8 @@
          * onAutoFocus will be called immediately with a fake value of
          * <code>success</code> set to <code>true</code>.
          *
-         * The auto-focus routine may lock auto-exposure and auto-white balance
-         * after it completes. To check for the state of these locks, use the
-         * {@link android.hardware.Camera.Parameters#getAutoExposureLock()} and
-         * {@link android.hardware.Camera.Parameters#getAutoWhiteBalanceLock()}
-         * methods. If such locking is undesirable, use
-         * {@link android.hardware.Camera.Parameters#setAutoExposureLock(boolean)}
-         * and
-         * {@link android.hardware.Camera.Parameters#setAutoWhiteBalanceLock(boolean)}
-         * to release the locks.
+         * The auto-focus routine does not lock auto-exposure and auto-white
+         * balance after it completes.
          *
          * @param success true if focus was successful, false if otherwise
          * @param camera  the Camera service object
@@ -805,16 +804,10 @@
      * {@link android.hardware.Camera.Parameters#FLASH_MODE_OFF}, flash may be
      * fired during auto-focus, depending on the driver and camera hardware.<p>
      *
-     * The auto-focus routine may lock auto-exposure and auto-white balance
-     * after it completes. To check for the state of these locks, use the
-     * {@link android.hardware.Camera.Parameters#getAutoExposureLock()} and
-     * {@link android.hardware.Camera.Parameters#getAutoWhiteBalanceLock()}
-     * methods after the {@link AutoFocusCallback#onAutoFocus(boolean, Camera)}
-     * callback is invoked. If such locking is undesirable, use
-     * {@link android.hardware.Camera.Parameters#setAutoExposureLock(boolean)}
-     * and
-     * {@link android.hardware.Camera.Parameters#setAutoWhiteBalanceLock(boolean)}
-     * to release the locks.
+     * Auto-exposure lock {@link android.hardware.Camera.Parameters#getAutoExposureLock()}
+     * and auto-white balance locks {@link android.hardware.Camera.Parameters#getAutoWhiteBalanceLock()}
+     * do not change during and after autofocus. But auto-focus routine may stop
+     * auto-exposure and auto-white balance transiently during focusing.
      *
      * @param cb the callback to run
      * @see #cancelAutoFocus()
@@ -834,13 +827,7 @@
      * this function will return the focus position to the default.
      * If the camera does not support auto-focus, this is a no-op.
      *
-     * Canceling auto-focus will return the auto-exposure lock and auto-white
-     * balance lock to their state before {@link #autoFocus(AutoFocusCallback)}
-     * was called.
-     *
      * @see #autoFocus(Camera.AutoFocusCallback)
-     * @see android.hardware.Camera.Parameters#setAutoExposureLock(boolean)
-     * @see android.hardware.Camera.Parameters#setAutoWhiteBalanceLock(boolean)
      */
     public final void cancelAutoFocus()
     {
@@ -2778,13 +2765,12 @@
          *
          * <p>Stopping preview with {@link #stopPreview()}, or triggering still
          * image capture with {@link #takePicture(Camera.ShutterCallback,
-         * Camera.PictureCallback, Camera.PictureCallback)}, will automatically
-         * set the lock to false. However, the lock can be re-enabled before
-         * preview is re-started to keep the same AE parameters.</p>
+         * Camera.PictureCallback, Camera.PictureCallback)}, will not change the
+         * lock.</p>
          *
-         * <p>Exposure compensation, in conjunction with re-enabling the AE and
-         * AWB locks after each still capture, can be used to capture an
-         * exposure-bracketed burst of images, for example.</p>
+         * <p>Exposure compensation, auto-exposure lock, and auto-white balance
+         * lock can be used to capture an exposure-bracketed burst of images,
+         * for example.</p>
          *
          * <p>Auto-exposure state, including the lock state, will not be
          * maintained after camera {@link #release()} is called.  Locking
@@ -2793,14 +2779,6 @@
          * run at all, and may result in severely over- or under-exposed
          * images.</p>
          *
-         * <p>The driver may also independently lock auto-exposure after
-         * auto-focus completes. If this is undesirable, be sure to always set
-         * the auto-exposure lock to false after the
-         * {@link AutoFocusCallback#onAutoFocus(boolean, Camera)} callback is
-         * received. The {@link #getAutoExposureLock()} method can be used after
-         * the callback to determine if the camera has locked auto-exposure
-         * independently.</p>
-         *
          * @param toggle new state of the auto-exposure lock. True means that
          *        auto-exposure is locked, false means that the auto-exposure
          *        routine is free to run normally.
@@ -2817,11 +2795,7 @@
          * {@link #setAutoExposureLock} for details about the lock.
          *
          * @return State of the auto-exposure lock. Returns true if
-         *         auto-exposure is currently locked, and false otherwise. The
-         *         auto-exposure lock may be independently enabled by the camera
-         *         subsystem when auto-focus has completed. This method can be
-         *         used after the {@link AutoFocusCallback#onAutoFocus(boolean,
-         *         Camera)} callback to determine if the camera has locked AE.
+         *         auto-exposure is currently locked, and false otherwise.
          *
          * @see #setAutoExposureLock(boolean)
          *
@@ -2859,29 +2833,20 @@
          *
          * <p>Stopping preview with {@link #stopPreview()}, or triggering still
          * image capture with {@link #takePicture(Camera.ShutterCallback,
-         * Camera.PictureCallback, Camera.PictureCallback)}, will automatically
-         * set the lock to false. However, the lock can be re-enabled before
-         * preview is re-started to keep the same white balance parameters.</p>
+         * Camera.PictureCallback, Camera.PictureCallback)}, will not change the
+         * the lock.</p>
          *
          * <p> Changing the white balance mode with {@link #setWhiteBalance}
          * will release the auto-white balance lock if it is set.</p>
          *
-         * <p>Exposure compensation, in conjunction with re-enabling the AE and
-         * AWB locks after each still capture, can be used to capture an
-         * exposure-bracketed burst of images, for example. Auto-white balance
-         * state, including the lock state, will not be maintained after camera
-         * {@link #release()} is called.  Locking auto-white balance after
-         * {@link #open()} but before the first call to {@link #startPreview()}
-         * will not allow the auto-white balance routine to run at all, and may
-         * result in severely incorrect color in captured images.</p>
-         *
-         * <p>The driver may also independently lock auto-white balance after
-         * auto-focus completes. If this is undesirable, be sure to always set
-         * the auto-white balance lock to false after the
-         * {@link AutoFocusCallback#onAutoFocus(boolean, Camera)} callback is
-         * received. The {@link #getAutoWhiteBalanceLock()} method can be used
-         * after the callback to determine if the camera has locked auto-white
-         * balance independently.</p>
+         * <p>Exposure compensation, AE lock, and AWB lock can be used to
+         * capture an exposure-bracketed burst of images, for example.
+         * Auto-white balance state, including the lock state, will not be
+         * maintained after camera {@link #release()} is called.  Locking
+         * auto-white balance after {@link #open()} but before the first call to
+         * {@link #startPreview()} will not allow the auto-white balance routine
+         * to run at all, and may result in severely incorrect color in captured
+         * images.</p>
          *
          * @param toggle new state of the auto-white balance lock. True means
          *        that auto-white balance is locked, false means that the
@@ -2902,11 +2867,7 @@
          *
          * @return State of the auto-white balance lock. Returns true if
          *         auto-white balance is currently locked, and false
-         *         otherwise. The auto-white balance lock may be independently
-         *         enabled by the camera subsystem when auto-focus has
-         *         completed. This method can be used after the
-         *         {@link AutoFocusCallback#onAutoFocus(boolean, Camera)}
-         *         callback to determine if the camera has locked AWB.
+         *         otherwise.
          *
          * @see #setAutoWhiteBalanceLock(boolean)
          *
diff --git a/core/java/android/net/DnsPinger.java b/core/java/android/net/DnsPinger.java
index 3e27b0d..3291e6b 100644
--- a/core/java/android/net/DnsPinger.java
+++ b/core/java/android/net/DnsPinger.java
@@ -53,7 +53,7 @@
 public final class DnsPinger extends Handler {
     private static final boolean V = true;
 
-    private static final int RECEIVE_POLL_INTERVAL_MS = 30;
+    private static final int RECEIVE_POLL_INTERVAL_MS = 200;
     private static final int DNS_PORT = 53;
 
     /** Short socket timeout so we don't block one any 'receive' call */
@@ -70,6 +70,9 @@
     private final ArrayList<InetAddress> mDefaultDns;
     private String TAG;
 
+    //Invalidates old dns requests upon a cancel
+    private AtomicInteger mCurrentToken = new AtomicInteger();
+
     private static final int BASE = Protocol.BASE_DNS_PINGER;
 
     /**
@@ -102,6 +105,17 @@
         long start = SystemClock.elapsedRealtime();
     }
 
+    /* Message argument for ACTION_PING_DNS */
+    private class DnsArg {
+        InetAddress dns;
+        int seq;
+
+        DnsArg(InetAddress d, int s) {
+            dns = d;
+            seq = s;
+        }
+    }
+
     public DnsPinger(Context context, String TAG, Looper looper,
             Handler target, int connectionType) {
         super(looper);
@@ -122,9 +136,13 @@
     public void handleMessage(Message msg) {
         switch (msg.what) {
             case ACTION_PING_DNS:
+                DnsArg dnsArg = (DnsArg) msg.obj;
+                if (dnsArg.seq != mCurrentToken.get()) {
+                    break;
+                }
                 try {
                     ActivePing newActivePing = new ActivePing();
-                    InetAddress dnsAddress = (InetAddress) msg.obj;
+                    InetAddress dnsAddress = dnsArg.dns;
                     newActivePing.internalId = msg.arg1;
                     newActivePing.timeout = msg.arg2;
                     newActivePing.socket = new DatagramSocket();
@@ -248,11 +266,13 @@
      */
     public int pingDnsAsync(InetAddress dns, int timeout, int delay) {
         int id = sCounter.incrementAndGet();
-        sendMessageDelayed(obtainMessage(ACTION_PING_DNS, id, timeout, dns), delay);
+        sendMessageDelayed(obtainMessage(ACTION_PING_DNS, id, timeout,
+                new DnsArg(dns, mCurrentToken.get())), delay);
         return id;
     }
 
     public void cancelPings() {
+        mCurrentToken.incrementAndGet();
         obtainMessage(ACTION_CANCEL_ALL_PINGS).sendToTarget();
     }
 
diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java
index a5cdf70..a6635be 100644
--- a/core/java/android/net/NetworkStatsHistory.java
+++ b/core/java/android/net/NetworkStatsHistory.java
@@ -270,6 +270,11 @@
                 || entry.operations < 0) {
             throw new IllegalArgumentException("tried recording negative data");
         }
+        if (entry.rxBytes == 0 && entry.rxPackets == 0 && entry.txBytes == 0 && entry.txPackets == 0
+                && entry.operations == 0) {
+            // nothing to record; skip
+            return;
+        }
 
         // create any buckets needed by this range
         ensureBuckets(start, end);
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index 2c875c8..9d28eff 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -353,6 +353,48 @@
     public abstract String toString();
 
     /**
+     * Return a string representation of the URI that is safe to print
+     * to logs and other places where PII should be avoided.
+     * @hide
+     */
+    public String toSafeString() {
+        String scheme = getScheme();
+        String ssp = getSchemeSpecificPart();
+        if (scheme != null) {
+            if (scheme.equalsIgnoreCase("tel") || scheme.equalsIgnoreCase("sip")
+                    || scheme.equalsIgnoreCase("sms") || scheme.equalsIgnoreCase("smsto")
+                    || scheme.equalsIgnoreCase("mailto")) {
+                StringBuilder builder = new StringBuilder(64);
+                builder.append(scheme);
+                builder.append(':');
+                if (ssp != null) {
+                    for (int i=0; i<ssp.length(); i++) {
+                        char c = ssp.charAt(i);
+                        if (c == '-' || c == '@' || c == '.') {
+                            builder.append(c);
+                        } else {
+                            builder.append('x');
+                        }
+                    }
+                }
+                return builder.toString();
+            }
+        }
+        // Not a sensitive scheme, but let's still be conservative about
+        // the data we include -- only the ssp, not the query params or
+        // fragment, because those can often have sensitive info.
+        StringBuilder builder = new StringBuilder(64);
+        if (scheme != null) {
+            builder.append(scheme);
+            builder.append(':');
+        }
+        if (ssp != null) {
+            builder.append(ssp);
+        }
+        return builder.toString();
+    }
+
+    /**
      * Constructs a new builder, copying the attributes from this Uri.
      */
     public abstract Builder buildUpon();
diff --git a/core/java/android/preference/PreferenceScreen.java b/core/java/android/preference/PreferenceScreen.java
index 45e3a4c..dd9dd25 100644
--- a/core/java/android/preference/PreferenceScreen.java
+++ b/core/java/android/preference/PreferenceScreen.java
@@ -25,6 +25,7 @@
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.Window;
 import android.widget.Adapter;
 import android.widget.AdapterView;
 import android.widget.ListAdapter;
@@ -156,13 +157,13 @@
 
         // Set the title bar if title is available, else no title bar
         final CharSequence title = getTitle();
-        Dialog dialog = mDialog = new Dialog(context, TextUtils.isEmpty(title)
-                ? com.android.internal.R.style.Theme_NoTitleBar
-                : com.android.internal.R.style.Theme);
-        dialog.setContentView(mListView);
-        if (!TextUtils.isEmpty(title)) {
+        Dialog dialog = mDialog = new Dialog(context, context.getThemeResId());
+        if (TextUtils.isEmpty(title)) {
+            dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
+        } else {
             dialog.setTitle(title);
         }
+        dialog.setContentView(mListView);
         dialog.setOnDismissListener(this);
         if (state != null) {
             dialog.onRestoreInstanceState(state);
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index a52d48e..1e17632 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -679,6 +679,12 @@
 
         wp.getFontMetricsInt(fmi);
 
+        updateMetrics(fmi, previousTop, previousAscent, previousDescent, previousBottom,
+                previousLeading);
+    }
+
+    static void updateMetrics(FontMetricsInt fmi, int previousTop, int previousAscent,
+            int previousDescent, int previousBottom, int previousLeading) {
         fmi.top     = Math.min(fmi.top,     previousTop);
         fmi.ascent  = Math.min(fmi.ascent,  previousAscent);
         fmi.descent = Math.max(fmi.descent, previousDescent);
@@ -809,7 +815,28 @@
         int textLimit = mStart + limit;
 
         if (needWidth || (c != null && runIsRtl)) {
+            int previousTop = 0;
+            int previousAscent = 0;
+            int previousDescent = 0;
+            int previousBottom = 0;
+            int previousLeading = 0;
+
+            boolean needUpdateMetrics = (fmi != null);
+
+            if (needUpdateMetrics) {
+                previousTop     = fmi.top;
+                previousAscent  = fmi.ascent;
+                previousDescent = fmi.descent;
+                previousBottom  = fmi.bottom;
+                previousLeading = fmi.leading;
+            }
+
             ret = replacement.getSize(wp, mText, textStart, textLimit, fmi);
+
+            if (needUpdateMetrics) {
+                updateMetrics(fmi, previousTop, previousAscent, previousDescent, previousBottom,
+                        previousLeading);
+            }
         }
 
         if (c != null) {
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 55c821d..45f9da2 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -116,6 +116,7 @@
     boolean isKeyguardLocked();
     boolean isKeyguardSecure();
     boolean inKeyguardRestrictedInputMode();
+    void dismissKeyguard();
 
     void closeSystemDialogs(String reason);
     
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f993160..3c67521 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -81,7 +81,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Locale;
-import java.util.WeakHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
@@ -1497,12 +1496,7 @@
     /**
      * Map used to store views' tags.
      */
-    private static WeakHashMap<View, SparseArray<Object>> sTags;
-
-    /**
-     * Lock used to access sTags.
-     */
-    private static final Object sTagsLock = new Object();
+    private SparseArray<Object> mKeyedTags;
 
     /**
      * The next available accessiiblity id.
@@ -3900,6 +3894,12 @@
      * Note: Called from the default {@link AccessibilityDelegate}.
      */
     boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
+        // Do not populate text to scroll events. They describe position change
+        // and usually come from container with a lot of text which is not very
+        // informative for accessibility purposes. Also they are fired frequently.
+        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
+            return true;
+        }
         onPopulateAccessibilityEvent(event);
         return false;
     }
@@ -12236,14 +12236,7 @@
      * @see #getTag()
      */
     public Object getTag(int key) {
-        SparseArray<Object> tags = null;
-        synchronized (sTagsLock) {
-            if (sTags != null) {
-                tags = sTags.get(this);
-            }
-        }
-
-        if (tags != null) return tags.get(key);
+        if (mKeyedTags != null) return mKeyedTags.get(key);
         return null;
     }
 
@@ -12276,7 +12269,7 @@
                     + "resource id.");
         }
 
-        setTagInternal(this, key, tag);
+        setKeyedTag(key, tag);
     }
 
     /**
@@ -12291,27 +12284,15 @@
                     + "resource id.");
         }
 
-        setTagInternal(this, key, tag);
+        setKeyedTag(key, tag);
     }
 
-    private static void setTagInternal(View view, int key, Object tag) {
-        SparseArray<Object> tags = null;
-        synchronized (sTagsLock) {
-            if (sTags == null) {
-                sTags = new WeakHashMap<View, SparseArray<Object>>();
-            } else {
-                tags = sTags.get(view);
-            }
+    private void setKeyedTag(int key, Object tag) {
+        if (mKeyedTags == null) {
+            mKeyedTags = new SparseArray<Object>();
         }
 
-        if (tags == null) {
-            tags = new SparseArray<Object>(2);
-            synchronized (sTagsLock) {
-                sTags.put(view, tags);
-            }
-        }
-
-        tags.put(key, tag);
+        mKeyedTags.put(key, tag);
     }
 
     /**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index b678c7d..a29cf13 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2176,13 +2176,15 @@
 
     @Override
     boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
-        // We first get a chance to populate the event.
-        super.dispatchPopulateAccessibilityEventInternal(event);
+        boolean handled = super.dispatchPopulateAccessibilityEventInternal(event);
+        if (handled) {
+            return handled;
+        }
         // Let our children have a shot in populating the event.
         for (int i = 0, count = getChildCount(); i < count; i++) {
             View child = getChildAt(i);
             if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
-                boolean handled = getChildAt(i).dispatchPopulateAccessibilityEvent(event);
+                handled = getChildAt(i).dispatchPopulateAccessibilityEvent(event);
                 if (handled) {
                     return handled;
                 }
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 1dbb083..4f67675 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -850,6 +850,11 @@
     public boolean inKeyguardRestrictedKeyInputMode();
 
     /**
+     * Ask the policy to dismiss the keyguard, if it is currently shown.
+     */
+    public void dismissKeyguardLw();
+
+    /**
      * Given an orientation constant, returns the appropriate surface rotation,
      * taking into account sensors, docking mode, rotation lock, and other factors.
      *
@@ -876,6 +881,13 @@
     public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation);
 
     /**
+     * Called by the window manager when the rotation changes.
+     *
+     * @param rotation The new rotation.
+     */
+    public void setRotationLw(int rotation);
+
+    /**
      * Called when the system is mostly done booting to determine whether
      * the system should go into safe mode.
      */
diff --git a/core/java/android/view/WindowOrientationListener.java b/core/java/android/view/WindowOrientationListener.java
index 726bf4a..c3c74a7 100755
--- a/core/java/android/view/WindowOrientationListener.java
+++ b/core/java/android/view/WindowOrientationListener.java
@@ -26,7 +26,7 @@
 
 /**
  * A special helper class used by the WindowManager
- *  for receiving notifications from the SensorManager when
+ * for receiving notifications from the SensorManager when
  * the orientation of the device has changed.
  *
  * NOTE: If changing anything here, please run the API demo
@@ -54,6 +54,7 @@
     private Sensor mSensor;
     private SensorEventListenerImpl mSensorEventListener;
     boolean mLogEnabled;
+    int mCurrentRotation = -1;
 
     /**
      * Creates a new WindowOrientationListener.
@@ -117,12 +118,25 @@
     }
 
     /**
-     * Gets the current orientation.
-     * @return The current rotation, or -1 if unknown.
+     * Sets the current rotation.
+     *
+     * @param rotation The current rotation.
      */
-    public int getCurrentRotation() {
+    public void setCurrentRotation(int rotation) {
+        mCurrentRotation = rotation;
+    }
+
+    /**
+     * Gets the proposed rotation.
+     *
+     * This method only returns a rotation if the orientation listener is certain
+     * of its proposal.  If the rotation is indeterminate, returns -1.
+     *
+     * @return The proposed rotation, or -1 if unknown.
+     */
+    public int getProposedRotation() {
         if (mEnabled) {
-            return mSensorEventListener.getCurrentRotation();
+            return mSensorEventListener.getProposedRotation();
         }
         return -1;
     }
@@ -137,10 +151,14 @@
     /**
      * Called when the rotation view of the device has changed.
      *
+     * This method is called whenever the orientation becomes certain of an orientation.
+     * It is called each time the orientation determination transitions from being
+     * uncertain to being certain again, even if it is the same orientation as before.
+     *
      * @param rotation The new orientation of the device, one of the Surface.ROTATION_* constants.
      * @see Surface
      */
-    public abstract void onOrientationChanged(int rotation);
+    public abstract void onProposedRotationChanged(int rotation);
 
     /**
      * Enables or disables the window orientation listener logging for use with
@@ -182,23 +200,8 @@
      *    to the corresponding orientation.  These thresholds have some hysteresis built-in
      *    to avoid oscillations between adjacent orientations.
      *
-     *  - Use the magnitude to judge the confidence of the orientation.
-     *    Under ideal conditions, the magnitude should equal to that of gravity.  When it
-     *    differs significantly, we know the device is under external acceleration and
-     *    we can't trust the data.
-     *
-     *  - Use the tilt angle to judge the confidence of the orientation.
-     *    When the tilt angle is high in absolute value then the device is nearly flat
-     *    so small physical movements produce large changes in orientation angle.
-     *    This can be the case when the device is being picked up from a table.
-     *
-     *  - Use the orientation angle to judge the confidence of the orientation.
-     *    The close the orientation angle is to the canonical orientation angle, the better.
-     *
-     *  - Based on the aggregate confidence, we determine how long we want to wait for
-     *    the new orientation to settle.  This is accomplished by integrating the confidence
-     *    for each orientation over time.  When a threshold integration sum is reached
-     *    then we actually change orientations.
+     *  - Wait for the device to settle for a little bit.  Once that happens, issue the
+     *    new orientation proposal.
      *
      * Details are explained inline.
      */
@@ -211,22 +214,8 @@
         private static final int ACCELEROMETER_DATA_Y = 1;
         private static final int ACCELEROMETER_DATA_Z = 2;
 
-        // Rotation constants.
-        // These are the same as Surface rotation constants with the addition of a 5th
-        // unknown state when we are not confident about the proporsed orientation.
-        // One important property of these constants is that they are equal to the
-        // orientation angle itself divided by 90.  We use this fact to map
-        // back and forth between orientation angles and rotation values.
-        private static final int ROTATION_UNKNOWN = -1;
-        //private static final int ROTATION_0 = Surface.ROTATION_0; // 0
-        //private static final int ROTATION_90 = Surface.ROTATION_90; // 1
-        //private static final int ROTATION_180 = Surface.ROTATION_180; // 2
-        //private static final int ROTATION_270 = Surface.ROTATION_270; // 3
-
         private final WindowOrientationListener mOrientationListener;
 
-        private int mRotation = ROTATION_UNKNOWN;
-
         /* State for first order low-pass filtering of accelerometer data.
          * See http://en.wikipedia.org/wiki/Low-pass_filter#Discrete-time_realization for
          * signal processing background.
@@ -235,6 +224,24 @@
         private long mLastTimestamp = Long.MAX_VALUE; // in nanoseconds
         private float mLastFilteredX, mLastFilteredY, mLastFilteredZ;
 
+        // The current proposal.  We wait for the proposal to be stable for a
+        // certain amount of time before accepting it.
+        //
+        // The basic idea is to ignore intermediate poses of the device while the
+        // user is picking up, putting down or turning the device.
+        private int mProposalRotation;
+        private long mProposalAgeMS;
+
+        // A historical trace of tilt and orientation angles.  Used to determine whether
+        // the device posture has settled down.
+        private static final int HISTORY_SIZE = 20;
+        private int mHistoryIndex; // index of most recent sample
+        private int mHistoryLength; // length of historical trace
+        private final long[] mHistoryTimestampMS = new long[HISTORY_SIZE];
+        private final float[] mHistoryMagnitudes = new float[HISTORY_SIZE];
+        private final int[] mHistoryTiltAngles = new int[HISTORY_SIZE];
+        private final int[] mHistoryOrientationAngles = new int[HISTORY_SIZE];
+
         // The maximum sample inter-arrival time in milliseconds.
         // If the acceleration samples are further apart than this amount in time, we reset the
         // state of the low-pass filter and orientation properties.  This helps to handle
@@ -242,24 +249,26 @@
         // a significant gap in samples.
         private static final float MAX_FILTER_DELTA_TIME_MS = 1000;
 
-        // The acceleration filter cutoff frequency.
-        // This is the frequency at which signals are attenuated by 3dB (half the passband power).
+        // The acceleration filter time constant.
+        //
+        // This time constant is used to tune the acceleration filter such that
+        // impulses and vibrational noise (think car dock) is suppressed before we
+        // try to calculate the tilt and orientation angles.
+        //
+        // The filter time constant is related to the filter cutoff frequency, which is the
+        // frequency at which signals are attenuated by 3dB (half the passband power).
         // Each successive octave beyond this frequency is attenuated by an additional 6dB.
         //
-        // We choose the cutoff frequency such that impulses and vibrational noise
-        // (think car dock) is suppressed.  However, this filtering does not eliminate
-        // all possible sources of orientation ambiguity so we also rely on a dynamic
-        // settle time for establishing a new orientation.  Filtering adds latency
-        // inversely proportional to the cutoff frequency so we don't want to make
-        // it too small or we can lose hundreds of milliseconds of responsiveness.
-        private static final float FILTER_CUTOFF_FREQUENCY_HZ = 1f;
-        private static final float FILTER_TIME_CONSTANT_MS = (float)(500.0f
-                / (Math.PI * FILTER_CUTOFF_FREQUENCY_HZ)); // t = 1 / (2pi * Fc) * 1000ms
-
-        // The filter gain.
-        // We choose a value slightly less than unity to avoid numerical instabilities due
-        // to floating-point error accumulation.
-        private static final float FILTER_GAIN = 0.999f;
+        // Given a time constant t in seconds, the filter cutoff frequency Fc in Hertz
+        // is given by Fc = 1 / (2pi * t).
+        //
+        // The higher the time constant, the lower the cutoff frequency, so more noise
+        // will be suppressed.
+        //
+        // Filtering adds latency proportional the time constant (inversely proportional
+        // to the cutoff frequency) so we don't want to make the time constant too
+        // large or we can lose responsiveness.
+        private static final float FILTER_TIME_CONSTANT_MS = 100.0f;
 
         /* State for orientation detection. */
 
@@ -297,10 +306,10 @@
         // The ideal tilt angle is 0 (when the device is vertical) so the limits establish
         // how close to vertical the device must be in order to change orientation.
         private static final int[][] TILT_TOLERANCE = new int[][] {
-            /* ROTATION_0   */ { -20, 75 },
-            /* ROTATION_90  */ { -20, 70 },
-            /* ROTATION_180 */ { -20, 65 },
-            /* ROTATION_270 */ { -20, 70 }
+            /* ROTATION_0   */ { -20, 70 },
+            /* ROTATION_90  */ { -20, 60 },
+            /* ROTATION_180 */ { -20, 50 },
+            /* ROTATION_270 */ { -20, 60 }
         };
 
         // The gap angle in degrees between adjacent orientation angles for hysteresis.
@@ -308,41 +317,31 @@
         // adjacent orientation.  No orientation proposal is made when the orientation
         // angle is within the gap between the current orientation and the adjacent
         // orientation.
-        private static final int ADJACENT_ORIENTATION_ANGLE_GAP = 30;
+        private static final int ADJACENT_ORIENTATION_ANGLE_GAP = 45;
 
-        // The confidence scale factors for angle, tilt and magnitude.
-        // When the distance between the actual value and the ideal value is the
-        // specified delta, orientation transitions will take twice as long as they would
-        // in the ideal case.  Increasing or decreasing the delta has an exponential effect
-        // on each factor's influence over the transition time.
+        // The number of milliseconds for which the device posture must be stable
+        // before we perform an orientation change.  If the device appears to be rotating
+        // (being picked up, put down) then we keep waiting until it settles.
+        private static final int SETTLE_TIME_MS = 200;
 
-        // Transition takes 2x longer when angle is 30 degrees from ideal orientation angle.
-        private static final float ORIENTATION_ANGLE_CONFIDENCE_SCALE =
-                confidenceScaleFromDelta(30);
+        // The maximum change in magnitude that can occur during the settle time.
+        // Tuning this constant particularly helps to filter out situations where the
+        // device is being picked up or put down by the user.
+        private static final float SETTLE_MAGNITUDE_MAX_DELTA =
+                SensorManager.STANDARD_GRAVITY * 0.2f;
 
-        // Transition takes 2x longer when tilt is 60 degrees from vertical.
-        private static final float TILT_ANGLE_CONFIDENCE_SCALE = confidenceScaleFromDelta(60);
+        // The maximum change in tilt angle that can occur during the settle time.
+        private static final int SETTLE_TILT_ANGLE_MAX_DELTA = 5;
 
-        // Transition takes 2x longer when acceleration is 0.5 Gs.
-        private static final float MAGNITUDE_CONFIDENCE_SCALE = confidenceScaleFromDelta(
-                SensorManager.STANDARD_GRAVITY * 0.5f);
-
-        // The number of milliseconds for which a new orientation must be stable before
-        // we perform an orientation change under ideal conditions.  It will take
-        // proportionally longer than this to effect an orientation change when
-        // the proposed orientation confidence is low.
-        private static final float ORIENTATION_SETTLE_TIME_MS = 250;
-
-        // The confidence that we have abount effecting each orientation change.
-        // When one of these values exceeds 1.0, we have determined our new orientation!
-        private float mConfidence[] = new float[4];
+        // The maximum change in orientation angle that can occur during the settle time.
+        private static final int SETTLE_ORIENTATION_ANGLE_MAX_DELTA = 5;
 
         public SensorEventListenerImpl(WindowOrientationListener orientationListener) {
             mOrientationListener = orientationListener;
         }
 
-        public int getCurrentRotation() {
-            return mRotation; // may be -1, if unknown
+        public int getProposedRotation() {
+            return mProposalAgeMS >= SETTLE_TIME_MS ? mProposalRotation : -1;
         }
 
         @Override
@@ -368,20 +367,18 @@
             // Reset the orientation listener state if the samples are too far apart in time
             // or when we see values of (0, 0, 0) which indicates that we polled the
             // accelerometer too soon after turning it on and we don't have any data yet.
-            final float timeDeltaMS = (event.timestamp - mLastTimestamp) * 0.000001f;
+            final long now = event.timestamp;
+            final float timeDeltaMS = (now - mLastTimestamp) * 0.000001f;
             boolean skipSample;
             if (timeDeltaMS <= 0 || timeDeltaMS > MAX_FILTER_DELTA_TIME_MS
                     || (x == 0 && y == 0 && z == 0)) {
                 if (log) {
                     Slog.v(TAG, "Resetting orientation listener.");
                 }
-                for (int i = 0; i < 4; i++) {
-                    mConfidence[i] = 0;
-                }
+                clearProposal();
                 skipSample = true;
             } else {
-                final float alpha = timeDeltaMS
-                        / (FILTER_TIME_CONSTANT_MS + timeDeltaMS) * FILTER_GAIN;
+                final float alpha = timeDeltaMS / (FILTER_TIME_CONSTANT_MS + timeDeltaMS);
                 x = alpha * (x - mLastFilteredX) + mLastFilteredX;
                 y = alpha * (y - mLastFilteredY) + mLastFilteredY;
                 z = alpha * (z - mLastFilteredZ) + mLastFilteredZ;
@@ -391,17 +388,13 @@
                 }
                 skipSample = false;
             }
-            mLastTimestamp = event.timestamp;
+            mLastTimestamp = now;
             mLastFilteredX = x;
             mLastFilteredY = y;
             mLastFilteredZ = z;
 
-            boolean orientationChanged = false;
+            final int oldProposedRotation = getProposedRotation();
             if (!skipSample) {
-                // Determine a proposed orientation based on the currently available data.
-                int proposedOrientation = ROTATION_UNKNOWN;
-                float combinedConfidence = 1.0f;
-
                 // Calculate the magnitude of the acceleration vector.
                 final float magnitude = (float) Math.sqrt(x * x + y * y + z * z);
                 if (magnitude < MIN_ACCELERATION_MAGNITUDE
@@ -410,6 +403,7 @@
                         Slog.v(TAG, "Ignoring sensor data, magnitude out of range: "
                                 + "magnitude=" + magnitude);
                     }
+                    clearProposal();
                 } else {
                     // Calculate the tilt angle.
                     // This is the angle between the up vector and the x-y plane (the plane of
@@ -417,123 +411,82 @@
                     //   -90 degrees: screen horizontal and facing the ground (overhead)
                     //     0 degrees: screen vertical
                     //    90 degrees: screen horizontal and facing the sky (on table)
-                   final int tiltAngle = (int) Math.round(
-                           Math.asin(z / magnitude) * RADIANS_TO_DEGREES);
+                    final int tiltAngle = (int) Math.round(
+                            Math.asin(z / magnitude) * RADIANS_TO_DEGREES);
 
-                   // If the tilt angle is too close to horizontal then we cannot determine
-                   // the orientation angle of the screen.
-                   if (Math.abs(tiltAngle) > MAX_TILT) {
-                       if (log) {
-                           Slog.v(TAG, "Ignoring sensor data, tilt angle too high: "
-                                   + "magnitude=" + magnitude + ", tiltAngle=" + tiltAngle);
-                       }
-                   } else {
-                       // Calculate the orientation angle.
-                       // This is the angle between the x-y projection of the up vector onto
-                       // the +y-axis, increasing clockwise in a range of [0, 360] degrees.
-                       int orientationAngle = (int) Math.round(
-                               -Math.atan2(-x, y) * RADIANS_TO_DEGREES);
-                       if (orientationAngle < 0) {
-                           // atan2 returns [-180, 180]; normalize to [0, 360]
-                           orientationAngle += 360;
-                       }
-
-                       // Find the nearest orientation.
-                       // An orientation of 0 can have a nearest angle of 0 or 360 depending
-                       // on which is closer to the measured orientation angle.  We leave the
-                       // nearest angle at 360 in that case since it makes the delta calculation
-                       // for orientation angle confidence easier below.
-                       int nearestOrientation = (orientationAngle + 45) / 90;
-                       int nearestOrientationAngle = nearestOrientation * 90;
-                       if (nearestOrientation == 4) {
-                           nearestOrientation = 0;
-                       }
-
-                       // Determine the proposed orientation.
-                       // The confidence of the proposal is 1.0 when it is ideal and it
-                       // decays exponentially as the proposal moves further from the ideal
-                       // angle, tilt and magnitude of the proposed orientation.
-                       if (isTiltAngleAcceptable(nearestOrientation, tiltAngle)
-                               && isOrientationAngleAcceptable(nearestOrientation,
-                                       orientationAngle)) {
-                           proposedOrientation = nearestOrientation;
-
-                           final float idealOrientationAngle = nearestOrientationAngle;
-                           final float orientationConfidence = confidence(orientationAngle,
-                                   idealOrientationAngle, ORIENTATION_ANGLE_CONFIDENCE_SCALE);
-
-                           final float idealTiltAngle = 0;
-                           final float tiltConfidence = confidence(tiltAngle,
-                                   idealTiltAngle, TILT_ANGLE_CONFIDENCE_SCALE);
-
-                           final float idealMagnitude = SensorManager.STANDARD_GRAVITY;
-                           final float magnitudeConfidence = confidence(magnitude,
-                                   idealMagnitude, MAGNITUDE_CONFIDENCE_SCALE);
-
-                           combinedConfidence = orientationConfidence
-                                   * tiltConfidence * magnitudeConfidence;
-
-                           if (log) {
-                               Slog.v(TAG, "Proposal: "
-                                       + "magnitude=" + magnitude
-                                       + ", tiltAngle=" + tiltAngle
-                                       + ", orientationAngle=" + orientationAngle
-                                       + ", proposedOrientation=" + proposedOrientation
-                                       + ", combinedConfidence=" + combinedConfidence
-                                       + ", orientationConfidence=" + orientationConfidence
-                                       + ", tiltConfidence=" + tiltConfidence
-                                       + ", magnitudeConfidence=" + magnitudeConfidence);
-                           }
-                       } else {
-                           if (log) {
-                               Slog.v(TAG, "Ignoring sensor data, no proposal: "
-                                       + "magnitude=" + magnitude + ", tiltAngle=" + tiltAngle
-                                       + ", orientationAngle=" + orientationAngle);
-                           }
-                       }
-                   }
-                }
-
-                // Sum up the orientation confidence weights.
-                // Detect an orientation change when the sum reaches 1.0.
-                final float confidenceAmount = combinedConfidence * timeDeltaMS
-                        / ORIENTATION_SETTLE_TIME_MS;
-                for (int i = 0; i < 4; i++) {
-                    if (i == proposedOrientation) {
-                        mConfidence[i] += confidenceAmount;
-                        if (mConfidence[i] >= 1.0f) {
-                            mConfidence[i] = 1.0f;
-
-                            if (i != mRotation) {
-                                if (log) {
-                                    Slog.v(TAG, "Orientation changed!  rotation=" + i);
-                                }
-                                mRotation = i;
-                                orientationChanged = true;
-                            }
+                    // If the tilt angle is too close to horizontal then we cannot determine
+                    // the orientation angle of the screen.
+                    if (Math.abs(tiltAngle) > MAX_TILT) {
+                        if (log) {
+                            Slog.v(TAG, "Ignoring sensor data, tilt angle too high: "
+                                    + "magnitude=" + magnitude + ", tiltAngle=" + tiltAngle);
                         }
+                        clearProposal();
                     } else {
-                        mConfidence[i] -= confidenceAmount;
-                        if (mConfidence[i] < 0.0f) {
-                            mConfidence[i] = 0.0f;
+                        // Calculate the orientation angle.
+                        // This is the angle between the x-y projection of the up vector onto
+                        // the +y-axis, increasing clockwise in a range of [0, 360] degrees.
+                        int orientationAngle = (int) Math.round(
+                                -Math.atan2(-x, y) * RADIANS_TO_DEGREES);
+                        if (orientationAngle < 0) {
+                            // atan2 returns [-180, 180]; normalize to [0, 360]
+                            orientationAngle += 360;
+                        }
+
+                        // Find the nearest rotation.
+                        int nearestRotation = (orientationAngle + 45) / 90;
+                        if (nearestRotation == 4) {
+                            nearestRotation = 0;
+                        }
+
+                        // Determine the proposed orientation.
+                        // The confidence of the proposal is 1.0 when it is ideal and it
+                        // decays exponentially as the proposal moves further from the ideal
+                        // angle, tilt and magnitude of the proposed orientation.
+                        if (!isTiltAngleAcceptable(nearestRotation, tiltAngle)
+                                || !isOrientationAngleAcceptable(nearestRotation,
+                                        orientationAngle)) {
+                            if (log) {
+                                Slog.v(TAG, "Ignoring sensor data, no proposal: "
+                                        + "magnitude=" + magnitude + ", tiltAngle=" + tiltAngle
+                                        + ", orientationAngle=" + orientationAngle);
+                            }
+                            clearProposal();
+                        } else {
+                            if (log) {
+                                Slog.v(TAG, "Proposal: "
+                                        + "magnitude=" + magnitude
+                                        + ", tiltAngle=" + tiltAngle
+                                        + ", orientationAngle=" + orientationAngle
+                                        + ", proposalRotation=" + mProposalRotation);
+                            }
+                            updateProposal(nearestRotation, now / 1000000L,
+                                    magnitude, tiltAngle, orientationAngle);
                         }
                     }
                 }
             }
 
             // Write final statistics about where we are in the orientation detection process.
+            final int proposedRotation = getProposedRotation();
             if (log) {
-                Slog.v(TAG, "Result: rotation=" + mRotation
-                        + ", confidence=["
-                        + mConfidence[0] + ", "
-                        + mConfidence[1] + ", "
-                        + mConfidence[2] + ", "
-                        + mConfidence[3] + "], timeDeltaMS=" + timeDeltaMS);
+                final float proposalConfidence = Math.min(
+                        mProposalAgeMS * 1.0f / SETTLE_TIME_MS, 1.0f);
+                Slog.v(TAG, "Result: currentRotation=" + mOrientationListener.mCurrentRotation
+                        + ", proposedRotation=" + proposedRotation
+                        + ", timeDeltaMS=" + timeDeltaMS
+                        + ", proposalRotation=" + mProposalRotation
+                        + ", proposalAgeMS=" + mProposalAgeMS
+                        + ", proposalConfidence=" + proposalConfidence);
             }
 
             // Tell the listener.
-            if (orientationChanged) {
-                mOrientationListener.onOrientationChanged(mRotation);
+            if (proposedRotation != oldProposedRotation && proposedRotation >= 0) {
+                if (log) {
+                    Slog.v(TAG, "Proposed rotation changed!  proposedRotation=" + proposedRotation
+                            + ", oldProposedRotation=" + oldProposedRotation);
+                }
+                mOrientationListener.onProposedRotationChanged(proposedRotation);
             }
         }
 
@@ -541,33 +494,34 @@
          * Returns true if the tilt angle is acceptable for a proposed
          * orientation transition.
          */
-        private boolean isTiltAngleAcceptable(int proposedOrientation,
+        private boolean isTiltAngleAcceptable(int proposedRotation,
                 int tiltAngle) {
-            return tiltAngle >= TILT_TOLERANCE[proposedOrientation][0]
-                    && tiltAngle <= TILT_TOLERANCE[proposedOrientation][1];
+            return tiltAngle >= TILT_TOLERANCE[proposedRotation][0]
+                    && tiltAngle <= TILT_TOLERANCE[proposedRotation][1];
         }
 
         /**
          * Returns true if the orientation angle is acceptable for a proposed
          * orientation transition.
+         *
          * This function takes into account the gap between adjacent orientations
          * for hysteresis.
          */
-        private boolean isOrientationAngleAcceptable(int proposedOrientation,
-                int orientationAngle) {
-            final int currentOrientation = mRotation;
-
+        private boolean isOrientationAngleAcceptable(int proposedRotation, int orientationAngle) {
             // If there is no current rotation, then there is no gap.
-            if (currentOrientation != ROTATION_UNKNOWN) {
-                // If the proposed orientation is the same or is counter-clockwise adjacent,
+            // The gap is used only to introduce hysteresis among advertised orientation
+            // changes to avoid flapping.
+            final int currentRotation = mOrientationListener.mCurrentRotation;
+            if (currentRotation >= 0) {
+                // If the proposed rotation is the same or is counter-clockwise adjacent,
                 // then we set a lower bound on the orientation angle.
-                // For example, if currentOrientation is ROTATION_0 and proposed is ROTATION_90,
+                // For example, if currentRotation is ROTATION_0 and proposed is ROTATION_90,
                 // then we want to check orientationAngle > 45 + GAP / 2.
-                if (proposedOrientation == currentOrientation
-                        || proposedOrientation == (currentOrientation + 1) % 4) {
-                    int lowerBound = proposedOrientation * 90 - 45
+                if (proposedRotation == currentRotation
+                        || proposedRotation == (currentRotation + 1) % 4) {
+                    int lowerBound = proposedRotation * 90 - 45
                             + ADJACENT_ORIENTATION_ANGLE_GAP / 2;
-                    if (proposedOrientation == 0) {
+                    if (proposedRotation == 0) {
                         if (orientationAngle >= 315 && orientationAngle < lowerBound + 360) {
                             return false;
                         }
@@ -578,15 +532,15 @@
                     }
                 }
 
-                // If the proposed orientation is the same or is clockwise adjacent,
+                // If the proposed rotation is the same or is clockwise adjacent,
                 // then we set an upper bound on the orientation angle.
-                // For example, if currentOrientation is ROTATION_0 and proposed is ROTATION_270,
+                // For example, if currentRotation is ROTATION_0 and proposed is ROTATION_270,
                 // then we want to check orientationAngle < 315 - GAP / 2.
-                if (proposedOrientation == currentOrientation
-                        || proposedOrientation == (currentOrientation + 3) % 4) {
-                    int upperBound = proposedOrientation * 90 + 45
+                if (proposedRotation == currentRotation
+                        || proposedRotation == (currentRotation + 3) % 4) {
+                    int upperBound = proposedRotation * 90 + 45
                             - ADJACENT_ORIENTATION_ANGLE_GAP / 2;
-                    if (proposedOrientation == 0) {
+                    if (proposedRotation == 0) {
                         if (orientationAngle <= 45 && orientationAngle > upperBound) {
                             return false;
                         }
@@ -600,21 +554,58 @@
             return true;
         }
 
-        /**
-         * Calculate an exponentially weighted confidence value in the range [0.0, 1.0].
-         * The further the value is from the target, the more the confidence trends to 0.
-         */
-        private static float confidence(float value, float target, float scale) {
-            return (float) Math.exp(-Math.abs(value - target) * scale);
+        private void clearProposal() {
+            mProposalRotation = -1;
+            mProposalAgeMS = 0;
         }
 
-        /**
-         * Calculate a scale factor for the confidence weight exponent.
-         * The scale value is chosen such that confidence(value, target, scale) == 0.5
-         * whenever abs(value - target) == cutoffDelta.
-         */
-        private static float confidenceScaleFromDelta(float cutoffDelta) {
-            return (float) -Math.log(0.5) / cutoffDelta;
+        private void updateProposal(int rotation, long timestampMS,
+                float magnitude, int tiltAngle, int orientationAngle) {
+            if (mProposalRotation != rotation) {
+                mProposalRotation = rotation;
+                mHistoryIndex = 0;
+                mHistoryLength = 0;
+            }
+
+            final int index = mHistoryIndex;
+            mHistoryTimestampMS[index] = timestampMS;
+            mHistoryMagnitudes[index] = magnitude;
+            mHistoryTiltAngles[index] = tiltAngle;
+            mHistoryOrientationAngles[index] = orientationAngle;
+            mHistoryIndex = (index + 1) % HISTORY_SIZE;
+            if (mHistoryLength < HISTORY_SIZE) {
+                mHistoryLength += 1;
+            }
+
+            long age = 0;
+            for (int i = 1; i < mHistoryLength; i++) {
+                final int olderIndex = (index + HISTORY_SIZE - i) % HISTORY_SIZE;
+                if (Math.abs(mHistoryMagnitudes[olderIndex] - magnitude)
+                        > SETTLE_MAGNITUDE_MAX_DELTA) {
+                    break;
+                }
+                if (angleAbsoluteDelta(mHistoryTiltAngles[olderIndex],
+                        tiltAngle) > SETTLE_TILT_ANGLE_MAX_DELTA) {
+                    break;
+                }
+                if (angleAbsoluteDelta(mHistoryOrientationAngles[olderIndex],
+                        orientationAngle) > SETTLE_ORIENTATION_ANGLE_MAX_DELTA) {
+                    break;
+                }
+                age = timestampMS - mHistoryTimestampMS[olderIndex];
+                if (age >= SETTLE_TIME_MS) {
+                    break;
+                }
+            }
+            mProposalAgeMS = age;
+        }
+
+        private static int angleAbsoluteDelta(int a, int b) {
+            int delta = Math.abs(a - b);
+            if (delta > 180) {
+                delta = 360 - delta;
+            }
+            return delta;
         }
     }
 }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index cb6922d..139f9f3 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1808,6 +1808,8 @@
     /**
      * Restore the display data that was save in {@link #savePicture}. Used in
      * conjunction with {@link #restoreState}.
+     *
+     * Note that this will not work if the WebView is hardware accelerated.
      * @param b A Bundle containing the saved display data.
      * @param src The file where the picture data was stored.
      * @return True if the picture was successfully restored.
@@ -4300,6 +4302,7 @@
             selectionDone();
         }
         mOrientation = newConfig.orientation;
+        contentInvalidateAll();
     }
 
     /**
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index ba89ef3..7b8c7f2 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1304,16 +1304,6 @@
         }
     }
 
-    @Override
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        // Do not append text content to scroll events they are fired frequently
-        // and the client has already received another event type with the text.
-        if (event.getEventType() != AccessibilityEvent.TYPE_VIEW_SCROLLED) {
-            super.dispatchPopulateAccessibilityEvent(event);
-        }
-        return false;
-    }
-
     /**
      * Indicates whether the children's drawing cache is used during a scroll.
      * By default, the drawing cache is enabled but this will consume more memory.
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 5392c2e..a4b4e78 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -881,31 +881,30 @@
 
     @Override
     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        // This is an exceptional case which occurs when a window gets the
-        // focus and sends a focus event via its focused child to announce
-        // current focus/selection. AdapterView fires selection but not focus
-        // events so we change the event type here.
-        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
-            event.setEventType(AccessibilityEvent.TYPE_VIEW_SELECTED);
+        final int eventType = event.getEventType();
+        switch (eventType) {
+            case AccessibilityEvent.TYPE_VIEW_SCROLLED:
+                // Do not populate the text of scroll events.
+                return true;
+            case AccessibilityEvent.TYPE_VIEW_FOCUSED:
+                // This is an exceptional case which occurs when a window gets the
+                // focus and sends a focus event via its focused child to announce
+                // current focus/selection. AdapterView fires selection but not focus
+                // events so we change the event type here.
+                if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
+                    event.setEventType(AccessibilityEvent.TYPE_VIEW_SELECTED);
+                }
+                break;
         }
 
         View selectedView = getSelectedView();
         if (selectedView != null && selectedView.getVisibility() == VISIBLE) {
-            // We first get a chance to populate the event.
-            onPopulateAccessibilityEvent(event);
+            getSelectedView().dispatchPopulateAccessibilityEvent(event);
         }
         return false;
     }
 
     @Override
-    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
-        super.onPopulateAccessibilityEvent(event);
-        // We send selection events only from AdapterView to avoid
-        // generation of such event for each child.
-        getSelectedView().dispatchPopulateAccessibilityEvent(event);
-    }
-
-    @Override
     public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
         if (super.onRequestSendAccessibilityEvent(child, event)) {
             // Add a record for ourselves as well.
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index f230031..adf2b7b 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -120,6 +120,7 @@
     private CharSequence mOldQueryText;
     private CharSequence mUserQuery;
     private boolean mExpandedInActionView;
+    private int mCollapsedImeOptions;
 
     private SearchableInfo mSearchable;
     private Bundle mAppSearchData;
@@ -1166,6 +1167,7 @@
         clearFocus();
         updateViewsVisibility(true);
         mQueryTextView.setText("");
+        mQueryTextView.setImeOptions(mCollapsedImeOptions);
         mExpandedInActionView = false;
     }
 
@@ -1175,6 +1177,8 @@
     @Override
     public void onActionViewExpanded() {
         mExpandedInActionView = true;
+        mCollapsedImeOptions = mQueryTextView.getImeOptions();
+        mQueryTextView.setImeOptions(mCollapsedImeOptions | EditorInfo.IME_FLAG_NO_FULLSCREEN);
         setIconified(false);
     }
 
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index 0db1ccc..aabea2c 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -200,8 +200,19 @@
             }
         }
 
-        final boolean hasOverflow = mReserveOverflow && mMenu != null &&
-                mMenu.getNonActionItems().size() > 0;
+        final ArrayList<MenuItemImpl> nonActionItems = mMenu != null ?
+                mMenu.getNonActionItems() : null;
+
+        boolean hasOverflow = false;
+        if (mReserveOverflow && nonActionItems != null) {
+            final int count = nonActionItems.size();
+            if (count == 1) {
+                hasOverflow = !nonActionItems.get(0).isActionViewExpanded();
+            } else {
+                hasOverflow = count > 0;
+            }
+        }
+
         if (hasOverflow) {
             if (mOverflowButton == null) {
                 mOverflowButton = new OverflowMenuButton(mContext);
diff --git a/core/java/com/android/internal/view/menu/ListMenuPresenter.java b/core/java/com/android/internal/view/menu/ListMenuPresenter.java
index 0141427..a331bec 100644
--- a/core/java/com/android/internal/view/menu/ListMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ListMenuPresenter.java
@@ -17,6 +17,7 @@
 package com.android.internal.view.menu;
 
 import android.content.Context;
+import android.database.DataSetObserver;
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.util.SparseArray;
@@ -47,7 +48,7 @@
     int mItemLayoutRes;
 
     private Callback mCallback;
-    private MenuAdapter mAdapter;
+    MenuAdapter mAdapter;
 
     private int mId;
 
@@ -216,14 +217,29 @@
     }
 
     private class MenuAdapter extends BaseAdapter {
+        private int mExpandedIndex = -1;
+
+        public MenuAdapter() {
+            registerDataSetObserver(new ExpandedIndexObserver());
+            findExpandedIndex();
+        }
+
         public int getCount() {
             ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
-            return items.size() - mItemIndexOffset;
+            int count = items.size() - mItemIndexOffset;
+            if (mExpandedIndex < 0) {
+                return count;
+            }
+            return count - 1;
         }
 
         public MenuItemImpl getItem(int position) {
             ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
-            return items.get(position + mItemIndexOffset);
+            position += mItemIndexOffset;
+            if (mExpandedIndex >= 0 && position >= mExpandedIndex) {
+                position++;
+            }
+            return items.get(position);
         }
 
         public long getItemId(int position) {
@@ -241,5 +257,28 @@
             itemView.initialize(getItem(position), 0);
             return convertView;
         }
+
+        void findExpandedIndex() {
+            final MenuItemImpl expandedItem = mMenu.getExpandedItem();
+            if (expandedItem != null) {
+                final ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
+                final int count = items.size();
+                for (int i = 0; i < count; i++) {
+                    final MenuItemImpl item = items.get(i);
+                    if (item == expandedItem) {
+                        mExpandedIndex = i;
+                        return;
+                    }
+                }
+            }
+            mExpandedIndex = -1;
+        }
+    }
+
+    private class ExpandedIndexObserver extends DataSetObserver {
+        @Override
+        public void onChanged() {
+            mAdapter.findExpandedIndex();
+        }
     }
 }
diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java
index c30e83b..9fbca82 100644
--- a/core/java/com/android/internal/view/menu/MenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/MenuBuilder.java
@@ -1258,4 +1258,8 @@
         }
         return collapsed;
     }
+
+    public MenuItemImpl getExpandedItem() {
+        return mExpandedItem;
+    }
 }
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 6265618..329b457 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.database.DataSetObserver;
 import android.os.Parcelable;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -286,22 +287,45 @@
         return false;
     }
 
+    @Override
+    public int getId() {
+        return 0;
+    }
+
+    @Override
+    public Parcelable onSaveInstanceState() {
+        return null;
+    }
+
+    @Override
+    public void onRestoreInstanceState(Parcelable state) {
+    }
+
     private class MenuAdapter extends BaseAdapter {
         private MenuBuilder mAdapterMenu;
+        private int mExpandedIndex = -1;
 
         public MenuAdapter(MenuBuilder menu) {
             mAdapterMenu = menu;
+            registerDataSetObserver(new ExpandedIndexObserver());
+            findExpandedIndex();
         }
 
         public int getCount() {
             ArrayList<MenuItemImpl> items = mOverflowOnly ?
                     mAdapterMenu.getNonActionItems() : mAdapterMenu.getVisibleItems();
-            return items.size();
+            if (mExpandedIndex < 0) {
+                return items.size();
+            }
+            return items.size() - 1;
         }
 
         public MenuItemImpl getItem(int position) {
             ArrayList<MenuItemImpl> items = mOverflowOnly ?
                     mAdapterMenu.getNonActionItems() : mAdapterMenu.getVisibleItems();
+            if (mExpandedIndex >= 0 && position >= mExpandedIndex) {
+                position++;
+            }
             return items.get(position);
         }
 
@@ -323,19 +347,28 @@
             itemView.initialize(getItem(position), 0);
             return convertView;
         }
+
+        void findExpandedIndex() {
+            final MenuItemImpl expandedItem = mMenu.getExpandedItem();
+            if (expandedItem != null) {
+                final ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
+                final int count = items.size();
+                for (int i = 0; i < count; i++) {
+                    final MenuItemImpl item = items.get(i);
+                    if (item == expandedItem) {
+                        mExpandedIndex = i;
+                        return;
+                    }
+                }
+            }
+            mExpandedIndex = -1;
+        }
     }
 
-    @Override
-    public int getId() {
-        return 0;
-    }
-
-    @Override
-    public Parcelable onSaveInstanceState() {
-        return null;
-    }
-
-    @Override
-    public void onRestoreInstanceState(Parcelable state) {
+    private class ExpandedIndexObserver extends DataSetObserver {
+        @Override
+        public void onChanged() {
+            mAdapter.findExpandedIndex();
+        }
     }
 }
diff --git a/core/java/com/android/internal/widget/AbsActionBarView.java b/core/java/com/android/internal/widget/AbsActionBarView.java
index 6c11288..06f5158 100644
--- a/core/java/com/android/internal/widget/AbsActionBarView.java
+++ b/core/java/com/android/internal/widget/AbsActionBarView.java
@@ -35,6 +35,8 @@
     protected ActionMenuView mMenuView;
     protected ActionMenuPresenter mActionMenuPresenter;
     protected ActionBarContainer mSplitView;
+    protected boolean mSplitActionBar;
+    protected boolean mSplitWhenNarrow;
     protected int mContentHeight;
 
     protected Animator mVisibilityAnim;
@@ -66,11 +68,31 @@
                 com.android.internal.R.attr.actionBarStyle, 0);
         setContentHeight(a.getLayoutDimension(R.styleable.ActionBar_height, 0));
         a.recycle();
+        if (mSplitWhenNarrow) {
+            setSplitActionBar(getContext().getResources().getBoolean(
+                    com.android.internal.R.bool.split_action_bar_is_narrow));
+        }
         if (mActionMenuPresenter != null) {
             mActionMenuPresenter.onConfigurationChanged(newConfig);
         }
     }
 
+    /**
+     * Sets whether the bar should be split right now, no questions asked.
+     * @param split true if the bar should split
+     */
+    public void setSplitActionBar(boolean split) {
+        mSplitActionBar = split;
+    }
+
+    /**
+     * Sets whether the bar should split if we enter a narrow screen configuration.
+     * @param splitWhenNarrow true if the bar should check to split after a config change
+     */
+    public void setSplitWhenNarrow(boolean splitWhenNarrow) {
+        mSplitWhenNarrow = splitWhenNarrow;
+    }
+
     public void setContentHeight(int height) {
         mContentHeight = height;
         requestLayout();
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index 7bc33c7..acffa5c 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -93,6 +93,39 @@
         a.recycle();
     }
 
+    @Override
+    public void setSplitActionBar(boolean split) {
+        if (mSplitActionBar != split) {
+            if (mActionMenuPresenter != null) {
+                // Mode is already active; move everything over and adjust the menu itself.
+                final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
+                        LayoutParams.MATCH_PARENT);
+                if (!split) {
+                    mMenuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
+                    mMenuView.setBackgroundDrawable(null);
+                    final ViewGroup oldParent = (ViewGroup) mMenuView.getParent();
+                    if (oldParent != null) oldParent.removeView(mMenuView);
+                    addView(mMenuView, layoutParams);
+                } else {
+                    // Allow full screen width in split mode.
+                    mActionMenuPresenter.setWidthLimit(
+                            getContext().getResources().getDisplayMetrics().widthPixels, true);
+                    // No limit to the item count; use whatever will fit.
+                    mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE);
+                    // Span the whole width
+                    layoutParams.width = LayoutParams.MATCH_PARENT;
+                    layoutParams.height = mContentHeight;
+                    mMenuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
+                    mMenuView.setBackgroundDrawable(mSplitBackground);
+                    final ViewGroup oldParent = (ViewGroup) mMenuView.getParent();
+                    if (oldParent != null) oldParent.removeView(mMenuView);
+                    mSplitView.addView(mMenuView, layoutParams);
+                }
+            }
+            super.setSplitActionBar(split);
+        }
+    }
+
     public void setContentHeight(int height) {
         mContentHeight = height;
     }
@@ -179,7 +212,7 @@
 
         final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
                 LayoutParams.MATCH_PARENT);
-        if (mSplitView == null) {
+        if (!mSplitActionBar) {
             menu.addMenuPresenter(mActionMenuPresenter);
             mMenuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
             mMenuView.setBackgroundDrawable(null);
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index bbecb6c..dc8feea 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -113,7 +113,6 @@
     private int mProgressStyle;
     private int mIndeterminateProgressStyle;
 
-    private boolean mSplitActionBar;
     private boolean mUserTitle;
     private boolean mIncludeTabs;
     private boolean mIsCollapsable;
@@ -301,6 +300,7 @@
         addView(mIndeterminateProgressView);
     }
 
+    @Override
     public void setSplitActionBar(boolean splitActionBar) {
         if (mSplitActionBar != splitActionBar) {
             if (mMenuView != null) {
@@ -316,7 +316,10 @@
                     addView(mMenuView);
                 }
             }
-            mSplitActionBar = splitActionBar;
+            if (mSplitView != null) {
+                mSplitView.setVisibility(splitActionBar ? VISIBLE : GONE);
+            }
+            super.setSplitActionBar(splitActionBar);
         }
     }
 
diff --git a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
index c03f91cc..ebd355a 100644
--- a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
@@ -114,6 +114,13 @@
         }
     };
 
+    private AnimatorListener mResetListenerWithPing = new AnimatorListenerAdapter() {
+        public void onAnimationEnd(Animator animator) {
+            ping();
+            switchToState(STATE_IDLE, mWaveCenterX, mWaveCenterY);
+        }
+    };
+
     private AnimatorUpdateListener mUpdateListener = new AnimatorUpdateListener() {
         public void onAnimationUpdate(ValueAnimator animation) {
             invalidateGlobalRegion(mHandleDrawable);
@@ -421,7 +428,7 @@
                     "x", mWaveCenterX,
                     "y", mWaveCenterY,
                     "onUpdate", mUpdateListener,
-                    "onComplete", mResetListener);
+                    "onComplete", mDragging ? mResetListenerWithPing : mResetListener);
         }
 
         setGrabbedState(OnTriggerListener.NO_HANDLE);
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 9313d0a..02c5bb3 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -758,21 +758,7 @@
             jfloat x, jfloat y, int flags, SkPaint* paint) {
 
         jint count = end - start;
-        sp<TextLayoutCacheValue> value;
-#if USE_TEXT_LAYOUT_CACHE
-        value = TextLayoutCache::getInstance().getValue(paint, textArray, start, count,
-                        end, flags);
-        if (value == NULL) {
-            LOGE("Cannot get TextLayoutCache value");
-            return ;
-        }
-#else
-        value = new TextLayoutCacheValue();
-        value->computeValues(paint, textArray, start, count, end, flags);
-#endif
-
-        doDrawGlyphs(canvas, value->getGlyphs(), 0, value->getGlyphsCount(),
-            x, y, flags, paint);
+        drawTextWithGlyphs(canvas, textArray + start, 0, count, count, x, y, flags, paint);
     }
 
     static void drawTextWithGlyphs(SkCanvas* canvas, const jchar* textArray,
@@ -781,19 +767,20 @@
 
         sp<TextLayoutCacheValue> value;
 #if USE_TEXT_LAYOUT_CACHE
-        value = TextLayoutCache::getInstance().getValue(paint, textArray, start, count,
-                        contextCount, flags);
+        value = TextLayoutCache::getInstance().getValue(paint, textArray, contextCount, flags);
         if (value == NULL) {
             LOGE("Cannot get TextLayoutCache value");
             return ;
         }
 #else
         value = new TextLayoutCacheValue();
-        value->computeValues(paint, textArray, start, count, contextCount, flags);
+        value->computeValues(paint, textArray, contextCount, flags);
 #endif
-
-        doDrawGlyphs(canvas, value->getGlyphs(), 0, value->getGlyphsCount(),
-                x, y, flags, paint);
+        size_t startIndex = 0;
+        size_t glyphsCount = 0;
+        value->getGlyphsIndexAndCount(start, count, &startIndex, &glyphsCount);
+        const jchar* glyphs = value->getGlyphs(startIndex, glyphsCount);
+        doDrawGlyphs(canvas, glyphs, 0, glyphsCount, x, y, flags, paint);
     }
 
     static void doDrawGlyphs(SkCanvas* canvas, const jchar* glyphArray, int index, int count,
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 7d222f6..3daf7d0 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -352,7 +352,7 @@
         jfloat result = 0;
 #if RTL_USE_HARFBUZZ
         TextLayout::getTextRunAdvances(paint, textArray, index, count, textLength,
-                paint->getFlags(), NULL /* dont need all advances */, result);
+                paint->getFlags(), NULL /* dont need all advances */, &result);
 #else
         // we double count, since measureText wants a byteLength
         SkScalar width = paint->measureText(textArray + index, count << 1);
@@ -382,7 +382,7 @@
 
 #if RTL_USE_HARFBUZZ
         TextLayout::getTextRunAdvances(paint, textArray, start, count, textLength,
-                paint->getFlags(), NULL /* dont need all advances */, width);
+                paint->getFlags(), NULL /* dont need all advances */, &width);
 #else
 
         width = SkScalarToFloat(paint->measureText(textArray + start, count << 1));
@@ -406,7 +406,7 @@
 
 #if RTL_USE_HARFBUZZ
         TextLayout::getTextRunAdvances(paint, textArray, 0, textLength, textLength,
-                paint->getFlags(), NULL /* dont need all advances */, width);
+                paint->getFlags(), NULL /* dont need all advances */, &width);
 #else
         width = SkScalarToFloat(paint->measureText(textArray, textLength << 1));
 #endif
@@ -435,10 +435,8 @@
         jfloat* widthsArray = autoWidths.ptr();
 
 #if RTL_USE_HARFBUZZ
-        jfloat totalAdvance;
-
         TextLayout::getTextRunAdvances(paint, text, 0, count, count,
-                paint->getFlags(), widthsArray, totalAdvance);
+                paint->getFlags(), widthsArray, NULL /* dont need totalAdvance */);
 #else
         SkScalar* scalarArray = (SkScalar*)widthsArray;
 
@@ -533,7 +531,7 @@
         jfloat totalAdvance = 0;
 
         TextLayout::getTextRunAdvances(paint, text, start, count, contextCount, flags,
-                                       advancesArray, totalAdvance);
+                                       advancesArray, &totalAdvance);
 
         if (advances != NULL) {
             env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray);
@@ -604,10 +602,9 @@
             jint count, jint flags, jint offset, jint opt) {
 #if RTL_USE_HARFBUZZ
         jfloat scalarArray[count];
-        jfloat totalAdvance = 0;
 
         TextLayout::getTextRunAdvances(paint, text, start, count, count, flags,
-                scalarArray, totalAdvance);
+                scalarArray, NULL /* dont need totalAdvance */);
 #else
         SkScalar scalarArray[count];
         jchar buffer[count];
diff --git a/core/jni/android/graphics/TextLayout.cpp b/core/jni/android/graphics/TextLayout.cpp
index a2d6efb..ae17aed 100644
--- a/core/jni/android/graphics/TextLayout.cpp
+++ b/core/jni/android/graphics/TextLayout.cpp
@@ -253,21 +253,22 @@
 
 void TextLayout::getTextRunAdvances(SkPaint* paint, const jchar* chars, jint start,
                                     jint count, jint contextCount, jint dirFlags,
-                                    jfloat* resultAdvances, jfloat& resultTotalAdvance) {
+                                    jfloat* resultAdvances, jfloat* resultTotalAdvance) {
     sp<TextLayoutCacheValue> value;
 #if USE_TEXT_LAYOUT_CACHE
     // Return advances from the cache. Compute them if needed
-    value = TextLayoutCache::getInstance().getValue(
-            paint, chars, start, count, contextCount, dirFlags);
+    value = TextLayoutCache::getInstance().getValue(paint, chars, contextCount, dirFlags);
 #else
     value = new TextLayoutCacheValue();
-    value->computeValues(paint, chars, start, count, contextCount, dirFlags);
+    value->computeValues(paint, chars, contextCount, dirFlags);
 #endif
     if (value != NULL) {
         if (resultAdvances != NULL) {
-            memcpy(resultAdvances, value->getAdvances(), value->getAdvancesCount() * sizeof(jfloat));
+            value->getAdvances(start, count, resultAdvances);
         }
-        resultTotalAdvance = value->getTotalAdvance();
+        if (resultTotalAdvance) {
+            *resultTotalAdvance = value->getTotalAdvance(start, count);
+        }
     }
 }
 
diff --git a/core/jni/android/graphics/TextLayout.h b/core/jni/android/graphics/TextLayout.h
index 9d8913c..9df3829 100644
--- a/core/jni/android/graphics/TextLayout.h
+++ b/core/jni/android/graphics/TextLayout.h
@@ -71,7 +71,7 @@
 
     static void getTextRunAdvances(SkPaint* paint, const jchar* chars, jint start,
                                    jint count, jint contextCount, jint dirFlags,
-                                   jfloat* resultAdvances, jfloat& resultTotalAdvance);
+                                   jfloat* resultAdvances, jfloat* resultTotalAdvance);
 
     static void getTextRunAdvancesICU(SkPaint* paint, const jchar* chars, jint start,
                                    jint count, jint contextCount, jint dirFlags,
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index e4eeec8..c045c07 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -106,7 +106,7 @@
  * Caching
  */
 sp<TextLayoutCacheValue> TextLayoutCache::getValue(SkPaint* paint,
-            const jchar* text, jint start, jint count, jint contextCount, jint dirFlags) {
+            const jchar* text, jint count, jint dirFlags) {
     AutoMutex _l(mLock);
     nsecs_t startTime = 0;
     if (mDebugEnabled) {
@@ -114,7 +114,7 @@
     }
 
     // Create the key
-    TextLayoutCacheKey key(paint, text, start, count, contextCount, dirFlags);
+    TextLayoutCacheKey key(paint, text, count, dirFlags);
 
     // Get value from cache if possible
     sp<TextLayoutCacheValue> value = mCache.get(key);
@@ -128,7 +128,7 @@
         value = new TextLayoutCacheValue();
 
         // Compute advances and store them
-        value->computeValues(paint, text, start, count, contextCount, dirFlags);
+        value->computeValues(paint, text, count, dirFlags);
 
         nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
@@ -157,20 +157,20 @@
                 // Update timing information for statistics
                 value->setElapsedTime(endTime - startTime);
 
-                LOGD("CACHE MISS: Added entry with start=%d, count=%d, "
-                        "contextCount=%d, entry size %d bytes, remaining space %d bytes"
+                LOGD("CACHE MISS: Added entry with "
+                        "count=%d, entry size %d bytes, remaining space %d bytes"
                         " - Compute time in nanos: %d - Text='%s' ",
-                        start, count, contextCount, size, mMaxSize - mSize, value->getElapsedTime(),
-                        String8(text, contextCount).string());
+                        count, size, mMaxSize - mSize, value->getElapsedTime(),
+                        String8(text, count).string());
             }
         } else {
             if (mDebugEnabled) {
                 LOGD("CACHE MISS: Calculated but not storing entry because it is too big "
-                        "with start=%d, count=%d, contextCount=%d, "
+                        "with count=%d, "
                         "entry size %d bytes, remaining space %d bytes"
                         " - Compute time in nanos: %lld - Text='%s'",
-                        start, count, contextCount, size, mMaxSize - mSize, endTime,
-                        String8(text, contextCount).string());
+                        count, size, mMaxSize - mSize, endTime,
+                        String8(text, count).string());
             }
             value.clear();
         }
@@ -184,12 +184,12 @@
             if (value->getElapsedTime() > 0) {
                 float deltaPercent = 100 * ((value->getElapsedTime() - elapsedTimeThruCacheGet)
                         / ((float)value->getElapsedTime()));
-                LOGD("CACHE HIT #%d with start=%d, count=%d, contextCount=%d "
+                LOGD("CACHE HIT #%d with count=%d "
                         "- Compute time in nanos: %d - "
                         "Cache get time in nanos: %lld - Gain in percent: %2.2f - Text='%s' ",
-                        mCacheHitCount, start, count, contextCount,
+                        mCacheHitCount, count,
                         value->getElapsedTime(), elapsedTimeThruCacheGet, deltaPercent,
-                        String8(text, contextCount).string());
+                        String8(text, count).string());
             }
             if (mCacheHitCount % DEFAULT_DUMP_STATS_CACHE_HIT_INTERVAL == 0) {
                 dumpCacheStats();
@@ -218,15 +218,14 @@
 /**
  * TextLayoutCacheKey
  */
-TextLayoutCacheKey::TextLayoutCacheKey(): text(NULL), start(0), count(0), contextCount(0),
+TextLayoutCacheKey::TextLayoutCacheKey(): text(NULL), count(0),
         dirFlags(0), typeface(NULL), textSize(0), textSkewX(0), textScaleX(0), flags(0),
         hinting(SkPaint::kNo_Hinting)  {
 }
 
 TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint,
-        const UChar* text, size_t start, size_t count,
-        size_t contextCount, int dirFlags) :
-            text(text), start(start), count(count), contextCount(contextCount),
+        const UChar* text, size_t count, int dirFlags) :
+            text(text), count(count),
             dirFlags(dirFlags) {
     typeface = paint->getTypeface();
     textSize = paint->getTextSize();
@@ -239,9 +238,7 @@
 TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) :
         text(NULL),
         textCopy(other.textCopy),
-        start(other.start),
         count(other.count),
-        contextCount(other.contextCount),
         dirFlags(other.dirFlags),
         typeface(other.typeface),
         textSize(other.textSize),
@@ -256,18 +253,15 @@
 
 bool TextLayoutCacheKey::operator<(const TextLayoutCacheKey& rhs) const {
     LTE_INT(count) {
-        LTE_INT(contextCount) {
-            LTE_INT(start) {
-                LTE_INT(typeface) {
-                    LTE_FLOAT(textSize) {
-                        LTE_FLOAT(textSkewX) {
-                            LTE_FLOAT(textScaleX) {
-                                LTE_INT(flags) {
-                                    LTE_INT(hinting) {
-                                        LTE_INT(dirFlags) {
-                                            return strncmp16(getText(), rhs.getText(), contextCount) < 0;
-                                        }
-                                    }
+        LTE_INT(typeface) {
+            LTE_FLOAT(textSize) {
+                LTE_FLOAT(textSkewX) {
+                    LTE_FLOAT(textScaleX) {
+                        LTE_INT(flags) {
+                            LTE_INT(hinting) {
+                                LTE_INT(dirFlags) {
+                                    return memcmp(getText(), rhs.getText(),
+                                            count * sizeof(UChar)) < 0;
                                 }
                             }
                         }
@@ -280,12 +274,12 @@
 }
 
 void TextLayoutCacheKey::internalTextCopy() {
-    textCopy.setTo(text, contextCount);
+    textCopy.setTo(text, count);
     text = NULL;
 }
 
 size_t TextLayoutCacheKey::getSize() {
-    return sizeof(TextLayoutCacheKey) + sizeof(UChar) * contextCount;
+    return sizeof(TextLayoutCacheKey) + sizeof(UChar) * count;
 }
 
 /**
@@ -303,23 +297,23 @@
     return mElapsedTime;
 }
 
-void TextLayoutCacheValue::computeValues(SkPaint* paint, const UChar* chars, size_t start,
-        size_t count, size_t contextCount, int dirFlags) {
-    // Give a hint for advances and glyphs vectors size
-    mAdvances.setCapacity(count);
-    mGlyphs.setCapacity(count);
-    computeValuesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags,
-            &mAdvances, &mTotalAdvance, &mGlyphs);
+void TextLayoutCacheValue::computeValues(SkPaint* paint, const UChar* chars,
+        size_t contextCount, int dirFlags) {
+    // Give a hint for advances, glyphs and log clusters vectors size
+    mAdvances.setCapacity(contextCount);
+    mGlyphs.setCapacity(contextCount);
+    mLogClusters.setCapacity(contextCount);
+
+    computeValuesWithHarfbuzz(paint, chars, contextCount, dirFlags,
+            &mAdvances, &mTotalAdvance, &mGlyphs, &mLogClusters);
 #if DEBUG_ADVANCES
-    LOGD("Advances - count=%d - countextCount=%d - totalAdvance=%f - "
-            "adv[0]=%f adv[1]=%f adv[2]=%f adv[3]=%f", count, contextCount, mTotalAdvance,
-            mAdvances[0], mAdvances[1], mAdvances[2], mAdvances[3]);
+    LOGD("Advances - countextCount=%d - totalAdvance=%f", contextCount, mTotalAdvance);
 #endif
 }
 
 size_t TextLayoutCacheValue::getSize() {
     return sizeof(TextLayoutCacheValue) + sizeof(jfloat) * mAdvances.capacity() +
-            sizeof(jchar) * mGlyphs.capacity();
+            sizeof(jchar) * mGlyphs.capacity() + sizeof(unsigned short) * mLogClusters.capacity();
 }
 
 void TextLayoutCacheValue::setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font,
@@ -391,9 +385,9 @@
 }
 
 void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
-        size_t start, size_t count, size_t contextCount, int dirFlags,
+        size_t contextCount, int dirFlags,
         Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
-        Vector<jchar>* const outGlyphs) {
+        Vector<jchar>* const outGlyphs, Vector<unsigned short>* const outLogClusters) {
 
         UBiDiLevel bidiReq = 0;
         bool forceLTR = false;
@@ -413,8 +407,8 @@
                     LOGD("computeValuesWithHarfbuzz -- forcing run with LTR=%d RTL=%d",
                             forceLTR, forceRTL);
 #endif
-            computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount, forceRTL,
-                    outAdvances, outTotalAdvance, outGlyphs);
+            computeRunValuesWithHarfbuzz(paint, chars, 0, contextCount, contextCount, forceRTL,
+                    outAdvances, outTotalAdvance, outGlyphs, outLogClusters);
         } else {
             UBiDi* bidi = ubidi_open();
             if (bidi) {
@@ -433,35 +427,16 @@
                         bool isRTL = (paraDir == 1);
 #if DEBUG_GLYPHS
                         LOGD("computeValuesWithHarfbuzz -- processing SINGLE run "
-                                "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
+                                "-- run-start=%d run-len=%d isRTL=%d", 0, contextCount, isRTL);
 #endif
-                        computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount,
-                                isRTL, outAdvances, outTotalAdvance, outGlyphs);
+                        computeRunValuesWithHarfbuzz(paint, chars, 0, contextCount, contextCount,
+                                isRTL, outAdvances, outTotalAdvance, outGlyphs, outLogClusters);
                     } else {
-                        int32_t end = start + count;
                         for (size_t i = 0; i < rc; ++i) {
                             int32_t startRun;
                             int32_t lengthRun;
                             UBiDiDirection runDir = ubidi_getVisualRun(bidi, i, &startRun, &lengthRun);
 
-                            if (startRun >= end) {
-                              break;
-                            }
-
-                            int32_t endRun = startRun + lengthRun;
-                            if (endRun <= start) {
-                              continue;
-                            }
-
-                            if (startRun < start) {
-                              startRun = start;
-                            }
-                            if (endRun > end) {
-                              endRun = end;
-                            }
-
-                            lengthRun = endRun - startRun;
-
                             bool isRTL = (runDir == UBIDI_RTL);
                             jfloat runTotalAdvance = 0;
 #if DEBUG_GLYPHS
@@ -471,7 +446,7 @@
                             computeRunValuesWithHarfbuzz(paint, chars, startRun,
                                     lengthRun, contextCount, isRTL,
                                     outAdvances, &runTotalAdvance,
-                                    outGlyphs);
+                                    outGlyphs, outLogClusters);
 
                             *outTotalAdvance += runTotalAdvance;
                         }
@@ -483,10 +458,10 @@
                 bool isRTL = (bidiReq = 1) || (bidiReq = UBIDI_DEFAULT_RTL);
 #if DEBUG_GLYPHS
                 LOGD("computeValuesWithHarfbuzz -- cannot run BiDi, considering a SINGLE Run "
-                        "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
+                        "-- run-start=%d run-len=%d isRTL=%d", 0, contextCount, isRTL);
 #endif
-                computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount, isRTL,
-                        outAdvances, outTotalAdvance, outGlyphs);
+                computeRunValuesWithHarfbuzz(paint, chars, 0, contextCount, contextCount, isRTL,
+                        outAdvances, outTotalAdvance, outGlyphs, outLogClusters);
             }
         }
 #if DEBUG_GLYPHS
@@ -506,7 +481,7 @@
 void TextLayoutCacheValue::computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
         size_t start, size_t count, size_t contextCount, bool isRTL,
         Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
-        Vector<jchar>* const outGlyphs) {
+        Vector<jchar>* const outGlyphs, Vector<unsigned short>* const outLogClusters) {
 
     HB_ShaperItem shaperItem;
     HB_FontRec font;
@@ -557,15 +532,15 @@
 #if DEBUG_ADVANCES
     for (size_t i = 0; i < count; i++) {
         LOGD("hb-adv[%d] = %f - log_clusters = %d - total = %f", i,
-                outAdvances[i], shaperItem.log_clusters[i], totalAdvance);
+                (*outAdvances)[i], shaperItem.log_clusters[i], totalAdvance);
     }
 #endif
 
     // Get Glyphs and reverse them in place if RTL
     if (outGlyphs) {
-        size_t count = shaperItem.num_glyphs;
-        for (size_t i = 0; i < count; i++) {
-            jchar glyph = (jchar) shaperItem.glyphs[(!isRTL) ? i : count - 1 - i];
+        size_t countGlyphs = shaperItem.num_glyphs;
+        for (size_t i = 0; i < countGlyphs; i++) {
+            jchar glyph = (jchar) shaperItem.glyphs[(!isRTL) ? i : countGlyphs - 1 - i];
 #if DEBUG_GLYPHS
             LOGD("HARFBUZZ  -- glyph[%d]=%d", i, glyph);
 #endif
@@ -573,6 +548,20 @@
         }
     }
 
+    // Get LogClusters
+    if (outLogClusters) {
+        size_t countLogClusters = outLogClusters->size();
+        size_t countGlyphs = shaperItem.num_glyphs;
+        for (size_t i = 0; i < countGlyphs; i++) {
+            // As there may be successive runs, we need to shift the log clusters
+            unsigned short logCluster = shaperItem.log_clusters[i] + countLogClusters;
+#if DEBUG_GLYPHS
+            LOGD("HARFBUZZ  -- logCluster[%d] relative=%d - absolute=%d", i, shaperItem.log_clusters[i], logCluster);
+#endif
+            outLogClusters->add(logCluster);
+        }
+    }
+
     // Cleaning
     deleteGlyphArrays(&shaperItem);
     HB_FreeFace(shaperItem.face);
@@ -603,5 +592,67 @@
     memset(shaperItem->offsets, 0, size * sizeof(shaperItem->offsets[0]));
 }
 
+void TextLayoutCacheValue::getAdvances(size_t start, size_t count, jfloat* outAdvances) const {
+    memcpy(outAdvances, mAdvances.array() + start, count * sizeof(jfloat));
+#if DEBUG_ADVANCES
+    LOGD("getAdvances - start=%d count=%d", start, count);
+    for (size_t i = 0; i < count; i++) {
+        LOGD("  adv[%d] = %f", i, outAdvances[i]);
+    }
+#endif
+}
+
+jfloat TextLayoutCacheValue::getTotalAdvance(size_t start, size_t count) const {
+    jfloat outTotalAdvance = 0;
+    for (size_t i = start; i < start + count; i++) {
+        outTotalAdvance += mAdvances[i];
+    }
+#if DEBUG_ADVANCES
+    LOGD("getTotalAdvance - start=%d count=%d - total=%f", start, count, outTotalAdvance);
+#endif
+     return outTotalAdvance;
+}
+
+void TextLayoutCacheValue::getGlyphsIndexAndCount(size_t start, size_t count, size_t* outStartIndex,
+        size_t* outGlyphsCount) const {
+    *outStartIndex = 0;
+    if (count == 0) {
+        *outGlyphsCount = 0;
+        return;
+    }
+    size_t endIndex = 0;
+    for(size_t i = 0; i < mGlyphs.size(); i++) {
+        if (mLogClusters[i] <= start) {
+            *outStartIndex = i;
+            endIndex = i;
+            continue;
+        }
+        if (mLogClusters[i] <= start + count) {
+            endIndex = i;
+        }
+    }
+    *outGlyphsCount = endIndex - *outStartIndex + 1;
+#if DEBUG_GLYPHS
+    LOGD("getGlyphsIndexes - start=%d count=%d - startIndex=%d count=%d", start, count,
+            *outStartIndex, *outGlyphsCount);
+    for(size_t i = 0; i < mGlyphs.size(); i++) {
+        LOGD("getGlyphs - all - glyph[%d] = %d", i, mGlyphs[i]);
+    }
+    for(size_t i = 0; i < mGlyphs.size(); i++) {
+        LOGD("getGlyphs - all - logcl[%d] = %d", i, mLogClusters[i]);
+    }
+#endif
+}
+
+const jchar* TextLayoutCacheValue::getGlyphs(size_t startIndex, size_t count) {
+    const jchar* glyphs = mGlyphs.array() + startIndex;
+#if DEBUG_GLYPHS
+    LOGD("getGlyphs - with startIndex = %d  count = %d", startIndex, count);
+    for (size_t i = 0; i < count; i++) {
+        LOGD("getGlyphs - result - glyph[%d] = %d", i, glyphs[i]);
+    }
+#endif
+    return glyphs;
+}
 
 } // namespace android
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 1f08bda..35dd6fd 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -68,9 +68,7 @@
 public:
     TextLayoutCacheKey();
 
-    TextLayoutCacheKey(const SkPaint* paint,
-            const UChar* text, size_t start, size_t count,
-            size_t contextCount, int dirFlags);
+    TextLayoutCacheKey(const SkPaint* paint, const UChar* text, size_t count, int dirFlags);
 
     TextLayoutCacheKey(const TextLayoutCacheKey& other);
 
@@ -90,9 +88,7 @@
 private:
     const UChar* text; // if text is NULL, use textCopy
     String16 textCopy;
-    size_t start;
     size_t count;
-    size_t contextCount;
     int dirFlags;
     SkTypeface* typeface;
     SkScalar textSize;
@@ -116,14 +112,13 @@
     void setElapsedTime(uint32_t time);
     uint32_t getElapsedTime();
 
-    void computeValues(SkPaint* paint, const UChar* chars, size_t start, size_t count,
-            size_t contextCount, int dirFlags);
+    void computeValues(SkPaint* paint, const UChar* chars, size_t contextCount, int dirFlags);
 
-    inline const jfloat* getAdvances() const { return mAdvances.array(); }
-    inline size_t getAdvancesCount() const { return mAdvances.size(); }
-    inline jfloat getTotalAdvance() const { return mTotalAdvance; }
-    inline const jchar* getGlyphs() const { return mGlyphs.array(); }
-    inline size_t getGlyphsCount() const { return mGlyphs.size(); }
+    void    getAdvances(size_t start, size_t count, jfloat* outAdvances) const;
+    jfloat  getTotalAdvance(size_t start, size_t count) const;
+    void    getGlyphsIndexAndCount(size_t start, size_t count, size_t* outStartIndex,
+                size_t* outGlyphsCount) const;
+    const jchar*  getGlyphs(size_t startIndex, size_t count);
 
     /**
      * Get the size of the Cache entry
@@ -138,14 +133,10 @@
             SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount,
             bool isRTL);
 
-    static void computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start,
-            size_t count, size_t contextCount, int dirFlags,
+    static void computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
+            size_t contextCount, int dirFlags,
             Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
-            Vector<jchar>* const outGlyphs);
-
-    static void computeAdvancesWithICU(SkPaint* paint, const UChar* chars, size_t start,
-            size_t count, size_t contextCount, int dirFlags,
-            jfloat* outAdvances, jfloat* outTotalAdvance);
+            Vector<jchar>* const outGlyphs, Vector<unsigned short>* const outLogClusters);
 
 private:
     /**
@@ -164,6 +155,11 @@
     Vector<jchar> mGlyphs;
 
     /**
+     * Harfbuzz Log Clusters
+     */
+    Vector<unsigned short> mLogClusters;
+
+    /**
      * Time for computing the values (in milliseconds)
      */
     uint32_t mElapsedTime;
@@ -175,7 +171,7 @@
     static void computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start,
             size_t count, size_t contextCount, bool isRTL,
             Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
-            Vector<jchar>* const outGlyphs);
+            Vector<jchar>* const outGlyphs, Vector<unsigned short>* const outLogClusters);
 }; // TextLayoutCacheValue
 
 /**
@@ -199,8 +195,8 @@
      */
     void operator()(TextLayoutCacheKey& text, sp<TextLayoutCacheValue>& desc);
 
-    sp<TextLayoutCacheValue> getValue(SkPaint* paint,
-            const jchar* text, jint start, jint count, jint contextCount, jint dirFlags);
+    sp<TextLayoutCacheValue> getValue(SkPaint* paint, const jchar* text, jint count,
+            jint dirFlags);
 
     /**
      * Clear the cache
diff --git a/core/jni/android_app_backup_FullBackup.cpp b/core/jni/android_app_backup_FullBackup.cpp
index b36fa3e..6ef62a9 100644
--- a/core/jni/android_app_backup_FullBackup.cpp
+++ b/core/jni/android_app_backup_FullBackup.cpp
@@ -76,10 +76,10 @@
     int ret;
 
     // Extract the various strings, allowing for null object pointers
-    const char* packagenamechars = env->GetStringUTFChars(packageNameObj, NULL);
-    const char* rootchars = env->GetStringUTFChars(rootpathObj, NULL);
-    const char* pathchars = env->GetStringUTFChars(pathObj, NULL);
-    const char* domainchars = env->GetStringUTFChars(domainObj, NULL);
+    const char* packagenamechars = (packageNameObj) ? env->GetStringUTFChars(packageNameObj, NULL) : NULL;
+    const char* rootchars = (rootpathObj) ? env->GetStringUTFChars(rootpathObj, NULL) : NULL;
+    const char* pathchars = (pathObj) ? env->GetStringUTFChars(pathObj, NULL) : NULL;
+    const char* domainchars = (domainObj) ? env->GetStringUTFChars(domainObj, NULL) : NULL;
 
     String8 packageName(packagenamechars ? packagenamechars : "");
     String8 rootpath(rootchars ? rootchars : "");
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 395e417..e542a47 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -477,19 +477,21 @@
 #if RTL_USE_HARFBUZZ
     sp<TextLayoutCacheValue> value;
 #if USE_TEXT_LAYOUT_CACHE
-    value = TextLayoutCache::getInstance().getValue(paint, text, 0, count, count, flags);
+    value = TextLayoutCache::getInstance().getValue(paint, text, count, flags);
     if (value == NULL) {
         LOGE("Cannot get TextLayoutCache value");
         return ;
     }
 #else
     value = new TextLayoutCacheValue();
-    value->computeValues(paint, text, 0, count, count, flags);
+    value->computeValues(paint, text, count, flags);
 #endif
-    const jchar* glyphArray = value->getGlyphs();
-    int glyphCount = value->getGlyphsCount();
-    int bytesCount = glyphCount * sizeof(jchar);
-    renderer->drawText((const char*) glyphArray, bytesCount, glyphCount, x, y, paint);
+    size_t startIndex = 0;
+    size_t glyphsCount = 0;
+    value->getGlyphsIndexAndCount(0, count, &startIndex, &glyphsCount);
+    const jchar* glyphs = value->getGlyphs(startIndex, glyphsCount);
+    int bytesCount = glyphsCount * sizeof(jchar);
+    renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint);
 #else
     const jchar *workText;
     jchar* buffer = NULL;
@@ -507,19 +509,21 @@
 #if RTL_USE_HARFBUZZ
     sp<TextLayoutCacheValue> value;
 #if USE_TEXT_LAYOUT_CACHE
-    value = TextLayoutCache::getInstance().getValue(paint, text, start, count, contextCount, flags);
+    value = TextLayoutCache::getInstance().getValue(paint, text, contextCount, flags);
     if (value == NULL) {
         LOGE("Cannot get TextLayoutCache value");
         return ;
     }
 #else
     value = new TextLayoutCacheValue();
-    value->computeValues(paint, text, start, count, contextCount, flags);
+    value->computeValues(paint, text, contextCount, flags);
 #endif
-    const jchar* glyphArray = value->getGlyphs();
-    int glyphCount = value->getGlyphsCount();
-    int bytesCount = glyphCount * sizeof(jchar);
-    renderer->drawText((const char*) glyphArray, bytesCount, glyphCount, x, y, paint);
+    size_t startIndex = 0;
+    size_t glyphsCount = 0;
+    value->getGlyphsIndexAndCount(start, count, &startIndex, &glyphsCount);
+    const jchar* glyphs = value->getGlyphs(startIndex, glyphsCount);
+    int bytesCount = glyphsCount * sizeof(jchar);
+    renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint);
 #else
     uint8_t rtl = flags & 0x1;
     if (rtl) {
diff --git a/core/res/res/values-mcc204/strings.xml b/core/res/res/values-mcc204/strings.xml
index c3fff3d..134e9d2 100644
--- a/core/res/res/values-mcc204/strings.xml
+++ b/core/res/res/values-mcc204/strings.xml
@@ -20,6 +20,6 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
     <!-- A string used to replace %s in a URL to fill in the locale for countries  -->
-    <!-- whose locale we don't natively support.  A 0 length string triggers no replacement -->
+    <!-- whose locale we don't natively support.  A 0 length string triggers no replacement.  Do not translate -->
     <string name="locale_replacement">nl_nl</string>    
 </resources>
diff --git a/core/res/res/values-mcc230/strings.xml b/core/res/res/values-mcc230/strings.xml
index 559b858..3078bf8 100644
--- a/core/res/res/values-mcc230/strings.xml
+++ b/core/res/res/values-mcc230/strings.xml
@@ -20,6 +20,6 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
     <!-- A string used to replace %s in a URL to fill in the locale for countries  -->
-    <!-- whose locale we don't natively support.  A 0 length string triggers no replacement -->
+    <!-- whose locale we don't natively support.  A 0 length string triggers no replacement. Do not translate -->
     <string name="locale_replacement">cs_cz</string>    
 </resources>
diff --git a/core/res/res/values-mcc232/strings.xml b/core/res/res/values-mcc232/strings.xml
index 494770f..809e4a0 100644
--- a/core/res/res/values-mcc232/strings.xml
+++ b/core/res/res/values-mcc232/strings.xml
@@ -20,6 +20,6 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
     <!-- A string used to replace %s in a URL to fill in the locale for countries  -->
-    <!-- whose locale we don't natively support.  A 0 length string triggers no replacement -->
+    <!-- whose locale we don't natively support.  A 0 length string triggers no replacement. Do not translate -->
     <string name="locale_replacement">de_at</string>    
 </resources>
diff --git a/core/res/res/values-mcc234/strings.xml b/core/res/res/values-mcc234/strings.xml
index 2e6a3f3..676defe 100644
--- a/core/res/res/values-mcc234/strings.xml
+++ b/core/res/res/values-mcc234/strings.xml
@@ -20,6 +20,6 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
     <!-- A string used to replace %s in a URL to fill in the locale for countries  -->
-    <!-- whose locale we don't natively support.  A 0 length string triggers no replacement -->
+    <!-- whose locale we don't natively support.  A 0 length string triggers no replacement. Do not translate -->
     <string name="locale_replacement">en_gb</string>    
 </resources>
diff --git a/core/res/res/values-mcc260/strings.xml b/core/res/res/values-mcc260/strings.xml
index 20c19dd..90f2521 100644
--- a/core/res/res/values-mcc260/strings.xml
+++ b/core/res/res/values-mcc260/strings.xml
@@ -20,6 +20,6 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
     <!-- A string used to replace %s in a URL to fill in the locale for countries  -->
-    <!-- whose locale we don't natively support.  A 0 length string triggers no replacement -->
+    <!-- whose locale we don't natively support.  A 0 length string triggers no replacement. Do not translate -->
     <string name="locale_replacement">pl_pl</string>    
 </resources>
diff --git a/core/res/res/values-mcc262/strings.xml b/core/res/res/values-mcc262/strings.xml
index 8ca0e31..ae323b8 100644
--- a/core/res/res/values-mcc262/strings.xml
+++ b/core/res/res/values-mcc262/strings.xml
@@ -20,6 +20,6 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
     <!-- A string used to replace %s in a URL to fill in the locale for countries  -->
-    <!-- whose locale we don't natively support.  A 0 length string triggers no replacement -->
+    <!-- whose locale we don't natively support.  A 0 length string triggers no replacement. Do not translate -->
     <string name="locale_replacement">de_de</string>    
 </resources>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 11531fc..727c6ea 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -710,11 +710,12 @@
         <enum name="preferExternal" value="2" />
     </attr>
 
-    <!-- Extra options for an activity's UI. If specified on the application
+    <!-- Extra options for an activity's UI. Applies to either the {@code &lt;activity&gt;} or
+         {@code &lt;application&gt;} tag. If specified on the {@code &lt;application&gt;}
          tag these will be considered defaults for all activities in the
          application. -->
     <attr name="uiOptions">
-        <!-- No extra UI options. -->
+        <!-- No extra UI options. This is the default. -->
         <flag name="none" value="0" />
         <!-- Split the options menu into a separate bar at the bottom of
              the screen when severely constrained for horizontal space.
diff --git a/data/fonts/Lohit_Hindi.ttf b/data/fonts/Lohit_Hindi.ttf
deleted file mode 100644
index 73caae3..0000000
--- a/data/fonts/Lohit_Hindi.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/Roboto-Bold.ttf b/data/fonts/Roboto-Bold.ttf
index c716bbb..e5d828d 100644
--- a/data/fonts/Roboto-Bold.ttf
+++ b/data/fonts/Roboto-Bold.ttf
Binary files differ
diff --git a/data/fonts/Roboto-BoldItalic.ttf b/data/fonts/Roboto-BoldItalic.ttf
index eeb5120..d8fa3ae 100644
--- a/data/fonts/Roboto-BoldItalic.ttf
+++ b/data/fonts/Roboto-BoldItalic.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Italic.ttf b/data/fonts/Roboto-Italic.ttf
index 1e88d3e..6682d17 100644
--- a/data/fonts/Roboto-Italic.ttf
+++ b/data/fonts/Roboto-Italic.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Regular.ttf b/data/fonts/Roboto-Regular.ttf
index 3033027..153c608 100644
--- a/data/fonts/Roboto-Regular.ttf
+++ b/data/fonts/Roboto-Regular.ttf
Binary files differ
diff --git a/data/fonts/fallback_fonts.xml b/data/fonts/fallback_fonts.xml
index e468558..881233a 100644
--- a/data/fonts/fallback_fonts.xml
+++ b/data/fonts/fallback_fonts.xml
@@ -56,7 +56,7 @@
     </family>
     <family>
         <fileset>
-            <file>Lohit_Hindi.ttf</file>
+            <file>Lohit-Devanagari.ttf</file>
         </fileset>
     </family>
     <family>
diff --git a/data/fonts/fonts.mk b/data/fonts/fonts.mk
index 5bac8f0..67d04c9 100644
--- a/data/fonts/fonts.mk
+++ b/data/fonts/fonts.mk
@@ -30,7 +30,6 @@
     frameworks/base/data/fonts/DroidSerif-Italic.ttf:system/fonts/DroidSerif-Italic.ttf \
     frameworks/base/data/fonts/DroidSerif-BoldItalic.ttf:system/fonts/DroidSerif-BoldItalic.ttf \
     frameworks/base/data/fonts/DroidSansMono.ttf:system/fonts/DroidSansMono.ttf \
-    frameworks/base/data/fonts/Lohit_Hindi.ttf:system/fonts/Lohit_Hindi.ttf \
     frameworks/base/data/fonts/DroidSansArmenian.ttf:system/fonts/DroidSansArmenian.ttf \
     frameworks/base/data/fonts/DroidSansGeorgian.ttf:system/fonts/DroidSansGeorgian.ttf \
     frameworks/base/data/fonts/Clockopia.ttf:system/fonts/Clockopia.ttf \
diff --git a/docs/html/guide/appendix/media-formats.jd b/docs/html/guide/appendix/media-formats.jd
index e128a1c..ccc63a2 100644
--- a/docs/html/guide/appendix/media-formats.jd
+++ b/docs/html/guide/appendix/media-formats.jd
@@ -37,11 +37,16 @@
 
 <ul>
   <li>RTSP (RTP, SDP)</li>
-  <li>HTTP progressive streaming</li>
-  <li>HTTP live streaming <a href="http://tools.ietf.org/html/draft-pantos-http-live-streaming-05">draft protocol</a> (Android 3.0 and above)</li>
+  <li>HTTP/HTTPS progressive streaming</li>
+  <li>HTTP/HTTPS live streaming <a href="http://tools.ietf.org/html/draft-pantos-http-live-streaming">draft protocol</a>: <ul>
+    <li>MPEG-2 TS media files only</li>
+    <li>Protocol version 3 (Android 4.0 and above)</li>
+    <li>Protocol version 2 (Android 3.x)</li>
+    <li>Not supported before Android 3.0</li>
+  </ul></li>
 </ul>
 
-<p class="note"><strong>Note:</strong> HTTPS is not supported at this time.</p>
+<p class="note"><strong>Note:</strong> HTTPS is not supported before Android 3.1.</p>
 
 
 <h2 id="core">Core Media Formats</h2>
@@ -71,7 +76,11 @@
 <td style="text-align: center;"><big>&bull;</big></td>
 <td rowspan="3">Mono/Stereo content in any combination of standard bit
 rates up to 160 kbps and sampling rates from 8 to 48kHz</td>
-<td rowspan="3">3GPP (.3gp), and MPEG-4 (.mp4, .m4a). ADTS raw AAC (.aac, decode only, ADIF not supported, Android 3.1+). </td>
+<td rowspan="3">
+  &bull; 3GPP (.3gp)<br>
+  &bull; MPEG-4 (.mp4, .m4a)<br>
+  &bull; ADTS raw AAC (.aac, decode in Android 3.1+, encode in Android 4.0+, ADIF not supported)<br>
+  &bull; MPEG-TS (.ts, not seekable, Android 3.0+)</td>
 </tr>
 
 <tr>
@@ -91,8 +100,8 @@
 <td style="text-align: center;"><big>&bull;</big></td>
 <td style="text-align: center;"><big>&bull;</big></td>
 <td>4.75 to 12.2 kbps sampled @ 8kHz</td>
-<td>3GPP (.3gp)
-</td>
+<td>
+  3GPP (.3gp)</td>
 </tr>
 
 <tr>
@@ -100,19 +109,21 @@
 <td style="text-align: center;"><big>&bull;</big></td>
 <td style="text-align: center;"><big>&bull;</big></td>
 <td>9 rates from 6.60 kbit/s to 23.85 kbit/s sampled @ 16kHz</td>
-<td>3GPP (.3gp)</td>
+<td>
+  3GPP (.3gp)</td>
 </tr>
 
 <tr>
 <td>FLAC</td>
 <td>&nbsp;</td>
-<td style="text-align: center;"><big>&bull;</big><br><small>(Android 3.1+)</small></td>
+<td style="text-align: center;" nowrap><big>&bull;</big><br><small>(Android 3.1+)</small></td>
 <td>Mono/Stereo (no multichannel). Sample rates up to 48 kHz (but up to 44.1
 kHz is recommended on devices with 44.1 kHz output, as the 48 to 44.1 kHz
 downsampler does not include a low-pass filter). 16-bit recommended;
 no dither applied for 24-bit.
 </td>
-<td>FLAC (.flac) only</td>
+<td>
+  FLAC (.flac) only</td>
 </tr>
 
 <tr>
@@ -121,7 +132,8 @@
 <td style="text-align: center;"><big>&bull;</big></td>
 <td>Mono/Stereo 8-320Kbps constant (CBR) or variable bit-rate (VBR)
 </td>
-<td>MP3 (.mp3)</td>
+<td>
+  MP3 (.mp3)</td>
 </tr>
 
 <tr>
@@ -129,15 +141,21 @@
 <td>&nbsp;</td>
 <td style="text-align: center;"><big>&bull;</big></td>
 <td>MIDI Type 0 and 1. DLS Version 1 and 2. XMF and Mobile XMF. Support for ringtone formats RTTTL/RTX, OTA, and iMelody </td>
-<td>Type 0 and 1 (.mid, .xmf, .mxmf). Also RTTTL/RTX (.rtttl, .rtx), OTA (.ota), and iMelody (.imy)</td>
+<td>
+  &bull; Type 0 and 1 (.mid, .xmf, .mxmf)<br>
+  &bull; RTTTL/RTX (.rtttl, .rtx)<br>
+  &bull; OTA (.ota)<br>
+  &bull; iMelody (.imy)</td>
 </tr>
 
 <tr>
-<td>Ogg Vorbis</td>
+<td>Vorbis</td>
 <td>&nbsp;</td>
 <td style="text-align: center;"><big>&bull;</big></td>
 <td>&nbsp;</td>
-<td>Ogg (.ogg)</td>
+<td>
+  &bull; Ogg (.ogg)<br>
+  &bull; Matroska (.mkv, Android 4.0+)</td>
 </tr>
 
 <tr>
@@ -145,16 +163,18 @@
 <td>&nbsp;</td>
 <td style="text-align: center;"><big>&bull;</big></td>
 <td>8- and 16-bit linear PCM (rates up to limit of hardware)</td>
-<td>WAVE (.wav)</td>
+<td>
+  WAVE (.wav)</td>
 </tr>
 
 <tr>
-<td rowspan="4">Image</td>
+<td rowspan="5">Image</td>
 <td>JPEG</td>
 <td style="text-align: center;"><big>&bull;</big></td>
 <td style="text-align: center;"><big>&bull;</big></td>
 <td>Base+progressive</td>
-<td>JPEG (.jpg)</td>
+<td>
+  JPEG (.jpg)</td>
 </tr>
 
 <tr>
@@ -162,7 +182,8 @@
 <td>&nbsp;</td>
 <td style="text-align: center;"><big>&bull;</big></td>
 <td>&nbsp;</td>
-<td>GIF (.gif)</td>
+<td>
+  GIF (.gif)</td>
 </tr>
 
 <tr>
@@ -170,7 +191,8 @@
 <td style="text-align: center;"><big>&bull;</big></td>
 <td style="text-align: center;"><big>&bull;</big></td>
 <td>&nbsp;</td>
-<td>PNG (.png)</td>
+<td>
+  PNG (.png)</td>
 </tr>
 
 <tr>
@@ -178,7 +200,17 @@
 <td>&nbsp;</td>
 <td style="text-align: center;"><big>&bull;</big></td>
 <td>&nbsp;</td>
-<td>BMP (.bmp)</td>
+<td>
+  BMP (.bmp)</td>
+</tr>
+
+<tr>
+<td>WEBP</td>
+<td style="text-align: center;" nowrap><big>&bull;</big><br><small>(Android 4.0+)</small></td>
+<td style="text-align: center;" nowrap><big>&bull;</big><br><small>(Android 4.0+)</small></td>
+<td>&nbsp;</td>
+<td>
+  WebP (.webp)</td>
 </tr>
 
 
@@ -188,15 +220,20 @@
 <td style="text-align: center;"><big>&bull;</big></td>
 <td style="text-align: center;"><big>&bull;</big></td>
 <td>&nbsp;</td>
-<td>3GPP (.3gp) and MPEG-4 (.mp4)</td>
+<td>
+  &bull; 3GPP (.3gp)<br>
+  &bull; MPEG-4 (.mp4)</td>
 </tr>
 
 <tr>
 <td>H.264 AVC</td>
 <td style="text-align: center;" nowrap><big>&bull;</big><br><small>(Android 3.0+)</small></td>
-<td style="text-align: center;"><big>&bull;</big></td>
+<td style="text-align: center;" nowrap><big>&bull;</big></td>
 <td>Baseline Profile (BP)</td>
-<td>3GPP (.3gp) and MPEG-4 (.mp4). MPEG-TS (.ts, AAC audio only, not seekable, Android 3.0+)</td>
+<td>
+  &bull; 3GPP (.3gp)<br>
+  &bull; MPEG-4 (.mp4)<br>
+  &bull; MPEG-TS (.ts, AAC audio only, not seekable, Android 3.0+)</td>
 </tr>
 
 <tr>
@@ -204,15 +241,18 @@
 <td>&nbsp;</td>
 <td style="text-align: center;"><big>&bull;</big></td>
 <td>&nbsp;</td>
-<td>3GPP (.3gp)</td>
+<td>
+  3GPP (.3gp)</td>
 </tr>
 
 <tr>
 <td>VP8</td>
 <td>&nbsp;</td>
-<td style="text-align: center;"><big>&bull;</big><br><small>(Android 2.3.3+)</small></td>
-<td>&nbsp;</td>
-<td><a href="http://www.webmproject.org/">WebM</a> (.webm)</td>
+<td style="text-align: center;" nowrap><big>&bull;</big><br><small>(Android 2.3.3+)</small></td>
+<td>Streamable only in Android 4.0 and above</td>
+<td>
+  &bull; <a href="http://www.webmproject.org/">WebM</a> (.webm)<br>
+  &bull; Matroska (.mkv, Android 4.0+)</td>
 </tr>
 
 </tbody></table>
@@ -220,7 +260,7 @@
 
 <h2 id="recommendations">Video Encoding Recommendations</h2>
 
-<p>Table 2, below, lists examples of video encoding profiles and parameters that the Android media framework supports for playback. In addition to these encoding parameter recommendations, a device's available video recording profiles can be used as a proxy for media playback capabilities. These profiles can be inspected using the {@link android.media.CamcorderProfile CamcorderProfile} class, which is available since API level 8.</p>
+<p>Table 2, below, lists examples of video encoding profiles and parameters that the Android media framework supports for playback. In addition to these encoding parameter recommendations, a device's available <em>video recording</em> profiles can be used as a proxy for media playback capabilities. These profiles can be inspected using the {@link android.media.CamcorderProfile CamcorderProfile} class, which is available since API level 8.</p>
 
 <p class="table-caption" id="encoding-recommendations-table"><strong>Table 2.</strong> Examples of supported video encoding parameters.</p>
 
@@ -228,45 +268,53 @@
   <thead>
   <tr>
     <th>&nbsp;</th>
-    <th style="background-color:#f3f3f3;font-weight:normal">Lower quality</th>
-    <th style="background-color:#f3f3f3;font-weight:normal">Higher quality</th>
+    <th style="background-color:#f3f3f3;font-weight:normal"><acronym title="Standard definition">SD</a> (Low quality)</th>
+    <th style="background-color:#f3f3f3;font-weight:normal"><acronym title="Standard definition">SD</a> (High quality)</th>
+    <th style="background-color:#f3f3f3;font-weight:normal"><acronym title="High definition">HD</a> (Not available on all devices)</th>
   </tr>
   </thead>
   <tbody>
   <tr>
     <th>Video codec</th>
-    <td>H.264 Baseline Profile</th>
-    <td>H.264 Baseline Profile</th>
+    <td>H.264 Baseline Profile</td>
+    <td>H.264 Baseline Profile</td>
+    <td>H.264 Baseline Profile</td>
   </tr>
   <tr>
     <th>Video resolution</th>
-    <td>176 x 144 px</th>
-    <td>480 x 360 px</th>
+    <td>176 x 144 px</td>
+    <td>480 x 360 px</td>
+    <td>1280 x 720 px</td>
   </tr>
   <tr>
     <th>Video frame rate</th>
-    <td>12 fps</th>
-    <td>30 fps</th>
+    <td>12 fps</td>
+    <td>30 fps</td>
+    <td>30 fps</td>
   </tr>
   <tr>
     <th>Video bitrate</th>
-    <td>56 Kbps</th>
-    <td>500 Kbps</th>
+    <td>56 Kbps</td>
+    <td>500 Kbps</td>
+    <td>2 Mbps</td>
   </tr>
   <tr>
     <th>Audio codec</th>
-    <td>AAC-LC</th>
-    <td>AAC-LC</th>
+    <td>AAC-LC</td>
+    <td>AAC-LC</td>
+    <td>AAC-LC</td>
   </tr>
   <tr>
     <th>Audio channels</th>
-    <td>1 (mono)</th>
-    <td>2 (stereo)</th>
+    <td>1 (mono)</td>
+    <td>2 (stereo)</td>
+    <td>2 (stereo)</td>
   </tr>
   <tr>
     <th>Audio bitrate</th>
-    <td>24 Kbps</th>
-    <td>128 Kbps</th>
+    <td>24 Kbps</td>
+    <td>128 Kbps</td>
+    <td>192 Kbps</td>
   </tr>
   </tbody>
 </table>
@@ -274,7 +322,8 @@
 <p style="margin-top: 2em">For video content that is streamed over HTTP or RTSP, there are additional requirements:</p>
 
 <ul>
-  <li>For 3GPP and MPEG-4 containers, the <code>moov</code> atom must precede any <code>mdat</code> atoms.</li>
+  <li>For 3GPP and MPEG-4 containers, the <code>moov</code> atom must precede any <code>mdat</code> atoms, but must succeed the
+      <code>ftyp</code> atom.</li>
   <li>For 3GPP, MPEG-4, and WebM containers, audio and video samples corresponding to the same time offset may be no more than 500 KB apart.
       To minimize this audio/video drift, consider interleaving audio and video in smaller chunk sizes.</li>
 </ul>
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index f799b0c..6c5d882 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -323,6 +323,16 @@
     }
   },
   {
+    tags: ['article', 'accountsync', 'data'],
+    path: 'articles/contacts.html',
+    title: {
+      en: 'Using the Contacts API'
+    },
+    description: {
+      en: 'Android provides a Contacts API for managing and integrating contacts from multiple accounts and data sources and allows apps to read various information about individual contacts.'
+    }
+  },
+  {
     tags: ['article', 'ui', 'web'],
     path: 'articles/using-webviews.html',
     title: {
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index 4a4bcfb..a520a6a 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -317,18 +317,13 @@
     // recalculate exposure values). Changing exposure compensation
     // settings will still affect the exposure settings while
     // auto-exposure is locked. Stopping preview or taking a still
-    // image will release the lock. However, the lock can be
-    // re-enabled prior to preview being re-started, to keep the
-    // exposure values from the previous lock. In conjunction with
+    // image will not change the lock. In conjunction with
     // exposure compensation, this allows for capturing multi-exposure
     // brackets with known relative exposure values. Locking
     // auto-exposure after open but before the first call to
     // startPreview may result in severely over- or under-exposed
-    // images.  The driver may independently enable the AE lock after
-    // auto-focus completes. If it does so, this key must have its
-    // value updated to reflect the lock's existence. Applications are
-    // free to release such a lock, to re-enable AE without restarting
-    // preview.
+    // images.  The driver will not change the AE lock after
+    // auto-focus completes.
     static const char KEY_AUTO_EXPOSURE_LOCK[];
     // Whether locking the auto-exposure is supported. "true" means it is, and
     // "false" or this key not existing means it is not supported.
@@ -339,18 +334,13 @@
     // change white balance values. If auto-white balance is already
     // locked, setting this to true again has no effect (the driver
     // will not recalculate white balance values). Stopping preview or
-    // taking a still image will release the lock. However, the lock
-    // can be re-enabled prior to preview being re-started, to keep
-    // the white balance values from the previous lock. In conjunction
+    // taking a still image will not change the lock. In conjunction
     // with exposure compensation, this allows for capturing
     // multi-exposure brackets with fixed white balance. Locking
     // auto-white balance after open but before the first call to
     // startPreview may result in severely incorrect color.  The
-    // driver may independently enable the AWB lock after auto-focus
-    // completes. If it does so, this key must have its value updated
-    // to reflect the lock's existence. Applications are free to
-    // release such a lock, to re-enable AWB without restarting
-    // preview.
+    // driver will not change the AWB lock after auto-focus
+    // completes.
     static const char KEY_AUTO_WHITEBALANCE_LOCK[];
     // Whether locking the auto-white balance is supported. "true"
     // means it is, and "false" or this key not existing means it is
diff --git a/media/libstagefright/AVIExtractor.cpp b/media/libstagefright/AVIExtractor.cpp
index d47e5d1..0be2ca4 100644
--- a/media/libstagefright/AVIExtractor.cpp
+++ b/media/libstagefright/AVIExtractor.cpp
@@ -56,11 +56,36 @@
     MediaBufferGroup *mBufferGroup;
     size_t mSampleIndex;
 
+    sp<MP3Splitter> mSplitter;
+
     DISALLOW_EVIL_CONSTRUCTORS(AVISource);
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 
+struct AVIExtractor::MP3Splitter : public RefBase {
+    MP3Splitter();
+
+    void clear();
+    void append(MediaBuffer *buffer);
+    status_t read(MediaBuffer **buffer);
+
+protected:
+    virtual ~MP3Splitter();
+
+private:
+    bool mFindSync;
+    int64_t mBaseTimeUs;
+    int64_t mNumSamplesRead;
+    sp<ABuffer> mBuffer;
+
+    bool resync();
+
+    DISALLOW_EVIL_CONSTRUCTORS(MP3Splitter);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
 AVIExtractor::AVISource::AVISource(
         const sp<AVIExtractor> &extractor, size_t trackIndex)
     : mExtractor(extractor),
@@ -84,6 +109,15 @@
     mBufferGroup->add_buffer(new MediaBuffer(mTrack.mMaxSampleSize));
     mSampleIndex = 0;
 
+    const char *mime;
+    CHECK(mTrack.mMeta->findCString(kKeyMIMEType, &mime));
+
+    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
+        mSplitter = new MP3Splitter;
+    } else {
+        mSplitter.clear();
+    }
+
     return OK;
 }
 
@@ -93,6 +127,8 @@
     delete mBufferGroup;
     mBufferGroup = NULL;
 
+    mSplitter.clear();
+
     return OK;
 }
 
@@ -116,39 +152,213 @@
         if (err != OK) {
             return ERROR_END_OF_STREAM;
         }
+
+        if (mSplitter != NULL) {
+            mSplitter->clear();
+        }
     }
 
-    off64_t offset;
-    size_t size;
-    bool isKey;
-    int64_t timeUs;
-    status_t err = mExtractor->getSampleInfo(
-            mTrackIndex, mSampleIndex, &offset, &size, &isKey, &timeUs);
+    for (;;) {
+        if (mSplitter != NULL) {
+            status_t err = mSplitter->read(buffer);
 
-    ++mSampleIndex;
+            if (err == OK) {
+                break;
+            } else if (err != -EAGAIN) {
+                return err;
+            }
+        }
 
-    if (err != OK) {
-        return ERROR_END_OF_STREAM;
+        off64_t offset;
+        size_t size;
+        bool isKey;
+        int64_t timeUs;
+        status_t err = mExtractor->getSampleInfo(
+                mTrackIndex, mSampleIndex, &offset, &size, &isKey, &timeUs);
+
+        ++mSampleIndex;
+
+        if (err != OK) {
+            return ERROR_END_OF_STREAM;
+        }
+
+        MediaBuffer *out;
+        CHECK_EQ(mBufferGroup->acquire_buffer(&out), (status_t)OK);
+
+        ssize_t n = mExtractor->mDataSource->readAt(offset, out->data(), size);
+
+        if (n < (ssize_t)size) {
+            return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED;
+        }
+
+        out->set_range(0, size);
+
+        out->meta_data()->setInt64(kKeyTime, timeUs);
+
+        if (isKey) {
+            out->meta_data()->setInt32(kKeyIsSyncFrame, 1);
+        }
+
+        if (mSplitter == NULL) {
+            *buffer = out;
+            break;
+        }
+
+        mSplitter->append(out);
+        out->release();
+        out = NULL;
     }
 
-    MediaBuffer *out;
-    CHECK_EQ(mBufferGroup->acquire_buffer(&out), (status_t)OK);
+    return OK;
+}
 
-    ssize_t n = mExtractor->mDataSource->readAt(offset, out->data(), size);
+////////////////////////////////////////////////////////////////////////////////
 
-    if (n < (ssize_t)size) {
-        return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED;
+AVIExtractor::MP3Splitter::MP3Splitter()
+    : mFindSync(true),
+      mBaseTimeUs(-1ll),
+      mNumSamplesRead(0) {
+}
+
+AVIExtractor::MP3Splitter::~MP3Splitter() {
+}
+
+void AVIExtractor::MP3Splitter::clear() {
+    mFindSync = true;
+    mBaseTimeUs = -1ll;
+    mNumSamplesRead = 0;
+
+    if (mBuffer != NULL) {
+        mBuffer->setRange(0, 0);
+    }
+}
+
+void AVIExtractor::MP3Splitter::append(MediaBuffer *buffer) {
+    size_t prevCapacity = (mBuffer != NULL) ? mBuffer->capacity() : 0;
+
+    if (mBaseTimeUs < 0) {
+        CHECK(mBuffer == NULL || mBuffer->size() == 0);
+        CHECK(buffer->meta_data()->findInt64(kKeyTime, &mBaseTimeUs));
+        mNumSamplesRead = 0;
     }
 
-    out->set_range(0, size);
-
-    out->meta_data()->setInt64(kKeyTime, timeUs);
-
-    if (isKey) {
-        out->meta_data()->setInt32(kKeyIsSyncFrame, 1);
+    if (mBuffer != NULL && mBuffer->offset() > 0) {
+        memmove(mBuffer->base(), mBuffer->data(), mBuffer->size());
+        mBuffer->setRange(0, mBuffer->size());
     }
 
-    *buffer = out;
+    if (mBuffer == NULL
+            || mBuffer->size() + buffer->range_length() > prevCapacity) {
+        size_t newCapacity =
+            (prevCapacity + buffer->range_length() + 1023) & ~1023;
+
+        sp<ABuffer> newBuffer = new ABuffer(newCapacity);
+        if (mBuffer != NULL) {
+            memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
+            newBuffer->setRange(0, mBuffer->size());
+        } else {
+            newBuffer->setRange(0, 0);
+        }
+        mBuffer = newBuffer;
+    }
+
+    memcpy(mBuffer->data() + mBuffer->size(),
+           (const uint8_t *)buffer->data() + buffer->range_offset(),
+           buffer->range_length());
+
+    mBuffer->setRange(0, mBuffer->size() + buffer->range_length());
+}
+
+bool AVIExtractor::MP3Splitter::resync() {
+    if (mBuffer == NULL) {
+        return false;
+    }
+
+    bool foundSync = false;
+    for (size_t offset = 0; offset + 3 < mBuffer->size(); ++offset) {
+        uint32_t firstHeader = U32_AT(mBuffer->data() + offset);
+
+        size_t frameSize;
+        if (!GetMPEGAudioFrameSize(firstHeader, &frameSize)) {
+            continue;
+        }
+
+        size_t subsequentOffset = offset + frameSize;
+        size_t i = 3;
+        while (i > 0) {
+            if (subsequentOffset + 3 >= mBuffer->size()) {
+                break;
+            }
+
+            static const uint32_t kMask = 0xfffe0c00;
+
+            uint32_t header = U32_AT(mBuffer->data() + subsequentOffset);
+            if ((header & kMask) != (firstHeader & kMask)) {
+                break;
+            }
+
+            if (!GetMPEGAudioFrameSize(header, &frameSize)) {
+                break;
+            }
+
+            subsequentOffset += frameSize;
+            --i;
+        }
+
+        if (i == 0) {
+            foundSync = true;
+            memmove(mBuffer->data(),
+                    mBuffer->data() + offset,
+                    mBuffer->size() - offset);
+
+            mBuffer->setRange(0, mBuffer->size() - offset);
+            break;
+        }
+    }
+
+    return foundSync;
+}
+
+status_t AVIExtractor::MP3Splitter::read(MediaBuffer **out) {
+    *out = NULL;
+
+    if (mFindSync) {
+        if (!resync()) {
+            return -EAGAIN;
+        }
+
+        mFindSync = false;
+    }
+
+    if (mBuffer->size() < 4) {
+        return -EAGAIN;
+    }
+
+    uint32_t header = U32_AT(mBuffer->data());
+    size_t frameSize;
+    int sampleRate;
+    int numSamples;
+    if (!GetMPEGAudioFrameSize(
+                header, &frameSize, &sampleRate, NULL, NULL, &numSamples)) {
+        return ERROR_MALFORMED;
+    }
+
+    if (mBuffer->size() < frameSize) {
+        return -EAGAIN;
+    }
+
+    MediaBuffer *mbuf = new MediaBuffer(frameSize);
+    memcpy(mbuf->data(), mBuffer->data(), frameSize);
+
+    int64_t timeUs = mBaseTimeUs + (mNumSamplesRead * 1000000ll) / sampleRate;
+    mNumSamplesRead += numSamples;
+
+    mbuf->meta_data()->setInt64(kKeyTime, timeUs);
+
+    mBuffer->setRange(
+            mBuffer->offset() + frameSize, mBuffer->size() - frameSize);
+
+    *out = mbuf;
 
     return OK;
 }
@@ -449,6 +659,8 @@
     track->mThumbnailSampleSize = 0;
     track->mThumbnailSampleIndex = -1;
     track->mMaxSampleSize = 0;
+    track->mAvgChunkSize = 1.0;
+    track->mFirstChunkSize = 0;
 
     return OK;
 }
@@ -467,8 +679,8 @@
 
     bool isVideo = (track->mKind == Track::VIDEO);
 
-    if ((isVideo && size < 40) || (!isVideo && size < 18)) {
-        // Expected a BITMAPINFO or WAVEFORMATEX structure, respectively.
+    if ((isVideo && size < 40) || (!isVideo && size < 16)) {
+        // Expected a BITMAPINFO or WAVEFORMAT(EX) structure, respectively.
         return ERROR_MALFORMED;
     }
 
@@ -651,6 +863,47 @@
     for (size_t i = 0; i < mTracks.size(); ++i) {
         Track *track = &mTracks.editItemAt(i);
 
+        if (track->mBytesPerSample > 0) {
+            // Assume all chunks are roughly the same size for now.
+
+            // Compute the avg. size of the first 128 chunks (if there are
+            // that many), but exclude the size of the first one, since
+            // it may be an outlier.
+            size_t numSamplesToAverage = track->mSamples.size();
+            if (numSamplesToAverage > 256) {
+                numSamplesToAverage = 256;
+            }
+
+            double avgChunkSize = 0;
+            size_t j;
+            for (j = 0; j <= numSamplesToAverage; ++j) {
+                off64_t offset;
+                size_t size;
+                bool isKey;
+                int64_t dummy;
+
+                status_t err =
+                    getSampleInfo(
+                            i, j,
+                            &offset, &size, &isKey, &dummy);
+
+                if (err != OK) {
+                    return err;
+                }
+
+                if (j == 0) {
+                    track->mFirstChunkSize = size;
+                    continue;
+                }
+
+                avgChunkSize += size;
+            }
+
+            avgChunkSize /= numSamplesToAverage;
+
+            track->mAvgChunkSize = avgChunkSize;
+        }
+
         int64_t durationUs;
         CHECK_EQ((status_t)OK,
                  getSampleTime(i, track->mSamples.size() - 1, &durationUs));
@@ -687,21 +940,6 @@
                 return err;
             }
         }
-
-        if (track->mBytesPerSample != 0) {
-            // Assume all chunks are the same size for now.
-
-            off64_t offset;
-            size_t size;
-            bool isKey;
-            int64_t sampleTimeUs;
-            CHECK_EQ((status_t)OK,
-                     getSampleInfo(
-                         i, 0,
-                         &offset, &size, &isKey, &sampleTimeUs));
-
-            track->mRate *= size / track->mBytesPerSample;
-        }
     }
 
     mFoundIndex = true;
@@ -904,6 +1142,18 @@
 
     *isKey = info.mIsKey;
 
+    if (track.mBytesPerSample > 0) {
+        size_t sampleStartInBytes;
+        if (sampleIndex == 0) {
+            sampleStartInBytes = 0;
+        } else {
+            sampleStartInBytes =
+                track.mFirstChunkSize + track.mAvgChunkSize * (sampleIndex - 1);
+        }
+
+        sampleIndex = sampleStartInBytes / track.mBytesPerSample;
+    }
+
     *sampleTimeUs = (sampleIndex * 1000000ll * track.mRate) / track.mScale;
 
     return OK;
@@ -928,8 +1178,24 @@
 
     const Track &track = mTracks.itemAt(trackIndex);
 
-    ssize_t closestSampleIndex =
-        timeUs / track.mRate * track.mScale / 1000000ll;
+    ssize_t closestSampleIndex;
+
+    if (track.mBytesPerSample > 0) {
+        size_t closestByteOffset =
+            (timeUs * track.mBytesPerSample)
+                / track.mRate * track.mScale / 1000000ll;
+
+        if (closestByteOffset <= track.mFirstChunkSize) {
+            closestSampleIndex = 0;
+        } else {
+            closestSampleIndex =
+                (closestByteOffset - track.mFirstChunkSize)
+                    / track.mAvgChunkSize;
+        }
+    } else {
+        // Each chunk contains a single sample.
+        closestSampleIndex = timeUs / track.mRate * track.mScale / 1000000ll;
+    }
 
     ssize_t numSamples = track.mSamples.size();
 
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index 306f1f6..2b27ee2 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -764,8 +764,8 @@
     // If the loop was exited as a result of stopping the recording,
     // it is OK
     if (mStopped) {
-        LOGV("Read: SurfaceMediaSource is stopped. Returning NO_INIT;");
-        return NO_INIT;
+        LOGV("Read: SurfaceMediaSource is stopped. Returning ERROR_END_OF_STREAM.");
+        return ERROR_END_OF_STREAM;
     }
 
     // Update the current buffer info
diff --git a/media/libstagefright/include/AVIExtractor.h b/media/libstagefright/include/AVIExtractor.h
index 75ce68d..ff5dcb5 100644
--- a/media/libstagefright/include/AVIExtractor.h
+++ b/media/libstagefright/include/AVIExtractor.h
@@ -42,6 +42,7 @@
 
 private:
     struct AVISource;
+    struct MP3Splitter;
 
     struct SampleInfo {
         uint32_t mOffset;
@@ -70,6 +71,10 @@
         size_t mThumbnailSampleSize;
         ssize_t mThumbnailSampleIndex;
         size_t mMaxSampleSize;
+
+        // If mBytesPerSample > 0:
+        double mAvgChunkSize;
+        size_t mFirstChunkSize;
     };
 
     sp<DataSource> mDataSource;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaBassBoostTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaBassBoostTest.java
index aa5c4d7..edc3e07 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaBassBoostTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaBassBoostTest.java
@@ -46,6 +46,10 @@
     private final static int MIN_ENERGY_RATIO_2 = 3;
     private final static short TEST_STRENGTH = 500;
     private final static int TEST_VOLUME = 4;
+    // Implementor UUID for volume controller effect defined in
+    // frameworks/base/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+    private final static UUID VOLUME_EFFECT_UUID =
+        UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b");
 
     private BassBoost mBassBoost = null;
     private int mSession = -1;
@@ -201,14 +205,15 @@
             // creating a volume controller on output mix ensures that ro.audio.silent mutes
             // audio after the effects and not before
             vc = new AudioEffect(
-                    AudioEffect.EFFECT_TYPE_NULL,
-                    UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"),
-                      0,
-                      0);
+                                AudioEffect.EFFECT_TYPE_NULL,
+                                VOLUME_EFFECT_UUID,
+                                0,
+                                0);
             vc.setEnabled(true);
 
             mp = new MediaPlayer();
             mp.setDataSource(MediaNames.SINE_200_1000);
+            mp.setLooping(true);
             mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
             getBassBoost(mp.getAudioSessionId());
             mp.prepare();
@@ -219,7 +224,7 @@
             int refEnergy1000 = probe.capture(1000);
             mBassBoost.setStrength((short)1000);
             mBassBoost.setEnabled(true);
-            Thread.sleep(500);
+            Thread.sleep(4000);
             // measure energy around 1kHz with band level at min
             int energy200 = probe.capture(200);
             int energy1000 = probe.capture(1000);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaEnvReverbTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaEnvReverbTest.java
index ba202a7..79b90d0 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaEnvReverbTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaEnvReverbTest.java
@@ -49,6 +49,14 @@
     private final static float DELAY_TOLERANCE = 1.05f;
     // allow +/- 5% tolerance between set and get ratios
     private final static float RATIO_TOLERANCE = 1.05f;
+    // Implementor UUID for volume controller effect defined in
+    // frameworks/base/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+    private final static UUID VOLUME_EFFECT_UUID =
+        UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b");
+    // Implementor UUID for environmental reverb effect defined in
+    // frameworks/base/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+    private final static UUID ENV_REVERB_EFFECT_UUID =
+        UUID.fromString("c7a511a0-a3bb-11df-860e-0002a5d5c51b");
 
     private EnvironmentalReverb mReverb = null;
     private int mSession = -1;
@@ -354,10 +362,10 @@
             // creating a volume controller on output mix ensures that ro.audio.silent mutes
             // audio after the effects and not before
             vc = new AudioEffect(
-                    AudioEffect.EFFECT_TYPE_NULL,
-                    UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"),
-                      0,
-                      0);
+                                AudioEffect.EFFECT_TYPE_NULL,
+                                VOLUME_EFFECT_UUID,
+                                0,
+                                0);
             vc.setEnabled(true);
 
             mp = new MediaPlayer();
@@ -424,10 +432,10 @@
             // creating a volume controller on output mix ensures that ro.audio.silent mutes
             // audio after the effects and not before
             vc = new AudioEffect(
-                    AudioEffect.EFFECT_TYPE_NULL,
-                    UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"),
-                      0,
-                      0);
+                                AudioEffect.EFFECT_TYPE_NULL,
+                                VOLUME_EFFECT_UUID,
+                                0,
+                                0);
             vc.setEnabled(true);
 
             mp = new MediaPlayer();
@@ -438,7 +446,7 @@
             // auxiliary reverb will be chosen by the effect framework as we are on session 0
             rvb = new AudioEffect(
                         AudioEffect.EFFECT_TYPE_NULL,
-                        UUID.fromString("c7a511a0-a3bb-11df-860e-0002a5d5c51b"),
+                        ENV_REVERB_EFFECT_UUID,
                         0,
                         0);
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaEqualizerTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaEqualizerTest.java
index 9146fb8..459f551 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaEqualizerTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaEqualizerTest.java
@@ -49,6 +49,11 @@
     private final static int TEST_FREQUENCY_MILLIHERTZ = 1000000;
     private final static int MIN_NUMBER_OF_PRESETS = 4;
     private final static int TEST_VOLUME = 4;
+    // Implementor UUID for volume controller effect defined in
+    // frameworks/base/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+    private final static UUID VOLUME_EFFECT_UUID =
+        UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b");
+
     private Equalizer mEqualizer = null;
     private int mSession = -1;
 
@@ -267,10 +272,10 @@
             // creating a volume controller on output mix ensures that ro.audio.silent mutes
             // audio after the effects and not before
             vc = new AudioEffect(
-                    AudioEffect.EFFECT_TYPE_NULL,
-                    UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"),
-                      0,
-                      0);
+                                AudioEffect.EFFECT_TYPE_NULL,
+                                VOLUME_EFFECT_UUID,
+                                0,
+                                0);
             vc.setEnabled(true);
 
             mp = new MediaPlayer();
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPresetReverbTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPresetReverbTest.java
index 242e6bb..8cc070e 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPresetReverbTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPresetReverbTest.java
@@ -43,6 +43,14 @@
  */
 public class MediaPresetReverbTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
     private String TAG = "MediaPresetReverbTest";
+    // Implementor UUID for volume controller effect defined in
+    // frameworks/base/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+    private final static UUID VOLUME_EFFECT_UUID =
+        UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b");
+    // Implementor UUID for preset reverb effect defined in
+    // frameworks/base/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+    private final static UUID PRESET_REVERB_EFFECT_UUID =
+        UUID.fromString("172cdf00-a3bc-11df-a72f-0002a5d5c51b");
 
     private PresetReverb mReverb = null;
     private int mSession = -1;
@@ -199,10 +207,10 @@
             // creating a volume controller on output mix ensures that ro.audio.silent mutes
             // audio after the effects and not before
             vc = new AudioEffect(
-                    AudioEffect.EFFECT_TYPE_NULL,
-                    UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"),
-                      0,
-                      0);
+                                AudioEffect.EFFECT_TYPE_NULL,
+                                VOLUME_EFFECT_UUID,
+                                0,
+                                0);
             vc.setEnabled(true);
 
             mp = new MediaPlayer();
@@ -267,24 +275,21 @@
             // creating a volume controller on output mix ensures that ro.audio.silent mutes
             // audio after the effects and not before
             vc = new AudioEffect(
-                    AudioEffect.EFFECT_TYPE_NULL,
-                    UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"),
-                      0,
-                      0);
+                                AudioEffect.EFFECT_TYPE_NULL,
+                                VOLUME_EFFECT_UUID,
+                                0,
+                                0);
             vc.setEnabled(true);
 
             mp = new MediaPlayer();
             mp.setDataSource(MediaNames.SINE_200_1000);
             mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
-            getReverb(mp.getAudioSessionId());
-            mReverb.setPreset((short)PresetReverb.PRESET_PLATE);
-            mReverb.setEnabled(true);
 
             // create reverb with UUID instead of PresetReverb constructor otherwise an auxiliary
             // reverb will be chosen by the effect framework as we are on session 0
             rvb = new AudioEffect(
                         AudioEffect.EFFECT_TYPE_NULL,
-                        UUID.fromString("172cdf00-a3bc-11df-a72f-0002a5d5c51b"),
+                        PRESET_REVERB_EFFECT_UUID,
                         0,
                         0);
 
@@ -317,7 +322,6 @@
             loge(msg, "sleep() interrupted");
         }
         finally {
-            releaseReverb();
             if (mp != null) {
                 mp.release();
             }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaVirtualizerTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaVirtualizerTest.java
index 7a35429..3d3c011 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaVirtualizerTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaVirtualizerTest.java
@@ -43,9 +43,13 @@
  */
 public class MediaVirtualizerTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
     private String TAG = "MediaVirtualizerTest";
-    private final static int MIN_ENERGY_RATIO_2 = 3;
+    private final static int MIN_ENERGY_RATIO_2 = 2;
     private final static short TEST_STRENGTH = 500;
     private final static int TEST_VOLUME = 4;
+    // Implementor UUID for volume controller effect defined in
+    // frameworks/base/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+    private final static UUID VOLUME_EFFECT_UUID =
+        UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b");
 
     private Virtualizer mVirtualizer = null;
     private int mSession = -1;
@@ -202,14 +206,15 @@
             // creating a volume controller on output mix ensures that ro.audio.silent mutes
             // audio after the effects and not before
             vc = new AudioEffect(
-                    AudioEffect.EFFECT_TYPE_NULL,
-                    UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"),
-                      0,
-                      0);
+                                AudioEffect.EFFECT_TYPE_NULL,
+                                VOLUME_EFFECT_UUID,
+                                0,
+                                0);
             vc.setEnabled(true);
 
             mp = new MediaPlayer();
             mp.setDataSource(MediaNames.SINE_200_1000);
+            mp.setLooping(true);
             mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
             getVirtualizer(mp.getAudioSessionId());
             mp.prepare();
@@ -220,7 +225,7 @@
             int refEnergy1000 = probe.capture(1000);
             mVirtualizer.setStrength((short)1000);
             mVirtualizer.setEnabled(true);
-            Thread.sleep(500);
+            Thread.sleep(4000);
             // measure energy around 1kHz with band level at min
             int energy200 = probe.capture(200);
             int energy1000 = probe.capture(1000);
@@ -230,7 +235,7 @@
             // audio file but is not the primary effect of the virtualizer. A better way would
             // be to have a stereo PCM capture and check that a strongly paned input is centered
             // when output. However, we cannot capture stereo with the visualizer.
-            assertTrue(msg + ": virtiualizer has no effect",
+            assertTrue(msg + ": virtualizer has no effect",
                     ((float)energy200/(float)energy1000) >
                     (MIN_ENERGY_RATIO_2 * ((float)refEnergy200/(float)refEnergy1000)));
             result = true;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaVisualizerTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaVisualizerTest.java
index 542ca8d..0d5c6b4 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaVisualizerTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaVisualizerTest.java
@@ -47,6 +47,10 @@
     private final static int MAX_SAMPLING_RATE = 48000000;
     private final static int MIN_CAPTURE_SIZE_MAX = 1024;
     private final static int MAX_CAPTURE_SIZE_MIN = 128;
+    // Implementor UUID for volume controller effect defined in
+    // frameworks/base/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+    private final static UUID VOLUME_EFFECT_UUID =
+        UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b");
 
     private Visualizer mVisualizer = null;
     private int mSession = -1;
@@ -205,10 +209,10 @@
             // creating a volume controller on output mix ensures that ro.audio.silent mutes
             // audio after the effects and not before
             vc = new AudioEffect(
-                    AudioEffect.EFFECT_TYPE_NULL,
-                    UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"),
-                      0,
-                      0);
+                                AudioEffect.EFFECT_TYPE_NULL,
+                                VOLUME_EFFECT_UUID,
+                                0,
+                                0);
             vc.setEnabled(true);
 
             mp = new MediaPlayer();
@@ -281,10 +285,10 @@
             // creating a volume controller on output mix ensures that ro.audio.silent mutes
             // audio after the effects and not before
             vc = new AudioEffect(
-                    AudioEffect.EFFECT_TYPE_NULL,
-                    UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"),
-                      0,
-                      0);
+                                AudioEffect.EFFECT_TYPE_NULL,
+                                VOLUME_EFFECT_UUID,
+                                0,
+                                0);
             vc.setEnabled(true);
 
             mp = new MediaPlayer();
diff --git a/packages/SystemUI/res/drawable/notification_row_bg.xml b/packages/SystemUI/res/drawable/notification_row_bg.xml
new file mode 100644
index 0000000..dc626d1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/notification_row_bg.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:exitFadeDuration="@android:integer/config_mediumAnimTime">
+
+    <item android:state_pressed="true"  android:drawable="@android:color/holo_blue_light" />
+    <item android:state_pressed="false" android:drawable="@drawable/notification_item_background_color" />
+</selector>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index ff86878..3220e62 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -23,6 +23,7 @@
         android:layout_alignParentLeft="true"
         android:scaleType="center"
         android:clickable="true"
+        android:background="@*android:drawable/notify_panel_notification_icon_bg_tile"
         />
 
     <com.android.systemui.statusbar.LatestItemView android:id="@+id/content"
@@ -33,14 +34,14 @@
         android:layout_alignParentRight="true"
         android:focusable="true"
         android:clickable="true"
-        android:background="@drawable/notification_item_background_color"
+        android:background="@drawable/notification_row_bg"
         />
 
     <View
         android:layout_width="match_parent"
         android:layout_height="@dimen/notification_divider_height"
         android:layout_alignParentBottom="true"
-        android:background="@drawable/status_bar_notification_row_background_color"
+        android:background="@drawable/notification_item_background_color"
         />
 
 </RelativeLayout>
diff --git a/packages/SystemUI/res/values-ar-xlarge/strings.xml b/packages/SystemUI/res/values-ar-xlarge/strings.xml
deleted file mode 100644
index d4fb873..0000000
--- a/packages/SystemUI/res/values-ar-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"محو الكل"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"لا اتصال بالإنترنت"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi متصل"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"جارٍ البحث عن GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"تم تعيين الموقع بواسطة GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"إيقاف التنبيهات"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"انقر هنا لإعادة تشغيل التنبيهات."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-bg-xlarge/strings.xml b/packages/SystemUI/res/values-bg-xlarge/strings.xml
deleted file mode 100644
index 4e730ae..0000000
--- a/packages/SystemUI/res/values-bg-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Изчистване"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Няма връзка с интернет"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: има връзка"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Търси се GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Местоположението е зададено от GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Известията са изключени"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Докоснете тук, за да включите отново известията."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-ca-xlarge/strings.xml b/packages/SystemUI/res/values-ca-xlarge/strings.xml
deleted file mode 100644
index 9fc74d0..0000000
--- a/packages/SystemUI/res/values-ca-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Esborra-ho"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"No connexió Internet"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: connectat"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"S\'està cercant un GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"S\'ha establert la ubicació per GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Notificacions desactivades"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Pica aquí per tornar a activar les notificacions."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-cs-xlarge/strings.xml b/packages/SystemUI/res/values-cs-xlarge/strings.xml
deleted file mode 100644
index 05b1248..0000000
--- a/packages/SystemUI/res/values-cs-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Vymazat vše"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Žádné připojení"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: připojeno"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Vyhledávání satelitů GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Poloha nastavena pomocí GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Oznámení jsou vypnuta"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Chcete-li oznámení znovu zapnout, klepněte sem."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-da-xlarge/strings.xml b/packages/SystemUI/res/values-da-xlarge/strings.xml
deleted file mode 100644
index dd20e64..0000000
--- a/packages/SystemUI/res/values-da-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Ryd alt"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Ingen internetforb."</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi er forbundet"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Søger efter GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Placeringen er angivet ved hjælp af GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Meddelelser: Fra"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Tryk her for at slå meddelelser til igen."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-de-xlarge/strings.xml b/packages/SystemUI/res/values-de-xlarge/strings.xml
deleted file mode 100644
index cc782da..0000000
--- a/packages/SystemUI/res/values-de-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Alle löschen"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Keine Internetverbindung"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Mit WLAN verbunden"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Suche nach GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Standort durch GPS festgelegt"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Benachrichtigungen aus"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Tippen Sie hier, um Benachrichtigungen wieder einzuschalten."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-el-xlarge/strings.xml b/packages/SystemUI/res/values-el-xlarge/strings.xml
deleted file mode 100644
index 4f7814a..0000000
--- a/packages/SystemUI/res/values-el-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Διαγ. όλων"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Χωρίς σύνδ. σε Διαδ."</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: συνδέθηκε"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Αναζήτηση για GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Ρύθμιση τοποθεσίας με GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Ειδοποιήσεις ανενεργές"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Πατήστε εδώ για να ενεργοποιήσετε τις ειδοποιήσεις"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-en-rGB-xlarge/strings.xml b/packages/SystemUI/res/values-en-rGB-xlarge/strings.xml
deleted file mode 100644
index 68986f0..0000000
--- a/packages/SystemUI/res/values-en-rGB-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Clear all"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"No Internet connection"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi connected"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Searching for GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Location set by GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Notifications off"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Tap here to turn notifications back on."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml b/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml
deleted file mode 100644
index fa9b762..0000000
--- a/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Eliminar todos"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Sin conexión a Int."</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"WiFi conectado"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Buscando GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"La ubicación se estableció por GPS."</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Notificaciones desactivadas"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Presiona aquí para volver a activar las notificaciones."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-es-xlarge/strings.xml b/packages/SystemUI/res/values-es-xlarge/strings.xml
deleted file mode 100644
index a7588da..0000000
--- a/packages/SystemUI/res/values-es-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Borrar todo"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Sin conexión a Internet"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Con conexión WiFi"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Buscando GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Ubicación definida por GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Notificaciones desactivadas"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Toca aquí para volver a activar las notificaciones."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-fa-xlarge/strings.xml b/packages/SystemUI/res/values-fa-xlarge/strings.xml
deleted file mode 100644
index a8e2543..0000000
--- a/packages/SystemUI/res/values-fa-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"پاک کردن همه"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"اتصال اینترنت موجود نیست"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi متصل شد"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"جستجوی GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"مکان تنظیم شده توسط GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"اعلان ها خاموش"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"برای روشن کردن مجدد اعلان ها، اینجا را ضربه بزنید."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-fi-xlarge/strings.xml b/packages/SystemUI/res/values-fi-xlarge/strings.xml
deleted file mode 100644
index 754c577..0000000
--- a/packages/SystemUI/res/values-fi-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Poista kaikki"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Ei internetyhteyttä"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wifi yhdistetty"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Haetaan GPS-yhteyttä"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Sijainti määritetty GPS:n avulla"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Ilmoitukset pois käytöstä"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Ota ilmoitukset uudelleen käyttöön napauttamalla tätä."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-fr-xlarge/strings.xml b/packages/SystemUI/res/values-fr-xlarge/strings.xml
deleted file mode 100644
index 08f673d..0000000
--- a/packages/SystemUI/res/values-fr-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Tout effacer"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Aucune connexion Internet"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Connecté au Wi-Fi"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Recherche de GPS en cours"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Position définie par GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Notifications désactivées"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Appuyez ici pour réactiver les notifications."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-hr-xlarge/strings.xml b/packages/SystemUI/res/values-hr-xlarge/strings.xml
deleted file mode 100644
index b6e15dc..0000000
--- a/packages/SystemUI/res/values-hr-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Izbriši sve"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Nema int. veze"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: povezano"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Pretraživanje GPS-a"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Lokaciju utvrdio GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Obavijesti isključene"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Dotaknite ovdje da biste ponovo uključili obavijesti."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-hu-xlarge/strings.xml b/packages/SystemUI/res/values-hu-xlarge/strings.xml
deleted file mode 100644
index fe2e5ee..0000000
--- a/packages/SystemUI/res/values-hu-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Össz.törl."</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Nincs internetkapcs."</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi csatlakozva"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"GPS keresése"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"A GPS beállította a helyet"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Értesítések kikapcsolva"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Itt érintse meg az értesítések bekapcsolásához."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-in-xlarge/strings.xml b/packages/SystemUI/res/values-in-xlarge/strings.xml
deleted file mode 100644
index a4ca341..0000000
--- a/packages/SystemUI/res/values-in-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Hapus semua"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Tidak ada sambungan internet"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi tersambung"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Menelusuri GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Lokasi yang disetel oleh GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Pemberitahuan mati"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Ketuk di sini untuk menghidupkan lagi pemberitahuan."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-it-xlarge/strings.xml b/packages/SystemUI/res/values-it-xlarge/strings.xml
deleted file mode 100644
index 24d88744..0000000
--- a/packages/SystemUI/res/values-it-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Canc. tutto"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"No connessione Internet"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: connesso"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Ricerca del GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Posizione stabilita dal GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Notifiche disattivate"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Tocca qui per riattivare le notifiche."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-iw-xlarge/strings.xml b/packages/SystemUI/res/values-iw-xlarge/strings.xml
deleted file mode 100644
index 97172b8..0000000
--- a/packages/SystemUI/res/values-iw-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"נקה הכל"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"אין חיבור לאינטרנט"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi מחובר"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"מחפש GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"מיקום מוגדר על ידי GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"מצב התראות כבוי"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"הקש כאן כדי להפעיל מחדש את ההתראות."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-ja-xlarge/strings.xml b/packages/SystemUI/res/values-ja-xlarge/strings.xml
deleted file mode 100644
index e67e0e1..0000000
--- a/packages/SystemUI/res/values-ja-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"すべて消去"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"インターネット未接続"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi接続済み"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"GPSで検索中"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"GPSにより現在地が設定されました"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"通知OFF"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"通知を有効にするにはここをタップします。"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-ko-xlarge/strings.xml b/packages/SystemUI/res/values-ko-xlarge/strings.xml
deleted file mode 100644
index e28ac63..0000000
--- a/packages/SystemUI/res/values-ko-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"모두 지우기"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"인터넷에 연결되지 않음"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi 연결됨"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"GPS 검색"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"GPS에서 설정한 위치"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"알림 사용 안함"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"알림을 다시 사용하려면 여기를 누르세요."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-lt-xlarge/strings.xml b/packages/SystemUI/res/values-lt-xlarge/strings.xml
deleted file mode 100644
index 12e8bb3..0000000
--- a/packages/SystemUI/res/values-lt-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Išv. viską"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Nėra interneto ryšio"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Prisijungta prie „Wi-Fi“"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Ieškoma GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"GPS nustatyta vieta"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Pranešimai išjungti"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Palieskite čia, kad vėl įjungtumėte pranešimus."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-lv-xlarge/strings.xml b/packages/SystemUI/res/values-lv-xlarge/strings.xml
deleted file mode 100644
index aecb471..0000000
--- a/packages/SystemUI/res/values-lv-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Notīr.visu"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Nav interneta sav."</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Izv. sav. ar Wi-Fi"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Notiek GPS meklēšana..."</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"GPS iestatītā atrašanās vieta"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Paziņojumi ir izslēgti."</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Pieskarieties šeit, lai vēlreiz ieslēgtu paziņojumus."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-nb-xlarge/strings.xml b/packages/SystemUI/res/values-nb-xlarge/strings.xml
deleted file mode 100644
index 717ee79..0000000
--- a/packages/SystemUI/res/values-nb-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Tøm alt"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Ingen Int.-tilkobl."</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: tilkoblet"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Søker etter GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Posisjon angitt av GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Varslinger er slått av"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Trykk her for å slå på varslinger igjen."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-nl-xlarge/strings.xml b/packages/SystemUI/res/values-nl-xlarge/strings.xml
deleted file mode 100644
index 7c84a7a..0000000
--- a/packages/SystemUI/res/values-nl-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Wissen"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Geen internetverb."</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Verbonden via Wi-Fi"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Zoeken naar GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Locatie bepaald met GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Meldingen uit"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Tik hier om meldingen weer in te schakelen."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-pl-xlarge/strings.xml b/packages/SystemUI/res/values-pl-xlarge/strings.xml
deleted file mode 100644
index 9db1cab..0000000
--- a/packages/SystemUI/res/values-pl-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Wyczyść wszystko"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Brak połączenia internetowego"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: połączono"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Wyszukiwanie sygnału GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Lokalizacja ustawiona wg GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Powiadomienia wyłączone"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Dotknij tutaj, aby z powrotem włączyć powiadomienia."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT-xlarge/strings.xml b/packages/SystemUI/res/values-pt-rPT-xlarge/strings.xml
deleted file mode 100644
index 7860208..0000000
--- a/packages/SystemUI/res/values-pt-rPT-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Limpar tudo"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Sem ligação internet"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi ligado"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"A procurar GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Localização definida por GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Notificações desativadas"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Toque aqui para voltar a ativar as notificações."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-pt-xlarge/strings.xml b/packages/SystemUI/res/values-pt-xlarge/strings.xml
deleted file mode 100644
index 2a1786d..0000000
--- a/packages/SystemUI/res/values-pt-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Limpar tudo"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Sem conex. à inter."</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi conectado"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Procurando GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Localização definida por GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Notificações desativadas"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Toque aqui para ativar novamente as notificações."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-ro-xlarge/strings.xml b/packages/SystemUI/res/values-ro-xlarge/strings.xml
deleted file mode 100644
index 21fd0ad..0000000
--- a/packages/SystemUI/res/values-ro-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Şterg. tot"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Fără conex. internet"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi conectat"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Se caută dispozitivul GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Locaţie setată prin GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Notificările sunt dezactivate"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Apăsaţi aici pentru a reactiva notificările."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-ru-xlarge/strings.xml b/packages/SystemUI/res/values-ru-xlarge/strings.xml
deleted file mode 100644
index bc31fb1..0000000
--- a/packages/SystemUI/res/values-ru-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Удалить все"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Нет подключения"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi подкл."</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Выполняется поиск при помощи GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Местоположение установлено при помощи GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Показ уведомлений отключен"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Нажмите здесь, чтобы снова включить показ уведомлений."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-sk-xlarge/strings.xml b/packages/SystemUI/res/values-sk-xlarge/strings.xml
deleted file mode 100644
index ee9e613..0000000
--- a/packages/SystemUI/res/values-sk-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Vymazať všetky"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Nepripoj. k Intern."</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: pripojené"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Hľadanie signálu GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Poloha určená pomocou GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Upozornenia sú vypnuté"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Klepnutím tu upozornenia znova povolíte."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-sl-xlarge/strings.xml b/packages/SystemUI/res/values-sl-xlarge/strings.xml
deleted file mode 100644
index 57ed9a7..0000000
--- a/packages/SystemUI/res/values-sl-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Izbriši vse"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Brez inter. povez."</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi – povezano"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Iskanje GPS-a"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Lokacija nastavljena z GPS-om"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Obvestila izklopljena"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Tapnite tukaj, da spet vklopite obvestila."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-sr-xlarge/strings.xml b/packages/SystemUI/res/values-sr-xlarge/strings.xml
deleted file mode 100644
index 95fbc2f..0000000
--- a/packages/SystemUI/res/values-sr-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Обриши све"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Нема интернет везе"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi је повезан"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Тражи се GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Локацију је подесио GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Обавештења су искључена"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Додирните овде да бисте поново укључили обавештења."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-sv-xlarge/strings.xml b/packages/SystemUI/res/values-sv-xlarge/strings.xml
deleted file mode 100644
index ce608c2..0000000
--- a/packages/SystemUI/res/values-sv-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Ta bort alla"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Ingen Internetansl."</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi-ansluten"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Sökning efter GPS pågår"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Platsen har identifierats av GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Aviseringar inaktiverade"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Knacka lätt här om du vill aktivera aviseringar igen."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-th-xlarge/strings.xml b/packages/SystemUI/res/values-th-xlarge/strings.xml
deleted file mode 100644
index 824de38..0000000
--- a/packages/SystemUI/res/values-th-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"ล้างหมด"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"ไม่มีการเชื่อมต่ออินเทอร์เน็ต"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"เชื่อมต่อ Wi-Fi แล้ว"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"การค้นหาสำหรับ GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"ตำแหน่งที่กำหนดโดย GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"การแจ้งเตือนปิดอยู่"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"แตะที่นี่เพื่อเปิดการแจ้งเตือนอีกครั้ง"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-tl-xlarge/strings.xml b/packages/SystemUI/res/values-tl-xlarge/strings.xml
deleted file mode 100644
index 582adbc..0000000
--- a/packages/SystemUI/res/values-tl-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"I-clear lahat"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Wala net connection"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Konektado ang WiFi"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Naghahanap ng GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Lokasyon na itinatakda ng GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Naka-off ang mga notification"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Mag-tap dito upang i-on muli ang mga notification."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-tr-xlarge/strings.xml b/packages/SystemUI/res/values-tr-xlarge/strings.xml
deleted file mode 100644
index 6db515f..0000000
--- a/packages/SystemUI/res/values-tr-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Tümünü temizle"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"İnternet bağlnts yok"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Kablosuz bağlandı"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"GPS aranıyor"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Konum GPS ile belirlendi"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Bildirimler kapalı"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Bildirimleri tekrar açmak için buraya hafifçe vurun."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-uk-xlarge/strings.xml b/packages/SystemUI/res/values-uk-xlarge/strings.xml
deleted file mode 100644
index 81e50c0..0000000
--- a/packages/SystemUI/res/values-uk-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Очист. все"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Інтернет не під\'єдн."</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi під\'єднано"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Виконується пошук за допомогою GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Місцезнаходження встановлено за допомогою GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Сповіщення вимкнено"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Торкніться тут, щоб знову ввімкнути сповіщення."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-vi-xlarge/strings.xml b/packages/SystemUI/res/values-vi-xlarge/strings.xml
deleted file mode 100644
index 6382fae..0000000
--- a/packages/SystemUI/res/values-vi-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Xóa tất cả"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Không có kết nối Internet"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Đã kết nối Wi-Fi"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"Tìm kiếm GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"Vị trí đặt bởi GPS"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"Tắt thông báo"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"Chạm vào đây để bật lại thông báo."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN-xlarge/strings.xml b/packages/SystemUI/res/values-zh-rCN-xlarge/strings.xml
deleted file mode 100644
index 207ebe4..0000000
--- a/packages/SystemUI/res/values-zh-rCN-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"全部清除"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"未连接至互联网"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi 已连接"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"正在搜索 GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"GPS 设置的位置"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"通知已关闭"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"点按此处可以重新打开通知。"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW-xlarge/strings.xml b/packages/SystemUI/res/values-zh-rTW-xlarge/strings.xml
deleted file mode 100644
index 14a10f2..0000000
--- a/packages/SystemUI/res/values-zh-rTW-xlarge/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="status_bar_clear_all_button" msgid="4722520806446512408">"全部清除"</string>
-    <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"沒有網路連線"</string>
-    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi 已連線"</string>
-    <string name="gps_notification_searching_text" msgid="894185519046488403">"正在搜尋 GPS"</string>
-    <string name="gps_notification_found_text" msgid="5306445324124275852">"GPS 已定位"</string>
-    <string name="notifications_off_title" msgid="2297252328026582111">"關閉通知"</string>
-    <string name="notifications_off_text" msgid="3754847213329718358">"輕觸這裡即可重新開啟通知。"</string>
-</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index da6bcd2..25b1bc1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -896,14 +896,6 @@
         }
     }
 
-    void workAroundBadLayerDrawableOpacity(View v) {
-        LayerDrawable d = (LayerDrawable)v.getBackground();
-        if (d == null) return;
-        v.setBackgroundDrawable(null);
-        d.setOpacity(PixelFormat.TRANSLUCENT);
-        v.setBackgroundDrawable(d);
-    }
-
     private boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
         StatusBarNotification sbn = entry.notification;
         RemoteViews remoteViews = sbn.notification.contentView;
@@ -915,7 +907,6 @@
         LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
         View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
-        workAroundBadLayerDrawableOpacity(row);
         View vetoButton = row.findViewById(R.id.veto);
         if (entry.notification.isClearable()) {
             final String _pkg = sbn.pkg;
@@ -1608,6 +1599,9 @@
                 // the user switches to home.  We know it is safe to do at this
                 // point, so make sure new activity switches are now allowed.
                 ActivityManagerNative.getDefault().resumeAppSwitches();
+                // Also, notifications can be launched from the lock screen,
+                // so dismiss the lock screen when the activity starts.
+                ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
             } catch (RemoteException e) {
             }
 
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 c2f07d6..435aa8c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -1308,6 +1308,9 @@
                 // the user switches to home.  We know it is safe to do at this
                 // point, so make sure new activity switches are now allowed.
                 ActivityManagerNative.getDefault().resumeAppSwitches();
+                // Also, notifications can be launched from the lock screen,
+                // so dismiss the lock screen when the activity starts.
+                ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
             } catch (RemoteException e) {
             }
 
diff --git a/policy/src/com/android/internal/policy/impl/AccountUnlockScreen.java b/policy/src/com/android/internal/policy/impl/AccountUnlockScreen.java
index f7d936c..a4baeed 100644
--- a/policy/src/com/android/internal/policy/impl/AccountUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/AccountUnlockScreen.java
@@ -54,7 +54,7 @@
 public class AccountUnlockScreen extends RelativeLayout implements KeyguardScreen,
         View.OnClickListener, TextWatcher {
     private static final String LOCK_PATTERN_PACKAGE = "com.android.settings";
-    private static final String LOCK_PATTERN_CLASS = LOCK_PATTERN_PACKAGE + ".ChooseLockPattern";
+    private static final String LOCK_PATTERN_CLASS = LOCK_PATTERN_PACKAGE + ".ChooseLockGeneric";
 
     /**
      * The amount of millis to stay awake once this screen detects activity
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index d9bd5f2b..ffb4838 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -114,6 +114,10 @@
     private final int MSG_SHOW_FACELOCK_AREA_VIEW = 0;
     private final int MSG_HIDE_FACELOCK_AREA_VIEW = 1;
 
+    // Long enough to stay black while dialer comes up
+    // Short enough to not be black if the user goes back immediately
+    private final int FACELOCK_VIEW_AREA_EMERGENCY_HIDE_TIMEOUT = 1000;
+
     /**
      * The current {@link KeyguardScreen} will use this to communicate back to us.
      */
@@ -311,6 +315,13 @@
             }
 
             public void takeEmergencyCallAction() {
+                // FaceLock must be stopped if it is running when emergency call is pressed
+                stopAndUnbindFromFaceLock();
+
+                // Delay hiding FaceLock area so unlock doesn't display while dialer is coming up
+                mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACELOCK_AREA_VIEW,
+                        FACELOCK_VIEW_AREA_EMERGENCY_HIDE_TIMEOUT);
+
                 pokeWakelock(EMERGENCY_CALL_TIMEOUT);
                 if (TelephonyManager.getDefault().getCallState()
                         == TelephonyManager.CALL_STATE_OFFHOOK) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 53b64a6..d562f15 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -2762,28 +2762,30 @@
                     }
 
                     boolean splitActionBar = false;
-                    if ((mUiOptions & ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW) != 0) {
+                    final boolean splitWhenNarrow =
+                            (mUiOptions & ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW) != 0;
+                    if (splitWhenNarrow) {
                         splitActionBar = getContext().getResources().getBoolean(
                                 com.android.internal.R.bool.split_action_bar_is_narrow);
                     } else {
                         splitActionBar = getWindowStyle().getBoolean(
                                 com.android.internal.R.styleable.Window_windowSplitActionBar, false);
                     }
-                    if (splitActionBar) {
-                        final ActionBarContainer splitView = (ActionBarContainer) findViewById(
-                                com.android.internal.R.id.split_action_bar);
-                        if (splitView != null) {
-                            splitView.setVisibility(View.VISIBLE);
-                            mActionBar.setSplitActionBar(splitActionBar);
-                            mActionBar.setSplitView(splitView);
+                    final ActionBarContainer splitView = (ActionBarContainer) findViewById(
+                            com.android.internal.R.id.split_action_bar);
+                    if (splitView != null) {
+                        mActionBar.setSplitView(splitView);
+                        mActionBar.setSplitActionBar(splitActionBar);
+                        mActionBar.setSplitWhenNarrow(splitWhenNarrow);
 
-                            final ActionBarContextView cab = (ActionBarContextView) findViewById(
-                                    com.android.internal.R.id.action_context_bar);
-                            cab.setSplitView(splitView);
-                        } else {
-                            Log.e(TAG, "Requested split action bar with " +
-                                    "incompatible window decor! Ignoring request.");
-                        }
+                        final ActionBarContextView cab = (ActionBarContextView) findViewById(
+                                com.android.internal.R.id.action_context_bar);
+                        cab.setSplitView(splitView);
+                        cab.setSplitActionBar(splitActionBar);
+                        cab.setSplitWhenNarrow(splitWhenNarrow);
+                    } else if (splitActionBar) {
+                        Log.e(TAG, "Requested split action bar with " +
+                                "incompatible window decor! Ignoring request.");
                     }
 
                     // Post the panel invalidate for later; avoid application onCreateOptionsMenu
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index b0abd97..968180c 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -446,9 +446,8 @@
         }
         
         @Override
-        public void onOrientationChanged(int rotation) {
-            // Send updates based on orientation value
-            if (localLOGV) Log.v(TAG, "onOrientationChanged, rotation changed to " +rotation);
+        public void onProposedRotationChanged(int rotation) {
+            if (localLOGV) Log.v(TAG, "onProposedRotationChanged, rotation=" + rotation);
             updateRotation(false);
         }
     }
@@ -654,6 +653,9 @@
         mKeyguardMediator = new KeyguardViewMediator(context, this, powerManager);
         mHandler = new Handler();
         mOrientationListener = new MyOrientationListener(mContext);
+        try {
+            mOrientationListener.setCurrentRotation(windowManager.getRotation());
+        } catch (RemoteException ex) { }
         SettingsObserver settingsObserver = new SettingsObserver(mHandler);
         settingsObserver.observe();
         mShortcutManager = new ShortcutManager(context, mHandler);
@@ -2871,6 +2873,18 @@
         return mKeyguardMediator.isInputRestricted();
     }
 
+    public void dismissKeyguardLw() {
+        if (!mKeyguardMediator.isSecure()) {
+            if (mKeyguardMediator.isShowing()) {
+                mHandler.post(new Runnable() {
+                    public void run() {
+                        mKeyguardMediator.keyguardDone(false, true);
+                    }
+                });
+            }
+        }
+    }
+
     void sendCloseSystemWindows() {
         sendCloseSystemWindows(mContext, null);
     }
@@ -2900,7 +2914,10 @@
         }
 
         synchronized (mLock) {
-            int sensorRotation = mOrientationListener.getCurrentRotation(); // may be -1
+            int sensorRotation = mOrientationListener.getProposedRotation(); // may be -1
+            if (sensorRotation < 0) {
+                sensorRotation = lastRotation;
+            }
 
             int preferredRotation = -1;
             if (mHdmiPlugged) {
@@ -2910,20 +2927,18 @@
                 // Ignore sensor when lid switch is open and rotation is forced.
                 preferredRotation = mLidOpenRotation;
             } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR
-                    && ((mCarDockEnablesAccelerometer && sensorRotation >= 0)
-                            || mCarDockRotation >= 0)) {
+                    && (mCarDockEnablesAccelerometer || mCarDockRotation >= 0)) {
                 // Ignore sensor when in car dock unless explicitly enabled.
                 // This case can override the behavior of NOSENSOR, and can also
                 // enable 180 degree rotation while docked.
-                preferredRotation = mCarDockEnablesAccelerometer && sensorRotation >= 0
+                preferredRotation = mCarDockEnablesAccelerometer
                         ? sensorRotation : mCarDockRotation;
             } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK
-                    && ((mDeskDockEnablesAccelerometer && sensorRotation >= 0)
-                            || mDeskDockRotation >= 0)) {
+                    && (mDeskDockEnablesAccelerometer || mDeskDockRotation >= 0)) {
                 // Ignore sensor when in desk dock unless explicitly enabled.
                 // This case can override the behavior of NOSENSOR, and can also
                 // enable 180 degree rotation while docked.
-                preferredRotation = mDeskDockEnablesAccelerometer && sensorRotation >= 0
+                preferredRotation = mDeskDockEnablesAccelerometer
                         ? sensorRotation : mDeskDockRotation;
             } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
                 // Ignore sensor when user locked rotation.
@@ -3024,6 +3039,11 @@
         }
     }
 
+    @Override
+    public void setRotationLw(int rotation) {
+        mOrientationListener.setCurrentRotation(rotation);
+    }
+
     private boolean isLandscapeOrSeascape(int rotation) {
         return rotation == mLandscapeRotation || rotation == mSeascapeRotation;
     }
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index a58f64c..88a05b2 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -7440,12 +7440,21 @@
     }
 }
 
+
+// The volume effect is used for automated tests only
+#ifndef OPENSL_ES_H_
+static const effect_uuid_t SL_IID_VOLUME_ = { 0x09e8ede0, 0xddde, 0x11db, 0xb4f6,
+                                            { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const effect_uuid_t * const SL_IID_VOLUME = &SL_IID_VOLUME_;
+#endif //OPENSL_ES_H_
+
 bool AudioFlinger::EffectChain::isEffectEligibleForSuspend(const effect_descriptor_t& desc)
 {
     // auxiliary effects and visualizer are never suspended on output mix
     if ((mSessionId == AUDIO_SESSION_OUTPUT_MIX) &&
         (((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) ||
-         (memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0))) {
+         (memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) ||
+         (memcmp(&desc.type, SL_IID_VOLUME, sizeof(effect_uuid_t)) == 0))) {
         return false;
     }
     return true;
diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/java/com/android/server/AlarmManagerService.java
index 5ffcdc5..b8c44d9 100644
--- a/services/java/com/android/server/AlarmManagerService.java
+++ b/services/java/com/android/server/AlarmManagerService.java
@@ -477,7 +477,7 @@
                         : bs.filterStats.entrySet()) {
                     pw.print("    "); pw.print(fe.getValue().count);
                             pw.print(" alarms: ");
-                            pw.println(fe.getKey().getIntent().toShortString(true, false));
+                            pw.println(fe.getKey().getIntent().toShortString(false, true, false));
                 }
             }
         }
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 327450a..991b7da 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -35,6 +35,7 @@
 import android.net.IConnectivityManager;
 import android.net.INetworkPolicyListener;
 import android.net.INetworkPolicyManager;
+import android.net.INetworkStatsService;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.LinkProperties.CompareResult;
@@ -306,8 +307,8 @@
     // the set of network types that can only be enabled by system/sig apps
     List mProtectedNetworks;
 
-    public ConnectivityService(
-            Context context, INetworkManagementService netd, INetworkPolicyManager policyManager) {
+    public ConnectivityService(Context context, INetworkManagementService netd,
+            INetworkStatsService statsService, INetworkPolicyManager policyManager) {
         if (DBG) log("ConnectivityService starting up");
 
         HandlerThread handlerThread = new HandlerThread("ConnectivityServiceThread");
@@ -496,7 +497,7 @@
         IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
         INetworkManagementService nmService = INetworkManagementService.Stub.asInterface(b);
 
-        mTethering = new Tethering(mContext, nmService, mHandler.getLooper());
+        mTethering = new Tethering(mContext, nmService, statsService, mHandler.getLooper());
         mTetheringConfigValid = ((mTethering.getTetherableUsbRegexs().length != 0 ||
                                   mTethering.getTetherableWifiRegexs().length != 0 ||
                                   mTethering.getTetherableBluetoothRegexs().length != 0) &&
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 977dd6f..72d1917 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -364,7 +364,8 @@
 
             try {
                 Slog.i(TAG, "Connectivity Service");
-                connectivity = new ConnectivityService(context, networkManagement, networkPolicy);
+                connectivity = new ConnectivityService(
+                        context, networkManagement, networkStats, networkPolicy);
                 ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
                 networkStats.bindConnectivityManager(connectivity);
                 networkPolicy.bindConnectivityManager(connectivity);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index ed960d6..2942c28 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3334,6 +3334,11 @@
             if ((samePackage || r.task == lastTask)
                     && (r.app == null || evenPersistent || !r.app.persistent)) {
                 if (!doit) {
+                    if (r.finishing) {
+                        // If this activity is just finishing, then it is not
+                        // interesting as far as something to stop.
+                        continue;
+                    }
                     return true;
                 }
                 didSomething = true;
@@ -3399,6 +3404,7 @@
                 }
             }
             mMainStack.resumeTopActivityLocked(null);
+            mMainStack.scheduleIdleLocked();
         }
         
         return didSomething;
@@ -3778,6 +3784,12 @@
         mWindowManager.showBootMessage(msg, always);
     }
 
+    public void dismissKeyguardOnNextActivity() {
+        synchronized (this) {
+            mMainStack.dismissKeyguardOnNextActivityLocked();
+        }
+    }
+
     final void finishBooting() {
         IntentFilter pkgFilter = new IntentFilter();
         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
@@ -7901,6 +7913,8 @@
         if (dumpAll) {
             pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
             pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
+            pw.println("  mDismissKeyguardOnNextActivity: "
+                    + mMainStack.mDismissKeyguardOnNextActivity);
         }
 
         if (mRecentTasks.size() > 0) {
@@ -8541,7 +8555,7 @@
                     for (int i=0; i<N; i++) {
                         sb.setLength(0);
                         sb.append("    Intent: ");
-                        intents.get(i).toShortString(sb, true, false);
+                        intents.get(i).toShortString(sb, false, true, false);
                         pw.println(sb.toString());
                         Bundle bundle = intents.get(i).getExtras();
                         if (bundle != null) {
@@ -8834,7 +8848,8 @@
                 } else if (complete) {
                     // Complete + brief == give a summary.  Isn't that obvious?!?
                     if (lastTask.intent != null) {
-                        pw.print(prefix); pw.print("  "); pw.println(lastTask.intent);
+                        pw.print(prefix); pw.print("  ");
+                                pw.println(lastTask.intent.toInsecureString());
                     }
                 }
             }
@@ -8845,7 +8860,7 @@
                 r.dump(pw, innerPrefix);
             } else if (complete) {
                 // Complete + brief == give a summary.  Isn't that obvious?!?
-                pw.print(innerPrefix); pw.println(r.intent);
+                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
                 if (r.app != null) {
                     pw.print(innerPrefix); pw.println(r.app);
                 }
@@ -10047,7 +10062,7 @@
         boolean created = false;
         try {
             mStringBuilder.setLength(0);
-            r.intent.getIntent().toShortString(mStringBuilder, false, true);
+            r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
             EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
                     System.identityHashCode(r), r.shortName,
                     mStringBuilder.toString(), r.app.pid);
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 73ffafb..ce45bfb1 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -122,7 +122,7 @@
                 pw.print(" processName="); pw.println(processName);
         pw.print(prefix); pw.print("launchedFromUid="); pw.print(launchedFromUid);
                 pw.print(" app="); pw.println(app);
-        pw.print(prefix); pw.println(intent);
+        pw.print(prefix); pw.println(intent.toInsecureString());
         pw.print(prefix); pw.print("frontOfTask="); pw.print(frontOfTask);
                 pw.print(" task="); pw.println(task);
         pw.print(prefix); pw.print("taskAffinity="); pw.println(taskAffinity);
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index a0aedf9..7bc19ab4 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -259,6 +259,11 @@
      */
     boolean mSleepTimeout = false;
 
+    /**
+     * Dismiss the keyguard after the next activity is displayed?
+     */
+    boolean mDismissKeyguardOnNextActivity = false;
+
     int mThumbnailWidth = -1;
     int mThumbnailHeight = -1;
 
@@ -765,9 +770,7 @@
                 // Still need to tell some activities to stop; can't sleep yet.
                 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
                         + mStoppingActivities.size() + " activities");
-                Message msg = Message.obtain();
-                msg.what = IDLE_NOW_MSG;
-                mHandler.sendMessage(msg);
+                scheduleIdleLocked();
                 return;
             }
 
@@ -978,9 +981,7 @@
                         // then give up on things going idle and start clearing
                         // them out.
                         if (DEBUG_PAUSE) Slog.v(TAG, "To many pending stops, forcing idle");
-                        Message msg = Message.obtain();
-                        msg.what = IDLE_NOW_MSG;
-                        mHandler.sendMessage(msg);
+                        scheduleIdleLocked();
                     } else {
                         checkReadyForSleepLocked();
                     }
@@ -2173,7 +2174,7 @@
         }
 
         if (err == START_SUCCESS) {
-            Slog.i(TAG, "Starting: " + intent + " from pid "
+            Slog.i(TAG, "START {" + intent.toShortString(true, true, true) + "} from pid "
                     + (callerApp != null ? callerApp.pid : callingPid));
         }
 
@@ -2228,6 +2229,7 @@
                     resultRecord, resultWho, requestCode,
                     Activity.RESULT_CANCELED, null);
             }
+            mDismissKeyguardOnNextActivity = false;
             return err;
         }
 
@@ -2239,6 +2241,7 @@
                     resultRecord, resultWho, requestCode,
                     Activity.RESULT_CANCELED, null);
             }
+            mDismissKeyguardOnNextActivity = false;
             String msg;
             if (!aInfo.exported) {
                 msg = "Permission Denial: starting " + intent.toString()
@@ -2276,6 +2279,7 @@
                     }
                     // We pretend to the caller that it was really started, but
                     // they will just get a cancel result.
+                    mDismissKeyguardOnNextActivity = false;
                     return START_SUCCESS;
                 }
             }
@@ -2299,6 +2303,7 @@
                     pal.grantedMode = grantedMode;
                     pal.onlyIfNeeded = onlyIfNeeded;
                     mService.mPendingActivityLaunches.add(pal);
+                    mDismissKeyguardOnNextActivity = false;
                     return START_SWITCHES_CANCELED;
                 }
             }
@@ -2317,8 +2322,17 @@
             mService.doPendingActivityLaunchesLocked(false);
         }
         
-        return startActivityUncheckedLocked(r, sourceRecord,
+        err = startActivityUncheckedLocked(r, sourceRecord,
                 grantedUriPermissions, grantedMode, onlyIfNeeded, true);
+        if (mDismissKeyguardOnNextActivity && mPausingActivity == null) {
+            // Someone asked to have the keyguard dismissed on the next
+            // activity start, but we are not actually doing an activity
+            // switch...  just dismiss the keyguard now, because we
+            // probably want to see whatever is behind it.
+            mDismissKeyguardOnNextActivity = false;
+            mService.mWindowManager.dismissKeyguard();
+        }
+        return err;
     }
   
     final void moveHomeToFrontFromLaunchLocked(int launchFlags) {
@@ -2987,6 +3001,11 @@
             w.thisTime = w.totalTime;
         }
         mService.notifyAll();
+
+        if (mDismissKeyguardOnNextActivity) {
+            mDismissKeyguardOnNextActivity = false;
+            mService.mWindowManager.dismissKeyguard();
+        }
     }
 
     void sendActivityResultLocked(int callingUid, ActivityRecord r,
@@ -3103,6 +3122,12 @@
         return stops;
     }
 
+    final void scheduleIdleLocked() {
+        Message msg = Message.obtain();
+        msg.what = IDLE_NOW_MSG;
+        mHandler.sendMessage(msg);
+    }
+
     final ActivityRecord activityIdleInternal(IBinder token, boolean fromTimeout,
             Configuration config) {
         if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
@@ -3413,9 +3438,7 @@
                     // If we already have a few activities waiting to stop,
                     // then give up on things going idle and start clearing
                     // them out.
-                    Message msg = Message.obtain();
-                    msg.what = IDLE_NOW_MSG;
-                    mHandler.sendMessage(msg);
+                    scheduleIdleLocked();
                 } else {
                     checkReadyForSleepLocked();
                 }
@@ -4126,4 +4149,8 @@
 
         return true;
     }
+    
+    public void dismissKeyguardOnNextActivityLocked() {
+        mDismissKeyguardOnNextActivity = true;
+    }
 }
diff --git a/services/java/com/android/server/am/IntentBindRecord.java b/services/java/com/android/server/am/IntentBindRecord.java
index 3a5ca66..2618c77 100644
--- a/services/java/com/android/server/am/IntentBindRecord.java
+++ b/services/java/com/android/server/am/IntentBindRecord.java
@@ -54,7 +54,7 @@
 
     void dumpInService(PrintWriter pw, String prefix) {
         pw.print(prefix); pw.print("intent={");
-                pw.print(intent.getIntent().toShortString(true, false));
+                pw.print(intent.getIntent().toShortString(false, true, false));
                 pw.println('}');
         pw.print(prefix); pw.print("binder="); pw.println(binder);
         pw.print(prefix); pw.print("requested="); pw.print(requested);
@@ -89,7 +89,7 @@
         sb.append(service.shortName);
         sb.append(':');
         if (intent != null) {
-            intent.getIntent().toShortString(sb, false, false);
+            intent.getIntent().toShortString(sb, false, false, false);
         }
         sb.append('}');
         return stringName = sb.toString();
diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/java/com/android/server/am/PendingIntentRecord.java
index 8ed0cc1..abd2a1f 100644
--- a/services/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/java/com/android/server/am/PendingIntentRecord.java
@@ -150,7 +150,8 @@
         public String toString() {
             return "Key{" + typeName() + " pkg=" + packageName
                 + " intent="
-                + (requestIntent != null ? requestIntent.toShortString(true, false) : "<null>")
+                + (requestIntent != null
+                        ? requestIntent.toShortString(false, true, false) : "<null>")
                 + " flags=0x" + Integer.toHexString(flags) + "}";
         }
         
@@ -317,7 +318,7 @@
         }
         if (key.requestIntent != null) {
             pw.print(prefix); pw.print("requestIntent=");
-                    pw.println(key.requestIntent.toShortString(true, true));
+                    pw.println(key.requestIntent.toShortString(false, true, true));
         }
         if (sent || canceled) {
             pw.print(prefix); pw.print("sent="); pw.print(sent);
diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java
index 004e963..257113b 100644
--- a/services/java/com/android/server/am/ServiceRecord.java
+++ b/services/java/com/android/server/am/ServiceRecord.java
@@ -192,7 +192,7 @@
     
     void dump(PrintWriter pw, String prefix) {
         pw.print(prefix); pw.print("intent={");
-                pw.print(intent.getIntent().toShortString(true, false));
+                pw.print(intent.getIntent().toShortString(false, true, false));
                 pw.println('}');
         pw.print(prefix); pw.print("packageName="); pw.println(packageName);
         pw.print(prefix); pw.print("processName="); pw.println(processName);
diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/java/com/android/server/am/TaskRecord.java
index 87129ea..a860763 100644
--- a/services/java/com/android/server/am/TaskRecord.java
+++ b/services/java/com/android/server/am/TaskRecord.java
@@ -94,14 +94,14 @@
         if (intent != null) {
             StringBuilder sb = new StringBuilder(128);
             sb.append(prefix); sb.append("intent={");
-            intent.toShortString(sb, true, false);
+            intent.toShortString(sb, false, true, false);
             sb.append('}');
             pw.println(sb.toString());
         }
         if (affinityIntent != null) {
             StringBuilder sb = new StringBuilder(128);
             sb.append(prefix); sb.append("affinityIntent={");
-            affinityIntent.toShortString(sb, true, false);
+            affinityIntent.toShortString(sb, false, true, false);
             sb.append('}');
             pw.println(sb.toString());
         }
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index 10f6d2c..6b9c088 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -29,6 +29,7 @@
 import android.net.ConnectivityManager;
 import android.net.IConnectivityManager;
 import android.net.INetworkManagementEventObserver;
+import android.net.INetworkStatsService;
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
@@ -88,7 +89,8 @@
     // upstream type list and the DUN_REQUIRED secure-setting
     private int mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_NONE;
 
-    private INetworkManagementService mNMService;
+    private final INetworkManagementService mNMService;
+    private final INetworkStatsService mStatsService;
     private Looper mLooper;
     private HandlerThread mThread;
 
@@ -124,9 +126,11 @@
     private boolean mUsbTetherRequested; // true if USB tethering should be started
                                          // when RNDIS is enabled
 
-    public Tethering(Context context, INetworkManagementService nmService, Looper looper) {
+    public Tethering(Context context, INetworkManagementService nmService,
+            INetworkStatsService statsService, Looper looper) {
         mContext = context;
         mNMService = nmService;
+        mStatsService = statsService;
         mLooper = looper;
 
         mIfaces = new HashMap<String, TetherInterfaceSM>();
@@ -913,6 +917,9 @@
                     case CMD_INTERFACE_DOWN:
                         if (mMyUpstreamIfaceName != null) {
                             try {
+                                // about to tear down NAT; gather remaining statistics
+                                mStatsService.forceUpdate();
+
                                 mNMService.disableNat(mIfaceName, mMyUpstreamIfaceName);
                                 mMyUpstreamIfaceName = null;
                             } catch (Exception e) {
@@ -957,6 +964,9 @@
                         }
                         if (mMyUpstreamIfaceName != null) {
                             try {
+                                // about to tear down NAT; gather remaining statistics
+                                mStatsService.forceUpdate();
+
                                 mNMService.disableNat(mIfaceName, mMyUpstreamIfaceName);
                                 mMyUpstreamIfaceName = null;
                             } catch (Exception e) {
@@ -995,6 +1005,9 @@
                     case CMD_TETHER_MODE_DEAD:
                         if (mMyUpstreamIfaceName != null) {
                             try {
+                                // about to tear down NAT; gather remaining statistics
+                                mStatsService.forceUpdate();
+
                                 mNMService.disableNat(mIfaceName, mMyUpstreamIfaceName);
                                 mMyUpstreamIfaceName = null;
                             } catch (Exception e) {
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index bc65205..aa46795 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -24,8 +24,8 @@
 import static android.content.Intent.ACTION_SHUTDOWN;
 import static android.content.Intent.ACTION_UID_REMOVED;
 import static android.content.Intent.EXTRA_UID;
-import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
 import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
+import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
 import static android.net.NetworkStats.IFACE_ALL;
 import static android.net.NetworkStats.SET_ALL;
 import static android.net.NetworkStats.SET_DEFAULT;
@@ -43,9 +43,12 @@
 import static android.provider.Settings.Secure.NETSTATS_TAG_MAX_HISTORY;
 import static android.provider.Settings.Secure.NETSTATS_UID_BUCKET_DURATION;
 import static android.provider.Settings.Secure.NETSTATS_UID_MAX_HISTORY;
+import static android.telephony.PhoneStateListener.LISTEN_DATA_CONNECTION_STATE;
+import static android.telephony.PhoneStateListener.LISTEN_NONE;
 import static android.text.format.DateUtils.DAY_IN_MILLIS;
 import static android.text.format.DateUtils.HOUR_IN_MILLIS;
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
+import static android.text.format.DateUtils.SECOND_IN_MILLIS;
 import static com.android.internal.util.Preconditions.checkNotNull;
 import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
 import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
@@ -80,6 +83,7 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.provider.Settings;
+import android.telephony.PhoneStateListener;
 import android.telephony.TelephonyManager;
 import android.util.EventLog;
 import android.util.Log;
@@ -121,7 +125,7 @@
  */
 public class NetworkStatsService extends INetworkStatsService.Stub {
     private static final String TAG = "NetworkStats";
-    private static final boolean LOGD = true;
+    private static final boolean LOGD = false;
     private static final boolean LOGV = false;
 
     /** File header magic number: "ANET" */
@@ -132,7 +136,8 @@
     private static final int VERSION_UID_WITH_TAG = 3;
     private static final int VERSION_UID_WITH_SET = 4;
 
-    private static final int MSG_PERFORM_POLL = 0x1;
+    private static final int MSG_PERFORM_POLL = 1;
+    private static final int MSG_UPDATE_IFACES = 2;
 
     /** Flags to control detail level of poll event. */
     private static final int FLAG_PERSIST_NETWORK = 0x10;
@@ -144,6 +149,7 @@
     private final INetworkManagementService mNetworkManager;
     private final IAlarmManager mAlarmManager;
     private final TrustedTime mTime;
+    private final TelephonyManager mTeleManager;
     private final NetworkStatsSettings mSettings;
 
     private final PowerManager.WakeLock mWakeLock;
@@ -227,6 +233,7 @@
         mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
         mAlarmManager = checkNotNull(alarmManager, "missing IAlarmManager");
         mTime = checkNotNull(time, "missing TrustedTime");
+        mTeleManager = checkNotNull(TelephonyManager.getDefault(), "missing TelephonyManager");
         mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
 
         final PowerManager powerManager = (PowerManager) context.getSystemService(
@@ -279,6 +286,10 @@
             // ignored; service lives in system_server
         }
 
+        // watch for networkType changes that aren't broadcast through
+        // CONNECTIVITY_ACTION_IMMEDIATE above.
+        mTeleManager.listen(mPhoneListener, LISTEN_DATA_CONNECTION_STATE);
+
         registerPollAlarmLocked();
         registerGlobalAlert();
 
@@ -288,10 +299,13 @@
 
     private void shutdownLocked() {
         mContext.unregisterReceiver(mConnReceiver);
+        mContext.unregisterReceiver(mTetherReceiver);
         mContext.unregisterReceiver(mPollReceiver);
         mContext.unregisterReceiver(mRemovedReceiver);
         mContext.unregisterReceiver(mShutdownReceiver);
 
+        mTeleManager.listen(mPhoneListener, LISTEN_NONE);
+
         writeNetworkStatsLocked();
         if (mUidStatsLoaded) {
             writeUidStatsLocked();
@@ -535,14 +549,7 @@
         public void onReceive(Context context, Intent intent) {
             // on background handler thread, and verified CONNECTIVITY_INTERNAL
             // permission above.
-            synchronized (mStatsLock) {
-                mWakeLock.acquire();
-                try {
-                    updateIfacesLocked();
-                } finally {
-                    mWakeLock.release();
-                }
-            }
+            updateIfaces();
         }
     };
 
@@ -619,6 +626,46 @@
         }
     };
 
+    private int mLastPhoneState = TelephonyManager.DATA_UNKNOWN;
+    private int mLastPhoneNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
+
+    /**
+     * Receiver that watches for {@link TelephonyManager} changes, such as
+     * transitioning between network types.
+     */
+    private PhoneStateListener mPhoneListener = new PhoneStateListener() {
+        @Override
+        public void onDataConnectionStateChanged(int state, int networkType) {
+            final boolean stateChanged = state != mLastPhoneState;
+            final boolean networkTypeChanged = networkType != mLastPhoneNetworkType;
+
+            if (networkTypeChanged && !stateChanged) {
+                // networkType changed without a state change, which means we
+                // need to roll our own update. delay long enough for
+                // ConnectivityManager to process.
+                // TODO: add direct event to ConnectivityService instead of
+                // relying on this delay.
+                if (LOGV) Slog.v(TAG, "triggering delayed updateIfaces()");
+                mHandler.sendMessageDelayed(
+                        mHandler.obtainMessage(MSG_UPDATE_IFACES), SECOND_IN_MILLIS);
+            }
+
+            mLastPhoneState = state;
+            mLastPhoneNetworkType = networkType;
+        }
+    };
+
+    private void updateIfaces() {
+        synchronized (mStatsLock) {
+            mWakeLock.acquire();
+            try {
+                updateIfacesLocked();
+            } finally {
+                mWakeLock.release();
+            }
+        }
+    }
+
     /**
      * Inspect all current {@link NetworkState} to derive mapping from {@code
      * iface} to {@link NetworkStatsHistory}. When multiple {@link NetworkInfo}
@@ -713,19 +760,6 @@
         final long threshold = mSettings.getPersistThreshold();
 
         try {
-            // record network stats
-            final NetworkStats networkSnapshot = mNetworkManager.getNetworkStatsSummary();
-            performNetworkPollLocked(networkSnapshot, currentTime);
-
-            // persist when enough network data has occurred
-            final NetworkStats persistNetworkDelta = computeStatsDelta(
-                    mLastPersistNetworkSnapshot, networkSnapshot, true);
-            final boolean networkPastThreshold = persistNetworkDelta.getTotalBytes() > threshold;
-            if (persistForce || (persistNetwork && networkPastThreshold)) {
-                writeNetworkStatsLocked();
-                mLastPersistNetworkSnapshot = networkSnapshot;
-            }
-
             // record tethering stats; persisted during normal UID cycle below
             final String[] ifacePairs = mConnManager.getTetheredIfacePairs();
             final NetworkStats tetherSnapshot = mNetworkManager.getNetworkStatsTethering(
@@ -744,6 +778,19 @@
                 writeUidStatsLocked();
                 mLastPersistUidSnapshot = uidSnapshot;
             }
+
+            // record network stats
+            final NetworkStats networkSnapshot = mNetworkManager.getNetworkStatsSummary();
+            performNetworkPollLocked(networkSnapshot, currentTime);
+
+            // persist when enough network data has occurred
+            final NetworkStats persistNetworkDelta = computeStatsDelta(
+                    mLastPersistNetworkSnapshot, networkSnapshot, true);
+            final boolean networkPastThreshold = persistNetworkDelta.getTotalBytes() > threshold;
+            if (persistForce || (persistNetwork && networkPastThreshold)) {
+                writeNetworkStatsLocked();
+                mLastPersistNetworkSnapshot = networkSnapshot;
+            }
         } catch (IllegalStateException e) {
             Log.wtf(TAG, "problem reading network stats", e);
         } catch (RemoteException e) {
@@ -1356,6 +1403,10 @@
                     performPoll(flags);
                     return true;
                 }
+                case MSG_UPDATE_IFACES: {
+                    updateIfaces();
+                    return true;
+                }
                 default: {
                     return false;
                 }
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 105e603..05f7cf0 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -945,7 +945,8 @@
                     } catch (FileNotFoundException e) {
                         Slog.w(TAG, "Boot class path not found: " + paths[i]);
                     } catch (IOException e) {
-                        Slog.w(TAG, "Exception reading boot class path: " + paths[i], e);
+                        Slog.w(TAG, "Cannot dexopt " + paths[i] + "; is it an APK or JAR? "
+                                + e.getMessage());
                     }
                 }
             } else {
@@ -968,7 +969,8 @@
                     } catch (FileNotFoundException e) {
                         Slog.w(TAG, "Library not found: " + lib);
                     } catch (IOException e) {
-                        Slog.w(TAG, "Exception reading library: " + lib, e);
+                        Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
+                                + e.getMessage());
                     }
                 }
             }
@@ -4350,7 +4352,10 @@
             if (p != null) {
                 PackageSetting ps = (PackageSetting)p.mExtras;
                 if (ps != null) {
-                    return ps.stopped;
+                    // System apps are never considered stopped for purposes of
+                    // filtering, because there may be no way for the user to
+                    // actually re-launch them.
+                    return ps.stopped && (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0;
                 }
             }
             return false;
@@ -4522,7 +4527,10 @@
             if (p != null) {
                 PackageSetting ps = (PackageSetting)p.mExtras;
                 if (ps != null) {
-                    return ps.stopped;
+                    // System apps are never considered stopped for purposes of
+                    // filtering, because there may be no way for the user to
+                    // actually re-launch them.
+                    return ps.stopped && (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0;
                 }
             }
             return false;
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 02b246a..3ea9e81 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -4525,6 +4525,16 @@
         return mPolicy.isKeyguardSecure();
     }
 
+    public void dismissKeyguard() {
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Requires DISABLE_KEYGUARD permission");
+        }
+        synchronized(mWindowMap) {
+            mPolicy.dismissKeyguardLw();
+        }
+    }
+
     public void closeSystemDialogs(String reason) {
         synchronized(mWindowMap) {
             for (int i=mWindows.size()-1; i>=0; i--) {
@@ -5183,6 +5193,7 @@
 
         mRotation = rotation;
         mAltOrientation = altOrientation;
+        mPolicy.setRotationLw(mRotation);
 
         mWindowsFreezingScreen = true;
         mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index 99ae027..2ead254 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -776,6 +776,7 @@
     private void expectNetworkStatsPoll() throws Exception {
         mNetManager.setGlobalAlert(anyLong());
         expectLastCall().anyTimes();
+        expect(mConnManager.getTetheredIfacePairs()).andReturn(null).anyTimes();
     }
 
     private void assertStatsFilesExist(boolean exist) {
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 3e8d255..ea349bf 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1567,6 +1567,14 @@
         // that has been collected.
         if (util.isValidNumber(pn)) {
           return false;
+        } else if ("BR".equalsIgnoreCase(defaultCountryIso) && number.length() >= 8) {
+          // This is to prevent Brazilian local numbers which start with 911 being incorrectly
+          // classified as emergency numbers. 911 is not an emergency number in Brazil; it is also
+          // not possible to append additional digits to an emergency number to dial the number in
+          // Brazil - it won't connect.
+          // TODO: Clean this up once a list of country-specific known emergency numbers is
+          // collected.
+          return false;
         }
       } catch (NumberParseException e) {
       }
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
index d3e4b78..849ff48 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
@@ -551,5 +551,8 @@
       // A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number
       // in Brazil, as 112 is not an emergency number there.
       assertFalse(PhoneNumberUtils.isEmergencyNumber("1121234567", "BR"));
+      // A valid local phone number from Brazil shouldn't be classified as an emergency number in
+      // Brazil.
+      assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "BR"));
     }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
index 940b290..5b57266 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
@@ -464,4 +464,7 @@
     public int getPreferredOptionsPanelGravity() throws RemoteException {
         return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
     }
+
+    public void dismissKeyguard() {
+    }
 }
diff --git a/tools/orientationplot/orientationplot.py b/tools/orientationplot/orientationplot.py
index 07449d4..3a44cb2 100755
--- a/tools/orientationplot/orientationplot.py
+++ b/tools/orientationplot/orientationplot.py
@@ -131,42 +131,28 @@
         self.orientation_angle_axes, 'orientation', 'black')
     self._add_timeseries_legend(self.orientation_angle_axes)
 
-    self.actual_orientation = self._make_timeseries()
-    self.proposed_orientation = self._make_timeseries()
+    self.current_rotation = self._make_timeseries()
+    self.proposed_rotation = self._make_timeseries()
+    self.proposal_rotation = self._make_timeseries()
     self.orientation_axes = self._add_timeseries_axes(
-        5, 'Actual / Proposed Orientation and Confidence', 'rotation', [-1, 4],
+        5, 'Current / Proposed Orientation and Confidence', 'rotation', [-1, 4],
         sharex=shared_axis,
         yticks=range(0, 4))
-    self.actual_orientation_line = self._add_timeseries_line(
-        self.orientation_axes, 'actual', 'black', linewidth=2)
-    self.proposed_orientation_line = self._add_timeseries_line(
-        self.orientation_axes, 'proposed', 'purple', linewidth=3)
+    self.current_rotation_line = self._add_timeseries_line(
+        self.orientation_axes, 'current', 'black', linewidth=2)
+    self.proposal_rotation_line = self._add_timeseries_line(
+        self.orientation_axes, 'proposal', 'purple', linewidth=3)
+    self.proposed_rotation_line = self._add_timeseries_line(
+        self.orientation_axes, 'proposed', 'green', linewidth=3)
     self._add_timeseries_legend(self.orientation_axes)
 
-    self.confidence = [[self._make_timeseries(), self._make_timeseries()] for i in range(0, 4)]
-    self.confidence_polys = []
-
-    self.combined_confidence = self._make_timeseries()
-    self.orientation_confidence = self._make_timeseries()
-    self.tilt_confidence = self._make_timeseries()
-    self.magnitude_confidence = self._make_timeseries()
-    self.confidence_axes = self._add_timeseries_axes(
-        6, 'Proposed Orientation Confidence Factors', 'confidence', [-0.1, 1.1],
-        sharex=shared_axis,
-        yticks=[0.0, 0.2, 0.4, 0.6, 0.8, 1.0])
-    self.combined_confidence_line = self._add_timeseries_line(
-        self.confidence_axes, 'combined', 'purple', linewidth=2)
-    self.orientation_confidence_line = self._add_timeseries_line(
-        self.confidence_axes, 'orientation', 'black')
-    self.tilt_confidence_line = self._add_timeseries_line(
-        self.confidence_axes, 'tilt', 'brown')
-    self.magnitude_confidence_line = self._add_timeseries_line(
-        self.confidence_axes, 'magnitude', 'orange')
-    self._add_timeseries_legend(self.confidence_axes)
+    self.proposal_confidence = [[self._make_timeseries(), self._make_timeseries()]
+      for i in range(0, 4)]
+    self.proposal_confidence_polys = []
 
     self.sample_latency = self._make_timeseries()
     self.sample_latency_axes = self._add_timeseries_axes(
-        7, 'Accelerometer Sampling Latency', 'ms', [-10, 500],
+        6, 'Accelerometer Sampling Latency', 'ms', [-10, 500],
         sharex=shared_axis,
         yticks=range(0, 500, 100))
     self.sample_latency_line = self._add_timeseries_line(
@@ -186,7 +172,7 @@
 
   # Add a subplot to the figure for a time series.
   def _add_timeseries_axes(self, index, title, ylabel, ylim, yticks, sharex=None):
-    num_graphs = 7
+    num_graphs = 6
     height = 0.9 / num_graphs
     top = 0.95 - height * index
     axes = self.fig.add_axes([0.1, top, 0.8, height],
@@ -234,13 +220,10 @@
     self.parse_magnitude = None
     self.parse_tilt_angle = None
     self.parse_orientation_angle = None
-    self.parse_proposed_orientation = None
-    self.parse_combined_confidence = None
-    self.parse_orientation_confidence = None
-    self.parse_tilt_confidence = None
-    self.parse_magnitude_confidence = None
-    self.parse_actual_orientation = None
-    self.parse_confidence = None
+    self.parse_current_rotation = None
+    self.parse_proposed_rotation = None
+    self.parse_proposal_rotation = None
+    self.parse_proposal_confidence = None
     self.parse_sample_latency = None
 
   # Update samples.
@@ -284,26 +267,13 @@
       if line.find('orientationAngle=') != -1:
         self.parse_orientation_angle = self._get_following_number(line, 'orientationAngle=')
 
-      if line.find('Proposal:') != -1:
-        self.parse_proposed_orientation = self._get_following_number(line, 'proposedOrientation=')
-        self.parse_combined_confidence = self._get_following_number(line, 'combinedConfidence=')
-        self.parse_orientation_confidence = self._get_following_number(line, 'orientationConfidence=')
-        self.parse_tilt_confidence = self._get_following_number(line, 'tiltConfidence=')
-        self.parse_magnitude_confidence = self._get_following_number(line, 'magnitudeConfidence=')
-
       if line.find('Result:') != -1:
-        self.parse_actual_orientation = self._get_following_number(line, 'rotation=')
-        self.parse_confidence = self._get_following_array_of_numbers(line, 'confidence=')
+        self.parse_current_rotation = self._get_following_number(line, 'currentRotation=')
+        self.parse_proposed_rotation = self._get_following_number(line, 'proposedRotation=')
+        self.parse_proposal_rotation = self._get_following_number(line, 'proposalRotation=')
+        self.parse_proposal_confidence = self._get_following_number(line, 'proposalConfidence=')
         self.parse_sample_latency = self._get_following_number(line, 'timeDeltaMS=')
 
-        for i in range(0, 4):
-          if self.parse_confidence is not None:
-            self._append(self.confidence[i][0], timeindex, i)
-            self._append(self.confidence[i][1], timeindex, i + self.parse_confidence[i])
-          else:
-            self._append(self.confidence[i][0], timeindex, None)
-            self._append(self.confidence[i][1], timeindex, None)
-
         self._append(self.raw_acceleration_x, timeindex, self.parse_raw_acceleration_x)
         self._append(self.raw_acceleration_y, timeindex, self.parse_raw_acceleration_y)
         self._append(self.raw_acceleration_z, timeindex, self.parse_raw_acceleration_z)
@@ -313,12 +283,22 @@
         self._append(self.magnitude, timeindex, self.parse_magnitude)
         self._append(self.tilt_angle, timeindex, self.parse_tilt_angle)
         self._append(self.orientation_angle, timeindex, self.parse_orientation_angle)
-        self._append(self.actual_orientation, timeindex, self.parse_actual_orientation)
-        self._append(self.proposed_orientation, timeindex, self.parse_proposed_orientation)
-        self._append(self.combined_confidence, timeindex, self.parse_combined_confidence)
-        self._append(self.orientation_confidence, timeindex, self.parse_orientation_confidence)
-        self._append(self.tilt_confidence, timeindex, self.parse_tilt_confidence)
-        self._append(self.magnitude_confidence, timeindex, self.parse_magnitude_confidence)
+        self._append(self.current_rotation, timeindex, self.parse_current_rotation)
+        if self.parse_proposed_rotation >= 0:
+          self._append(self.proposed_rotation, timeindex, self.parse_proposed_rotation)
+        else:
+          self._append(self.proposed_rotation, timeindex, None)
+        if self.parse_proposal_rotation >= 0:
+          self._append(self.proposal_rotation, timeindex, self.parse_proposal_rotation)
+        else:
+          self._append(self.proposal_rotation, timeindex, None)
+        for i in range(0, 4):
+          self._append(self.proposal_confidence[i][0], timeindex, i)
+          if i == self.parse_proposal_rotation:
+            self._append(self.proposal_confidence[i][1], timeindex,
+              i + self.parse_proposal_confidence)
+          else:
+            self._append(self.proposal_confidence[i][1], timeindex, i)
         self._append(self.sample_latency, timeindex, self.parse_sample_latency)
         self._reset_parse_state()
 
@@ -335,16 +315,13 @@
       self._scroll(self.magnitude, bottom)
       self._scroll(self.tilt_angle, bottom)
       self._scroll(self.orientation_angle, bottom)
-      self._scroll(self.actual_orientation, bottom)
-      self._scroll(self.proposed_orientation, bottom)
-      self._scroll(self.combined_confidence, bottom)
-      self._scroll(self.orientation_confidence, bottom)
-      self._scroll(self.tilt_confidence, bottom)
-      self._scroll(self.magnitude_confidence, bottom)
-      self._scroll(self.sample_latency, bottom)
+      self._scroll(self.current_rotation, bottom)
+      self._scroll(self.proposed_rotation, bottom)
+      self._scroll(self.proposal_rotation, bottom)
       for i in range(0, 4):
-        self._scroll(self.confidence[i][0], bottom)
-        self._scroll(self.confidence[i][1], bottom)
+        self._scroll(self.proposal_confidence[i][0], bottom)
+        self._scroll(self.proposal_confidence[i][1], bottom)
+      self._scroll(self.sample_latency, bottom)
 
     # Redraw the plots.
     self.raw_acceleration_line_x.set_data(self.raw_acceleration_x)
@@ -356,20 +333,19 @@
     self.magnitude_line.set_data(self.magnitude)
     self.tilt_angle_line.set_data(self.tilt_angle)
     self.orientation_angle_line.set_data(self.orientation_angle)
-    self.actual_orientation_line.set_data(self.actual_orientation)
-    self.proposed_orientation_line.set_data(self.proposed_orientation)
-    self.combined_confidence_line.set_data(self.combined_confidence)
-    self.orientation_confidence_line.set_data(self.orientation_confidence)
-    self.tilt_confidence_line.set_data(self.tilt_confidence)
-    self.magnitude_confidence_line.set_data(self.magnitude_confidence)
+    self.current_rotation_line.set_data(self.current_rotation)
+    self.proposed_rotation_line.set_data(self.proposed_rotation)
+    self.proposal_rotation_line.set_data(self.proposal_rotation)
     self.sample_latency_line.set_data(self.sample_latency)
 
-    for poly in self.confidence_polys:
+    for poly in self.proposal_confidence_polys:
       poly.remove()
-    self.confidence_polys = []
+    self.proposal_confidence_polys = []
     for i in range(0, 4):
-      self.confidence_polys.append(self.orientation_axes.fill_between(self.confidence[i][0][0],
-        self.confidence[i][0][1], self.confidence[i][1][1],
+      self.proposal_confidence_polys.append(self.orientation_axes.fill_between(
+        self.proposal_confidence[i][0][0],
+        self.proposal_confidence[i][0][1],
+        self.proposal_confidence[i][1][1],
         facecolor='goldenrod', edgecolor='goldenrod'))
 
     self.fig.canvas.draw_idle()
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index fe0e850..af8c486 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -589,12 +589,11 @@
                             updateBssids();
                             transitionTo(mDnsCheckingState);
                             mNetEventCounter++;
-                            return HANDLED;
-                        case DISCONNECTED:
-                        case DISCONNECTING:
+                            break;
+                        default:
                             mNetEventCounter++;
                             transitionTo(mNotConnectedState);
-                            return HANDLED;
+                            break;
                     }
                     return HANDLED;
                 case EVENT_WIFI_RADIO_STATE_CHANGE: