Merge "Refactor CameraService to handle errors properly." into klp-dev
diff --git a/api/current.txt b/api/current.txt
index 5a3c7db..f912a0b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1015,6 +1015,7 @@
     field public static final int summaryOff = 16843248; // 0x10101f0
     field public static final int summaryOn = 16843247; // 0x10101ef
     field public static final int supportsRtl = 16843695; // 0x10103af
+    field public static final int supportsSwitchingToNextInputMethod = 16843753; // 0x10103e9
     field public static final int supportsUploading = 16843419; // 0x101029b
     field public static final int switchMinWidth = 16843632; // 0x1010370
     field public static final int switchPadding = 16843633; // 0x1010371
@@ -10924,7 +10925,9 @@
 
   public final class CaptureRequest extends android.hardware.camera2.CameraMetadata implements android.os.Parcelable {
     method public void addTarget(android.view.Surface);
+    method public java.lang.Object getTag();
     method public void removeTarget(android.view.Surface);
+    method public void setTag(java.lang.Object);
     field public static final android.hardware.camera2.CameraMetadata.Key BLACK_LEVEL_LOCK;
     field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_GAINS;
     field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_MODE;
@@ -12598,6 +12601,7 @@
     ctor public MediaFormat();
     method public final boolean containsKey(java.lang.String);
     method public static final android.media.MediaFormat createAudioFormat(java.lang.String, int, int);
+    method public static final android.media.MediaFormat createSubtitleFormat(java.lang.String, java.lang.String);
     method public static final android.media.MediaFormat createVideoFormat(java.lang.String, int, int);
     method public final java.nio.ByteBuffer getByteBuffer(java.lang.String);
     method public final float getFloat(java.lang.String);
@@ -12620,6 +12624,7 @@
     field public static final java.lang.String KEY_HEIGHT = "height";
     field public static final java.lang.String KEY_IS_ADTS = "is-adts";
     field public static final java.lang.String KEY_I_FRAME_INTERVAL = "i-frame-interval";
+    field public static final java.lang.String KEY_LANGUAGE = "language";
     field public static final java.lang.String KEY_MAX_INPUT_SIZE = "max-input-size";
     field public static final java.lang.String KEY_MIME = "mime";
     field public static final java.lang.String KEY_SAMPLE_RATE = "sample-rate";
@@ -18108,8 +18113,14 @@
   public class ParcelFileDescriptor implements java.io.Closeable android.os.Parcelable {
     ctor public ParcelFileDescriptor(android.os.ParcelFileDescriptor);
     method public static android.os.ParcelFileDescriptor adoptFd(int);
+    method public boolean canDetectErrors();
+    method public void checkError(boolean) throws java.io.IOException;
     method public void close() throws java.io.IOException;
+    method public void closeWithError(java.lang.String) throws java.io.IOException;
     method public static android.os.ParcelFileDescriptor[] createPipe() throws java.io.IOException;
+    method public static android.os.ParcelFileDescriptor[] createReliablePipe() throws java.io.IOException;
+    method public static android.os.ParcelFileDescriptor[] createReliableSocketPair() throws java.io.IOException;
+    method public static android.os.ParcelFileDescriptor[] createSocketPair() throws java.io.IOException;
     method public int describeContents();
     method public int detachFd();
     method public static android.os.ParcelFileDescriptor dup(java.io.FileDescriptor) throws java.io.IOException;
@@ -18121,6 +18132,7 @@
     method public java.io.FileDescriptor getFileDescriptor();
     method public long getStatSize();
     method public static android.os.ParcelFileDescriptor open(java.io.File, int) throws java.io.FileNotFoundException;
+    method public static android.os.ParcelFileDescriptor open(java.io.File, int, android.os.Handler, android.os.ParcelFileDescriptor.OnCloseListener) throws java.io.IOException;
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int MODE_APPEND = 33554432; // 0x2000000
@@ -18128,8 +18140,8 @@
     field public static final int MODE_READ_ONLY = 268435456; // 0x10000000
     field public static final int MODE_READ_WRITE = 805306368; // 0x30000000
     field public static final int MODE_TRUNCATE = 67108864; // 0x4000000
-    field public static final int MODE_WORLD_READABLE = 1; // 0x1
-    field public static final int MODE_WORLD_WRITEABLE = 2; // 0x2
+    field public static final deprecated int MODE_WORLD_READABLE = 1; // 0x1
+    field public static final deprecated int MODE_WORLD_WRITEABLE = 2; // 0x2
     field public static final int MODE_WRITE_ONLY = 536870912; // 0x20000000
   }
 
@@ -18141,6 +18153,10 @@
     ctor public ParcelFileDescriptor.AutoCloseOutputStream(android.os.ParcelFileDescriptor);
   }
 
+  public static abstract interface ParcelFileDescriptor.OnCloseListener {
+    method public abstract void onClose(java.io.IOException, boolean);
+  }
+
   public class ParcelFormatException extends java.lang.RuntimeException {
     ctor public ParcelFormatException();
     ctor public ParcelFormatException(java.lang.String);
@@ -29491,19 +29507,18 @@
   public abstract class Transition implements java.lang.Cloneable {
     ctor public Transition();
     method public void addListener(android.view.transition.Transition.TransitionListener);
-    method protected void cancelTransition();
+    method protected void cancel();
     method protected abstract void captureValues(android.view.transition.TransitionValues, boolean);
     method public android.view.transition.Transition clone();
     method public long getDuration();
     method public android.animation.TimeInterpolator getInterpolator();
     method public java.util.ArrayList<android.view.transition.Transition.TransitionListener> getListeners();
+    method public java.lang.String getName();
     method public long getStartDelay();
     method public int[] getTargetIds();
     method public android.view.View[] getTargets();
+    method public java.lang.String[] getTransitionProperties();
     method protected android.view.transition.TransitionValues getTransitionValues(android.view.View, boolean);
-    method protected void onTransitionCancel();
-    method protected void onTransitionEnd();
-    method protected void onTransitionStart();
     method protected android.animation.Animator play(android.view.ViewGroup, android.view.transition.TransitionValues, android.view.transition.TransitionValues);
     method public void removeListener(android.view.transition.Transition.TransitionListener);
     method public android.view.transition.Transition setDuration(long);
@@ -29516,6 +29531,8 @@
   public static abstract interface Transition.TransitionListener {
     method public abstract void onTransitionCancel(android.view.transition.Transition);
     method public abstract void onTransitionEnd(android.view.transition.Transition);
+    method public abstract void onTransitionPause(android.view.transition.Transition);
+    method public abstract void onTransitionResume(android.view.transition.Transition);
     method public abstract void onTransitionStart(android.view.transition.Transition);
   }
 
@@ -29562,6 +29579,7 @@
     method protected android.animation.Animator appear(android.view.ViewGroup, android.view.transition.TransitionValues, int, android.view.transition.TransitionValues, int);
     method protected void captureValues(android.view.transition.TransitionValues, boolean);
     method protected android.animation.Animator disappear(android.view.ViewGroup, android.view.transition.TransitionValues, int, android.view.transition.TransitionValues, int);
+    method public boolean isVisible(android.view.transition.TransitionValues);
   }
 
 }
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 45fed2d..5cabfeef 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -2060,7 +2060,7 @@
 
     private final class ParcelFileDescriptorInner extends ParcelFileDescriptor {
         private final IContentProvider mContentProvider;
-        private boolean mReleaseProviderFlag = false;
+        private boolean mProviderReleased;
 
         ParcelFileDescriptorInner(ParcelFileDescriptor pfd, IContentProvider icp) {
             super(pfd);
@@ -2069,17 +2069,10 @@
 
         @Override
         public void close() throws IOException {
-            if(!mReleaseProviderFlag) {
-                super.close();
+            super.close();
+            if (!mProviderReleased) {
                 ContentResolver.this.releaseProvider(mContentProvider);
-                mReleaseProviderFlag = true;
-            }
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            if (!mReleaseProviderFlag) {
-                close();
+                mProviderReleased = true;
             }
         }
     }
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 1a10bdd..63d6134 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -53,6 +53,7 @@
 
     private final Object mLock = new Object();
     private final HashSet<Surface> mSurfaceSet = new HashSet<Surface>();
+    private Object mUserTag;
 
     /**
      * @hide
@@ -89,6 +90,42 @@
         }
     }
 
+    /**
+     * Set a tag for this request.
+     *
+     * <p>This tag is not used for anything by the camera device, but can be
+     * used by an application to easily identify a CaptureRequest when it is
+     * returned by
+     * {@link CameraDevice.CaptureListener#onCaptureComplete CaptureListener.onCaptureComplete}
+     *
+     * @param tag an arbitrary Object to store with this request
+     * @see #getTag
+     */
+    public void setTag(Object tag) {
+        synchronized (mLock) {
+            mUserTag = tag;
+        }
+    }
+
+    /**
+     * Retrieve the tag for this request, if any.
+     *
+     * <p>This tag is not used for anything by the camera device, but can be
+     * used by an application to easily identify a CaptureRequest when it is
+     * returned by
+     * {@link CameraDevice.CaptureListener#onCaptureComplete CaptureListener.onCaptureComplete}
+     * </p>
+     *
+     * @return the last tag Object set on this request, or {@code null} if
+     *     no tag has been set.
+     * @see #setTag
+     */
+    public Object getTag() {
+        synchronized (mLock) {
+            return mUserTag;
+        }
+    }
+
     public static final Parcelable.Creator<CaptureRequest> CREATOR =
             new Parcelable.Creator<CaptureRequest>() {
         @Override
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 12f7915..46b0150 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -1520,6 +1520,11 @@
         return fd != null ? new ParcelFileDescriptor(fd) : null;
     }
 
+    /** {@hide} */
+    public final FileDescriptor readRawFileDescriptor() {
+        return nativeReadFileDescriptor(mNativePtr);
+    }
+
     /*package*/ static native FileDescriptor openFileDescriptor(String file,
             int mode) throws FileNotFoundException;
     /*package*/ static native FileDescriptor dupFileDescriptor(FileDescriptor orig)
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 3de362c..579971d 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -16,8 +16,25 @@
 
 package android.os;
 
+import static libcore.io.OsConstants.AF_UNIX;
+import static libcore.io.OsConstants.SEEK_SET;
+import static libcore.io.OsConstants.SOCK_STREAM;
+import static libcore.io.OsConstants.S_ISLNK;
+import static libcore.io.OsConstants.S_ISREG;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentProvider;
+import android.util.Log;
+
 import dalvik.system.CloseGuard;
 
+import libcore.io.ErrnoException;
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
+import libcore.io.Memory;
+import libcore.io.OsConstants;
+import libcore.io.StructStat;
+
 import java.io.Closeable;
 import java.io.File;
 import java.io.FileDescriptor;
@@ -27,36 +44,80 @@
 import java.io.IOException;
 import java.net.DatagramSocket;
 import java.net.Socket;
+import java.nio.ByteOrder;
 
 /**
  * The FileDescriptor returned by {@link Parcel#readFileDescriptor}, allowing
  * you to close it when done with it.
  */
 public class ParcelFileDescriptor implements Parcelable, Closeable {
-    private final FileDescriptor mFileDescriptor;
+    private static final String TAG = "ParcelFileDescriptor";
+
+    private final FileDescriptor mFd;
+
+    /**
+     * Optional socket used to communicate close events, status at close, and
+     * detect remote process crashes.
+     */
+    private FileDescriptor mCommFd;
 
     /**
      * Wrapped {@link ParcelFileDescriptor}, if any. Used to avoid
-     * double-closing {@link #mFileDescriptor}.
+     * double-closing {@link #mFd}.
      */
     private final ParcelFileDescriptor mWrapped;
 
+    /**
+     * Maximum {@link #mStatusBuf} size; longer status messages will be
+     * truncated.
+     */
+    private static final int MAX_STATUS = 1024;
+
+    /**
+     * Temporary buffer used by {@link #readCommStatus(FileDescriptor, byte[])},
+     * allocated on-demand.
+     */
+    private byte[] mStatusBuf;
+
+    /**
+     * Status read by {@link #checkError(boolean)}, or null if not read yet.
+     */
+    private Status mStatus;
+
     private volatile boolean mClosed;
 
     private final CloseGuard mGuard = CloseGuard.get();
 
     /**
-     * For use with {@link #open}: if {@link #MODE_CREATE} has been supplied
-     * and this file doesn't already exist, then create the file with
-     * permissions such that any application can read it.
+     * For use with {@link #open}: if {@link #MODE_CREATE} has been supplied and
+     * this file doesn't already exist, then create the file with permissions
+     * such that any application can read it.
+     *
+     * @deprecated Creating world-readable files is very dangerous, and likely
+     *             to cause security holes in applications. It is strongly
+     *             discouraged; instead, applications should use more formal
+     *             mechanism for interactions such as {@link ContentProvider},
+     *             {@link BroadcastReceiver}, and {@link android.app.Service}.
+     *             There are no guarantees that this access mode will remain on
+     *             a file, such as when it goes through a backup and restore.
      */
+    @Deprecated
     public static final int MODE_WORLD_READABLE = 0x00000001;
 
     /**
-     * For use with {@link #open}: if {@link #MODE_CREATE} has been supplied
-     * and this file doesn't already exist, then create the file with
-     * permissions such that any application can write it.
+     * For use with {@link #open}: if {@link #MODE_CREATE} has been supplied and
+     * this file doesn't already exist, then create the file with permissions
+     * such that any application can write it.
+     *
+     * @deprecated Creating world-writable files is very dangerous, and likely
+     *             to cause security holes in applications. It is strongly
+     *             discouraged; instead, applications should use more formal
+     *             mechanism for interactions such as {@link ContentProvider},
+     *             {@link BroadcastReceiver}, and {@link android.app.Service}.
+     *             There are no guarantees that this access mode will remain on
+     *             a file, such as when it goes through a backup and restore.
      */
+    @Deprecated
     public static final int MODE_WORLD_WRITEABLE = 0x00000002;
 
     /**
@@ -90,32 +151,102 @@
     public static final int MODE_APPEND = 0x02000000;
 
     /**
+     * Create a new ParcelFileDescriptor wrapped around another descriptor. By
+     * default all method calls are delegated to the wrapped descriptor.
+     */
+    public ParcelFileDescriptor(ParcelFileDescriptor wrapped) {
+        // We keep a strong reference to the wrapped PFD, and rely on its
+        // finalizer to trigger CloseGuard. All calls are delegated to wrapper.
+        mWrapped = wrapped;
+        mFd = null;
+        mCommFd = null;
+        mClosed = true;
+    }
+
+    /** {@hide} */
+    public ParcelFileDescriptor(FileDescriptor fd) {
+        this(fd, null);
+    }
+
+    /** {@hide} */
+    public ParcelFileDescriptor(FileDescriptor fd, FileDescriptor commChannel) {
+        if (fd == null) {
+            throw new NullPointerException("FileDescriptor must not be null");
+        }
+        mWrapped = null;
+        mFd = fd;
+        mCommFd = commChannel;
+        mGuard.open("close");
+    }
+
+    /**
      * Create a new ParcelFileDescriptor accessing a given file.
      *
      * @param file The file to be opened.
      * @param mode The desired access mode, must be one of
-     * {@link #MODE_READ_ONLY}, {@link #MODE_WRITE_ONLY}, or
-     * {@link #MODE_READ_WRITE}; may also be any combination of
-     * {@link #MODE_CREATE}, {@link #MODE_TRUNCATE},
-     * {@link #MODE_WORLD_READABLE}, and {@link #MODE_WORLD_WRITEABLE}.
-     *
-     * @return Returns a new ParcelFileDescriptor pointing to the given
-     * file.
-     *
-     * @throws FileNotFoundException Throws FileNotFoundException if the given
-     * file does not exist or can not be opened with the requested mode.
+     *            {@link #MODE_READ_ONLY}, {@link #MODE_WRITE_ONLY}, or
+     *            {@link #MODE_READ_WRITE}; may also be any combination of
+     *            {@link #MODE_CREATE}, {@link #MODE_TRUNCATE},
+     *            {@link #MODE_WORLD_READABLE}, and
+     *            {@link #MODE_WORLD_WRITEABLE}.
+     * @return a new ParcelFileDescriptor pointing to the given file.
+     * @throws FileNotFoundException if the given file does not exist or can not
+     *             be opened with the requested mode.
      */
-    public static ParcelFileDescriptor open(File file, int mode)
-            throws FileNotFoundException {
-        String path = file.getPath();
+    public static ParcelFileDescriptor open(File file, int mode) throws FileNotFoundException {
+        final FileDescriptor fd = openInternal(file, mode);
+        if (fd == null) return null;
 
-        if ((mode&MODE_READ_WRITE) == 0) {
+        return new ParcelFileDescriptor(fd);
+    }
+
+    /**
+     * Create a new ParcelFileDescriptor accessing a given file.
+     *
+     * @param file The file to be opened.
+     * @param mode The desired access mode, must be one of
+     *            {@link #MODE_READ_ONLY}, {@link #MODE_WRITE_ONLY}, or
+     *            {@link #MODE_READ_WRITE}; may also be any combination of
+     *            {@link #MODE_CREATE}, {@link #MODE_TRUNCATE},
+     *            {@link #MODE_WORLD_READABLE}, and
+     *            {@link #MODE_WORLD_WRITEABLE}.
+     * @param handler to call listener from; must not be null.
+     * @param listener to be invoked when the returned descriptor has been
+     *            closed; must not be null.
+     * @return a new ParcelFileDescriptor pointing to the given file.
+     * @throws FileNotFoundException if the given file does not exist or can not
+     *             be opened with the requested mode.
+     */
+    public static ParcelFileDescriptor open(
+            File file, int mode, Handler handler, OnCloseListener listener) throws IOException {
+        if (handler == null) {
+            throw new IllegalArgumentException("Handler must not be null");
+        }
+        if (listener == null) {
+            throw new IllegalArgumentException("Listener must not be null");
+        }
+
+        final FileDescriptor fd = openInternal(file, mode);
+        if (fd == null) return null;
+
+        final FileDescriptor[] comm = createCommSocketPair(true);
+        final ParcelFileDescriptor pfd = new ParcelFileDescriptor(fd, comm[0]);
+
+        // Kick off thread to watch for status updates
+        final ListenerBridge bridge = new ListenerBridge(comm[1], handler.getLooper(), listener);
+        bridge.start();
+
+        return pfd;
+    }
+
+    private static FileDescriptor openInternal(File file, int mode) throws FileNotFoundException {
+        if ((mode & MODE_READ_WRITE) == 0) {
             throw new IllegalArgumentException(
                     "Must specify MODE_READ_ONLY, MODE_WRITE_ONLY, or MODE_READ_WRITE");
         }
 
-        FileDescriptor fd = Parcel.openFileDescriptor(path, mode);
-        return fd != null ? new ParcelFileDescriptor(fd) : null;
+        final String path = file.getPath();
+        return Parcel.openFileDescriptor(path, mode);
     }
 
     /**
@@ -125,8 +256,12 @@
      * original file descriptor.
      */
     public static ParcelFileDescriptor dup(FileDescriptor orig) throws IOException {
-        FileDescriptor fd = Parcel.dupFileDescriptor(orig);
-        return fd != null ? new ParcelFileDescriptor(fd) : null;
+        try {
+            final FileDescriptor fd = Libcore.os.dup(orig);
+            return new ParcelFileDescriptor(fd);
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
     }
 
     /**
@@ -136,7 +271,11 @@
      * original file descriptor.
      */
     public ParcelFileDescriptor dup() throws IOException {
-        return dup(getFileDescriptor());
+        if (mWrapped != null) {
+            return mWrapped.dup();
+        } else {
+            return dup(getFileDescriptor());
+        }
     }
 
     /**
@@ -150,12 +289,16 @@
      * for a dup of the given fd.
      */
     public static ParcelFileDescriptor fromFd(int fd) throws IOException {
-        FileDescriptor fdesc = getFileDescriptorFromFd(fd);
-        return new ParcelFileDescriptor(fdesc);
-    }
+        final FileDescriptor original = new FileDescriptor();
+        original.setInt$(fd);
 
-    // Extracts the file descriptor from the specified socket and returns it untouched
-    private static native FileDescriptor getFileDescriptorFromFd(int fd) throws IOException;
+        try {
+            final FileDescriptor dup = Libcore.os.dup(original);
+            return new ParcelFileDescriptor(dup);
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
+    }
 
     /**
      * Take ownership of a raw native fd in to a new ParcelFileDescriptor.
@@ -168,13 +311,12 @@
      * for the given fd.
      */
     public static ParcelFileDescriptor adoptFd(int fd) {
-        FileDescriptor fdesc = getFileDescriptorFromFdNoDup(fd);
+        final FileDescriptor fdesc = new FileDescriptor();
+        fdesc.setInt$(fd);
+
         return new ParcelFileDescriptor(fdesc);
     }
 
-    // Extracts the file descriptor from the specified socket and returns it untouched
-    private static native FileDescriptor getFileDescriptorFromFdNoDup(int fd);
-
     /**
      * Create a new ParcelFileDescriptor from the specified Socket.  The new
      * ParcelFileDescriptor holds a dup of the original FileDescriptor in
@@ -212,15 +354,90 @@
      * is the write side.
      */
     public static ParcelFileDescriptor[] createPipe() throws IOException {
-        FileDescriptor[] fds = new FileDescriptor[2];
-        createPipeNative(fds);
-        ParcelFileDescriptor[] pfds = new ParcelFileDescriptor[2];
-        pfds[0] = new ParcelFileDescriptor(fds[0]);
-        pfds[1] = new ParcelFileDescriptor(fds[1]);
-        return pfds;
+        try {
+            final FileDescriptor[] fds = Libcore.os.pipe();
+            return new ParcelFileDescriptor[] {
+                    new ParcelFileDescriptor(fds[0]),
+                    new ParcelFileDescriptor(fds[1]) };
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
     }
 
-    private static native void createPipeNative(FileDescriptor[] outFds) throws IOException;
+    /**
+     * Create two ParcelFileDescriptors structured as a data pipe. The first
+     * ParcelFileDescriptor in the returned array is the read side; the second
+     * is the write side.
+     * <p>
+     * The write end has the ability to deliver an error message through
+     * {@link #closeWithError(String)} which can be handled by the read end
+     * calling {@link #checkError(boolean)}, usually after detecting an EOF.
+     * This can also be used to detect remote crashes.
+     */
+    public static ParcelFileDescriptor[] createReliablePipe() throws IOException {
+        try {
+            final FileDescriptor[] comm = createCommSocketPair(false);
+            final FileDescriptor[] fds = Libcore.os.pipe();
+            return new ParcelFileDescriptor[] {
+                    new ParcelFileDescriptor(fds[0], comm[0]),
+                    new ParcelFileDescriptor(fds[1], comm[1]) };
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
+    }
+
+    /**
+     * Create two ParcelFileDescriptors structured as a pair of sockets
+     * connected to each other. The two sockets are indistinguishable.
+     */
+    public static ParcelFileDescriptor[] createSocketPair() throws IOException {
+        try {
+            final FileDescriptor fd0 = new FileDescriptor();
+            final FileDescriptor fd1 = new FileDescriptor();
+            Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd0, fd1);
+            return new ParcelFileDescriptor[] {
+                    new ParcelFileDescriptor(fd0),
+                    new ParcelFileDescriptor(fd1) };
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
+    }
+
+    /**
+     * Create two ParcelFileDescriptors structured as a pair of sockets
+     * connected to each other. The two sockets are indistinguishable.
+     * <p>
+     * Both ends have the ability to deliver an error message through
+     * {@link #closeWithError(String)} which can be detected by the other end
+     * calling {@link #checkError(boolean)}, usually after detecting an EOF.
+     * This can also be used to detect remote crashes.
+     */
+    public static ParcelFileDescriptor[] createReliableSocketPair() throws IOException {
+        try {
+            final FileDescriptor[] comm = createCommSocketPair(false);
+            final FileDescriptor fd0 = new FileDescriptor();
+            final FileDescriptor fd1 = new FileDescriptor();
+            Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd0, fd1);
+            return new ParcelFileDescriptor[] {
+                    new ParcelFileDescriptor(fd0, comm[0]),
+                    new ParcelFileDescriptor(fd1, comm[1]) };
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
+    }
+
+    private static FileDescriptor[] createCommSocketPair(boolean blocking) throws IOException {
+        try {
+            final FileDescriptor comm1 = new FileDescriptor();
+            final FileDescriptor comm2 = new FileDescriptor();
+            Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, comm1, comm2);
+            IoUtils.setBlocking(comm1, blocking);
+            IoUtils.setBlocking(comm2, blocking);
+            return new FileDescriptor[] { comm1, comm2 };
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
+    }
 
     /**
      * @hide Please use createPipe() or ContentProvider.openPipeHelper().
@@ -250,21 +467,51 @@
      * @return Returns the FileDescriptor associated with this object.
      */
     public FileDescriptor getFileDescriptor() {
-        return mFileDescriptor;
+        if (mWrapped != null) {
+            return mWrapped.getFileDescriptor();
+        } else {
+            return mFd;
+        }
     }
 
     /**
-     * Return the total size of the file representing this fd, as determined
-     * by stat().  Returns -1 if the fd is not a file.
+     * Return the total size of the file representing this fd, as determined by
+     * {@code stat()}. Returns -1 if the fd is not a file.
      */
-    public native long getStatSize();
+    public long getStatSize() {
+        if (mWrapped != null) {
+            return mWrapped.getStatSize();
+        } else {
+            try {
+                final StructStat st = Libcore.os.fstat(mFd);
+                if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
+                    return st.st_size;
+                } else {
+                    return -1;
+                }
+            } catch (ErrnoException e) {
+                Log.w(TAG, "fstat() failed: " + e);
+                return -1;
+            }
+        }
+    }
 
     /**
      * This is needed for implementing AssetFileDescriptor.AutoCloseOutputStream,
      * and I really don't think we want it to be public.
      * @hide
      */
-    public native long seekTo(long pos);
+    public long seekTo(long pos) throws IOException {
+        if (mWrapped != null) {
+            return mWrapped.seekTo(pos);
+        } else {
+            try {
+                return Libcore.os.lseek(mFd, pos, SEEK_SET);
+            } catch (ErrnoException e) {
+                throw e.rethrowAsIOException();
+            }
+        }
+    }
 
     /**
      * Return the native fd int for this ParcelFileDescriptor.  The
@@ -272,34 +519,39 @@
      * through this API.
      */
     public int getFd() {
-        if (mClosed) {
-            throw new IllegalStateException("Already closed");
+        if (mWrapped != null) {
+            return mWrapped.getFd();
+        } else {
+            if (mClosed) {
+                throw new IllegalStateException("Already closed");
+            }
+            return mFd.getInt$();
         }
-        return getFdNative();
     }
 
-    private native int getFdNative();
-
     /**
-     * Return the native fd int for this ParcelFileDescriptor and detach it
-     * from the object here.  You are now responsible for closing the fd in
-     * native code.
+     * Return the native fd int for this ParcelFileDescriptor and detach it from
+     * the object here. You are now responsible for closing the fd in native
+     * code.
+     * <p>
+     * You should not detach when the original creator of the descriptor is
+     * expecting a reliable signal through {@link #close()} or
+     * {@link #closeWithError(String)}.
+     *
+     * @see #canDetectErrors()
      */
     public int detachFd() {
-        if (mClosed) {
-            throw new IllegalStateException("Already closed");
-        }
         if (mWrapped != null) {
-            int fd = mWrapped.detachFd();
-            mClosed = true;
-            mGuard.close();
+            return mWrapped.detachFd();
+        } else {
+            if (mClosed) {
+                throw new IllegalStateException("Already closed");
+            }
+            final int fd = getFd();
+            Parcel.clearFileDescriptor(mFd);
+            writeCommStatusAndClose(Status.DETACHED, null);
             return fd;
         }
-        int fd = getFd();
-        mClosed = true;
-        mGuard.close();
-        Parcel.clearFileDescriptor(mFileDescriptor);
-        return fd;
     }
 
     /**
@@ -311,16 +563,176 @@
      */
     @Override
     public void close() throws IOException {
-        if (mClosed) return;
-        mClosed = true;
-        mGuard.close();
-
         if (mWrapped != null) {
-            // If this is a proxy to another file descriptor, just call through to its
-            // close method.
             mWrapped.close();
         } else {
-            Parcel.closeFileDescriptor(mFileDescriptor);
+            closeWithStatus(Status.OK, null);
+        }
+    }
+
+    /**
+     * Close the ParcelFileDescriptor, informing any peer that an error occurred
+     * while processing. If the creator of this descriptor is not observing
+     * errors, it will close normally.
+     *
+     * @param msg describing the error; must not be null.
+     */
+    public void closeWithError(String msg) throws IOException {
+        if (mWrapped != null) {
+            mWrapped.closeWithError(msg);
+        } else {
+            if (msg == null) {
+                throw new IllegalArgumentException("Message must not be null");
+            }
+            closeWithStatus(Status.ERROR, msg);
+        }
+    }
+
+    private void closeWithStatus(int status, String msg) throws IOException {
+        if (mWrapped != null) {
+            mWrapped.closeWithStatus(status, msg);
+        } else {
+            if (mClosed) return;
+            mClosed = true;
+            mGuard.close();
+            // Status MUST be sent before closing actual descriptor
+            writeCommStatusAndClose(status, msg);
+            IoUtils.closeQuietly(mFd);
+        }
+    }
+
+    private byte[] getOrCreateStatusBuffer() {
+        if (mStatusBuf == null) {
+            mStatusBuf = new byte[MAX_STATUS];
+        }
+        return mStatusBuf;
+    }
+
+    private void writeCommStatusAndClose(int status, String msg) {
+        if (mCommFd == null) {
+            // Not reliable, or someone already sent status
+            if (msg != null) {
+                Log.w(TAG, "Unable to inform peer: " + msg);
+            }
+            return;
+        }
+
+        if (status == Status.DETACHED) {
+            Log.w(TAG, "Peer expected signal when closed; unable to deliver after detach");
+        }
+
+        try {
+            try {
+                if (status != Status.SILENCE) {
+                    final byte[] buf = getOrCreateStatusBuffer();
+                    int writePtr = 0;
+
+                    Memory.pokeInt(buf, writePtr, status, ByteOrder.BIG_ENDIAN);
+                    writePtr += 4;
+
+                    if (msg != null) {
+                        final byte[] rawMsg = msg.getBytes();
+                        final int len = Math.min(rawMsg.length, buf.length - writePtr);
+                        System.arraycopy(rawMsg, 0, buf, writePtr, len);
+                        writePtr += len;
+                    }
+
+                    Libcore.os.write(mCommFd, buf, 0, writePtr);
+                }
+            } catch (ErrnoException e) {
+                // Reporting status is best-effort
+                Log.w(TAG, "Failed to report status: " + e);
+            }
+
+            if (status != Status.SILENCE) {
+                // Since we're about to close, read off any remote status. It's
+                // okay to remember missing here.
+                mStatus = readCommStatus(mCommFd, getOrCreateStatusBuffer());
+            }
+
+        } finally {
+            IoUtils.closeQuietly(mCommFd);
+            mCommFd = null;
+        }
+    }
+
+    private static Status readCommStatus(FileDescriptor comm, byte[] buf) {
+        try {
+            final int n = Libcore.os.read(comm, buf, 0, buf.length);
+            if (n == 0) {
+                // EOF means they're dead
+                return new Status(Status.DEAD);
+            } else {
+                final int status = Memory.peekInt(buf, 0, ByteOrder.BIG_ENDIAN);
+                if (status == Status.ERROR) {
+                    final String msg = new String(buf, 4, n - 4);
+                    return new Status(status, msg);
+                }
+                return new Status(status);
+            }
+        } catch (ErrnoException e) {
+            if (e.errno == OsConstants.EAGAIN) {
+                // Remote is still alive, but no status written yet
+                return null;
+            } else {
+                Log.d(TAG, "Failed to read status; assuming dead: " + e);
+                return new Status(Status.DEAD);
+            }
+        }
+    }
+
+    /**
+     * Indicates if this ParcelFileDescriptor can communicate and detect remote
+     * errors/crashes.
+     *
+     * @see #checkError(boolean)
+     */
+    public boolean canDetectErrors() {
+        if (mWrapped != null) {
+            return mWrapped.canDetectErrors();
+        } else {
+            return mCommFd != null;
+        }
+    }
+
+    /**
+     * Detect and throw if the other end of a pipe or socket pair encountered an
+     * error or crashed. This allows a reader to distinguish between a valid EOF
+     * and an error/crash.
+     * <p>
+     * If this ParcelFileDescriptor is unable to detect remote errors, it will
+     * return silently.
+     *
+     * @param throwIfDetached requests that an exception be thrown if the remote
+     *            side called {@link #detachFd()}. Once detached, the remote
+     *            side is unable to communicate any errors through
+     *            {@link #closeWithError(String)}. An application may pass true
+     *            if it needs a stronger guarantee that the stream was closed
+     *            normally and was not merely detached.
+     * @see #canDetectErrors()
+     */
+    public void checkError(boolean throwIfDetached) throws IOException {
+        if (mWrapped != null) {
+            mWrapped.checkError(throwIfDetached);
+        } else {
+            if (mStatus == null) {
+                if (mCommFd == null) {
+                    Log.w(TAG, "Peer didn't provide a comm channel; unable to check for errors");
+                    return;
+                }
+
+                // Try reading status; it might be null if nothing written yet.
+                // Either way, we keep comm open to write our status later.
+                mStatus = readCommStatus(mCommFd, getOrCreateStatusBuffer());
+            }
+
+            if (mStatus == null || mStatus.status == Status.OK
+                    || (mStatus.status == Status.DETACHED && !throwIfDetached)) {
+                // No status yet, or everything is peachy!
+                return;
+            } else {
+                throw mStatus.asIOException();
+            }
         }
     }
 
@@ -330,17 +742,17 @@
      * ParcelFileDescriptor.close()} for you when the stream is closed.
      */
     public static class AutoCloseInputStream extends FileInputStream {
-        private final ParcelFileDescriptor mFd;
+        private final ParcelFileDescriptor mPfd;
 
-        public AutoCloseInputStream(ParcelFileDescriptor fd) {
-            super(fd.getFileDescriptor());
-            mFd = fd;
+        public AutoCloseInputStream(ParcelFileDescriptor pfd) {
+            super(pfd.getFileDescriptor());
+            mPfd = pfd;
         }
 
         @Override
         public void close() throws IOException {
             try {
-                mFd.close();
+                mPfd.close();
             } finally {
                 super.close();
             }
@@ -353,17 +765,17 @@
      * ParcelFileDescriptor.close()} for you when the stream is closed.
      */
     public static class AutoCloseOutputStream extends FileOutputStream {
-        private final ParcelFileDescriptor mFd;
+        private final ParcelFileDescriptor mPfd;
 
-        public AutoCloseOutputStream(ParcelFileDescriptor fd) {
-            super(fd.getFileDescriptor());
-            mFd = fd;
+        public AutoCloseOutputStream(ParcelFileDescriptor pfd) {
+            super(pfd.getFileDescriptor());
+            mPfd = pfd;
         }
 
         @Override
         public void close() throws IOException {
             try {
-                mFd.close();
+                mPfd.close();
             } finally {
                 super.close();
             }
@@ -372,7 +784,11 @@
 
     @Override
     public String toString() {
-        return "{ParcelFileDescriptor: " + mFileDescriptor + "}";
+        if (mWrapped != null) {
+            return mWrapped.toString();
+        } else {
+            return "{ParcelFileDescriptor: " + mFd + "}";
+        }
     }
 
     @Override
@@ -382,32 +798,20 @@
         }
         try {
             if (!mClosed) {
-                close();
+                closeWithStatus(Status.LEAKED, null);
             }
         } finally {
             super.finalize();
         }
     }
 
-    public ParcelFileDescriptor(ParcelFileDescriptor descriptor) {
-        mWrapped = descriptor;
-        mFileDescriptor = mWrapped.mFileDescriptor;
-        mGuard.open("close");
-    }
-
-    /** {@hide} */
-    public ParcelFileDescriptor(FileDescriptor descriptor) {
-        if (descriptor == null) {
-            throw new NullPointerException("descriptor must not be null");
-        }
-        mWrapped = null;
-        mFileDescriptor = descriptor;
-        mGuard.open("close");
-    }
-
     @Override
     public int describeContents() {
-        return Parcelable.CONTENTS_FILE_DESCRIPTOR;
+        if (mWrapped != null) {
+            return mWrapped.describeContents();
+        } else {
+            return Parcelable.CONTENTS_FILE_DESCRIPTOR;
+        }
     }
 
     /**
@@ -417,12 +821,22 @@
      */
     @Override
     public void writeToParcel(Parcel out, int flags) {
-        out.writeFileDescriptor(mFileDescriptor);
-        if ((flags&PARCELABLE_WRITE_RETURN_VALUE) != 0 && !mClosed) {
-            try {
-                close();
-            } catch (IOException e) {
-                // Empty
+        if (mWrapped != null) {
+            mWrapped.writeToParcel(out, flags);
+        } else {
+            out.writeFileDescriptor(mFd);
+            if (mCommFd != null) {
+                out.writeInt(1);
+                out.writeFileDescriptor(mCommFd);
+            } else {
+                out.writeInt(0);
+            }
+            if ((flags & PARCELABLE_WRITE_RETURN_VALUE) != 0 && !mClosed) {
+                try {
+                    // Not a real close, so emit no status
+                    closeWithStatus(Status.SILENCE, null);
+                } catch (IOException e) {
+                }
             }
         }
     }
@@ -431,7 +845,12 @@
             = new Parcelable.Creator<ParcelFileDescriptor>() {
         @Override
         public ParcelFileDescriptor createFromParcel(Parcel in) {
-            return in.readFileDescriptor();
+            final FileDescriptor fd = in.readRawFileDescriptor();
+            FileDescriptor commChannel = null;
+            if (in.readInt() != 0) {
+                commChannel = in.readRawFileDescriptor();
+            }
+            return new ParcelFileDescriptor(fd, commChannel);
         }
 
         @Override
@@ -439,4 +858,111 @@
             return new ParcelFileDescriptor[size];
         }
     };
+
+    /**
+     * Callback indicating that a ParcelFileDescriptor has been closed.
+     */
+    public interface OnCloseListener {
+        /**
+         * Event indicating the ParcelFileDescriptor to which this listener was
+         * attached has been closed.
+         *
+         * @param e error state, or {@code null} if closed cleanly.
+         * @param fromDetach indicates if close event was result of
+         *            {@link ParcelFileDescriptor#detachFd()}. After detach the
+         *            remote side may continue reading/writing to the underlying
+         *            {@link FileDescriptor}, but they can no longer deliver
+         *            reliable close/error events.
+         */
+        public void onClose(IOException e, boolean fromDetach);
+    }
+
+    /**
+     * Internal class representing a remote status read by
+     * {@link ParcelFileDescriptor#readCommStatus(FileDescriptor, byte[])}.
+     */
+    private static class Status {
+        /** Special value indicating remote side died. */
+        public static final int DEAD = -2;
+        /** Special value indicating no status should be written. */
+        public static final int SILENCE = -1;
+
+        /** Remote reported that everything went better than expected. */
+        public static final int OK = 0;
+        /** Remote reported error; length and message follow. */
+        public static final int ERROR = 1;
+        /** Remote reported {@link #detachFd()} and went rogue. */
+        public static final int DETACHED = 2;
+        /** Remote reported their object was finalized. */
+        public static final int LEAKED = 3;
+
+        public final int status;
+        public final String msg;
+
+        public Status(int status) {
+            this(status, null);
+        }
+
+        public Status(int status, String msg) {
+            this.status = status;
+            this.msg = msg;
+        }
+
+        public IOException asIOException() {
+            switch (status) {
+                case DEAD:
+                    return new IOException("Remote side is dead");
+                case OK:
+                    return null;
+                case ERROR:
+                    return new IOException("Remote error: " + msg);
+                case DETACHED:
+                    return new IOException("Remote side is detached");
+                case LEAKED:
+                    return new IOException("Remote side was leaked");
+                default:
+                    return new IOException("Unknown status: " + status);
+            }
+        }
+    }
+
+    /**
+     * Bridge to watch for remote status, and deliver to listener. Currently
+     * requires that communication socket is <em>blocking</em>.
+     */
+    private static final class ListenerBridge extends Thread {
+        // TODO: switch to using Looper to avoid burning a thread
+
+        private FileDescriptor mCommFd;
+        private final Handler mHandler;
+
+        public ListenerBridge(FileDescriptor comm, Looper looper, final OnCloseListener listener) {
+            mCommFd = comm;
+            mHandler = new Handler(looper) {
+                @Override
+                public void handleMessage(Message msg) {
+                    final Status s = (Status) msg.obj;
+                    if (s.status == Status.DETACHED) {
+                        listener.onClose(null, true);
+                    } else if (s.status == Status.OK) {
+                        listener.onClose(null, false);
+                    } else {
+                        listener.onClose(s.asIOException(), false);
+                    }
+                }
+            };
+        }
+
+        @Override
+        public void run() {
+            try {
+                final byte[] buf = new byte[MAX_STATUS];
+                final Status status = readCommStatus(mCommFd, buf);
+                mHandler.obtainMessage(0, status).sendToTarget();
+            } finally {
+                IoUtils.closeQuietly(mCommFd);
+                mCommFd = null;
+            }
+        }
+    }
 }
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index 2b805a9..22675b4 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -816,9 +816,10 @@
      */
     public static Formatter formatDateRange(Context context, Formatter formatter, long startMillis,
                                             long endMillis, int flags, String timeZone) {
-        // icu4c will fall back to the locale's preferred 12/24 format,
+        // If we're being asked to format a time without being explicitly told whether to use
+        // the 12- or 24-hour clock, icu4c will fall back to the locale's preferred 12/24 format,
         // but we want to fall back to the user's preference.
-        if ((flags & (FORMAT_12HOUR | FORMAT_24HOUR)) == 0) {
+        if ((flags & (FORMAT_SHOW_TIME | FORMAT_12HOUR | FORMAT_24HOUR)) == FORMAT_SHOW_TIME) {
             flags |= DateFormat.is24HourFormat(context) ? FORMAT_24HOUR : FORMAT_12HOUR;
         }
 
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index f574efa..c874c82 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5357,6 +5357,18 @@
     }
 
     /**
+     * Returns whether layout calls on this container are currently being
+     * suppressed, due to an earlier call to {@link #suppressLayout(boolean)}.
+     *
+     * @return true if layout calls are currently suppressed, false otherwise.
+     *
+     * @hide
+     */
+    public boolean isLayoutSuppressed() {
+        return mSuppressLayout;
+    }
+
+    /**
      * {@inheritDoc}
      */
     @Override
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index feaab3ea..c440c7b 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -82,11 +82,16 @@
     private final boolean mIsAuxIme;
 
     /**
-     * Cavert: mForceDefault must be false for production. This flag is only for test.
+     * Caveat: mForceDefault must be false for production. This flag is only for test.
      */
     private final boolean mForceDefault;
 
     /**
+     * The flag whether this IME supports ways to switch to a next input method (e.g. globe key.)
+     */
+    private final boolean mSupportsSwitchingToNextInputMethod;
+
+    /**
      * Constructor.
      *
      * @param context The Context in which we are parsing the input method.
@@ -114,6 +119,7 @@
         ServiceInfo si = service.serviceInfo;
         mId = new ComponentName(si.packageName, si.name).flattenToShortString();
         boolean isAuxIme = true;
+        boolean supportsSwitchingToNextInputMethod = false; // false as default
         mForceDefault = false;
 
         PackageManager pm = context.getPackageManager();
@@ -149,6 +155,9 @@
                     com.android.internal.R.styleable.InputMethod_settingsActivity);
             isDefaultResId = sa.getResourceId(
                     com.android.internal.R.styleable.InputMethod_isDefault, 0);
+            supportsSwitchingToNextInputMethod = sa.getBoolean(
+                    com.android.internal.R.styleable.InputMethod_supportsSwitchingToNextInputMethod,
+                    false);
             sa.recycle();
 
             final int depth = parser.getDepth();
@@ -216,6 +225,7 @@
         mSettingsActivityName = settingsActivityComponent;
         mIsDefaultResId = isDefaultResId;
         mIsAuxIme = isAuxIme;
+        mSupportsSwitchingToNextInputMethod = supportsSwitchingToNextInputMethod;
     }
 
     InputMethodInfo(Parcel source) {
@@ -223,6 +233,7 @@
         mSettingsActivityName = source.readString();
         mIsDefaultResId = source.readInt();
         mIsAuxIme = source.readInt() == 1;
+        mSupportsSwitchingToNextInputMethod = source.readInt() == 1;
         mService = ResolveInfo.CREATOR.createFromParcel(source);
         source.readTypedList(mSubtypes, InputMethodSubtype.CREATOR);
         mForceDefault = false;
@@ -254,6 +265,7 @@
             mSubtypes.addAll(subtypes);
         }
         mForceDefault = forceDefault;
+        mSupportsSwitchingToNextInputMethod = true;
     }
 
     private static ResolveInfo buildDummyResolveInfo(String packageName, String className,
@@ -435,6 +447,14 @@
     }
 
     /**
+     * @return true if this input method supports ways to switch to a next input method.
+     * @hide
+     */
+    public boolean supportsSwitchingToNextInputMethod() {
+        return mSupportsSwitchingToNextInputMethod;
+    }
+
+    /**
      * Used to package this object into a {@link Parcel}.
      * 
      * @param dest The {@link Parcel} to be written.
@@ -446,6 +466,7 @@
         dest.writeString(mSettingsActivityName);
         dest.writeInt(mIsDefaultResId);
         dest.writeInt(mIsAuxIme ? 1 : 0);
+        dest.writeInt(mSupportsSwitchingToNextInputMethod ? 1 : 0);
         mService.writeToParcel(dest, flags);
         dest.writeTypedList(mSubtypes);
     }
diff --git a/core/java/android/view/transition/Fade.java b/core/java/android/view/transition/Fade.java
index 4fd60c1..45c21d8 100644
--- a/core/java/android/view/transition/Fade.java
+++ b/core/java/android/view/transition/Fade.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
@@ -35,6 +36,7 @@
     private static boolean DBG = Transition.DBG && false;
 
     private static final String LOG_TAG = "Fade";
+    private static final String PROPNAME_ALPHA = "android:fade:alpha";
     private static final String PROPNAME_SCREEN_X = "android:fade:screenX";
     private static final String PROPNAME_SCREEN_Y = "android:fade:screenY";
 
@@ -74,20 +76,28 @@
     /**
      * Utility method to handle creating and running the Animator.
      */
-    private Animator runAnimation(View view, float startAlpha, float endAlpha,
-            Animator.AnimatorListener listener) {
+    private Animator createAnimation(View view, float startAlpha, float endAlpha,
+            AnimatorListenerAdapter listener) {
+        if (startAlpha == endAlpha) {
+            // run listener if we're noop'ing the animation, to get the end-state results now
+            if (listener != null) {
+                listener.onAnimationEnd(null);
+            }
+            return null;
+        }
         final ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", startAlpha, endAlpha);
         if (listener != null) {
             anim.addListener(listener);
+            anim.addPauseListener(listener);
         }
-        // TODO: Maybe extract a method into Transition to run an animation that handles the
-        // duration/startDelay stuff for all subclasses.
         return anim;
     }
 
     @Override
     protected void captureValues(TransitionValues values, boolean start) {
         super.captureValues(values, start);
+        float alpha = values.view.getAlpha();
+        values.values.put(PROPNAME_ALPHA, alpha);
         int[] loc = new int[2];
         values.view.getLocationOnScreen(loc);
         values.values.put(PROPNAME_SCREEN_X, loc[0]);
@@ -95,6 +105,23 @@
     }
 
     @Override
+    protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+            TransitionValues endValues) {
+        Animator animator = super.play(sceneRoot, startValues, endValues);
+        if (animator == null && startValues != null && endValues != null) {
+            boolean endVisible = isVisible(endValues);
+            final View endView = endValues.view;
+            float endAlpha = endView.getAlpha();
+            float startAlpha = (Float) startValues.values.get(PROPNAME_ALPHA);
+            if ((endVisible && startAlpha < endAlpha && (mFadingMode & Fade.IN) != 0) ||
+                    (!endVisible && startAlpha > endAlpha && (mFadingMode & Fade.OUT) != 0)) {
+                animator = createAnimation(endView, startAlpha, endAlpha, null);
+            }
+        }
+        return animator;
+    }
+
+    @Override
     protected Animator appear(ViewGroup sceneRoot,
             TransitionValues startValues, int startVisibility,
             TransitionValues endValues, int endVisibility) {
@@ -102,15 +129,11 @@
             return null;
         }
         final View endView = endValues.view;
-        endView.setAlpha(0);
-        final Animator.AnimatorListener endListener = new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                // Always end animation with full alpha, in case it's canceled mid-stream
-                endView.setAlpha(1);
-            }
-        };
-        return runAnimation(endView, 0, 1, endListener);
+        // if alpha < 1, just fade it in from the current value
+        if (endView.getAlpha() == 1.0f) {
+            endView.setAlpha(0);
+        }
+        return createAnimation(endView, endView.getAlpha(), 1, null);
     }
 
     @Override
@@ -129,7 +152,7 @@
         }
         View overlayView = null;
         View viewToKeep = null;
-        if (endView == null) {
+        if (endView == null || endView.getParent() == null) {
             // view was removed: add the start view to the Overlay
             view = startView;
             overlayView = view;
@@ -167,7 +190,7 @@
             final View finalOverlayView = overlayView;
             final View finalViewToKeep = viewToKeep;
             final ViewGroup finalSceneRoot = sceneRoot;
-            final Animator.AnimatorListener endListener = new AnimatorListenerAdapter() {
+            final AnimatorListenerAdapter endListener = new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEnd(Animator animation) {
                     finalView.setAlpha(startAlpha);
@@ -179,8 +202,22 @@
                         finalSceneRoot.getOverlay().remove(finalOverlayView);
                     }
                 }
+
+                @Override
+                public void onAnimationPause(Animator animation) {
+                    if (finalOverlayView != null) {
+                        finalSceneRoot.getOverlay().remove(finalOverlayView);
+                    }
+                }
+
+                @Override
+                public void onAnimationResume(Animator animation) {
+                    if (finalOverlayView != null) {
+                        finalSceneRoot.getOverlay().add(finalOverlayView);
+                    }
+                }
             };
-            return runAnimation(view, startAlpha, endAlpha, endListener);
+            return createAnimation(view, startAlpha, endAlpha, endListener);
         }
         if (viewToKeep != null) {
             // TODO: find a different way to do this, like just changing the view to be
@@ -193,12 +230,42 @@
             final View finalOverlayView = overlayView;
             final View finalViewToKeep = viewToKeep;
             final ViewGroup finalSceneRoot = sceneRoot;
-            final Animator.AnimatorListener endListener = new AnimatorListenerAdapter() {
+            final AnimatorListenerAdapter endListener = new AnimatorListenerAdapter() {
+                boolean mCanceled = false;
+                float mPausedAlpha = -1;
+
+                @Override
+                public void onAnimationPause(Animator animation) {
+                    if (finalViewToKeep != null && !mCanceled) {
+                        finalViewToKeep.setVisibility(finalVisibility);
+                    }
+                    mPausedAlpha = finalView.getAlpha();
+                    finalView.setAlpha(startAlpha);
+                }
+
+                @Override
+                public void onAnimationResume(Animator animation) {
+                    if (finalViewToKeep != null && !mCanceled) {
+                        finalViewToKeep.setVisibility(View.VISIBLE);
+                    }
+                    finalView.setAlpha(mPausedAlpha);
+                }
+
+                @Override
+                public void onAnimationCancel(Animator animation) {
+                    mCanceled = true;
+                    if (mPausedAlpha >= 0) {
+                        finalView.setAlpha(mPausedAlpha);
+                    }
+                }
+
                 @Override
                 public void onAnimationEnd(Animator animation) {
-                    finalView.setAlpha(startAlpha);
+                    if (!mCanceled) {
+                        finalView.setAlpha(startAlpha);
+                    }
                     // TODO: restore view offset from overlay repositioning
-                    if (finalViewToKeep != null) {
+                    if (finalViewToKeep != null && !mCanceled) {
                         finalViewToKeep.setVisibility(finalVisibility);
                     }
                     if (finalOverlayView != null) {
@@ -206,7 +273,7 @@
                     }
                 }
             };
-            return runAnimation(view, startAlpha, endAlpha, endListener);
+            return createAnimation(view, startAlpha, endAlpha, endListener);
         }
         return null;
     }
diff --git a/core/java/android/view/transition/Move.java b/core/java/android/view/transition/Move.java
index ceda5a5..ae7d759 100644
--- a/core/java/android/view/transition/Move.java
+++ b/core/java/android/view/transition/Move.java
@@ -25,8 +25,6 @@
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
-import android.util.ArrayMap;
-import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -42,6 +40,13 @@
     private static final String PROPNAME_PARENT = "android:move:parent";
     private static final String PROPNAME_WINDOW_X = "android:move:windowX";
     private static final String PROPNAME_WINDOW_Y = "android:move:windowY";
+    private static String[] sTransitionProperties = {
+            PROPNAME_BOUNDS,
+            PROPNAME_PARENT,
+            PROPNAME_WINDOW_X,
+            PROPNAME_WINDOW_Y
+    };
+
     int[] tempLocation = new int[2];
     boolean mResizeClip = false;
     boolean mReparent = false;
@@ -49,6 +54,11 @@
 
     private static RectEvaluator sRectEvaluator = new RectEvaluator();
 
+    @Override
+    public String[] getTransitionProperties() {
+        return sTransitionProperties;
+    }
+
     public void setResizeClip(boolean resizeClip) {
         mResizeClip = resizeClip;
     }
@@ -146,12 +156,33 @@
                     if (view.getParent() instanceof ViewGroup) {
                         final ViewGroup parent = (ViewGroup) view.getParent();
                         parent.suppressLayout(true);
-                        anim.addListener(new AnimatorListenerAdapter() {
+                        TransitionListener transitionListener = new TransitionListenerAdapter() {
+                            boolean mCanceled = false;
+
                             @Override
-                            public void onAnimationEnd(Animator animation) {
+                            public void onTransitionCancel(Transition transition) {
+                                parent.suppressLayout(false);
+                                mCanceled = true;
+                            }
+
+                            @Override
+                            public void onTransitionEnd(Transition transition) {
+                                if (!mCanceled) {
+                                    parent.suppressLayout(false);
+                                }
+                            }
+
+                            @Override
+                            public void onTransitionPause(Transition transition) {
                                 parent.suppressLayout(false);
                             }
-                        });
+
+                            @Override
+                            public void onTransitionResume(Transition transition) {
+                                parent.suppressLayout(true);
+                            }
+                        };
+                        addListener(transitionListener);
                     }
                     return anim;
                 } else {
@@ -191,12 +222,33 @@
                     if (view.getParent() instanceof ViewGroup) {
                         final ViewGroup parent = (ViewGroup) view.getParent();
                         parent.suppressLayout(true);
-                        anim.addListener(new AnimatorListenerAdapter() {
+                        TransitionListener transitionListener = new TransitionListenerAdapter() {
+                            boolean mCanceled = false;
+
                             @Override
-                            public void onAnimationEnd(Animator animation) {
+                            public void onTransitionCancel(Transition transition) {
+                                parent.suppressLayout(false);
+                                mCanceled = true;
+                            }
+
+                            @Override
+                            public void onTransitionEnd(Transition transition) {
+                                if (!mCanceled) {
+                                    parent.suppressLayout(false);
+                                }
+                            }
+
+                            @Override
+                            public void onTransitionPause(Transition transition) {
                                 parent.suppressLayout(false);
                             }
-                        });
+
+                            @Override
+                            public void onTransitionResume(Transition transition) {
+                                parent.suppressLayout(true);
+                            }
+                        };
+                        addListener(transitionListener);
                     }
                     anim.addListener(new AnimatorListenerAdapter() {
                         @Override
diff --git a/core/java/android/view/transition/Transition.java b/core/java/android/view/transition/Transition.java
index f99ddc0..0444843 100644
--- a/core/java/android/view/transition/Transition.java
+++ b/core/java/android/view/transition/Transition.java
@@ -22,7 +22,6 @@
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.LongSparseArray;
-import android.util.Pair;
 import android.util.SparseArray;
 import android.view.SurfaceView;
 import android.view.TextureView;
@@ -60,6 +59,8 @@
     private static final String LOG_TAG = "Transition";
     static final boolean DBG = false;
 
+    private String mName = getClass().getName();
+
     long mStartDelay = -1;
     long mDuration = -1;
     TimeInterpolator mInterpolator = null;
@@ -69,29 +70,29 @@
     private TransitionValuesMaps mEndValues = new TransitionValuesMaps();
     TransitionGroup mParent = null;
 
+    // Per-animator information used for later canceling when future transitions overlap
+    private static ThreadLocal<ArrayMap<Animator, AnimationInfo>> sRunningAnimators =
+            new ThreadLocal<ArrayMap<Animator, AnimationInfo>>();
+
     // Scene Root is set at play() time in the cloned Transition
     ViewGroup mSceneRoot = null;
 
-    // Used to carry data between setup() and play(), cleared before every scene transition
-    private ArrayList<TransitionValues> mPlayStartValuesList = new ArrayList<TransitionValues>();
-    private ArrayList<TransitionValues> mPlayEndValuesList = new ArrayList<TransitionValues>();
-
     // Track all animators in use in case the transition gets canceled and needs to
     // cancel running animators
     private ArrayList<Animator> mCurrentAnimators = new ArrayList<Animator>();
 
     // Number of per-target instances of this Transition currently running. This count is
-    // determined by calls to startTransition() and endTransition()
+    // determined by calls to start() and end()
     int mNumInstances = 0;
 
-
+    // Whether this transition is currently paused, due to a call to pause()
+    boolean mPaused = false;
 
     // The set of listeners to be sent transition lifecycle events.
     ArrayList<TransitionListener> mListeners = null;
 
     // The set of animators collected from calls to play(), to be run in runAnimations()
-    ArrayMap<Pair<TransitionValues, TransitionValues>, Animator> mAnimatorMap =
-            new ArrayMap<Pair<TransitionValues, TransitionValues>, Animator>();
+    ArrayList<Animator> mAnimators = new ArrayList<Animator>();
 
     /**
      * Constructs a Transition object with no target objects. A transition with
@@ -115,6 +116,14 @@
         return this;
     }
 
+    /**
+     * Returns the duration set on this transition. If no duration has been set,
+     * the returned value will be negative, indicating that resulting animators will
+     * retain their own durations.
+     *
+     * @return The duration set on this transition, if one has been set, otherwise
+     * returns a negative number.
+     */
     public long getDuration() {
         return mDuration;
     }
@@ -131,6 +140,14 @@
         mStartDelay = startDelay;
     }
 
+    /**
+     * Returns the startDelay set on this transition. If no startDelay has been set,
+     * the returned value will be negative, indicating that resulting animators will
+     * retain their own startDelays.
+     *
+     * @return The startDealy set on this transition, if one has been set, otherwise
+     * returns a negative number.
+     */
     public long getStartDelay() {
         return mStartDelay;
     }
@@ -147,11 +164,44 @@
         mInterpolator = interpolator;
     }
 
+    /**
+     * Returns the interpolator set on this transition. If no interpolator has been set,
+     * the returned value will be null, indicating that resulting animators will
+     * retain their own interpolators.
+     *
+     * @return The interpolator set on this transition, if one has been set, otherwise
+     * returns null.
+     */
     public TimeInterpolator getInterpolator() {
         return mInterpolator;
     }
 
     /**
+     * Returns the set of property names used stored in the {@link TransitionValues}
+     * object passed into {@link #captureValues(TransitionValues, boolean)} that
+     * this transition cares about for the purposes of canceling overlapping animations.
+     * When any transition is started on a given scene root, all transitions
+     * currently running on that same scene root are checked to see whether the
+     * properties on which they based their animations agree with the end values of
+     * the same properties in the new transition. If the end values are not equal,
+     * then the old animation is canceled since the new transition will start a new
+     * animation to these new values. If the values are equal, the old animation is
+     * allowed to continue and no new animation is started for that transition.
+     *
+     * <p>A transition does not need to override this method. However, not doing so
+     * will mean that the cancellation logic outlined in the previous paragraph
+     * will be skipped for that transition, possibly leading to artifacts as
+     * old transitions and new transitions on the same targets run in parallel,
+     * animating views toward potentially different end values.</p>
+     *
+     * @return An array of property names as described in the class documentation for
+     * {@link TransitionValues}. The default implementation returns <code>null</code>.
+     */
+    public String[] getTransitionProperties() {
+        return null;
+    }
+
+    /**
      * This method is called by the transition's parent (all the way up to the
      * topmost Transition in the hierarchy) with the sceneRoot and start/end
      * values that the transition may need to set up initial target values
@@ -210,8 +260,6 @@
         if (DBG) {
             Log.d(LOG_TAG, "play() for " + this);
         }
-        mPlayStartValuesList.clear();
-        mPlayEndValuesList.clear();
         ArrayMap<View, TransitionValues> endCopy =
                 new ArrayMap<View, TransitionValues>(endValues.viewValues);
         SparseArray<TransitionValues> endIdCopy =
@@ -316,6 +364,7 @@
             startValuesList.add(start);
             endValuesList.add(end);
         }
+        ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
         for (int i = 0; i < startValuesList.size(); ++i) {
             TransitionValues start = startValuesList.get(i);
             TransitionValues end = endValuesList.get(i);
@@ -345,14 +394,46 @@
                     // TODO: what to do about targetIds and itemIds?
                     Animator animator = play(sceneRoot, start, end);
                     if (animator != null) {
-                        mAnimatorMap.put(new Pair(start, end), animator);
-                        // Note: we've already done the check against targetIDs in these lists
-                        mPlayStartValuesList.add(start);
-                        mPlayEndValuesList.add(end);
+                        // Save animation info for future cancellation purposes
+                        View view = null;
+                        TransitionValues infoValues = null;
+                        if (end != null) {
+                            view = end.view;
+                            String[] properties = getTransitionProperties();
+                            if (view != null && properties != null && properties.length > 0) {
+                                infoValues = new TransitionValues();
+                                infoValues.view = view;
+                                TransitionValues newValues = endValues.viewValues.get(view);
+                                if (newValues != null) {
+                                    for (int j = 0; j < properties.length; ++j) {
+                                        infoValues.values.put(properties[j],
+                                                newValues.values.get(properties[j]));
+                                    }
+                                }
+                                int numExistingAnims = runningAnimators.size();
+                                for (int j = 0; j < numExistingAnims; ++j) {
+                                    Animator anim = runningAnimators.keyAt(j);
+                                    AnimationInfo info = runningAnimators.get(anim);
+                                    if (info.values != null && info.view == view &&
+                                            ((info.name == null && getName() == null) ||
+                                            info.name.equals(getName()))) {
+                                        if (info.values.equals(infoValues)) {
+                                            // Favor the old animator
+                                            animator = null;
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+                        } else {
+                            view = (start != null) ? start.view : null;
+                        }
+                        if (animator != null) {
+                            AnimationInfo info = new AnimationInfo(view, getName(), infoValues);
+                            runningAnimators.put(animator, info);
+                            mAnimators.add(animator);
+                        }
                     }
-                } else if (DBG) {
-                    View view = (end != null) ? end.view : start.view;
-                    Log.d(LOG_TAG, "  No change for view " + view);
                 }
             }
         }
@@ -389,6 +470,15 @@
         return false;
     }
 
+    private static ArrayMap<Animator, AnimationInfo> getRunningAnimators() {
+        ArrayMap<Animator, AnimationInfo> runningAnimators = sRunningAnimators.get();
+        if (runningAnimators == null) {
+            runningAnimators = new ArrayMap<Animator, AnimationInfo>();
+            sRunningAnimators.set(runningAnimators);
+        }
+        return runningAnimators;
+    }
+
     /**
      * This is called internally once all animations have been set up by the
      * transition hierarchy. \
@@ -396,28 +486,27 @@
      * @hide
      */
     protected void runAnimations() {
-        if (DBG && mPlayStartValuesList.size() > 0) {
-            Log.d(LOG_TAG, "runAnimations (" + mPlayStartValuesList.size() + ") on " + this);
+        if (DBG) {
+            Log.d(LOG_TAG, "runAnimations() on " + this);
         }
-        startTransition();
-        // Now walk the list of TransitionValues, calling play for each pair
-        for (int i = 0; i < mPlayStartValuesList.size(); ++i) {
-            TransitionValues start = mPlayStartValuesList.get(i);
-            TransitionValues end = mPlayEndValuesList.get(i);
-            Animator anim = mAnimatorMap.get(new Pair(start, end));
+        start();
+        ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+        // Now start every Animator that was previously created for this transition in play()
+        for (Animator anim : mAnimators) {
             if (DBG) {
                 Log.d(LOG_TAG, "  anim: " + anim);
             }
-            startTransition();
-            runAnimator(anim);
+            if (runningAnimators.containsKey(anim)) {
+                start();
+                runAnimator(anim, runningAnimators);
+            }
         }
-        mPlayStartValuesList.clear();
-        mPlayEndValuesList.clear();
-        mAnimatorMap.clear();
-        endTransition();
+        mAnimators.clear();
+        end();
     }
 
-    private void runAnimator(Animator animator) {
+    private void runAnimator(Animator animator,
+            final ArrayMap<Animator, AnimationInfo> runningAnimators) {
         if (animator != null) {
             // TODO: could be a single listener instance for all of them since it uses the param
             animator.addListener(new AnimatorListenerAdapter() {
@@ -427,6 +516,7 @@
                 }
                 @Override
                 public void onAnimationEnd(Animator animation) {
+                    runningAnimators.remove(animation);
                     mCurrentAnimators.remove(animation);
                 }
             });
@@ -691,11 +781,112 @@
     }
 
     /**
+     * Pauses this transition, sending out calls to {@link
+     * TransitionListener#onTransitionPause(Transition)} to all listeners
+     * and pausing all running animators started by this transition.
+     *
+     * @hide
+     */
+    public void pause() {
+        ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+        int numOldAnims = runningAnimators.size();
+        for (int i = numOldAnims - 1; i >= 0; i--) {
+            Animator anim = runningAnimators.keyAt(i);
+            anim.pause();
+        }
+        if (mListeners != null && mListeners.size() > 0) {
+            ArrayList<TransitionListener> tmpListeners =
+                    (ArrayList<TransitionListener>) mListeners.clone();
+            int numListeners = tmpListeners.size();
+            for (int i = 0; i < numListeners; ++i) {
+                tmpListeners.get(i).onTransitionPause(this);
+            }
+        }
+        mPaused = true;
+    }
+
+    /**
+     * Resumes this transition, sending out calls to {@link
+     * TransitionListener#onTransitionPause(Transition)} to all listeners
+     * and pausing all running animators started by this transition.
+     *
+     * @hide
+     */
+    public void resume() {
+        if (mPaused) {
+            ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+            int numOldAnims = runningAnimators.size();
+            for (int i = numOldAnims - 1; i >= 0; i--) {
+                Animator anim = runningAnimators.keyAt(i);
+                anim.resume();
+            }
+            if (mListeners != null && mListeners.size() > 0) {
+                ArrayList<TransitionListener> tmpListeners =
+                        (ArrayList<TransitionListener>) mListeners.clone();
+                int numListeners = tmpListeners.size();
+                for (int i = 0; i < numListeners; ++i) {
+                    tmpListeners.get(i).onTransitionResume(this);
+                }
+            }
+            mPaused = false;
+        }
+    }
+
+    /**
      * Called by TransitionManager to play the transition. This calls
      * play() to set things up and create all of the animations and then
      * runAnimations() to actually start the animations.
      */
     void playTransition(ViewGroup sceneRoot) {
+        ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+        int numOldAnims = runningAnimators.size();
+        for (int i = numOldAnims - 1; i >= 0; i--) {
+            Animator anim = runningAnimators.keyAt(i);
+            if (anim != null) {
+                anim.resume();
+                AnimationInfo oldInfo = runningAnimators.get(anim);
+                if (oldInfo != null) {
+                    boolean cancel = false;
+                    TransitionValues oldValues = oldInfo.values;
+                    View oldView = oldInfo.view;
+                    TransitionValues newValues = mEndValues.viewValues != null ?
+                            mEndValues.viewValues.get(oldView) : null;
+                    if (oldValues == null || newValues == null) {
+                        if (oldValues != null || newValues != null) {
+                            cancel = true;
+                        }
+                    } else {
+                        for (String key : oldValues.values.keySet()) {
+                            Object oldValue = oldValues.values.get(key);
+                            Object newValue = newValues.values.get(key);
+                            if ((oldValue == null && newValue != null) ||
+                                    (oldValue != null && !oldValue.equals(newValue))) {
+                                cancel = true;
+                                if (DBG) {
+                                    Log.d(LOG_TAG, "Transition.play: oldValue != newValue for " +
+                                            key + ": old, new = " + oldValue + ", " + newValue);
+                                }
+                                break;
+                            }
+                        }
+                    }
+                    if (cancel) {
+                        if (anim.isRunning() || anim.isStarted()) {
+                            if (DBG) {
+                                Log.d(LOG_TAG, "Canceling anim " + anim);
+                            }
+                            anim.cancel();
+                        } else {
+                            if (DBG) {
+                                Log.d(LOG_TAG, "removing anim from info list: " + anim);
+                            }
+                            runningAnimators.remove(anim);
+                        }
+                    }
+                }
+            }
+        }
+
         // setup() must be called on entire transition hierarchy and set of views
         // before calling play() on anything; every transition needs a chance to set up
         // target views appropriately before transitions begin running
@@ -707,7 +898,7 @@
      * This is a utility method used by subclasses to handle standard parts of
      * setting up and running an Animator: it sets the {@link #getDuration()
      * duration} and the {@link #getStartDelay() startDelay}, starts the
-     * animation, and, when the animator ends, calls {@link #endTransition()}.
+     * animation, and, when the animator ends, calls {@link #end()}.
      *
      * @param animator The Animator to be run during this transition.
      *
@@ -716,7 +907,7 @@
     protected void animate(Animator animator) {
         // TODO: maybe pass auto-end as a boolean parameter?
         if (animator == null) {
-            endTransition();
+            end();
         } else {
             if (getDuration() >= 0) {
                 animator.setDuration(getDuration());
@@ -730,7 +921,7 @@
             animator.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEnd(Animator animation) {
-                    endTransition();
+                    end();
                     animation.removeListener(this);
                 }
             });
@@ -739,39 +930,14 @@
     }
 
     /**
-     * Subclasses may override to receive notice of when the transition starts.
-     * This is equivalent to listening for the
-     * {@link TransitionListener#onTransitionStart(Transition)} callback.
-     */
-    protected void onTransitionStart() {
-    }
-
-    /**
-     * Subclasses may override to receive notice of when the transition is
-     * canceled. This is equivalent to listening for the
-     * {@link TransitionListener#onTransitionCancel(Transition)} callback.
-     */
-    protected void onTransitionCancel() {
-    }
-
-    /**
-     * Subclasses may override to receive notice of when the transition ends.
-     * This is equivalent to listening for the
-     * {@link TransitionListener#onTransitionEnd(Transition)} callback.
-     */
-    protected void onTransitionEnd() {
-    }
-
-    /**
      * This method is called automatically by the transition and
      * TransitionGroup classes prior to a Transition subclass starting;
      * subclasses should not need to call it directly.
      *
      * @hide
      */
-    protected void startTransition() {
+    protected void start() {
         if (mNumInstances == 0) {
-            onTransitionStart();
             if (mListeners != null && mListeners.size() > 0) {
                 ArrayList<TransitionListener> tmpListeners =
                         (ArrayList<TransitionListener>) mListeners.clone();
@@ -790,15 +956,14 @@
      * a transition did nothing (returned a null Animator from
      * {@link Transition#play(ViewGroup, TransitionValues,
      * TransitionValues)}) or because the transition returned a valid
-     * Animator and endTransition() was called in the onAnimationEnd()
+     * Animator and end() was called in the onAnimationEnd()
      * callback of the AnimatorListener.
      *
      * @hide
      */
-    protected void endTransition() {
+    protected void end() {
         --mNumInstances;
         if (mNumInstances == 0) {
-            onTransitionEnd();
             if (mListeners != null && mListeners.size() > 0) {
                 ArrayList<TransitionListener> tmpListeners =
                         (ArrayList<TransitionListener>) mListeners.clone();
@@ -828,7 +993,7 @@
      * This method cancels a transition that is currently running.
      * Implementation TBD.
      */
-    protected void cancelTransition() {
+    protected void cancel() {
         // TODO: how does this work with instances?
         // TODO: this doesn't actually do *anything* yet
         int numAnimators = mCurrentAnimators.size();
@@ -836,7 +1001,6 @@
             Animator animator = mCurrentAnimators.get(i);
             animator.cancel();
         }
-        onTransitionCancel();
         if (mListeners != null && mListeners.size() > 0) {
             ArrayList<TransitionListener> tmpListeners =
                     (ArrayList<TransitionListener>) mListeners.clone();
@@ -901,11 +1065,28 @@
         Transition clone = null;
         try {
             clone = (Transition) super.clone();
+            clone.mAnimators = new ArrayList<Animator>();
         } catch (CloneNotSupportedException e) {}
 
         return clone;
     }
 
+    /**
+     * Returns the name of this Transition. This name is used internally to distinguish
+     * between different transitions to determine when interrupting transitions overlap.
+     * For example, a Move running on the same target view as another Move should determine
+     * whether the old transition is animating to different end values and should be
+     * canceled in favor of the new transition.
+     *
+     * <p>By default, a Transition's name is simply the value of {@link Class#getName()},
+     * but subclasses are free to override and return something different.</p>
+     *
+     * @return The name of this transition.
+     */
+    public String getName() {
+        return mName;
+    }
+
     String toString(String indent) {
         String result = indent + getClass().getSimpleName() + "@" +
                 Integer.toHexString(hashCode()) + ": ";
@@ -943,8 +1124,7 @@
 
     /**
      * A transition listener receives notifications from a transition.
-     * Notifications indicate transition lifecycle events: when the transition
-     * begins, ends, or is canceled.
+     * Notifications indicate transition lifecycle events.
      */
     public static interface TransitionListener {
         /**
@@ -957,7 +1137,7 @@
         /**
          * Notification about the end of the transition. Canceled transitions
          * will always notify listeners of both the cancellation and end
-         * events. That is, {@link #onTransitionEnd()} is always called,
+         * events. That is, {@link #onTransitionEnd(Transition)} is always called,
          * regardless of whether the transition was canceled or played
          * through to completion.
          *
@@ -967,10 +1147,38 @@
 
         /**
          * Notification about the cancellation of the transition.
+         * Note that cancel() may be called by a parent {@link TransitionGroup} on
+         * a child transition which has not yet started. This allows the child
+         * transition to restore state on target objects which was set at
+         * {@link #play(android.view.ViewGroup, TransitionValues, TransitionValues)
+         * play()} time.
          *
          * @param transition The transition which was canceled.
          */
         void onTransitionCancel(Transition transition);
+
+        /**
+         * Notification when a transition is paused.
+         * Note that play() may be called by a parent {@link TransitionGroup} on
+         * a child transition which has not yet started. This allows the child
+         * transition to restore state on target objects which was set at
+         * {@link #play(android.view.ViewGroup, TransitionValues, TransitionValues)
+         * play()} time.
+         *
+         * @param transition The transition which was paused.
+         */
+        void onTransitionPause(Transition transition);
+
+        /**
+         * Notification when a transition is resumed.
+         * Note that resume() may be called by a parent {@link TransitionGroup} on
+         * a child transition which has not yet started. This allows the child
+         * transition to restore state which may have changed in an earlier call
+         * to {@link #onTransitionPause(Transition)}.
+         *
+         * @param transition The transition which was resumed.
+         */
+        void onTransitionResume(Transition transition);
     }
 
     /**
@@ -991,6 +1199,32 @@
         @Override
         public void onTransitionCancel(Transition transition) {
         }
+
+        @Override
+        public void onTransitionPause(Transition transition) {
+        }
+
+        @Override
+        public void onTransitionResume(Transition transition) {
+        }
     }
 
+    /**
+     * Holds information about each animator used when a new transition starts
+     * while other transitions are still running to determine whether a running
+     * animation should be canceled or a new animation noop'd. The structure holds
+     * information about the state that an animation is going to, to be compared to
+     * end state of a new animation.
+     */
+    private static class AnimationInfo {
+        View view;
+        String name;
+        TransitionValues values;
+
+        AnimationInfo(View view, String name, TransitionValues values) {
+            this.view = view;
+            this.name = name;
+            this.values = values;
+        }
+    }
 }
diff --git a/core/java/android/view/transition/TransitionGroup.java b/core/java/android/view/transition/TransitionGroup.java
index 313e33e..b3bacde 100644
--- a/core/java/android/view/transition/TransitionGroup.java
+++ b/core/java/android/view/transition/TransitionGroup.java
@@ -164,7 +164,7 @@
         @Override
         public void onTransitionStart(Transition transition) {
             if (!mTransitionGroup.mStarted) {
-                mTransitionGroup.startTransition();
+                mTransitionGroup.start();
                 mTransitionGroup.mStarted = true;
             }
         }
@@ -175,7 +175,7 @@
             if (mTransitionGroup.mCurrentListeners == 0) {
                 // All child trans
                 mTransitionGroup.mStarted = false;
-                mTransitionGroup.endTransition();
+                mTransitionGroup.end();
             }
             transition.removeListener(this);
         }
@@ -233,12 +233,32 @@
         }
     }
 
+    /** @hide */
     @Override
-    protected void cancelTransition() {
-        super.cancelTransition();
+    public void pause() {
+        super.pause();
         int numTransitions = mTransitions.size();
         for (int i = 0; i < numTransitions; ++i) {
-            mTransitions.get(i).cancelTransition();
+            mTransitions.get(i).pause();
+        }
+    }
+
+    /** @hide */
+    @Override
+    public void resume() {
+        super.resume();
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            mTransitions.get(i).resume();
+        }
+    }
+
+    @Override
+    protected void cancel() {
+        super.cancel();
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            mTransitions.get(i).cancel();
         }
     }
 
diff --git a/core/java/android/view/transition/TransitionManager.java b/core/java/android/view/transition/TransitionManager.java
index 7836268..3cb6f68 100644
--- a/core/java/android/view/transition/TransitionManager.java
+++ b/core/java/android/view/transition/TransitionManager.java
@@ -18,6 +18,7 @@
 
 import android.util.ArrayMap;
 import android.util.Log;
+import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 
@@ -45,8 +46,8 @@
     ArrayMap<Scene, Transition> mSceneTransitions = new ArrayMap<Scene, Transition>();
     ArrayMap<Scene, ArrayMap<Scene, Transition>> mScenePairTransitions =
             new ArrayMap<Scene, ArrayMap<Scene, Transition>>();
-    static ArrayMap<ViewGroup, Transition> sRunningTransitions =
-            new ArrayMap<ViewGroup, Transition>();
+    private static ThreadLocal<ArrayMap<ViewGroup, ArrayList<Transition>>> sRunningTransitions =
+            new ThreadLocal<ArrayMap<ViewGroup, ArrayList<Transition>>>();
     private static ArrayList<ViewGroup> sPendingTransitions = new ArrayList<ViewGroup>();
 
 
@@ -160,6 +161,16 @@
         sceneChangeRunTransition(sceneRoot, transitionClone);
     }
 
+    private static ArrayMap<ViewGroup, ArrayList<Transition>> getRunningTransitions() {
+        ArrayMap<ViewGroup, ArrayList<Transition>> runningTransitions =
+                sRunningTransitions.get();
+        if (runningTransitions == null) {
+            runningTransitions = new ArrayMap<ViewGroup, ArrayList<Transition>>();
+            sRunningTransitions.set(runningTransitions);
+        }
+        return runningTransitions;
+    }
+
     private static void sceneChangeRunTransition(final ViewGroup sceneRoot,
             final Transition transition) {
         if (transition != null) {
@@ -169,16 +180,31 @@
                     sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
                     sPendingTransitions.remove(sceneRoot);
                     // Add to running list, handle end to remove it
-                    sRunningTransitions.put(sceneRoot, transition);
+                    final ArrayMap<ViewGroup, ArrayList<Transition>> runningTransitions =
+                            getRunningTransitions();
+                    ArrayList<Transition> currentTransitions = runningTransitions.get(sceneRoot);
+                    if (currentTransitions == null) {
+                        currentTransitions = new ArrayList<Transition>();
+                        runningTransitions.put(sceneRoot, currentTransitions);
+                    }
+                    currentTransitions.add(transition);
                     transition.addListener(new Transition.TransitionListenerAdapter() {
                         @Override
                         public void onTransitionEnd(Transition transition) {
-                            sRunningTransitions.remove(sceneRoot);
+                            ArrayList<Transition> currentTransitions =
+                                    runningTransitions.get(sceneRoot);
+                            currentTransitions.remove(transition);
                         }
                     });
                     transition.captureValues(sceneRoot, false);
                     transition.playTransition(sceneRoot);
-                    return true;
+
+                    // Returning false from onPreDraw() skips the current frame. This is
+                    // necessary to avoid artifacts caused by resetting target views
+                    // to their proper end states for capturing. Waiting until the next
+                    // frame to draw allows these views to have their mid-transition
+                    // values set on them again and avoid artifacts.
+                    return false;
                 }
             });
         }
@@ -187,16 +213,18 @@
     private static void sceneChangeSetup(ViewGroup sceneRoot, Transition transition) {
 
         // Capture current values
-        Transition runningTransition = sRunningTransitions.get(sceneRoot);
+        ArrayList<Transition> runningTransitions = getRunningTransitions().get(sceneRoot);
+
+        if (runningTransitions != null && runningTransitions.size() > 0) {
+            for (Transition runningTransition : runningTransitions) {
+                runningTransition.pause();
+            }
+        }
 
         if (transition != null) {
             transition.captureValues(sceneRoot, true);
         }
 
-        if (runningTransition != null) {
-            runningTransition.cancelTransition();
-        }
-
         // Notify previous scene that it is being exited
         Scene previousScene = sceneRoot.getCurrentScene();
         if (previousScene != null) {
diff --git a/core/java/android/view/transition/Visibility.java b/core/java/android/view/transition/Visibility.java
index 6d39ab6..96ea044 100644
--- a/core/java/android/view/transition/Visibility.java
+++ b/core/java/android/view/transition/Visibility.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewOverlay;
 import android.view.ViewParent;
 
 /**
@@ -38,6 +39,10 @@
 
     private static final String PROPNAME_VISIBILITY = "android:visibility:visibility";
     private static final String PROPNAME_PARENT = "android:visibility:parent";
+    private static String[] sTransitionProperties = {
+            PROPNAME_VISIBILITY,
+            PROPNAME_PARENT,
+    };
 
     private static class VisibilityInfo {
         boolean visibilityChange;
@@ -52,12 +57,42 @@
     private VisibilityInfo mTmpVisibilityInfo = new VisibilityInfo();
 
     @Override
+    public String[] getTransitionProperties() {
+        return sTransitionProperties;
+    }
+
+    @Override
     protected void captureValues(TransitionValues values, boolean start) {
         int visibility = values.view.getVisibility();
         values.values.put(PROPNAME_VISIBILITY, visibility);
         values.values.put(PROPNAME_PARENT, values.view.getParent());
     }
 
+    /**
+     * Returns whether the view is 'visible' according to the given values
+     * object. This is determined by testing the same properties in the values
+     * object that are used to determine whether the object is appearing or
+     * disappearing in the {@link
+     * #play(android.view.ViewGroup, TransitionValues, TransitionValues)}
+     * method. This method can be called by, for example, subclasses that want
+     * to know whether the object is visible in the same way that Visibility
+     * determines it for the actual animation.
+     *
+     * @param values The TransitionValues object that holds the information by
+     * which visibility is determined.
+     * @return True if the view reference by <code>values</code> is visible,
+     * false otherwise.
+     */
+    public boolean isVisible(TransitionValues values) {
+        if (values == null) {
+            return false;
+        }
+        int visibility = (Integer) values.values.get(PROPNAME_VISIBILITY);
+        View parent = (View) values.values.get(PROPNAME_PARENT);
+
+        return visibility == View.VISIBLE && parent != null;
+    }
+
     private boolean isHierarchyVisibilityChanging(ViewGroup sceneRoot, ViewGroup view) {
 
         if (view == sceneRoot) {
@@ -197,5 +232,4 @@
             TransitionValues endValues, int endVisibility) {
         return null;
     }
-
 }
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 07198c75..285e6f2 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1211,13 +1211,19 @@
     }
 
     /**
-     * Enables fast scrolling by letting the user quickly scroll through lists by
-     * dragging the fast scroll thumb. The adapter attached to the list may want
-     * to implement {@link SectionIndexer} if it wishes to display alphabet preview and
-     * jump between sections of the list.
+     * Specifies whether fast scrolling is enabled or disabled.
+     * <p>
+     * When fast scrolling is enabled, the user can quickly scroll through lists
+     * by dragging the fast scroll thumb.
+     * <p>
+     * If the adapter backing this list implements {@link SectionIndexer}, the
+     * fast scroller will display section header previews as the user scrolls.
+     * Additionally, the user will be able to quickly jump between sections by
+     * tapping along the length of the scroll bar.
+     *
      * @see SectionIndexer
      * @see #isFastScrollEnabled()
-     * @param enabled whether or not to enable fast scrolling
+     * @param enabled true to enable fast scrolling, false otherwise
      */
     public void setFastScrollEnabled(final boolean enabled) {
         if (mFastScrollEnabled != enabled) {
@@ -1252,13 +1258,16 @@
     }
 
     /**
-     * Set whether or not the fast scroller should always be shown in place of the
-     * standard scrollbars. Fast scrollers shown in this way will not fade out and will
-     * be a permanent fixture within the list. Best combined with an inset scroll bar style
-     * that will ensure enough padding. This will enable fast scrolling if it is not
+     * Set whether or not the fast scroller should always be shown in place of
+     * the standard scroll bars. This will enable fast scrolling if it is not
      * already enabled.
+     * <p>
+     * Fast scrollers shown in this way will not fade out and will be a
+     * permanent fixture within the list. This is best combined with an inset
+     * scroll bar style to ensure the scroll bar does not overlap content.
      *
-     * @param alwaysShow true if the fast scroller should always be displayed.
+     * @param alwaysShow true if the fast scroller should always be displayed,
+     *            false otherwise
      * @see #setScrollBarStyle(int)
      * @see #setFastScrollEnabled(boolean)
      */
@@ -1297,10 +1306,9 @@
     }
 
     /**
-     * Returns true if the fast scroller is set to always show on this view rather than
-     * fade out when not in use.
+     * Returns true if the fast scroller is set to always show on this view.
      *
-     * @return true if the fast scroller will always show.
+     * @return true if the fast scroller will always show
      * @see #setFastScrollAlwaysVisible(boolean)
      */
     public boolean isFastScrollAlwaysVisible() {
@@ -1316,7 +1324,8 @@
     }
 
     /**
-     * Returns the current state of the fast scroll feature.
+     * Returns true if the fast scroller is enabled.
+     *
      * @see #setFastScrollEnabled(boolean)
      * @return true if fast scroll is enabled, false otherwise
      */
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index 414c318..2b4e520 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -16,6 +16,9 @@
 
 package android.widget;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.database.DataSetObserver;
 import android.graphics.Rect;
@@ -23,6 +26,7 @@
 import android.os.Handler;
 import android.text.TextUtils;
 import android.util.AttributeSet;
+import android.util.IntProperty;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
@@ -31,6 +35,7 @@
 import android.view.View.OnTouchListener;
 import android.view.ViewGroup;
 import android.view.ViewParent;
+import android.view.animation.AccelerateDecelerateInterpolator;
 
 import java.util.Locale;
 
@@ -956,6 +961,33 @@
     }
 
     /**
+     * Receives motion events forwarded from a source view. This is used
+     * internally to implement support for drag-to-open.
+     *
+     * @param src view from which the event was forwarded
+     * @param srcEvent forwarded motion event in source-local coordinates
+     * @param activePointerId id of the pointer that activated forwarding
+     * @return whether the event was handled
+     * @hide
+     */
+    public boolean onForwardedEvent(View src, MotionEvent srcEvent, int activePointerId) {
+        final DropDownListView dst = mDropDownList;
+        if (dst == null || !dst.isShown()) {
+            return false;
+        }
+
+        // Convert event to local coordinates.
+        final MotionEvent dstEvent = MotionEvent.obtainNoHistory(srcEvent);
+        src.toGlobalMotionEvent(dstEvent);
+        dst.toLocalMotionEvent(dstEvent);
+
+        // Forward converted event, then recycle it.
+        final boolean handled = dst.onForwardedEvent(dstEvent, activePointerId);
+        dstEvent.recycle();
+        return handled;
+    }
+
+    /**
      * <p>Builds the popup window's content and returns the height the popup
      * should have. Returns -1 when the content already exists.</p>
      *
@@ -1130,6 +1162,27 @@
      */
     private static class DropDownListView extends ListView {
         private static final String TAG = ListPopupWindow.TAG + ".DropDownListView";
+
+        /** Duration in milliseconds of the drag-to-open click animation. */
+        private static final long CLICK_ANIM_DURATION = 150;
+
+        /** Target alpha value for drag-to-open click animation. */
+        private static final int CLICK_ANIM_ALPHA = 0x80;
+
+        /** Wrapper around Drawable's <code>alpha</code> property. */
+        private static final IntProperty<Drawable> DRAWABLE_ALPHA =
+                new IntProperty<Drawable>("alpha") {
+                    @Override
+                    public void setValue(Drawable object, int value) {
+                        object.setAlpha(value);
+                    }
+
+                    @Override
+                    public Integer get(Drawable object) {
+                        return object.getAlpha();
+                    }
+                };
+
         /*
          * WARNING: This is a workaround for a touch mode issue.
          *
@@ -1165,6 +1218,12 @@
          */
         private boolean mHijackFocus;
 
+        /** Whether to force drawing of the pressed state selector. */
+        private boolean mDrawsInPressedState;
+
+        /** Current drag-to-open click animation, if any. */
+        private Animator mClickAnimation;
+
         /**
          * <p>Creates a new list view wrapper.</p>
          *
@@ -1178,6 +1237,119 @@
         }
 
         /**
+         * Handles forwarded events.
+         *
+         * @param activePointerId id of the pointer that activated forwarding
+         * @return whether the event was handled
+         */
+        public boolean onForwardedEvent(MotionEvent event, int activePointerId) {
+            boolean handledEvent = true;
+            boolean clearPressedItem = false;
+
+            final int actionMasked = event.getActionMasked();
+            switch (actionMasked) {
+                case MotionEvent.ACTION_CANCEL:
+                    handledEvent = false;
+                    break;
+                case MotionEvent.ACTION_UP:
+                    handledEvent = false;
+                    // $FALL-THROUGH$
+                case MotionEvent.ACTION_MOVE:
+                    final int activeIndex = event.findPointerIndex(activePointerId);
+                    if (activeIndex < 0) {
+                        handledEvent = false;
+                        break;
+                    }
+
+                    final int x = (int) event.getX(activeIndex);
+                    final int y = (int) event.getY(activeIndex);
+                    final int position = pointToPosition(x, y);
+                    if (position == INVALID_POSITION) {
+                        clearPressedItem = true;
+                        break;
+                    }
+
+                    final View child = getChildAt(position - getFirstVisiblePosition());
+                    setPressedItem(child, position);
+                    handledEvent = true;
+
+                    if (actionMasked == MotionEvent.ACTION_UP) {
+                        clickPressedItem(child, position);
+                    }
+                    break;
+            }
+
+            // Failure to handle the event cancels forwarding.
+            if (!handledEvent || clearPressedItem) {
+                clearPressedItem();
+            }
+
+            return handledEvent;
+        }
+
+        /**
+         * Starts an alpha animation on the selector. When the animation ends,
+         * the list performs a click on the item.
+         */
+        private void clickPressedItem(final View child, final int position) {
+            final long id = getItemIdAtPosition(position);
+            final Animator anim = ObjectAnimator.ofInt(
+                    mSelector, DRAWABLE_ALPHA, 0xFF, CLICK_ANIM_ALPHA, 0xFF);
+            anim.setDuration(CLICK_ANIM_DURATION);
+            anim.setInterpolator(new AccelerateDecelerateInterpolator());
+            anim.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                public void onAnimationEnd(Animator animation) {
+                    performItemClick(child, position, id);
+                }
+            });
+            anim.start();
+
+            if (mClickAnimation != null) {
+                mClickAnimation.cancel();
+            }
+            mClickAnimation = anim;
+        }
+
+        private void clearPressedItem() {
+            mDrawsInPressedState = false;
+            setPressed(false);
+            updateSelectorState();
+
+            if (mClickAnimation != null) {
+                mClickAnimation.cancel();
+                mClickAnimation = null;
+            }
+        }
+
+        private void setPressedItem(View child, int position) {
+            mDrawsInPressedState = true;
+
+            // Ordering is essential. First update the pressed state and layout
+            // the children. This will ensure the selector actually gets drawn.
+            setPressed(true);
+            layoutChildren();
+
+            // Ensure that keyboard focus starts from the last touched position.
+            setSelectedPositionInt(position);
+            positionSelector(position, child);
+
+            // Refresh the drawable state to reflect the new pressed state,
+            // which will also update the selector state.
+            refreshDrawableState();
+
+            if (mClickAnimation != null) {
+                mClickAnimation.cancel();
+                mClickAnimation = null;
+            }
+        }
+
+        @Override
+        boolean touchModeDrawsInPressedState() {
+            return mDrawsInPressedState || super.touchModeDrawsInPressedState();
+        }
+
+        /**
          * <p>Avoids jarring scrolling effect by ensuring that list elements
          * made of a text view fit on a single line.</p>
          *
diff --git a/core/java/android/widget/SectionIndexer.java b/core/java/android/widget/SectionIndexer.java
index a1c71f4..f6333d1 100644
--- a/core/java/android/widget/SectionIndexer.java
+++ b/core/java/android/widget/SectionIndexer.java
@@ -17,38 +17,62 @@
 package android.widget;
 
 /**
- * Interface that should be implemented on Adapters to enable fast scrolling 
- * in an {@link AbsListView} between sections of the list. A section is a group of list items
- * to jump to that have something in common. For example, they may begin with the
- * same letter or they may be songs from the same artist. ExpandableListAdapters that
- * consider groups and sections as synonymous should account for collapsed groups and return
- * an appropriate section/position.
+ * Interface that may implemented on {@link Adapter}s to enable fast scrolling
+ * between sections of an {@link AbsListView}.
+ * <p>
+ * A section is a group of list items that have something in common. For
+ * example, they may begin with the same letter or they may be songs from the
+ * same artist.
+ * <p>
+ * {@link ExpandableListAdapter}s that consider groups and sections as
+ * synonymous should account for collapsed groups and return an appropriate
+ * section/position.
+ *
+ * @see AbsListView#setFastScrollEnabled(boolean)
  */
 public interface SectionIndexer {
     /**
-     * This provides the list view with an array of section objects. In the simplest
-     * case these are Strings, each containing one letter of the alphabet.
-     * They could be more complex objects that indicate the grouping for the adapter's
-     * consumption. The list view will call toString() on the objects to get the
-     * preview letter to display while scrolling.
-     * @return the array of objects that indicate the different sections of the list.
+     * Returns an array of objects representing sections of the list. The
+     * returned array and its contents should be non-null.
+     * <p>
+     * The list view will call toString() on the objects to get the preview text
+     * to display while scrolling. For example, an adapter may return an array
+     * of Strings representing letters of the alphabet. Or, it may return an
+     * array of objects whose toString() methods return their section titles.
+     *
+     * @return the array of section objects
      */
     Object[] getSections();
-    
+
     /**
-     * Provides the starting index in the list for a given section.
-     * @param section the index of the section to jump to.
-     * @return the starting position of that section. If the section is out of bounds, the
-     * position must be clipped to fall within the size of the list.
+     * Given the index of a section within the array of section objects, returns
+     * the starting position of that section within the adapter.
+     * <p>
+     * If the section's starting position is outside of the adapter bounds, the
+     * position must be clipped to fall within the size of the adapter.
+     *
+     * @param sectionIndex the index of the section within the array of section
+     *            objects
+     * @return the starting position of that section within the adapter,
+     *         constrained to fall within the adapter bounds
      */
-    int getPositionForSection(int section);
-    
+    int getPositionForSection(int sectionIndex);
+
     /**
-     * This is a reverse mapping to fetch the section index for a given position
-     * in the list.
-     * @param position the position for which to return the section
-     * @return the section index. If the position is out of bounds, the section index
+     * Given a position within the adapter, returns the index of the
+     * corresponding section within the array of section objects.
+     * <p>
+     * If the section index is outside of the section array bounds, the index
      * must be clipped to fall within the size of the section array.
+     * <p>
+     * For example, consider an indexer where the section at array index 0
+     * starts at adapter position 100. Calling this method with position 10,
+     * which is before the first section, must return index 0.
+     *
+     * @param position the position within the adapter for which to return the
+     *            corresponding section index
+     * @return the index of the corresponding section within the array of
+     *         section objects, constrained to fall within the array bounds
      */
-    int getSectionForPosition(int position);    
+    int getSectionForPosition(int position);
 }
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index e33c4d4..1c1d77a 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -22,10 +22,12 @@
 import android.content.res.TypedArray;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.text.format.DateFormat;
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.inputmethod.EditorInfo;
@@ -105,6 +107,9 @@
 
     private Locale mCurrentLocale;
 
+    private boolean mHourWithTwoDigit;
+    private char mHourFormat;
+
     /**
      * The callback interface used to indicate the time has been adjusted.
      */
@@ -164,7 +169,7 @@
         // divider (only for the new widget style)
         mDivider = (TextView) findViewById(R.id.divider);
         if (mDivider != null) {
-            mDivider.setText(R.string.time_picker_separator);
+            setDividerText();
         }
 
         // minute
@@ -235,6 +240,24 @@
             mAmPmSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
         }
 
+        if (isAmPmAtStart()) {
+            // Move the am/pm view to the beginning
+            ViewGroup amPmParent = (ViewGroup) findViewById(R.id.timePickerLayout);
+            amPmParent.removeView(amPmView);
+            amPmParent.addView(amPmView, 0);
+            // Swap layout margins if needed. They may be not symmetrical (Old Standard Theme for
+            // example and not for Holo Theme)
+            ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) amPmView.getLayoutParams();
+            final int startMargin = lp.getMarginStart();
+            final int endMargin = lp.getMarginEnd();
+            if (startMargin != endMargin) {
+                lp.setMarginStart(endMargin);
+                lp.setMarginEnd(startMargin);
+            }
+        }
+
+        getHourFormatData();
+
         // update controls to initial state
         updateHourControl();
         updateMinuteControl();
@@ -259,6 +282,35 @@
         }
     }
 
+    private void getHourFormatData() {
+        final Locale defaultLocale = Locale.getDefault();
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(defaultLocale,
+                (mIs24HourView) ? "Hm" : "hm");
+        final int lengthPattern = bestDateTimePattern.length();
+        mHourWithTwoDigit = false;
+        char hourFormat = '\0';
+        // Check if the returned pattern is single or double 'H', 'h', 'K', 'k'. We also save
+        // the hour format that we found.
+        for (int i = 0; i < lengthPattern; i++) {
+            final char c = bestDateTimePattern.charAt(i);
+            if (c == 'H' || c == 'h' || c == 'K' || c == 'k') {
+                mHourFormat = c;
+                if (i + 1 < lengthPattern && c == bestDateTimePattern.charAt(i + 1)) {
+                    mHourWithTwoDigit = true;
+                }
+                break;
+            }
+        }
+    }
+
+    private boolean isAmPmAtStart() {
+        final Locale defaultLocale = Locale.getDefault();
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(defaultLocale,
+                "hm" /* skeleton */);
+
+        return bestDateTimePattern.startsWith("a");
+    }
+
     @Override
     public void setEnabled(boolean enabled) {
         if (mIsEnabled == enabled) {
@@ -423,9 +475,11 @@
         if (mIs24HourView == is24HourView) {
             return;
         }
-        mIs24HourView = is24HourView;
-        // cache the current hour since spinner range changes
+        // cache the current hour since spinner range changes and BEFORE changing mIs24HourView!!
         int currentHour = getCurrentHour();
+        // Order is important here.
+        mIs24HourView = is24HourView;
+        getHourFormatData();
         updateHourControl();
         // set value after spinner range is updated
         setCurrentHour(currentHour);
@@ -458,6 +512,38 @@
         onTimeChanged();
     }
 
+    /**
+     * The time separator is defined in the Unicode CLDR and cannot be supposed to be ":".
+     *
+     * See http://unicode.org/cldr/trac/browser/trunk/common/main
+     *
+     * We pass the correct "skeleton" depending on 12 or 24 hours view and then extract the
+     * separator as the character which is just after the hour marker in the returned pattern.
+     */
+    private void setDividerText() {
+        final Locale defaultLocale = Locale.getDefault();
+        final String skeleton = (mIs24HourView) ? "Hm" : "hm";
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(defaultLocale,
+                skeleton);
+        final String separatorText;
+        int hourIndex = bestDateTimePattern.lastIndexOf('H');
+        if (hourIndex == -1) {
+            hourIndex = bestDateTimePattern.lastIndexOf('h');
+        }
+        if (hourIndex == -1) {
+            // Default case
+            separatorText = ":";
+        } else {
+            int minuteIndex = bestDateTimePattern.indexOf('m', hourIndex + 1);
+            if  (minuteIndex == -1) {
+                separatorText = Character.toString(bestDateTimePattern.charAt(hourIndex + 1));
+            } else {
+                separatorText = bestDateTimePattern.substring(hourIndex + 1, minuteIndex);
+            }
+        }
+        mDivider.setText(separatorText);
+    }
+
     @Override
     public int getBaseline() {
         return mHourSpinner.getBaseline();
@@ -500,14 +586,25 @@
 
     private void updateHourControl() {
         if (is24HourView()) {
-            mHourSpinner.setMinValue(0);
-            mHourSpinner.setMaxValue(23);
-            mHourSpinner.setFormatter(NumberPicker.getTwoDigitFormatter());
+            // 'k' means 1-24 hour
+            if (mHourFormat == 'k') {
+                mHourSpinner.setMinValue(1);
+                mHourSpinner.setMaxValue(24);
+            } else {
+                mHourSpinner.setMinValue(0);
+                mHourSpinner.setMaxValue(23);
+            }
         } else {
-            mHourSpinner.setMinValue(1);
-            mHourSpinner.setMaxValue(12);
-            mHourSpinner.setFormatter(null);
+            // 'K' means 0-11 hour
+            if (mHourFormat == 'K') {
+                mHourSpinner.setMinValue(0);
+                mHourSpinner.setMaxValue(11);
+            } else {
+                mHourSpinner.setMinValue(1);
+                mHourSpinner.setMaxValue(12);
+            }
         }
+        mHourSpinner.setFormatter(mHourWithTwoDigit ? NumberPicker.getTwoDigitFormatter() : null);
     }
 
     private void updateMinuteControl() {
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index ff9678c..863d8cc 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -30,9 +30,7 @@
 import android.view.ViewConfiguration;
 import android.view.View.MeasureSpec;
 import android.view.ViewGroup;
-import android.widget.AbsListView;
 import android.widget.ImageButton;
-import android.widget.ListPopupWindow;
 
 import com.android.internal.view.ActionBarPolicy;
 import com.android.internal.view.menu.ActionMenuView.ActionMenuChildView;
@@ -694,32 +692,43 @@
         }
 
         @Override
-        public boolean onTouchObserved(View v, MotionEvent ev) {
-            if (ev.getActionMasked() == MotionEvent.ACTION_MOVE && v.isEnabled()
-                    && !v.pointInView(ev.getX(), ev.getY(), mScaledTouchSlop)) {
-                mActivePointerId = ev.getPointerId(0);
-                v.performClick();
-                return true;
-            }
-
-            return false;
-        }
-
-        @Override
-        public boolean onTouchForwarded(View v, MotionEvent ev) {
-            if (!v.isEnabled() || mOverflowPopup == null || !mOverflowPopup.isShowing()) {
+        public boolean onTouchObserved(View src, MotionEvent srcEvent) {
+            if (!src.isEnabled()) {
                 return false;
             }
 
-            if (mActivePointerId != MotionEvent.INVALID_POINTER_ID) {
-                if (mOverflowPopup.forwardMotionEvent(v, ev, mActivePointerId)) {
+            // Always start forwarding events when the source view is touched.
+            mActivePointerId = srcEvent.getPointerId(0);
+            src.performClick();
+            return true;
+        }
+
+        @Override
+        public boolean onTouchForwarded(View src, MotionEvent srcEvent) {
+            final OverflowPopup popup = mOverflowPopup;
+            if (popup != null && popup.isShowing()) {
+                final int activePointerId = mActivePointerId;
+                if (activePointerId != MotionEvent.INVALID_POINTER_ID && src.isEnabled()
+                        && popup.forwardMotionEvent(src, srcEvent, activePointerId)) {
+                    // Handled the motion event, continue forwarding.
                     return true;
                 }
 
-                mActivePointerId = MotionEvent.INVALID_POINTER_ID;
+                final int activePointerIndex = srcEvent.findPointerIndex(activePointerId);
+                if (activePointerIndex >= 0) {
+                    final float x = srcEvent.getX(activePointerIndex);
+                    final float y = srcEvent.getY(activePointerIndex);
+                    if (src.pointInView(x, y, mScaledTouchSlop)) {
+                        // The user is touching the source view. Cancel
+                        // forwarding, but don't dismiss the popup.
+                        return false;
+                    }
+                }
+
+                popup.dismiss();
             }
 
-            mOverflowPopup.dismiss();
+            // Cancel forwarding.
             return false;
         }
     }
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 945f42b..9b266df 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -27,7 +27,6 @@
 import android.view.View.MeasureSpec;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
-import android.widget.AbsListView;
 import android.widget.AdapterView;
 import android.widget.BaseAdapter;
 import android.widget.FrameLayout;
@@ -48,8 +47,6 @@
 
     static final int ITEM_LAYOUT = com.android.internal.R.layout.popup_menu_item_layout;
 
-    private final int[] mTempLocation = new int[2];
-
     private final Context mContext;
     private final LayoutInflater mInflater;
     private final MenuBuilder mMenu;
@@ -162,67 +159,20 @@
         return mPopup != null && mPopup.isShowing();
     }
 
-    public boolean forwardMotionEvent(View v, MotionEvent ev, int activePointerId) {
+    /**
+     * Forwards motion events from a source view to the popup window.
+     *
+     * @param src view from which the event was forwarded
+     * @param event forwarded motion event in source-local coordinates
+     * @param activePointerId id of the pointer that activated forwarding
+     * @return whether the event was handled
+     */
+    public boolean forwardMotionEvent(View src, MotionEvent event, int activePointerId) {
         if (mPopup == null || !mPopup.isShowing()) {
             return false;
         }
 
-        final AbsListView dstView = mPopup.getListView();
-        if (dstView == null || !dstView.isShown()) {
-            return false;
-        }
-
-        boolean cancelForwarding = false;
-        final int actionMasked = ev.getActionMasked();
-        switch (actionMasked) {
-            case MotionEvent.ACTION_CANCEL:
-                cancelForwarding = true;
-                break;
-            case MotionEvent.ACTION_UP:
-                cancelForwarding = true;
-                // $FALL-THROUGH$
-            case MotionEvent.ACTION_MOVE:
-                final int activeIndex = ev.findPointerIndex(activePointerId);
-                if (activeIndex < 0) {
-                    return false;
-                }
-
-                final int[] location = mTempLocation;
-                int x = (int) ev.getX(activeIndex);
-                int y = (int) ev.getY(activeIndex);
-
-                // Convert to global coordinates.
-                v.getLocationOnScreen(location);
-                x += location[0];
-                y += location[1];
-
-                // Convert to local coordinates.
-                dstView.getLocationOnScreen(location);
-                x -= location[0];
-                y -= location[1];
-
-                final int position = dstView.pointToPosition(x, y);
-                if (position >= 0) {
-                    final int childCount = dstView.getChildCount();
-                    final int firstVisiblePosition = dstView.getFirstVisiblePosition();
-                    final int index = position - firstVisiblePosition;
-                    if (index < childCount) {
-                        final View child = dstView.getChildAt(index);
-                        if (actionMasked == MotionEvent.ACTION_UP) {
-                            // Touch ended, click highlighted item.
-                            final long id = dstView.getItemIdAtPosition(position);
-                            dstView.performItemClick(child, position, id);
-                        } else if (actionMasked == MotionEvent.ACTION_MOVE) {
-                            // TODO: Highlight touched item, activate after
-                            // long-hover. Consider forwarding events as HOVER and
-                            // letting ListView handle this.
-                        }
-                    }
-                }
-                break;
-        }
-
-        return true;
+        return mPopup.onForwardedEvent(src, event, activePointerId);
     }
 
     @Override
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 0efa227..65b3678 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -63,7 +63,6 @@
 	android_os_FileUtils.cpp \
 	android_os_MemoryFile.cpp \
 	android_os_MessageQueue.cpp \
-	android_os_ParcelFileDescriptor.cpp \
 	android_os_Parcel.cpp \
 	android_os_SELinux.cpp \
 	android_os_SystemClock.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 91fdcc2..63310ab 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -135,7 +135,6 @@
 extern int register_android_os_Debug(JNIEnv* env);
 extern int register_android_os_MessageQueue(JNIEnv* env);
 extern int register_android_os_Parcel(JNIEnv* env);
-extern int register_android_os_ParcelFileDescriptor(JNIEnv *env);
 extern int register_android_os_SELinux(JNIEnv* env);
 extern int register_android_os_SystemProperties(JNIEnv *env);
 extern int register_android_os_SystemClock(JNIEnv* env);
@@ -1178,7 +1177,6 @@
     REG_JNI(register_android_os_FileObserver),
     REG_JNI(register_android_os_FileUtils),
     REG_JNI(register_android_os_MessageQueue),
-    REG_JNI(register_android_os_ParcelFileDescriptor),
     REG_JNI(register_android_os_SELinux),
     REG_JNI(register_android_os_Trace),
     REG_JNI(register_android_os_UEventObserver),
diff --git a/core/jni/android_os_ParcelFileDescriptor.cpp b/core/jni/android_os_ParcelFileDescriptor.cpp
deleted file mode 100644
index 99a2d04..0000000
--- a/core/jni/android_os_ParcelFileDescriptor.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-
-#include "JNIHelp.h"
-
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <stdio.h>
-
-#include <utils/Log.h>
-
-#include <android_runtime/AndroidRuntime.h>
-
-namespace android
-{
-
-static struct parcel_file_descriptor_offsets_t
-{
-    jfieldID mFileDescriptor;
-} gParcelFileDescriptorOffsets;
-
-static jobject android_os_ParcelFileDescriptor_getFileDescriptorFromFd(JNIEnv* env,
-    jobject clazz, jint origfd)
-{
-    int fd = dup(origfd);
-    if (fd < 0) {
-        jniThrowException(env, "java/io/IOException", strerror(errno));
-        return NULL;
-    }
-    return jniCreateFileDescriptor(env, fd);
-}
-
-static jobject android_os_ParcelFileDescriptor_getFileDescriptorFromFdNoDup(JNIEnv* env,
-    jobject clazz, jint fd)
-{
-    return jniCreateFileDescriptor(env, fd);
-}
-
-static void android_os_ParcelFileDescriptor_createPipeNative(JNIEnv* env,
-    jobject clazz, jobjectArray outFds)
-{
-    int fds[2];
-    if (pipe(fds) < 0) {
-        int therr = errno;
-        jniThrowException(env, "java/io/IOException", strerror(therr));
-        return;
-    }
-
-    for (int i=0; i<2; i++) {
-        jobject fdObj = jniCreateFileDescriptor(env, fds[i]);
-        env->SetObjectArrayElement(outFds, i, fdObj);
-    }
-}
-
-static jint getFd(JNIEnv* env, jobject clazz)
-{
-    jobject descriptor = env->GetObjectField(clazz, gParcelFileDescriptorOffsets.mFileDescriptor);
-    if (descriptor == NULL) return -1;
-    return jniGetFDFromFileDescriptor(env, descriptor);
-}
-
-static jlong android_os_ParcelFileDescriptor_getStatSize(JNIEnv* env,
-    jobject clazz)
-{
-    jint fd = getFd(env, clazz);
-    if (fd < 0) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", "bad file descriptor");
-        return -1;
-    }
-
-    struct stat st;
-    if (fstat(fd, &st) != 0) {
-        return -1;
-    }
-
-    if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
-        return st.st_size;
-    }
-
-    return -1;
-}
-
-static jlong android_os_ParcelFileDescriptor_seekTo(JNIEnv* env,
-    jobject clazz, jlong pos)
-{
-    jint fd = getFd(env, clazz);
-    if (fd < 0) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", "bad file descriptor");
-        return -1;
-    }
-
-    return lseek(fd, pos, SEEK_SET);
-}
-
-static jlong android_os_ParcelFileDescriptor_getFdNative(JNIEnv* env, jobject clazz)
-{
-    jint fd = getFd(env, clazz);
-    if (fd < 0) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", "bad file descriptor");
-        return -1;
-    }
-
-    return fd;
-}
-
-static const JNINativeMethod gParcelFileDescriptorMethods[] = {
-    {"getFileDescriptorFromFd", "(I)Ljava/io/FileDescriptor;",
-        (void*)android_os_ParcelFileDescriptor_getFileDescriptorFromFd},
-    {"getFileDescriptorFromFdNoDup", "(I)Ljava/io/FileDescriptor;",
-        (void*)android_os_ParcelFileDescriptor_getFileDescriptorFromFdNoDup},
-    {"createPipeNative", "([Ljava/io/FileDescriptor;)V",
-        (void*)android_os_ParcelFileDescriptor_createPipeNative},
-    {"getStatSize", "()J",
-        (void*)android_os_ParcelFileDescriptor_getStatSize},
-    {"seekTo", "(J)J",
-        (void*)android_os_ParcelFileDescriptor_seekTo},
-    {"getFdNative", "()I",
-        (void*)android_os_ParcelFileDescriptor_getFdNative}
-};
-
-const char* const kParcelFileDescriptorPathName = "android/os/ParcelFileDescriptor";
-
-int register_android_os_ParcelFileDescriptor(JNIEnv* env)
-{
-    jclass clazz = env->FindClass(kParcelFileDescriptorPathName);
-    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor");
-    gParcelFileDescriptorOffsets.mFileDescriptor = env->GetFieldID(clazz, "mFileDescriptor", "Ljava/io/FileDescriptor;");
-    LOG_FATAL_IF(gParcelFileDescriptorOffsets.mFileDescriptor == NULL,
-                 "Unable to find mFileDescriptor field in android.os.ParcelFileDescriptor");
-
-    return AndroidRuntime::registerNativeMethods(
-        env, kParcelFileDescriptorPathName,
-        gParcelFileDescriptorMethods, NELEM(gParcelFileDescriptorMethods));
-}
-
-}
diff --git a/core/res/res/layout/time_picker.xml b/core/res/res/layout/time_picker.xml
index a78cd85..4fa94f3 100644
--- a/core/res/res/layout/time_picker.xml
+++ b/core/res/res/layout/time_picker.xml
@@ -20,6 +20,7 @@
 <!-- Layout of time picker-->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/timePickerLayout"
     android:orientation="horizontal"
     android:layout_gravity="center_horizontal"
     android:layout_width="wrap_content"
diff --git a/core/res/res/layout/time_picker_holo.xml b/core/res/res/layout/time_picker_holo.xml
index 7d8900e..c6b7d3a 100644
--- a/core/res/res/layout/time_picker_holo.xml
+++ b/core/res/res/layout/time_picker_holo.xml
@@ -20,14 +20,19 @@
 <!-- Layout of time picker -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/timePickerLayout"
     android:orientation="horizontal"
     android:layout_gravity="center_horizontal"
     android:layout_width="wrap_content"
-    android:layout_height="wrap_content">
+    android:layout_height="wrap_content"
+    android:paddingStart="8dip"
+    android:paddingEnd="8dip">
 
     <LinearLayout android:orientation="horizontal"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:paddingStart="8dip"
+        android:paddingEnd="8dip"
         android:layoutDirection="ltr">
 
         <!-- hour -->
@@ -37,8 +42,6 @@
             android:layout_height="wrap_content"
             android:layout_marginTop="16dip"
             android:layout_marginBottom="16dip"
-            android:layout_marginStart="16dip"
-            android:layout_marginEnd="6dip"
             android:focusable="true"
             android:focusableInTouchMode="true"
             />
@@ -48,6 +51,8 @@
             android:id="@+id/divider"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_marginStart="6dip"
+            android:layout_marginEnd="6dip"
             android:layout_gravity="center_vertical"
             android:importantForAccessibility="no"
             />
@@ -59,8 +64,6 @@
             android:layout_height="wrap_content"
             android:layout_marginTop="16dip"
             android:layout_marginBottom="16dip"
-            android:layout_marginStart="6dip"
-            android:layout_marginEnd="8dip"
             android:focusable="true"
             android:focusableInTouchMode="true"
             />
@@ -75,7 +78,7 @@
         android:layout_marginTop="16dip"
         android:layout_marginBottom="16dip"
         android:layout_marginStart="8dip"
-        android:layout_marginEnd="16dip"
+        android:layout_marginEnd="8dip"
         android:focusable="true"
         android:focusableInTouchMode="true"
         />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 03e9045..50ea08b 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2378,6 +2378,9 @@
         <!-- Set to true in all of the configurations for which this input
              method should be considered an option as the default. -->
         <attr name="isDefault" format="boolean" />
+        <!-- Set to true if this input method supports ways to switch to
+             a next input method (e.g. a globe key.). -->
+        <attr name="supportsSwitchingToNextInputMethod" format="boolean" />
     </declare-styleable>
 
     <!-- This is the subtype of InputMethod. Subtype can describe locales (e.g. en_US, fr_FR...)
diff --git a/core/res/res/values/donottranslate.xml b/core/res/res/values/donottranslate.xml
index b49e7bd..a7288e1 100644
--- a/core/res/res/values/donottranslate.xml
+++ b/core/res/res/values/donottranslate.xml
@@ -24,8 +24,6 @@
     <bool name="lockscreen_isPortrait">true</bool>
     <!-- @hide DO NOT TRANSLATE. Control aspect ratio of lock pattern -->
     <string name="lock_pattern_view_aspect">square</string>
-    <!-- @hide DO NOT TRANSLATE. Separator between the hour and minute elements in a TimePicker widget -->
-    <string name="time_picker_separator">:</string>
     <!-- @hide DO NOT TRANSLATE. ICU pattern for "Mon, 14 January" -->
     <string name="icu_abbrev_wday_month_day_no_year">eeeMMMMd</string>
     <!-- @hide DO NOT TRANSLATE. date formatting pattern for system ui.-->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 80c9184..f2ec04f 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2072,5 +2072,6 @@
   <public type="attr" name="isAsciiCapable" />
   <public type="attr" name="customRoots" />
   <public type="attr" name="autoMirrored" />
+  <public type="attr" name="supportsSwitchingToNextInputMethod" />
 
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 14ae1e6..ca93d1c 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -217,6 +217,7 @@
   <java-symbol type="id" name="pin_new_text" />
   <java-symbol type="id" name="pin_confirm_text" />
   <java-symbol type="id" name="pin_error_message" />
+  <java-symbol type="id" name="timePickerLayout" />
 
   <java-symbol type="attr" name="actionModeShareDrawable" />
   <java-symbol type="attr" name="alertDialogCenterButtons" />
@@ -773,7 +774,6 @@
   <java-symbol type="string" name="time_picker_increment_hour_button" />
   <java-symbol type="string" name="time_picker_increment_minute_button" />
   <java-symbol type="string" name="time_picker_increment_set_pm_button" />
-  <java-symbol type="string" name="time_picker_separator" />
   <java-symbol type="string" name="upload_file" />
   <java-symbol type="string" name="user_switched" />
   <java-symbol type="string" name="volume_alarm" />
diff --git a/docs/downloads/design/roboto-1.100141.zip b/docs/downloads/design/roboto-1.100141.zip
new file mode 100644
index 0000000..93dfda7
--- /dev/null
+++ b/docs/downloads/design/roboto-1.100141.zip
Binary files differ
diff --git a/docs/html/design/downloads/index.jd b/docs/html/design/downloads/index.jd
index b13ba62..6d9a60d 100644
--- a/docs/html/design/downloads/index.jd
+++ b/docs/html/design/downloads/index.jd
@@ -102,7 +102,7 @@
 
 <p>
   <a class="download-button"  onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Roboto ZIP']);"
-    href="https://github.com/google/roboto/archive/latest-hinted.zip">Roboto</a>
+    href="{@docRoot}downloads/design/roboto-1.100141.zip">Roboto</a>
   <a class="download-button"  onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Roboto Specemin Book']);"
     href="{@docRoot}downloads/design/Roboto_Specimen_Book_20111129.pdf">Specimen Book</a>
 </p>
diff --git a/docs/html/design/style/typography.jd b/docs/html/design/style/typography.jd
index 0d681ab..818af4c 100644
--- a/docs/html/design/style/typography.jd
+++ b/docs/html/design/style/typography.jd
@@ -12,7 +12,7 @@
 
 <p>
   <a class="download-button"  onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Roboto ZIP']);"
-    href="https://github.com/google/roboto/archive/latest-hinted.zip">Download Roboto</a>
+    href="{@docRoot}downloads/design/roboto-1.100141.zip">Download Roboto</a>
 </p>
 
 <p>The Android design language relies on traditional typographic tools such as scale, space, rhythm,
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index df966e1..f9cf9a2 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -331,6 +331,11 @@
 void Caches::flush(FlushMode mode) {
     FLUSH_LOGD("Flushing caches (mode %d)", mode);
 
+    // We must stop tasks before clearing caches
+    if (mode > kFlushMode_Layers) {
+        tasks.stop();
+    }
+
     switch (mode) {
         case kFlushMode_Full:
             textureCache.clear();
@@ -338,13 +343,13 @@
             dropShadowCache.clear();
             gradientCache.clear();
             fontRenderer->clear();
+            fboCache.clear();
             dither.clear();
             // fall through
         case kFlushMode_Moderate:
             fontRenderer->flush();
             textureCache.flush();
             pathCache.clear();
-            tasks.stop();
             // fall through
         case kFlushMode_Layers:
             layerCache.clear();
diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java
index ee748d39..c9162fe 100644
--- a/location/java/android/location/LocationRequest.java
+++ b/location/java/android/location/LocationRequest.java
@@ -146,7 +146,7 @@
     private long mExpireAt = Long.MAX_VALUE;  // no expiry
     private int mNumUpdates = Integer.MAX_VALUE;  // no expiry
     private float mSmallestDisplacement = 0.0f;    // meters
-    private WorkSource mWorkSource = new WorkSource();
+    private WorkSource mWorkSource = null;
     private boolean mHideFromAppOps = false; // True if this request shouldn't be counted by AppOps
 
     private String mProvider = LocationManager.FUSED_PROVIDER;  // for deprecated APIs that explicitly request a provider
@@ -498,7 +498,16 @@
         return mSmallestDisplacement;
     }
 
-    /** @hide */
+    /**
+     * Sets the WorkSource to use for power blaming of this location request.
+     *
+     * <p>No permissions are required to make this call, however the LocationManager
+     * will throw a SecurityException when requesting location updates if the caller
+     * doesn't have the {@link android.Manifest.permission#UPDATE_DEVICE_STATS} permission.
+     *
+     * @param workSource WorkSource defining power blame for this location request.
+     * @hide
+     */
     public void setWorkSource(WorkSource workSource) {
         mWorkSource = workSource;
     }
@@ -508,7 +517,20 @@
         return mWorkSource;
     }
 
-    /** @hide */
+    /**
+     * Sets whether or not this location request should be hidden from AppOps.
+     *
+     * <p>Hiding a location request from AppOps will remove user visibility in the UI as to this
+     * request's existence.  It does not affect power blaming in the Battery page.
+     *
+     * <p>No permissions are required to make this call, however the LocationManager
+     * will throw a SecurityException when requesting location updates if the caller
+     * doesn't have the {@link android.Manifest.permission#UPDATE_APP_OPS_STATS} permission.
+     *
+     * @param hideFromAppOps If true AppOps won't keep track of this location request.
+     * @see android.app.AppOpsManager
+     * @hide
+     */
     public void setHideFromAppOps(boolean hideFromAppOps) {
         mHideFromAppOps = hideFromAppOps;
     }
@@ -564,7 +586,7 @@
             request.setHideFromAppOps(in.readInt() != 0);
             String provider = in.readString();
             if (provider != null) request.setProvider(provider);
-            WorkSource workSource = in.readParcelable(WorkSource.class.getClassLoader());
+            WorkSource workSource = in.readParcelable(null);
             if (workSource != null) request.setWorkSource(workSource);
             return request;
         }
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index 8ddc094..f3356c9 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -20,7 +20,6 @@
 import android.graphics.PixelFormat;
 import android.os.Handler;
 import android.os.Looper;
-import android.os.Message;
 import android.view.Surface;
 
 import java.lang.ref.WeakReference;
@@ -130,11 +129,26 @@
     }
 
     /**
-     * <p>Get the next Image from the ImageReader's queue. Returns {@code null}
-     * if no new image is available.</p>
+     * <p>
+     * Get the next Image from the ImageReader's queue. Returns {@code null} if
+     * no new image is available.
+     * </p>
+     * <p>
+     * This operation will fail by throwing an
+     * {@link Surface.OutOfResourcesException OutOfResourcesException} if too
+     * many images have been acquired with {@link #getNextImage}. In particular
+     * a sequence of {@link #getNextImage} calls greater than {@link #getMaxImages}
+     * without calling {@link Image#close} or {@link #releaseImage} in-between
+     * will exhaust the underlying queue. At such a time,
+     * {@link Surface.OutOfResourcesException OutOfResourcesException} will be
+     * thrown until more images are released with {@link Image#close} or
+     * {@link #releaseImage}.
+     * </p>
      *
      * @return a new frame of image data, or {@code null} if no image data is
-     * available.
+     *         available.
+     * @throws Surface.OutOfResourcesException if too many images are currently
+     *         acquired
      */
     public Image getNextImage() {
         SurfaceImage si = new SurfaceImage();
@@ -172,6 +186,8 @@
      * @param listener the listener that will be run
      * @param handler The handler on which the listener should be invoked, or null
      * if the listener should be invoked on the calling thread's looper.
+     *
+     * @throws IllegalArgumentException if no handler specified and the calling thread has no looper
      */
    public void setImageAvailableListener(OnImageAvailableListener listener, Handler handler) {
         mImageListener = listener;
@@ -260,8 +276,9 @@
      * Called from Native code when an Event happens.
      */
     private static void postEventFromNative(Object selfRef) {
-        WeakReference weakSelf = (WeakReference)selfRef;
-        final ImageReader ir = (ImageReader)weakSelf.get();
+        @SuppressWarnings("unchecked")
+        WeakReference<ImageReader> weakSelf = (WeakReference<ImageReader>)selfRef;
+        final ImageReader ir = weakSelf.get();
         if (ir == null) {
             return;
         }
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 3fbaf69..278d661 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -26,7 +26,7 @@
  *
  * The format of the media data is specified as string/value pairs.
  *
- * Keys common to all formats, <b>all keys not marked optional are mandatory</b>:
+ * Keys common to all audio/video formats, <b>all keys not marked optional are mandatory</b>:
  *
  * <table>
  * <tr><th>Name</th><th>Value Type</th><th>Description</th></tr>
@@ -57,6 +57,11 @@
  * <tr><td>{@link #KEY_FLAC_COMPRESSION_LEVEL}</td><td>Integer</td><td><b>encoder-only</b>, optional, if content is FLAC audio, specifies the desired compression level.</td></tr>
  * </table>
  *
+ * Subtitle formats have the following keys:
+ * <table>
+ * <tr><td>{@link #KEY_MIME}</td><td>String</td><td>The type of the format.</td></tr>
+ * <tr><td>{@link #KEY_LANGUAGE}</td><td>String</td><td>The language of the content.</td></tr>
+ * </table>
  */
 public final class MediaFormat {
     private Map<String, Object> mMap;
@@ -68,6 +73,12 @@
     public static final String KEY_MIME = "mime";
 
     /**
+     * A key describing the language of the content.
+     * The associated value is a string.
+     */
+    public static final String KEY_LANGUAGE = "language";
+
+    /**
      * A key describing the sample rate of an audio format.
      * The associated value is an integer
      */
@@ -277,6 +288,23 @@
     }
 
     /**
+     * Creates a minimal subtitle format.
+     * @param mime The mime type of the content.
+     * @param language The language of the content.  Specify "und" if language
+     *        information is only included in the content (similarly, if there
+     *        are multiple language tracks in the content.)
+     */
+    public static final MediaFormat createSubtitleFormat(
+            String mime,
+            String language) {
+        MediaFormat format = new MediaFormat();
+        format.setString(KEY_MIME, mime);
+        format.setString(KEY_LANGUAGE, language);
+
+        return format;
+    }
+
+    /**
      * Creates a minimal video format.
      * @param mime The mime type of the content.
      * @param width The width of the content (in pixels)
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index cd589de..7d914d2 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -44,6 +44,9 @@
 
 using namespace android;
 
+static const char* const OutOfResourcesException =
+    "android/view/Surface$OutOfResourcesException";
+
 enum {
     IMAGE_READER_MAX_NUM_PLANES = 3,
 };
@@ -609,7 +612,8 @@
     nativeFormat = Image_getPixelFormat(env, format);
 
     sp<BufferQueue> bq = new BufferQueue();
-    sp<CpuConsumer> consumer = new CpuConsumer(bq, true, maxImages);
+    sp<CpuConsumer> consumer = new CpuConsumer(bq, maxImages,
+                                               /*controlledByApp*/true);
     // TODO: throw dvm exOutOfMemoryError?
     if (consumer == NULL) {
         jniThrowRuntimeException(env, "Failed to allocate native CpuConsumer");
@@ -702,7 +706,17 @@
     status_t res = consumer->lockNextBuffer(buffer);
     if (res != NO_ERROR) {
         if (res != BAD_VALUE /*no buffers*/) {
-            ALOGE("%s Fail to lockNextBuffer with error: %d ", __FUNCTION__, res);
+            if (res == NOT_ENOUGH_DATA) {
+                jniThrowException(env, OutOfResourcesException,
+                          "Too many outstanding images, close existing images"
+                          " to be able to acquire more.");
+            } else {
+                ALOGE("%s Fail to lockNextBuffer with error: %d ",
+                      __FUNCTION__, res);
+                jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+                          "Unknown error (%d) when we tried to lock buffer.",
+                          res);
+            }
         }
         return false;
     }
@@ -714,6 +728,7 @@
         ALOGE("crop left: %d, top = %d", lt.x, lt.y);
         jniThrowException(env, "java/lang/UnsupportedOperationException",
                           "crop left top corner need to at origin");
+        return false;
     }
 
     // Check if the producer buffer configurations match what ImageReader configured.
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 16a1e48..60142cd 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -753,7 +753,9 @@
 
     status_t err = drm->provideKeyResponse(sessionId, response, keySetId);
 
-    throwExceptionAsNecessary(env, err, "Failed to handle key response");
+    if (throwExceptionAsNecessary(env, err, "Failed to handle key response")) {
+        return NULL;
+    }
     return VectorToJByteArray(env, keySetId);
 }
 
@@ -1104,7 +1106,9 @@
 
     status_t err = drm->encrypt(sessionId, keyId, input, iv, output);
 
-    throwExceptionAsNecessary(env, err, "Failed to encrypt");
+    if (throwExceptionAsNecessary(env, err, "Failed to encrypt")) {
+        return NULL;
+    }
 
     return VectorToJByteArray(env, output);
 }
@@ -1132,7 +1136,9 @@
     Vector<uint8_t> output;
 
     status_t err = drm->decrypt(sessionId, keyId, input, iv, output);
-    throwExceptionAsNecessary(env, err, "Failed to decrypt");
+    if (throwExceptionAsNecessary(env, err, "Failed to decrypt")) {
+        return NULL;
+    }
 
     return VectorToJByteArray(env, output);
 }
@@ -1160,7 +1166,9 @@
 
     status_t err = drm->sign(sessionId, keyId, message, signature);
 
-    throwExceptionAsNecessary(env, err, "Failed to sign");
+    if (throwExceptionAsNecessary(env, err, "Failed to sign")) {
+        return NULL;
+    }
 
     return VectorToJByteArray(env, signature);
 }
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 9b2c127..2bed730 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -201,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OUTO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Kennisgewings verskyn hier"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Verkry enige tyd toegang tot hulle deur af te sleep.\nSleep weer af vir stelselkontroles."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Sleep rand van skerm om balk te wys"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Sleep van rand van skerm af om stelselbalk te wys"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 4aa452d..ebbad16 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -164,7 +164,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi ተያይዟል"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"ለGPS በመፈለግ ላይ"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"በ GPS የተዘጋጀ ሥፍራ"</string>
-    <string name="accessibility_location_active" msgid="2427290146138169014">"ገባሪ የአካባቢ ጥያቄዎች"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"የአካባቢ ጥያቄዎች ነቅተዋል"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"ሁሉንም ማሳወቂያዎች አጽዳ"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"የመተግበሪያ መረጃ"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ማያ ገጽ በራስ ሰር ይዞራል።"</string>
@@ -201,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ራስ-ሰር"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"ማሳወቂያዎች እዚህ ላይ ይታያሉ"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"ወደ ታች በማንሸራተት በማንኛውም ጊዜ ይድረሱባቸው።\nSwipe የስርዓት መቆጣጠሪያዎችን ለማምጣት እንደገና ወደ ታች ያንሸራትቱ።"</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"አሞሌውን ለማሳየት የማያ ገጹን ጠርዝ ላይ ያንሸራትቱ"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"አሞሌውን ለማሳየት ከማያ ገጹ ጠርዝ ጀምረው ያንሸራትቱ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index f7f5e37..7aac94e 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -201,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"تلقائي"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"تظهر الإشعارات هنا"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"يمكنك الدخول إليها في أي وقت بالتمرير السريع إلى أسفل.\nيمكنك التمرير السريع إلى أسفل مرة أخرى للوصول إلى عناصر تحكم النظام."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"مرر سريعًا لحافة الشاشة لإظهار الشريط"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"مرر سريعًا من حافة الشاشة لإظهار شريط النظام"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index aaca584..76d0580 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -206,8 +206,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АЎТА"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Апавяшчэнні з\'яўляюцца тут"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Атрымлівайце доступ да іх у любы час, праводзячы пальцам уніз.\nПравядзіце пальцам уніз яшчэ раз, каб атрымаць доступ да сродкаў кіравання сістэмай."</string>
-    <!-- no translation found for hiding_navigation_confirmation_message (3227814171674734332) -->
-    <skip />
-    <!-- no translation found for hiding_navigation_confirmation_message_long (7854368870786524950) -->
-    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index b10f5ff..605dd97 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -164,8 +164,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: Има връзка"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Търси се GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Местоположението е зададено от GPS"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Активни заявки за местоположение"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Изчистване на всички известия."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Информация за приложението"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екранът ще се завърта автоматично."</string>
@@ -202,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТ."</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Известията се показват тук"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Осъществявайте достъп до тях по всяко време, като прекарате пръст надолу.\nНаправете го отново за системните контроли."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Прекарайте пръст по ръба на екрана, за да се покаже лентата"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Прекарайте пръст от ръба на екрана, за да се покаже системната лента"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 0a95005..83e7020 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -166,8 +166,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: connectada"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"S\'està cercant un GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"S\'ha establert la ubicació per GPS"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Sol·licituds d\'ubicació actives"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Esborra totes les notificacions."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informació de l\'aplicació"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girarà automàticament."</string>
@@ -204,6 +203,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÀTICA"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Les notificacions apareixen aquí"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Accedeix-hi en qualsevol moment: només has de fer lliscar el dit cap avall.\nTorna a fer lliscar el dit cap avall per fer que es mostrin els controls del sistema."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Fes lliscar el dit per la vora de la pantalla perquè es mostri la barra"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Fes lliscar el dit des de la vora de la pantalla perquè es mostri la barra del sistema"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 178238f..4497735 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -203,6 +203,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATICKY"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Zde se zobrazují oznámení"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Můžete je kdykoli zobrazit tím, že přejedete prstem dolů.\nPřejedete-li prstem dolů ještě jednou, zobrazí se ovládací prvky systému."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Panel zobrazíte přejetím přes okraj obrazovky"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Systémový panel zobrazíte přejetím přes okraj obrazovky"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 1c772b5..be42612 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -164,8 +164,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi er forbundet"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Søger efter GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Placeringen er angivet ved hjælp af GPS"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Aktive placeringsanmodninger"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Ryd alle meddelelser."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Oplysninger om appen"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skærmen roterer automatisk."</string>
@@ -202,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Underretninger vises her"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Få adgang til dem når som helst ved at stryge ned.\nStryg ned igen for at komme til systemindstillingerne."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Stryg fra skærmkanten for at se bjælken"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Stryg med fingeren fra skærmens kant for at få vist systembjælken"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 86ea82d..052990c 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -166,8 +166,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"WLAN verbunden"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS wird gesucht"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Standort durch GPS festgelegt"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Standortanfragen aktiv"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Alle Benachrichtigungen löschen"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"App-Details"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Bildschirm wird automatisch gedreht."</string>
@@ -204,6 +203,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Benachrichtigungen erscheinen hier"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Greifen Sie jederzeit auf sie zu, indem Sie nach unten wischen.\nWischen Sie für Systemeinstellungen erneut nach unten."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Zum Einblenden der Leiste vom Rand weg wischen"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Zum Einblenden der Systemleiste vom Display-Rand weg wischen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index f965773..d23b8d5 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -203,6 +203,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ΑΥΤΟΜΑΤΗ"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Οι ειδοποιήσεις εμφανίζονται εδώ"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Μεταβείτε σε αυτές ανά πάσα στιγμή σύροντας προς τα κάτω.\nΣύρετε ξανά προς τα κάτω για τα στοιχεία ελέγχου συστήματος."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Σύρετε από την άκρη της οθόνης για να εμφανίσετε τη γραμμή"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Σύρετε από την άκρη της οθόνης για να εμφανίσετε τη γραμμή συστήματος"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index a7d621352..2ac1040 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -201,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Notifications appear here"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Access them any time by swiping down.\nSwipe down again for system controls."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Swipe edge of screen to reveal bar"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Swipe from edge of screen to reveal system bar"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index bdd0363..d11d413 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -166,8 +166,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi conectado"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Buscando GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"La ubicación se estableció por GPS"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de ubicación activas"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Eliminar todas las notificaciones"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Información de la aplicación"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girará automáticamente."</string>
@@ -204,6 +203,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÁTICO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Las notificaciones aparecen aquí."</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Desliza el dedo hacia abajo para acceder al contenido.\nVuelve a deslizar el dedo hacia abajo para acceder a los controles del sistema."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Desliza el dedo desde el borde de la pantalla para mostrar la barra."</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Desliza el dedo desde el borde de la pantalla para mostrar la barra del sistema."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index a81a2b4..068af45 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -201,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Las notificaciones aparecen aquí"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Desliza el dedo hacia abajo para acceder al contenido.\nVuelve a deslizar el dedo hacia abajo para acceder a los controles del sistema."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Desliza el borde de la pantalla para mostrar la barra"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Desliza el borde de la pantalla para mostrar la barra del sistema"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index c4fda13..28ece65 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -201,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMAATNE"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Märguanded ilmuvad siia"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Juurdepääs igal ajal sõrmega alla pühkides.\nSüsteemi juhtnuppude jaoks pühkige uuesti alla."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Riba kuvamiseks pühkige ekraani serva"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Süsteemiriba kuvamiseks pühkige ekraani servast"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index a84b9b4..2ba0427 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -201,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"خودکار"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"اعلان‌ها در اینجا نمایش داده می‌شوند"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"با کشیدن انگشت به طرف پایین به آنها دسترسی پیدا کنید.\nبرای کنترل‌های سیستم دوباره انگشت خود را به سمت پایین بکشید."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"برای نمایش نوار، انگشت خود را از لبه‌ صفحه به داخل بکشید"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"برای نمایش نوار سیستم، انگشت خود را از لبه‌ صفحه به داخل بکشید"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index f2cce06..b652cb0 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -201,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Ilmoitukset näkyvät tässä"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Näet ilmoitukset liu\'uttamalla sormea alas ruudulla.\nVoit palauttaa järjestelmän ohjaimet näkyviin liu\'uttamalla sormea alas uudelleen."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Tuo palkki näkyviin liu\'uttamalla ruudun reunasta"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Tuo järjestelmäpalkki näkyviin liu\'uttamalla ruudun reunasta"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 7fe1143..d00e4a3 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -166,8 +166,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Connecté au Wi-Fi"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Recherche de GPS..."</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Position définie par GPS"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Demandes de localisation actives"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Supprimer toutes les notifications"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informations sur l\'application"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"L\'écran pivote automatiquement."</string>
@@ -204,6 +203,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATIQUE"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Les notifications s’affichent ici"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Accédez-y à tout moment en faisant glisser le doigt vers le bas.\nRépétez l\'opération pour accéder aux commandes du système."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Faites glisser le doigt sur le côté de l\'écran pour afficher la barre."</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Faites glisser le doigt à partir d\'un côté de l\'écran pour afficher la barre système."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index a1de7a1..45b5813 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -201,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"स्वत:"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"सूचनाएं यहां दिखाई देती हैं"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"नीचे स्वाइप करके उन तक कभी भी पहुंचें.\nसिस्टम नियंत्रणों के लिए पुन: नीचे स्वाइप करें."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"बार को प्रदर्शित करने के लिए स्क्रीन के किनारे को स्वाइप करें"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"सिस्टम बार को प्रदर्शित करने के लिए स्क्रीन के किनारे से स्वाइप करें"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index f8ff35d..9f8559c 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -201,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATSKI"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Obavijesti se prikazuju ovdje"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Pristupite im u bilo kojem trenutku tako da prstom trznete prema dolje. \nPonovo prstom trznite prema dolje za kontrole sustava."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Prijeđite prstom po rubu zaslona da bi se prikazala traka"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Prijeđite prstom od ruba zaslona da bi se prikazala traka sustava"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 118baed..f2dcd93 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -201,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"automatikus"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Az értesítések itt jelennek meg."</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Bármikor elérheti őket, ha lefelé húzza az ujját.\nHúzza le az ujját még egyszer a rendszerbeállítások eléréséhez."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Csúsztassa ujját a képernyő szélén a sáv megjelenítéséhez"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Csúsztassa ujját a képernyő szélétől a rendszersáv megjelenítéséhez"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 013bd99..6846056 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -164,8 +164,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi tersambung"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Menelusuri GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi yang disetel oleh GPS"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Permintaan lokasi aktif"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Menghapus semua pemberitahuan."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Info aplikasi"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Layar akan diputar secara otomatis."</string>
@@ -202,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OTOMATIS"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Pemberitahuan muncul di sini"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Akses kapan saja dengan menggesek ke bawah.\nGesek ke bawah sekali lagi untuk kontrol sistem."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Gesek tepi layar untuk membuka bilah"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Gesek dari bagian tepi layar untuk membuka bilah sistem"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index ff539be..a889342 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -203,6 +203,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Le notifiche vengono visualizzate qui"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Puoi accedervi in qualsiasi momento scorrendo verso il basso.\nFai scorrere di nuovo verso il basso per visualizzare i controlli del sistema."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Fai scorrere il bordo dello schermo per visualizzare la barra"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Fai scorrere il dito dal bordo dello schermo per visualizzare la barra di sistema"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index c80ad7c..899f092 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -164,8 +164,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi מחובר"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"מחפש GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"מיקום מוגדר על ידי GPS"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"בקשות מיקום פעילות"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"נקה את כל ההתראות."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"פרטי יישום"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"המסך יסתובב באופן אוטומטי."</string>
@@ -202,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"אוטומטי"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"הודעות מופיעות כאן"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"גש אליהם בכל עת על ידי החלקה למטה.\nהחלק למטה שוב למעבר למרכז הבקרה של המערכת."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"החלק מקצה המסך כדי להציג את הסרגל"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"החלק מקצה המסך כדי להציג את סרגל המערכת"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 73aa558..e92e8be 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -166,8 +166,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi接続済み"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPSで検索中"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPSにより現在地が設定されました"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"現在地リクエストがアクティブ"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"通知をすべて消去。"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"アプリ情報"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"画面は自動的に回転します。"</string>
@@ -204,6 +203,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"ここに通知が表示されます"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"下にスワイプすると、いつでも通知を表示できます。\nシステムを管理するにはもう一度下にスワイプしてください。"</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"バーを表示するには、画面の端からスワイプします"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"システムバーを表示するには、画面の端からスワイプします"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 403c94b..6319184 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -164,8 +164,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi 연결됨"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS 검색 중"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS에서 위치 설정"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"위치 요청 있음"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"모든 알림 지우기"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"앱 정보"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"화면이 자동으로 회전됩니다."</string>
@@ -202,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"자동"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"알림이 여기에 표시됨"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"아래로 스와이프하여 언제든 액세스하세요.\n한 번 더 아래로 스와이프하면 시스템 관리로 이동합니다."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"화면 가장자리에서 스와이프하여 표시줄 표시"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"화면 가장자리에서 스와이프하여 시스템 표시줄 표시"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 11b67ed..4400d37 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -164,8 +164,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Prisij. prie „Wi-Fi“"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Ieškoma GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS nustatyta vieta"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Vietovės užklausos aktyvios"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Išvalyti visus pranešimus."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Programos informacija"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekranas bus sukamas automatiškai."</string>
@@ -202,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATINIS"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Pranešimai rodomi čia"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Perbraukę žemyn bet kuriuo metu pasieksite pranešimus.\nJei norite naudoti sistemos valdiklius, perbraukite žemyn dar kartą."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Jei norite, kad būtų rodoma juosta, perbraukite ekrano krašte"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Jei norite, kad būtų rodoma sistemos juosta, perbraukite iš ekrano krašto"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 85ab3fd..b2bee8c 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -164,8 +164,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Izv. sav. ar Wi-Fi"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Notiek GPS meklēšana..."</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS iestatītā atrašanās vieta"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Aktīvi atrašanās vietu pieprasījumi"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Notīrīt visus paziņojumus"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informācija par lietotni"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekrāns tiks pagriezts automātiski."</string>
@@ -202,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMĀTISKI"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Šeit tiek rādīti paziņojumi"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Piekļūstiet tiem jebkurā laikā, velkot uz leju.\nVēlreiz velciet, lai tiktu parādītas sistēmas vadīklas."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Velciet no ekrāna malas, lai piekļūtu joslai."</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Velciet no ekrāna malas, lai piekļūtu sistēmas joslai."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index b6b3577..9c76eae 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -201,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Pemberitahuan dipaparkan di sini"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Akses panel pada bila-bila masa dengan meleret ke bawah.\nLeret ke bawah sekali lagi untuk mendapatkan kawalan sistem."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Leret ke bahagian tepi skrin untuk menampakkan bar"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Leret dari tepi skrin untuk menampakkan bar sistem"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 6f7d727..d850cf3 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -164,8 +164,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi tilkoblet"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Søker etter GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Posisjon angitt av GPS"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Aktive stedsforespørsler"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Fjern alle varslinger."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Info om app"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skjermen roterer automatisk."</string>
@@ -202,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Varslene vises her"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Bruk dem når som helst ved å sveipe nedover.\nSveip nedover igjen for å gå til systemkontrollene."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Sveip på kanten av skjermen for å få frem feltet"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Sveip fra kanten på skjermen for å få frem systemfeltet"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 02a5b45..5b6ebab 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -201,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATISCH"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Meldingen worden hier weergegeven"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"U kunt de meldingen op elk gewenst moment openen door met uw vinger omlaag te vegen.\nVeeg nogmaals met uw vinger omlaag om de systeembesturingselementen weer te geven."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Veeg vanaf de rand om balk weer te geven"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Veeg vanaf de rand van het scherm om de systeembalk weer te geven"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index d17c45e..6bff7af 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -164,8 +164,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: połączono"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Wyszukiwanie sygnału GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokalizacja z GPSa"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Prośby o lokalizację są aktywne"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Usuń wszystkie powiadomienia."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"O aplikacji"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran zostanie obrócony automatycznie."</string>
@@ -202,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATYCZNA"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Tutaj pokazują się powiadomienia"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Możesz je otworzyć w dowolnej chwili, przesuwając w dół.\nPrzesuń jeszcze raz w dół, by otworzyć ustawienia systemowe."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Przesuń palcem od krawędzi ekranu, by odkryć pasek"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Przesuń palcem od krawędzi ekranu, by odkryć pasek systemu"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index b520319..6aa94e0 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -164,8 +164,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi ligado"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"A procurar GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Localização definida por GPS"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Pedidos de localização ativos"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informações da aplicação"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"O ecrã será rodado automaticamente."</string>
@@ -202,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÁTICO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"As notificações são apresentadas aqui"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Pode aceder em qualquer altura, deslizando rapidamente para baixo com o dedo.\nDeslize novamente para baixo para aceder aos controlos do sistema."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Deslize da extremidade do ecrã para revelar a barra"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Deslize da extremidade do ecrã para revelar a barra do sistema"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 2a2f336..aa972fb 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -166,8 +166,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi conectado"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Buscando GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Local definido por GPS"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Solicitações de localização ativas"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informações do aplicativo"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A tela girará automaticamente."</string>
@@ -204,6 +203,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"As notificações aparecem aqui"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Acesse a qualquer momento deslizando para baixo.\nDeslize para baixo novamente para acessar os controles do sistema."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Deslize a borda da tela para ver a barra"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Deslize a partir da borda da tela ver a barra do sistema"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index 22a857e..05b7453 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -372,8 +372,4 @@
     <skip />
     <!-- no translation found for status_bar_help_text (7874607155052076323) -->
     <skip />
-    <!-- no translation found for hiding_navigation_confirmation_message (3227814171674734332) -->
-    <skip />
-    <!-- no translation found for hiding_navigation_confirmation_message_long (7854368870786524950) -->
-    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 375d12cb..9c5ad00 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -164,8 +164,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi conectat"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Se caută GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Locaţie setată prin GPS"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Solicitări locație active"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Ștergeţi toate notificările."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informaţii despre aplicaţie"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ecranul se va roti în mod automat."</string>
@@ -202,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMAT"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Notificările se afişează aici"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Accesaţi-le oricând glisând în jos.\nGlisaţi în jos din nou pentru comenzile sistemului."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Glisați dinspre marginea ecranului pentru a afișa bara"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Glisați dinspre marginea ecranului pentru a afișa bara de sistem"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 15adf90..3020624 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -166,8 +166,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi подключено"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Поиск GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Координаты по GPS"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Есть активные запросы на определение местоположения"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Удалить все уведомления"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"О приложении"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран будет поворачиваться автоматически."</string>
@@ -206,6 +205,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТОНАСТРОЙКА"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Это панель уведомлений"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Ее можно открыть, пролистнув экран вниз.\nЧтобы открыть настройки, проведите пальцем вниз ещё раз."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Чтобы открыть панель, проведите пальцем от края к центру экрана"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Чтобы открыть панель навигации, проведите пальцем от края к центру экрана"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index bb70f36..59af9ab 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -166,8 +166,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: pripojené"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Vyhľadávanie satelitov GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Poloha nastavená pomocou GPS"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Žiadosti o polohu sú aktívne"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Vymazať všetky upozornenia."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informácie o aplikácii"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Obrazovka sa automaticky otočí."</string>
@@ -204,6 +203,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATICKY"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Tu sa zobrazujú upozornenia"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Môžete ich kedykoľvek zobraziť tak, že posuniete prstom nadol.\nAk posuniete prstom nadol ešte raz, zobrazia sa ovládacie prvky systému."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Panel zobrazíte posunutím cez okraj obrazovky"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Systémový panel zobrazíte posunutím cez okraj obrazovky"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 46a5826..338ff44 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -164,8 +164,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi povezan"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Iskanje GPS-a"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokacija nastavljena z GPS-om"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Aktivne zahteve za lokacijo"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Izbriši vsa obvestila."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Podatki o aplikaciji"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Zaslon se bo samodejno zasukal."</string>
@@ -202,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"SAMODEJNO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Obvestila so prikazana tukaj"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Do njih lahko kadar koli dostopate tako, da povlečete navzdol.\nZa prikaz sistemskih kontrolnikov znova povlecite navzdol."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Vrstico prikažete tako, da povlečete z roba zaslona"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Sistemsko vrstico prikažete tako, da povlečete z roba zaslona"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 163bc06..b501d69 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -201,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АУТОМАТСКА"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Обавештења се појављују овде"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Приступите им у било ком тренутку листањем надоле.\nПоново листајте надоле да би се приказале системске контроле."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Превуците по ивици екрана да би се приказала трака"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Превуците од ивице екрана да би се приказала системска трака"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index c5335f4..560a00e 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -164,8 +164,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi-ansluten"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Sökning efter GPS pågår"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Platsen har identifierats av GPS"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Det finns aktiva platsbegäranden"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Ta bort alla meddelanden."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Info om appen"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skärmen roteras automatiskt."</string>
@@ -202,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Meddelanden visas här"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Du kommer åt dem när som helst genom att dra nedåt.\nDra nedåt igen om du vill visa systemkontroller."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Dra från kanten av skärmen om du vill visa fältet"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Dra från kanten av skärmen om du vill visa systemfältet"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index a0fb0a8..e3338de 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -199,6 +199,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"KIOTOMATIKI"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Arifa zitaonekana hapa"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Zifikie wakati wowote kwa kutelezesha chini.\nTelezesha chini tena kupata vidhibiti vya mfumo."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Telezesha kidole kutoka ukingo wa skrini ili kuonyesha upau"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Telezesha kidole kutoka ukingo wa skrini ili kuonyesha upau wa mfumo"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 2552e5c..3127eb3 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -201,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"อัตโนมัติ"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"การแจ้งเตือนจะแสดงขึ้นที่นี่"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"เข้าถึงได้ทุกเมื่อด้วยการกวาดนิ้วลง\nกวาดนิ้วลงอีกครั้งสำหรับการควบคุมระบบ"</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"กวาดขอบของหน้าจอเพื่อแสดงแถบ"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"กวาดจากขอบของหน้าจอเพื่อแสดงแถบระบบ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index dfc6c7d..9d4d9de 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -201,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Dito lumalabas ang mga notification"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"I-access ang mga ito anumang oras sa pamamagitan ng pag-swipe pababa.\nMuling mag-swipe pababa para sa mga kontrol ng system."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Mag-swipe sa gilid ng screen upang ipakita ang bar"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Mag-swipe mula sa gilid ng screen upang ipakita ang system bar"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index f7b34de..b885344 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -164,8 +164,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Kablosuz bağlandı"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS aranıyor"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Konum GPS ile belirlendi"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Konum bilgisi istekleri etkin"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Tüm bildirimleri temizle"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Uygulama bilgileri"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran otomatik olarak dönecektir."</string>
@@ -202,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OTOMATİK"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Bildirimler burada görünür"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Aşağıya hızlıca kaydırarak bunlara istediğiniz zaman erişebilirsiniz.\nSistem denetimleri için tekrar hızlıca aşağı kaydırın."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Çubuğu görüntülemek için ekranın kenarından hızlıca kaydırın"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Sistem çubuğunu görüntülemek için ekranın kenarından hızlıca kaydırın"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 23e276b..1f3c131 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -164,8 +164,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi під’єднано"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Виконується пошук GPS-сигналу"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Місцезнаходження встановлено за допомогою GPS"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Запити про місцезнаходження активні"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Очистити всі сповіщення."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Інформація про програму"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екран обертатиметься автоматично."</string>
@@ -202,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТО"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Сповіщення з’являються тут"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Отримуйте до них доступ будь-коли, провівши пальцем униз.\nЗнову проведіть униз, щоб відкрити елементи керування системи."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Гортайте від краю екрана, щоб з’явилась панель"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Проведіть пальцем від краю екрана, щоб з’явилась навігаційна панель"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 31fc2c8..01ec999 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -164,8 +164,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Đã kết nối Wi-Fi"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Đang tìm kiếm GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Vị trí đặt bởi GPS"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Yêu cầu về thông tin vị trí hiện hoạt"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Xóa tất cả thông báo."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Thông tin về ứng dụng"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Màn hình sẽ xoay tự động."</string>
@@ -202,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"TỰ ĐỘNG"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Thông báo xuất hiện tại đây"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Truy cập vào chúng bất kỳ lúc nào bằng cách vuốt xuống.\nVuốt lại xuống để hiển thị các điều khiển hệ thống."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Vuốt cạnh màn hình để hiển thị thanh"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Vuốt từ cạnh màn hình để hiển thị thanh hệ thống"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index b8b56c9..867cb17 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -166,8 +166,7 @@
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"WLAN 已连接"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"正在搜索 GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"已通过 GPS 确定位置"</string>
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
+    <string name="accessibility_location_active" msgid="2427290146138169014">"应用发出了有效位置信息请求"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"应用信息"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"屏幕会自动旋转。"</string>
@@ -204,6 +203,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自动"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"通知会显示在这里"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"向下滑动可随时查看通知。\n再次向下滑动可使用系统控制功能。"</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"从屏幕边缘向里滑可显示系统栏"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"从屏幕边缘向里滑动即可显示系统栏"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index a0bb92a..1d5b2ac 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -203,6 +203,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"系統會在這裡顯示通知"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"向下滑動即可隨時存取通知。\n再次向下滑動即可使用系統控制項。"</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"從螢幕邊緣向內滑動即可顯示導覽列"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"從螢幕邊緣向內滑動即可顯示導覽列"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 53e7db0..662d3cb 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -201,6 +201,4 @@
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OKUZENZAKALELAYO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Izaziso zivela lapha"</string>
     <string name="status_bar_help_text" msgid="7874607155052076323">"Kufinyelele noma kunini ngokuswayiphela phansi.\nSwayiphela phansi futhi ngezilawuli zesistimu."</string>
-    <string name="hiding_navigation_confirmation_message" msgid="3227814171674734332">"Swayipha kunqenqema lwesikrini ukuze uveze ibha"</string>
-    <string name="hiding_navigation_confirmation_message_long" msgid="7854368870786524950">"Swayipha kusuka kunqenqema ukuze uveze ibha yesistimu"</string>
 </resources>
diff --git a/services/java/com/android/server/content/SyncManager.java b/services/java/com/android/server/content/SyncManager.java
index ee5b890..a6b69a2 100644
--- a/services/java/com/android/server/content/SyncManager.java
+++ b/services/java/com/android/server/content/SyncManager.java
@@ -2889,11 +2889,12 @@
             // determine if we need to set or cancel the alarm
             boolean shouldSet = false;
             boolean shouldCancel = false;
-            final boolean alarmIsActive = mAlarmScheduleTime != null;
+            final boolean alarmIsActive = (mAlarmScheduleTime != null) && (now < mAlarmScheduleTime);
             final boolean needAlarm = alarmTime != Long.MAX_VALUE;
             if (needAlarm) {
-                // Need the alarm if it's currently not set, or if our time is before the currently
-                // set time.
+                // Need the alarm if
+                //  - it's currently not set
+                //  - if the alarm is set in the past.
                 if (!alarmIsActive || alarmTime < mAlarmScheduleTime) {
                     shouldSet = true;
                 }
@@ -2910,7 +2911,7 @@
                             + " secs from now");
                 }
                 mAlarmScheduleTime = alarmTime;
-                mAlarmService.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmTime,
+                mAlarmService.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmTime,
                         mSyncAlarmIntent);
             } else if (shouldCancel) {
                 mAlarmScheduleTime = null;
diff --git a/services/java/com/android/server/content/SyncStorageEngine.java b/services/java/com/android/server/content/SyncStorageEngine.java
index 25529a6..e3693f8 100644
--- a/services/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/java/com/android/server/content/SyncStorageEngine.java
@@ -53,6 +53,7 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.HashMap;
@@ -71,7 +72,7 @@
 
     private static final String TAG = "SyncManager";
     private static final boolean DEBUG = true;
-    private static final boolean DEBUG_FILE = true;
+    private static final String TAG_FILE = "SyncManagerFile";
 
     private static final String XML_ATTR_NEXT_AUTHORITY_ID = "nextAuthorityId";
     private static final String XML_ATTR_LISTEN_FOR_TICKLES = "listen-for-tickles";
@@ -420,9 +421,12 @@
         File systemDir = new File(dataDir, "system");
         File syncDir = new File(systemDir, "sync");
         syncDir.mkdirs();
+
+        maybeDeleteLegacyPendingInfoLocked(syncDir);
+
         mAccountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
         mStatusFile = new AtomicFile(new File(syncDir, "status.bin"));
-        mPendingFile = new AtomicFile(new File(syncDir, "pending.bin"));
+        mPendingFile = new AtomicFile(new File(syncDir, "pending.xml"));
         mStatisticsFile = new AtomicFile(new File(syncDir, "stats.bin"));
 
         readAccountInfoLocked();
@@ -676,7 +680,8 @@
                         continue;
                     }
                     for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
-                        if (providerName != null && !providerName.equals(authorityInfo.authority)) {
+                        if (providerName != null
+                                && !providerName.equals(authorityInfo.authority)) {
                             continue;
                         }
                         if (authorityInfo.backoffTime != nextSyncTime
@@ -774,10 +779,12 @@
         }
         synchronized (mAuthorities) {
             if (toUpdate.period <= 0 && add) {
-                Log.e(TAG, "period < 0, should never happen in updateOrRemovePeriodicSync: add-" + add);
+                Log.e(TAG, "period < 0, should never happen in updateOrRemovePeriodicSync: add-"
+                        + add);
             }
             if (toUpdate.extras == null) {
-                Log.e(TAG, "period < 0, should never happen in updateOrRemovePeriodicSync: add-" + add);
+                Log.e(TAG, "null extras, should never happen in updateOrRemovePeriodicSync: add-"
+                        + add);
             }
             try {
                 AuthorityInfo authority =
@@ -806,7 +813,7 @@
                     if (!alreadyPresent) {
                         authority.periodicSyncs.add(new PeriodicSync(toUpdate));
                         SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
-                        status.setPeriodicSyncTime(authority.periodicSyncs.size() - 1, 0);
+                        status.setPeriodicSyncTime(authority.periodicSyncs.size() - 1, 0L);
                     }
                 } else {
                     // Remove any periodic syncs that match the authority and extras.
@@ -824,7 +831,8 @@
                             if (status != null) {
                                 status.removePeriodicSyncTime(i);
                             } else {
-                                Log.e(TAG, "Tried removing sync status on remove periodic sync but did not find it.");
+                                Log.e(TAG, "Tried removing sync status on remove periodic sync but"
+                                        + "did not find it.");
                             }
                         } else {
                             i++;
@@ -942,7 +950,7 @@
             op = new PendingOperation(op);
             op.authorityId = authority.ident;
             mPendingOperations.add(op);
-            writePendingOperationsLocked();
+            appendPendingOperationLocked(op);
 
             SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
             status.pending = true;
@@ -1660,7 +1668,9 @@
         FileInputStream fis = null;
         try {
             fis = mAccountInfoFile.openRead();
-            if (DEBUG_FILE) Log.v(TAG, "Reading " + mAccountInfoFile.getBaseFile());
+            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                Log.v(TAG, "Reading " + mAccountInfoFile.getBaseFile());
+            }
             XmlPullParser parser = Xml.newPullParser();
             parser.setInput(fis, null);
             int eventType = parser.getEventType();
@@ -1745,6 +1755,20 @@
     }
 
     /**
+     * Ensure the old pending.bin is deleted, as it has been changed to pending.xml.
+     * pending.xml was used starting in KLP.
+     * @param syncDir directory where the sync files are located.
+     */
+    private void maybeDeleteLegacyPendingInfoLocked(File syncDir) {
+        File file = new File(syncDir, "pending.bin");
+        if (!file.exists()) {
+            return;
+        } else {
+            file.delete();
+        }
+    }
+
+    /**
      * some authority names have changed. copy over their settings and delete the old ones
      * @return true if a change was made
      */
@@ -1832,18 +1856,21 @@
                 syncable = "unknown";
             }
             authority = mAuthorities.get(id);
-            if (DEBUG_FILE) Log.v(TAG, "Adding authority: account="
-                    + accountName + " auth=" + authorityName
-                    + " user=" + userId
-                    + " enabled=" + enabled
-                    + " syncable=" + syncable);
+            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                Log.v(TAG, "Adding authority: account="
+                        + accountName + " auth=" + authorityName
+                        + " user=" + userId
+                        + " enabled=" + enabled
+                        + " syncable=" + syncable);
+            }
             if (authority == null) {
-                if (DEBUG_FILE) {
+                if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
                     Log.v(TAG, "Creating entry");
                 }
                 if (accountName != null && accountType != null) {
                     authority = getOrCreateAuthorityLocked(
-                            new Account(accountName, accountType), userId, authorityName, id, false);
+                            new Account(accountName, accountType), userId, authorityName, id,
+                                false);
                 } else {
                     authority = getOrCreateAuthorityLocked(
                             new ComponentName(packageName, className), userId, id, false);
@@ -1943,7 +1970,9 @@
      * Write all account information to the account file.
      */
     private void writeAccountInfoLocked() {
-        if (DEBUG_FILE) Log.v(TAG, "Writing new " + mAccountInfoFile.getBaseFile());
+        if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+            Log.v(TAG, "Writing new " + mAccountInfoFile.getBaseFile());
+        }
         FileOutputStream fos = null;
 
         try {
@@ -2041,7 +2070,9 @@
             final boolean hasType = db.getVersion() >= 11;
 
             // Copy in all of the status information, as well as accounts.
-            if (DEBUG_FILE) Log.v(TAG, "Reading legacy sync accounts db");
+            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                Log.v(TAG, "Reading legacy sync accounts db");
+            }
             SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
             qb.setTables("stats, status");
             HashMap<String,String> map = new HashMap<String,String>();
@@ -2151,7 +2182,9 @@
      * Read all sync status back in to the initial engine state.
      */
     private void readStatusLocked() {
-        if (DEBUG_FILE) Log.v(TAG, "Reading " + mStatusFile.getBaseFile());
+        if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+            Log.v(TAG, "Reading " + mStatusFile.getBaseFile());
+        }
         try {
             byte[] data = mStatusFile.readFully();
             Parcel in = Parcel.obtain();
@@ -2163,8 +2196,10 @@
                     SyncStatusInfo status = new SyncStatusInfo(in);
                     if (mAuthorities.indexOfKey(status.authorityId) >= 0) {
                         status.pending = false;
-                        if (DEBUG_FILE) Log.v(TAG, "Adding status for id "
-                                + status.authorityId);
+                        if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                            Log.v(TAG, "Adding status for id "
+                                    + status.authorityId);
+                        }
                         mSyncStatus.put(status.authorityId, status);
                     }
                 } else {
@@ -2182,7 +2217,9 @@
      * Write all sync status to the sync status file.
      */
     private void writeStatusLocked() {
-        if (DEBUG_FILE) Log.v(TAG, "Writing new " + mStatusFile.getBaseFile());
+        if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+            Log.v(TAG, "Writing new " + mStatusFile.getBaseFile());
+        }
 
         // The file is being written, so we don't need to have a scheduled
         // write until the next change.
@@ -2211,103 +2248,97 @@
         }
     }
 
-    public static final int PENDING_OPERATION_VERSION = 4;
+    public static final int PENDING_OPERATION_VERSION = 3;
 
-    /**
-     * Read all pending operations back in to the initial engine state.
-     */
+    /** Read all pending operations back in to the initial engine state. */
     private void readPendingOperationsLocked() {
-        if (DEBUG_FILE) Log.v(TAG, "Reading " + mPendingFile.getBaseFile());
-        try {
-            readPendingAsXml();
-        } catch (XmlPullParserException e) {
-            Log.d(TAG, "Error parsing pending as xml, trying as parcel.");
-            try {
-                readPendingAsParcelled();
-            } catch (java.io.IOException e1) {
-                Log.i(TAG, "No initial pending operations");
+        FileInputStream fis = null;
+        if (!mPendingFile.getBaseFile().exists()) {
+            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                Log.v(TAG_FILE, "No pending operation file.");
+                return;
             }
         }
-    }
-
-    private void readPendingAsXml() throws XmlPullParserException {
-        FileInputStream fis = null;
         try {
             fis = mPendingFile.openRead();
-            XmlPullParser parser = Xml.newPullParser();
+            XmlPullParser parser;
+            parser = Xml.newPullParser();
             parser.setInput(fis, null);
+
             int eventType = parser.getEventType();
             while (eventType != XmlPullParser.START_TAG &&
                     eventType != XmlPullParser.END_DOCUMENT) {
                 eventType = parser.next();
             }
-            if (eventType == XmlPullParser.END_DOCUMENT) return;
+            if (eventType == XmlPullParser.END_DOCUMENT) return; // Nothing to read.
 
             String tagName = parser.getName();
-            if ("pending".equals(tagName)) {
-                int version = -1;
-                String versionString = parser.getAttributeValue(null, "version");
-                if (versionString == null ||
-                        Integer.parseInt(versionString) != PENDING_OPERATION_VERSION) {
-                    Log.w(TAG, "Unknown pending operation version "
-                            + version + "; trying to read as binary.");
-                    throw new XmlPullParserException("Unknown version.");
-                }
-                eventType = parser.next();
+            do {
                 PendingOperation pop = null;
-                do {
-                    if (eventType == XmlPullParser.START_TAG) {
-                        try {
-                            tagName = parser.getName();
-                            if (parser.getDepth() == 2 && "op".equals(tagName)) {
-                                int authorityId = Integer.valueOf(parser.getAttributeValue(
-                                        null, XML_ATTR_AUTHORITYID));
-                                boolean expedited = Boolean.valueOf(parser.getAttributeValue(
-                                        null, XML_ATTR_EXPEDITED));
-                                int syncSource = Integer.valueOf(parser.getAttributeValue(
-                                        null, XML_ATTR_SOURCE));
-                                int reason = Integer.valueOf(parser.getAttributeValue(
-                                        null, XML_ATTR_REASON));
-                                AuthorityInfo authority = mAuthorities.get(authorityId);
-                                if (DEBUG_FILE) {
-                                    Log.v(TAG, authorityId + " " + expedited + " " + syncSource + " " + reason);
-                                }
-                                if (authority != null) {
-                                    pop = new PendingOperation(
-                                            authority.account, authority.userId, reason, syncSource,
-                                            authority.authority, new Bundle(), expedited);
-                                    pop.authorityId = authorityId;
-                                    pop.flatExtras = null; // No longer used.
-                                    mPendingOperations.add(pop);
-                                    if (DEBUG_FILE) Log.v(TAG, "Adding pending op: account=" + pop.account
-                                            + " auth=" + pop.authority
+                if (eventType == XmlPullParser.START_TAG) {
+                    try {
+                        tagName = parser.getName();
+                        if (parser.getDepth() == 1 && "op".equals(tagName)) {
+                            // Verify version.
+                            String versionString =
+                                    parser.getAttributeValue(null, XML_ATTR_VERSION);
+                            if (versionString == null ||
+                                    Integer.parseInt(versionString) != PENDING_OPERATION_VERSION) {
+                                Log.w(TAG, "Unknown pending operation version " + versionString);
+                                throw new java.io.IOException("Unknown version.");
+                            }
+                            int authorityId = Integer.valueOf(parser.getAttributeValue(
+                                    null, XML_ATTR_AUTHORITYID));
+                            boolean expedited = Boolean.valueOf(parser.getAttributeValue(
+                                    null, XML_ATTR_EXPEDITED));
+                            int syncSource = Integer.valueOf(parser.getAttributeValue(
+                                    null, XML_ATTR_SOURCE));
+                            int reason = Integer.valueOf(parser.getAttributeValue(
+                                    null, XML_ATTR_REASON));
+                            AuthorityInfo authority = mAuthorities.get(authorityId);
+                            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                                Log.v(TAG_FILE, authorityId + " " + expedited + " " + syncSource + " "
+                                        + reason);
+                            }
+                            if (authority != null) {
+                                pop = new PendingOperation(
+                                        authority.account, authority.userId, reason,
+                                        syncSource, authority.authority, new Bundle(),
+                                        expedited);
+                                pop.flatExtras = null; // No longer used.
+                                mPendingOperations.add(pop);
+                                if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                                    Log.v(TAG_FILE, "Adding pending op: "
+                                            + pop.authority
                                             + " src=" + pop.syncSource
                                             + " reason=" + pop.reason
                                             + " expedited=" + pop.expedited);
-                                } else {
-                                    // Skip non-existent authority;
-                                    pop = null;
-                                    if (DEBUG_FILE) {
-                                        Log.v(TAG, "No authority found for " + authorityId
-                                                + ", skipping");
-                                    }
                                 }
-                            } else if (parser.getDepth() == 3 &&
-                                        pop != null &&
-                                        "extra".equals(tagName)) {
-                                    parseExtra(parser, pop.extras);
+                            } else {
+                                // Skip non-existent authority.
+                                pop = null;
+                                if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                                    Log.v(TAG_FILE, "No authority found for " + authorityId
+                                            + ", skipping");
+                                }
                             }
-                        } catch (NumberFormatException e) {
-                            Log.d(TAG, "Invalid data in xml file.", e);
+                        } else if (parser.getDepth() == 2 &&
+                                pop != null &&
+                                "extra".equals(tagName)) {
+                            parseExtra(parser, pop.extras);
                         }
+                    } catch (NumberFormatException e) {
+                        Log.d(TAG, "Invalid data in xml file.", e);
                     }
-                    eventType = parser.next();
-                } while(eventType != XmlPullParser.END_DOCUMENT);
-            }
+                }
+                eventType = parser.next();
+            } while(eventType != XmlPullParser.END_DOCUMENT);
         } catch (java.io.IOException e) {
-            if (fis == null) Log.i(TAG, "No initial pending operations.");
-            else Log.w(TAG, "Error reading pending data.", e);
-            return;
+            Log.w(TAG_FILE, "Error reading pending data.", e);
+        } catch (XmlPullParserException e) {
+            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                Log.w(TAG_FILE, "Error parsing pending ops xml.", e);
+            }
         } finally {
             if (fis != null) {
                 try {
@@ -2316,57 +2347,96 @@
             }
         }
     }
+
+    private static final String XML_ATTR_AUTHORITYID = "authority_id";
+    private static final String XML_ATTR_SOURCE = "source";
+    private static final String XML_ATTR_EXPEDITED = "expedited";
+    private static final String XML_ATTR_REASON = "reason";
+    private static final String XML_ATTR_VERSION = "version";
+
     /**
-     * Old format of reading pending.bin as a parcelled file. Replaced in lieu of JSON because
-     * persisting parcels is unsafe.
-     * @throws java.io.IOException
+     * Write all currently pending ops to the pending ops file.
      */
-    private void readPendingAsParcelled() throws java.io.IOException {
-        byte[] data = mPendingFile.readFully();
-        Parcel in = Parcel.obtain();
-        in.unmarshall(data, 0, data.length);
-        in.setDataPosition(0);
-        final int SIZE = in.dataSize();
-        while (in.dataPosition() < SIZE) {
-            int version = in.readInt();
-            if (version != 3 && version != 1) {
-                Log.w(TAG, "Unknown pending operation version "
-                        + version + "; dropping all ops");
-                break;
-            }
-            int authorityId = in.readInt();
-            int syncSource = in.readInt();
-            byte[] flatExtras = in.createByteArray();
-            boolean expedited;
-            if (version == PENDING_OPERATION_VERSION) {
-                expedited = in.readInt() != 0;
-            } else {
-                expedited = false;
-            }
-            int reason = in.readInt();
-            AuthorityInfo authority = mAuthorities.get(authorityId);
-            if (authority != null) {
-                Bundle extras;
-                if (flatExtras != null) {
-                    extras = unflattenBundle(flatExtras);
-                } else {
-                    // if we are unable to parse the extras for whatever reason convert this
-                    // to a regular sync by creating an empty extras
-                    extras = new Bundle();
+    private void writePendingOperationsLocked() {
+        final int N = mPendingOperations.size();
+        FileOutputStream fos = null;
+        try {
+            if (N == 0) {
+                if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                    Log.v(TAG_FILE, "Truncating " + mPendingFile.getBaseFile());
                 }
-                PendingOperation op = new PendingOperation(
-                        authority.account, authority.userId, reason, syncSource,
-                        authority.authority, extras, expedited);
-                op.authorityId = authorityId;
-                op.flatExtras = flatExtras;
-                if (DEBUG_FILE) Log.v(TAG, "Adding pending op: account=" + op.account
-                        + " auth=" + op.authority
-                        + " src=" + op.syncSource
-                        + " reason=" + op.reason
-                        + " expedited=" + op.expedited
-                        + " extras=" + op.extras);
-                mPendingOperations.add(op);
+                mPendingFile.truncate();
+                return;
             }
+            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                Log.v(TAG_FILE, "Writing new " + mPendingFile.getBaseFile());
+            }
+            fos = mPendingFile.startWrite();
+            XmlSerializer out = new FastXmlSerializer();
+            out.setOutput(fos, "utf-8");
+
+            for (int i = 0; i < N; i++) {
+                PendingOperation pop = mPendingOperations.get(i);
+                writePendingOperationLocked(pop, out);
+            }
+            out.endDocument();
+            mPendingFile.finishWrite(fos);
+        } catch (java.io.IOException e1) {
+            Log.w(TAG, "Error writing pending operations", e1);
+            if (fos != null) {
+                mPendingFile.failWrite(fos);
+            }
+        }
+    }
+
+    /** Write all currently pending ops to the pending ops file. */
+     private void writePendingOperationLocked(PendingOperation pop, XmlSerializer out)
+             throws IOException {
+         // Pending operation.
+         out.startTag(null, "op");
+
+         out.attribute(null, XML_ATTR_VERSION, Integer.toString(PENDING_OPERATION_VERSION));
+         out.attribute(null, XML_ATTR_AUTHORITYID, Integer.toString(pop.authorityId));
+         out.attribute(null, XML_ATTR_SOURCE, Integer.toString(pop.syncSource));
+         out.attribute(null, XML_ATTR_EXPEDITED, Boolean.toString(pop.expedited));
+         out.attribute(null, XML_ATTR_REASON, Integer.toString(pop.reason));
+         extrasToXml(out, pop.extras);
+
+         out.endTag(null, "op");
+     }
+
+    /**
+     * Append the given operation to the pending ops file; if unable to,
+     * write all pending ops.
+     */
+    private void appendPendingOperationLocked(PendingOperation op) {
+        if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+            Log.v(TAG, "Appending to " + mPendingFile.getBaseFile());
+        }
+        FileOutputStream fos = null;
+        try {
+            fos = mPendingFile.openAppend();
+        } catch (java.io.IOException e) {
+            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                Log.v(TAG, "Failed append; writing full file");
+            }
+            writePendingOperationsLocked();
+            return;
+        }
+
+        try {
+            XmlSerializer out = new FastXmlSerializer();
+            out.setOutput(fos, "utf-8");
+            writePendingOperationLocked(op, out);
+            out.endDocument();
+            mPendingFile.finishWrite(fos);
+        } catch (java.io.IOException e1) {
+            Log.w(TAG, "Error writing appending operation", e1);
+            mPendingFile.failWrite(fos);
+        } finally {
+            try {
+                fos.close();
+            } catch (IOException e) {}
         }
     }
 
@@ -2399,54 +2469,6 @@
         return bundle;
     }
 
-    private static final String XML_ATTR_AUTHORITYID = "authority_id";
-    private static final String XML_ATTR_SOURCE = "source";
-    private static final String XML_ATTR_EXPEDITED = "expedited";
-    private static final String XML_ATTR_REASON = "reason";
-    /**
-     * Write all currently pending ops to the pending ops file. TODO: Change this from xml
-     * so that we can append to this file as before.
-     */
-    private void writePendingOperationsLocked() {
-        final int N = mPendingOperations.size();
-        FileOutputStream fos = null;
-        try {
-            if (N == 0) {
-                if (DEBUG_FILE) Log.v(TAG, "Truncating " + mPendingFile.getBaseFile());
-                mPendingFile.truncate();
-                return;
-            }
-            if (DEBUG_FILE) Log.v(TAG, "Writing new " + mPendingFile.getBaseFile());
-            fos = mPendingFile.startWrite();
-            XmlSerializer out = new FastXmlSerializer();
-            out.setOutput(fos, "utf-8");
-            out.startDocument(null, true);
-            out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
-
-            out.startTag(null, "pending");
-            out.attribute(null, "version", Integer.toString(PENDING_OPERATION_VERSION));
-
-            for (int i = 0; i < N; i++) {
-                PendingOperation pop = mPendingOperations.get(i);
-                out.startTag(null, "op");
-                out.attribute(null, XML_ATTR_AUTHORITYID, Integer.toString(pop.authorityId));
-                out.attribute(null, XML_ATTR_SOURCE, Integer.toString(pop.syncSource));
-                out.attribute(null, XML_ATTR_EXPEDITED, Boolean.toString(pop.expedited));
-                out.attribute(null, XML_ATTR_REASON, Integer.toString(pop.reason));
-                extrasToXml(out, pop.extras);
-                out.endTag(null, "op");
-             }
-             out.endTag(null, "pending");
-             out.endDocument();
-             mPendingFile.finishWrite(fos);
-        } catch (java.io.IOException e1) {
-            Log.w(TAG, "Error writing pending operations", e1);
-            if (fos != null) {
-                mPendingFile.failWrite(fos);
-            }
-        }
-    }
-
     private void extrasToXml(XmlSerializer out, Bundle extras) throws java.io.IOException {
         for (String key : extras.keySet()) {
             out.startTag(null, "extra");
@@ -2479,35 +2501,6 @@
         }
     }
 
-//    /**
-//     * Update the pending ops file, if e
-//     */
-//    private void appendPendingOperationLocked(PendingOperation op) {
-//        if (DEBUG_FILE) Log.v(TAG, "Appending to " + mPendingFile.getBaseFile());
-//        FileOutputStream fos = null;
-//        try {
-//            fos = mPendingFile.openAppend();
-//        } catch (java.io.IOException e) {
-//            if (DEBUG_FILE) Log.v(TAG, "Failed append; writing full file");
-//            writePendingOperationsLocked();
-//            return;
-//        }
-//
-//        try {
-//            Parcel out = Parcel.obtain();
-//            writePendingOperationLocked(op, out);
-//            fos.write(out.marshall());
-//            out.recycle();
-//        } catch (java.io.IOException e1) {
-//            Log.w(TAG, "Error writing pending operations", e1);
-//        } finally {
-//            try {
-//                fos.close();
-//            } catch (java.io.IOException e2) {
-//            }
-//        }
-//    }
-
     private void requestSync(Account account, int userId, int reason, String authority,
             Bundle extras) {
         // If this is happening in the system process, then call the syncrequest listener
@@ -2568,7 +2561,9 @@
      * Write all sync statistics to the sync status file.
      */
     private void writeStatisticsLocked() {
-        if (DEBUG_FILE) Log.v(TAG, "Writing new " + mStatisticsFile.getBaseFile());
+        if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+            Log.v(TAG, "Writing new " + mStatisticsFile.getBaseFile());
+        }
 
         // The file is being written, so we don't need to have a scheduled
         // write until the next change.
@@ -2611,7 +2606,7 @@
         sb.append("Pending Ops: ").append(mPendingOperations.size()).append(" operation(s)\n");
         for (PendingOperation pop : mPendingOperations) {
             sb.append("(" + pop.account)
-                .append(", " + pop.userId)
+                .append(", u" + pop.userId)
                 .append(", " + pop.authority)
                 .append(", " + pop.extras)
                 .append(")\n");
diff --git a/services/java/com/android/server/wifi/WifiService.java b/services/java/com/android/server/wifi/WifiService.java
index db030f1..c215f40 100644
--- a/services/java/com/android/server/wifi/WifiService.java
+++ b/services/java/com/android/server/wifi/WifiService.java
@@ -345,6 +345,12 @@
         return mBatchedScanSupported;
     }
 
+    public void pollBatchedScan() {
+        enforceChangePermission();
+        if (mBatchedScanSupported == false) return;
+        mWifiStateMachine.requestBatchedScanPoll();
+    }
+
     /**
      * see {@link android.net.wifi.WifiManager#requestBatchedScan()}
      */
diff --git a/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
index dff6661..e44652f 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
@@ -67,7 +67,7 @@
 
     /**
      * Test that we handle the case of a history row being old enough to purge before the
-     * correcponding sync is finished. This can happen if the clock changes while we are syncing.
+     * corresponding sync is finished. This can happen if the clock changes while we are syncing.
      *
      */
     // TODO: this test causes AidlTest to fail. Omit for now
@@ -104,6 +104,17 @@
         engine.clearAndReadState();
 
         assert(engine.getPendingOperationCount() == 1);
+        List<SyncStorageEngine.PendingOperation> pops = engine.getPendingOperations();
+        SyncStorageEngine.PendingOperation popRetrieved = pops.get(0);
+        assertEquals(pop.account, popRetrieved.account);
+        assertEquals(pop.reason, popRetrieved.reason);
+        assertEquals(pop.userId, popRetrieved.userId);
+        assertEquals(pop.syncSource, popRetrieved.syncSource);
+        assertEquals(pop.authority, popRetrieved.authority);
+        assertEquals(pop.expedited, popRetrieved.expedited);
+        assertEquals(pop.serviceName, popRetrieved.serviceName);
+        assert(android.content.PeriodicSync.syncExtrasEquals(pop.extras, popRetrieved.extras));
+
     }
 
     /**
diff --git a/wifi/java/android/net/wifi/BatchedScanSettings.java b/wifi/java/android/net/wifi/BatchedScanSettings.java
index 82945d6..44a2ab4 100644
--- a/wifi/java/android/net/wifi/BatchedScanSettings.java
+++ b/wifi/java/android/net/wifi/BatchedScanSettings.java
@@ -51,6 +51,7 @@
     public final static int MAX_AP_FOR_DISTANCE = MAX_AP_PER_SCAN;
     public final static int DEFAULT_AP_FOR_DISTANCE = 0;
 
+    public final static int MAX_WIFI_CHANNEL = 196;
 
     /** The expected number of scans per batch.  Note that the firmware may drop scans
      *  leading to fewer scans during the normal batch scan duration.  This value need not
@@ -113,7 +114,7 @@
         for (String channel : channelSet) {
             try {
                 int i = Integer.parseInt(channel);
-                if (i > 0 && i < 197) continue;
+                if (i > 0 && i <= MAX_WIFI_CHANNEL) continue;
             } catch (NumberFormatException e) {}
             if (channel.equals("A") || channel.equals("B")) continue;
             return false;
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index c8cf323..4f68ca0 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -124,5 +124,7 @@
     List<BatchedScanResult> getBatchedScanResults(String callingPackage);
 
     boolean isBatchedScanSupported();
+
+    void pollBatchedScan();
 }
 
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 01ca378..a15b664 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -840,6 +840,32 @@
     }
 
     /**
+     * Force a re-reading of batched scan results.  This will attempt
+     * to read more information from the chip, but will do so at the expense
+     * of previous data.  Rate limited to the current scan frequency.
+     *
+     * pollBatchedScan will always wait 1 period from the start of the batch
+     * before trying to read from the chip, so if your #scans/batch == 1 this will
+     * have no effect.
+     *
+     * If you had already waited 1 period before calling, this should have
+     * immediate (though async) effect.
+     *
+     * If you call before that 1 period is up this will set up a timer and fetch
+     * results when the 1 period is up.
+     *
+     * Servicing a pollBatchedScan request (immediate or after timed delay) starts a
+     * new batch, so if you were doing 10 scans/batch and called in the 4th scan, you
+     * would get data in the 4th and then again 10 scans later.
+     * @hide
+     */
+    public void pollBatchedScan() {
+        try {
+            mService.pollBatchedScan();
+        } catch (RemoteException e) { }
+    }
+
+    /**
      * Return dynamic information about the current Wi-Fi connection, if any is active.
      * @return the Wi-Fi information, contained in {@link WifiInfo}.
      */
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 0359076..c3ed03c 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -82,8 +82,13 @@
 
     public WifiNative(String interfaceName) {
         mInterfaceName = interfaceName;
-        mInterfacePrefix = "IFNAME=" + interfaceName + " ";
         mTAG = "WifiNative-" + interfaceName;
+        if (!interfaceName.equals("p2p0")) {
+            mInterfacePrefix = "IFNAME=" + interfaceName + " ";
+        } else {
+            // commands for p2p0 interface don't need prefix
+            mInterfacePrefix = "";
+        }
     }
 
     public boolean connectToSupplicant() {
@@ -221,8 +226,9 @@
 
     /**
      * Format of command
-     * DRIVER WLS_BATCHING SET SCAN_FRQ=x BESTN=y CHANNEL=<z, w, t> RTT=s
+     * DRIVER WLS_BATCHING SET SCAN_FRQ=x MSCAN=r BESTN=y CHANNEL=<z, w, t> RTT=s
      * where x is an ascii representation of an integer number of seconds between scans
+     *       r is an ascii representation of an integer number of scans per batch
      *       y is an ascii representation of an integer number of the max AP to remember per scan
      *       z, w, t represent a 1..n size list of channel numbers and/or 'A', 'B' values
      *           indicating entire ranges of channels
@@ -235,8 +241,9 @@
     public String setBatchedScanSettings(BatchedScanSettings settings) {
         if (settings == null) return doStringCommand("DRIVER WLS_BATCHING STOP");
         String cmd = "DRIVER WLS_BATCHING SET SCAN_FRQ=" + settings.scanIntervalSec;
+        cmd += " MSCAN=" + settings.maxScansPerBatch;
         if (settings.maxApPerScan != BatchedScanSettings.UNSPECIFIED) {
-            cmd += " BESTN " + settings.maxApPerScan;
+            cmd += " BESTN=" + settings.maxApPerScan;
         }
         if (settings.channelSet != null && !settings.channelSet.isEmpty()) {
             cmd += " CHANNEL=<";
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 764c00a..8b7b8ae 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -127,6 +127,8 @@
     private final List<BatchedScanResult> mBatchedScanResults =
             new ArrayList<BatchedScanResult>();
     private int mBatchedScanOwnerUid = UNKNOWN_SCAN_SOURCE;
+    private int mExpectedBatchedScans = 0;
+    private long mBatchedScanMinPollTime = 0;
 
     /* Chipset supports background scan */
     private final boolean mBackgroundScanSupported;
@@ -366,8 +368,9 @@
      * arg1 = responsible UID
      * obj = the new settings
      */
-    public static final int CMD_SET_BATCH_SCAN            = BASE + 135;
+    public static final int CMD_SET_BATCHED_SCAN          = BASE + 135;
     public static final int CMD_START_NEXT_BATCHED_SCAN   = BASE + 136;
+    public static final int CMD_POLL_BATCHED_SCAN         = BASE + 137;
 
     public static final int CONNECT_MODE                   = 1;
     public static final int SCAN_ONLY_MODE                 = 2;
@@ -766,7 +769,7 @@
      * start or stop batched scanning using the given settings
      */
     public void setBatchedScanSettings(BatchedScanSettings settings, int callingUid) {
-        sendMessage(CMD_SET_BATCH_SCAN, callingUid, 0, settings);
+        sendMessage(CMD_SET_BATCHED_SCAN, callingUid, 0, settings);
     }
 
     public List<BatchedScanResult> syncGetBatchedScanResultsList() {
@@ -780,6 +783,10 @@
         }
     }
 
+    public void requestBatchedScanPoll() {
+        sendMessage(CMD_POLL_BATCHED_SCAN);
+    }
+
     private void startBatchedScan() {
         // first grab any existing data
         retrieveBatchedScanData();
@@ -789,8 +796,8 @@
         String scansExpected = mWifiNative.setBatchedScanSettings(mBatchedScanSettings);
 
         try {
-            int expected = Integer.parseInt(scansExpected);
-            setNextBatchedAlarm(expected);
+            mExpectedBatchedScans = Integer.parseInt(scansExpected);
+            setNextBatchedAlarm(mExpectedBatchedScans);
         } catch (NumberFormatException e) {
             loge("Exception parsing WifiNative.setBatchedScanSettings response " + e);
         }
@@ -803,9 +810,27 @@
 
     private void startNextBatchedScan() {
         // first grab any existing data
-        int nextCount = retrieveBatchedScanData();
+        retrieveBatchedScanData();
 
-        setNextBatchedAlarm(nextCount);
+        setNextBatchedAlarm(mExpectedBatchedScans);
+    }
+
+    private void handleBatchedScanPollRequest() {
+        // if there is no appropriate PollTime that's because we either aren't
+        // batching or we've already set a time for a poll request
+        if (mBatchedScanMinPollTime == 0) return;
+        if (mBatchedScanSettings == null) return;
+
+        long now = System.currentTimeMillis();
+
+        if (now > mBatchedScanMinPollTime) {
+            // do the poll and reset our timers
+            startNextBatchedScan();
+        } else {
+            mAlarmManager.set(AlarmManager.RTC_WAKEUP, mBatchedScanMinPollTime,
+                    mBatchedScanIntervalIntent);
+            mBatchedScanMinPollTime = 0;
+        }
     }
 
     // return true if new/different
@@ -832,6 +857,9 @@
 
         if (mBatchedScanSettings == null || scansExpected < 1) return;
 
+        mBatchedScanMinPollTime = System.currentTimeMillis() +
+                mBatchedScanSettings.scanIntervalSec * 1000;
+
         if (mBatchedScanSettings.maxScansPerBatch < scansExpected) {
             scansExpected = mBatchedScanSettings.maxScansPerBatch;
         }
@@ -876,22 +904,18 @@
      *   etc
      *   "----"
      */
-    private int retrieveBatchedScanData() {
+    private void retrieveBatchedScanData() {
         String rawData = mWifiNative.getBatchedScanResults();
+        mBatchedScanMinPollTime = 0;
         if (rawData == null) {
             loge("Unexpected null BatchedScanResults");
-            return 0;
+            return;
         }
 
-        int nextCount = 0;
         int scanCount = 0;
-        final String END_OF_SCAN = "====";
-        final String END_OF_BATCH = "%%%%";
         final String END_OF_BATCHES = "----";
         final String SCANCOUNT = "scancount=";
-        final String NEXTCOUNT = "nextcount=";
         final String TRUNCATED = "trunc";
-        final String APCOUNT = "apcount=";
         final String AGE = "age=";
         final String DIST = "dist=";
         final String DISTSD = "distsd=";
@@ -905,16 +929,7 @@
         }
         if (scanCount == 0) {
             loge("scanCount not found");
-            return 0;
-        }
-        if (splitData[n].startsWith(NEXTCOUNT)) {
-            try {
-                nextCount = Integer.parseInt(splitData[n++].substring(NEXTCOUNT.length()));
-            } catch (NumberFormatException e) {}
-        }
-        if (nextCount == 0) {
-            loge("nextCount not found");
-            return 0;
+            return;
         }
 
         final Intent intent = new Intent(WifiManager.BATCHED_SCAN_RESULTS_AVAILABLE_ACTION);
@@ -942,9 +957,9 @@
                         if (mBatchedScanResults.size() > 0) {
                             mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
                         }
-                        return nextCount;
+                        return;
                     }
-                    if ((splitData[n].equals(END_OF_SCAN)) || splitData[n].equals(END_OF_BATCH)) {
+                    if ((splitData[n].equals(END_STR)) || splitData[n].equals(DELIMITER_STR)) {
                         if (bssid != null) {
                             batchedScanResult.scanResults.add(new ScanResult(
                                     wifiSsid, bssid, "", level, freq, tsf, dist, distSd));
@@ -955,7 +970,7 @@
                             tsf = 0;
                             dist = distSd = ScanResult.UNSPECIFIED;
                         }
-                        if (splitData[n].equals(END_OF_BATCH)) {
+                        if (splitData[n].equals(END_STR)) {
                             if (batchedScanResult.scanResults.size() != 0) {
                                 mBatchedScanResults.add(batchedScanResult);
                                 batchedScanResult = new BatchedScanResult();
@@ -1010,7 +1025,7 @@
                 rawData = mWifiNative.getBatchedScanResults();
                 if (rawData == null) {
                     loge("Unexpected null BatchedScanResults");
-                    return nextCount;
+                    return;
                 }
                 splitData = rawData.split("\n");
                 if (splitData.length == 0 || splitData[0].equals("ok")) {
@@ -1018,7 +1033,7 @@
                     if (mBatchedScanResults.size() > 0) {
                         mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
                     }
-                    return nextCount;
+                    return;
                 }
                 n = 0;
             }
@@ -2266,9 +2281,11 @@
                         sendMessageAtFrontOfQueue(CMD_SET_COUNTRY_CODE, countryCode);
                     }
                     break;
-                case CMD_SET_BATCH_SCAN:
+                case CMD_SET_BATCHED_SCAN:
                     recordBatchedScanSettings((BatchedScanSettings)message.obj);
                     break;
+                case CMD_POLL_BATCHED_SCAN:
+                    handleBatchedScanPollRequest();
                 case CMD_START_NEXT_BATCHED_SCAN:
                     startNextBatchedScan();
                     break;
@@ -2808,7 +2825,7 @@
                     noteScanStart(message.arg1, (WorkSource) message.obj);
                     startScanNative(WifiNative.SCAN_WITH_CONNECTION_SETUP);
                     break;
-                case CMD_SET_BATCH_SCAN:
+                case CMD_SET_BATCHED_SCAN:
                     recordBatchedScanSettings((BatchedScanSettings)message.obj);
                     startBatchedScan();
                     break;