Merge "Import translations. DO NOT MERGE" into klp-dev
diff --git a/api/current.txt b/api/current.txt
index ab48c8d..7fc59d8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -10862,6 +10862,7 @@
 
   public abstract class CameraMetadata {
     method public abstract T get(android.hardware.camera2.CameraMetadata.Key<T>);
+    method public java.util.List<android.hardware.camera2.CameraMetadata.Key<?>> getKeys();
     field public static final int COLOR_CORRECTION_MODE_FAST = 1; // 0x1
     field public static final int COLOR_CORRECTION_MODE_HIGH_QUALITY = 2; // 0x2
     field public static final int COLOR_CORRECTION_MODE_TRANSFORM_MATRIX = 0; // 0x0
@@ -10987,6 +10988,8 @@
 
   public final class CameraProperties extends android.hardware.camera2.CameraMetadata {
     method public T get(android.hardware.camera2.CameraMetadata.Key<T>);
+    method public java.util.List<android.hardware.camera2.CameraMetadata.Key<?>> getAvailableCaptureRequestKeys();
+    method public java.util.List<android.hardware.camera2.CameraMetadata.Key<?>> getAvailableCaptureResultKeys();
     field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
     field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES;
     field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_COMPENSATION_RANGE;
@@ -11131,6 +11134,7 @@
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_SENSITIVITY;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TEMPERATURE;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TIMESTAMP;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACES;
     field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_DETECT_MODE;
     field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_IDS;
     field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_LANDMARKS;
@@ -11146,14 +11150,16 @@
     field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_MODE;
   }
 
-  public static class CaptureResult.Face {
-    ctor public CaptureResult.Face();
+  public final class Face {
     method public android.graphics.Rect getBounds();
     method public int getId();
-    method public android.graphics.Point getLeftEye();
-    method public android.graphics.Point getMouth();
-    method public android.graphics.Point getRightEye();
+    method public android.graphics.Point getLeftEyePosition();
+    method public android.graphics.Point getMouthPosition();
+    method public android.graphics.Point getRightEyePosition();
     method public int getScore();
+    field public static final int ID_UNSUPPORTED = -1; // 0xffffffff
+    field public static final int SCORE_MAX = 100; // 0x64
+    field public static final int SCORE_MIN = 1; // 0x1
   }
 
   public final class Rational {
@@ -12334,7 +12340,7 @@
     field public static final int EULER_Z = 2; // 0x2
   }
 
-  public abstract interface Image implements java.lang.AutoCloseable {
+  public abstract class Image implements java.lang.AutoCloseable {
     method public abstract void close();
     method public abstract int getFormat();
     method public abstract int getHeight();
@@ -12343,23 +12349,23 @@
     method public abstract int getWidth();
   }
 
-  public static abstract interface Image.Plane {
+  public static abstract class Image.Plane {
     method public abstract java.nio.ByteBuffer getBuffer();
     method public abstract int getPixelStride();
     method public abstract int getRowStride();
   }
 
-  public final class ImageReader implements java.lang.AutoCloseable {
-    ctor public ImageReader(int, int, int, int);
+  public class ImageReader implements java.lang.AutoCloseable {
+    method public android.media.Image acquireLatestImage();
+    method public android.media.Image acquireNextImage();
     method public void close();
     method public int getHeight();
     method public int getImageFormat();
     method public int getMaxImages();
-    method public android.media.Image getNextImage();
     method public android.view.Surface getSurface();
     method public int getWidth();
-    method public void releaseImage(android.media.Image);
-    method public void setImageAvailableListener(android.media.ImageReader.OnImageAvailableListener, android.os.Handler);
+    method public static android.media.ImageReader newInstance(int, int, int, int);
+    method public void setOnImageAvailableListener(android.media.ImageReader.OnImageAvailableListener, android.os.Handler);
   }
 
   public static abstract interface ImageReader.OnImageAvailableListener {
@@ -15211,9 +15217,9 @@
     field public static final java.lang.String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES";
     field public static final java.lang.String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
     field public static final java.lang.String EXTRA_TAG = "android.nfc.extra.TAG";
-    field public static final int FLAG_READER_KOVIO = 16; // 0x10
     field public static final int FLAG_READER_NFC_A = 1; // 0x1
     field public static final int FLAG_READER_NFC_B = 2; // 0x2
+    field public static final int FLAG_READER_NFC_BARCODE = 16; // 0x10
     field public static final int FLAG_READER_NFC_F = 4; // 0x4
     field public static final int FLAG_READER_NFC_V = 8; // 0x8
     field public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 256; // 0x100
@@ -19168,15 +19174,21 @@
 
   public final class PrintJob {
     method public void cancel();
-    method public int getId();
+    method public android.print.PrintJobId getId();
     method public android.print.PrintJobInfo getInfo();
   }
 
+  public final class PrintJobId implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
   public final class PrintJobInfo implements android.os.Parcelable {
     method public int describeContents();
     method public android.print.PrintAttributes getAttributes();
     method public int getCopies();
-    method public int getId();
+    method public android.print.PrintJobId getId();
     method public java.lang.String getLabel();
     method public android.print.PageRange[] getPages();
     method public android.print.PrinterId getPrinterId();
@@ -19188,6 +19200,7 @@
     field public static final int STATE_BLOCKED = 4; // 0x4
     field public static final int STATE_CANCELED = 7; // 0x7
     field public static final int STATE_COMPLETED = 5; // 0x5
+    field public static final int STATE_CREATED = 1; // 0x1
     field public static final int STATE_FAILED = 6; // 0x6
     field public static final int STATE_QUEUED = 2; // 0x2
     field public static final int STATE_STARTED = 3; // 0x3
@@ -19195,7 +19208,6 @@
 
   public final class PrintManager {
     method public java.util.List<android.print.PrintJob> getPrintJobs();
-    method public android.print.PrintJob print(java.lang.String, java.io.File, android.print.PrintDocumentInfo, android.print.PrintAttributes);
     method public android.print.PrintJob print(java.lang.String, android.print.PrintDocumentAdapter, android.print.PrintAttributes);
   }
 
@@ -19306,7 +19318,7 @@
     method public boolean complete();
     method public boolean fail(java.lang.String);
     method public android.printservice.PrintDocument getDocument();
-    method public int getId();
+    method public android.print.PrintJobId getId();
     method public android.print.PrintJobInfo getInfo();
     method public boolean isBlocked();
     method public boolean isCancelled();
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index d78572b..c18f542 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -100,6 +100,7 @@
                 "       am monitor [--gdb <port>]\n" +
                 "       am hang [--allow-restart]\n" +
                 "       am restart\n" +
+                "       am idle-maintenance\n" +
                 "       am screen-compat [on|off] <PACKAGE>\n" +
                 "       am to-uri [INTENT]\n" +
                 "       am to-intent-uri [INTENT]\n" +
@@ -189,6 +190,8 @@
                 "\n" +
                 "am restart: restart the user-space system.\n" +
                 "\n" +
+                "am idle-maintenance: perform idle maintenance now.\n" +
+                "\n" +
                 "am screen-compat: control screen compatibility mode of <PACKAGE>.\n" +
                 "\n" +
                 "am to-uri: print the given Intent specification as a URI.\n" +
@@ -295,6 +298,8 @@
             runHang();
         } else if (op.equals("restart")) {
             runRestart();
+        } else if (op.equals("idle-maintenance")) {
+            runIdleMaintenance();
         } else if (op.equals("screen-compat")) {
             runScreenCompat();
         } else if (op.equals("to-uri")) {
@@ -1393,6 +1398,20 @@
         mAm.restart();
     }
 
+    private void runIdleMaintenance() throws Exception {
+        String opt;
+        while ((opt=nextOption()) != null) {
+            System.err.println("Error: Unknown option: " + opt);
+            return;
+        }
+
+        System.out.println("Performing idle maintenance...");
+        Intent intent = new Intent(
+                "com.android.server.IdleMaintenanceService.action.FORCE_IDLE_MAINTENANCE");
+        mAm.broadcastIntent(null, intent, null, null, 0, null, null, null,
+                android.app.AppOpsManager.OP_NONE, true, false, UserHandle.USER_ALL);
+    }
+
     private void runScreenCompat() throws Exception {
         String mode = nextArgRequired();
         boolean enabled;
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 370db31..a727b07 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1995,6 +1995,13 @@
             reply.writeParcelableArray(uris, 0);
             return true;
         }
+
+        case PERFORM_IDLE_MAINTENANCE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            performIdleMaintenance();
+            reply.writeNoException();
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -4578,5 +4585,15 @@
         return uris;
     }
 
+    public void performIdleMaintenance() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(PERFORM_IDLE_MAINTENANCE_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index b2ae298..25c02df 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -403,6 +403,8 @@
             String sourcePackage, String targetPackage, int modeFlags, int modeMask)
             throws RemoteException;
 
+    public void performIdleMaintenance() throws RemoteException;
+
     /*
      * Private non-Binder interfaces
      */
@@ -685,4 +687,5 @@
     int REPORT_ACTIVITY_FULLY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+176;
     int RESTART_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+177;
     int GET_GRANTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+178;
+    int PERFORM_IDLE_MAINTENANCE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+179;
 }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 92a9c7c..02ccaa5 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2132,13 +2132,8 @@
     public static final String UPDATE_LOCK_SERVICE = "updatelock";
 
     /**
-     * Use with {@link #getSystemService} to retrieve a {@link
-     * android.net.NetworkManagementService} for handling management of
-     * system network services
-     *
+     * Constant for the internal network management service, not really a Context service.
      * @hide
-     * @see #getSystemService
-     * @see android.net.NetworkManagementService
      */
     public static final String NETWORKMANAGEMENT_SERVICE = "network_management";
 
@@ -2327,7 +2322,7 @@
      * android.hardware.SerialManager} for access to serial ports.
      *
      * @see #getSystemService
-     * @see android.harware.SerialManager
+     * @see android.hardware.SerialManager
      *
      * @hide
      */
@@ -2353,17 +2348,6 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a
-     * {@link android.os.SchedulingPolicyService} for managing scheduling policy.
-     *
-     * @see #getSystemService
-     * @see android.os.SchedulingPolicyService
-     *
-     * @hide
-     */
-    public static final String SCHEDULING_POLICY_SERVICE = "scheduling_policy";
-
-    /**
-     * Use with {@link #getSystemService} to retrieve a
      * {@link android.os.UserManager} for managing users on devices that support multiple users.
      *
      * @see #getSystemService
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 4494e69..2e25177 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1441,18 +1441,29 @@
 */
         boolean required = true; // Optional <uses-permission> not supported
 
+        int maxSdkVersion = 0;
+        TypedValue val = sa.peekValue(
+                com.android.internal.R.styleable.AndroidManifestUsesPermission_maxSdkVersion);
+        if (val != null) {
+            if (val.type >= TypedValue.TYPE_FIRST_INT && val.type <= TypedValue.TYPE_LAST_INT) {
+                maxSdkVersion = val.data;
+            }
+        }
+
         sa.recycle();
 
-        if (name != null) {
-            int index = pkg.requestedPermissions.indexOf(name);
-            if (index == -1) {
-                pkg.requestedPermissions.add(name.intern());
-                pkg.requestedPermissionsRequired.add(required ? Boolean.TRUE : Boolean.FALSE);
-            } else {
-                if (pkg.requestedPermissionsRequired.get(index) != required) {
-                    outError[0] = "conflicting <uses-permission> entries";
-                    mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
-                    return false;
+        if ((maxSdkVersion == 0) || (maxSdkVersion >= Build.VERSION.RESOURCES_SDK_INT)) {
+            if (name != null) {
+                int index = pkg.requestedPermissions.indexOf(name);
+                if (index == -1) {
+                    pkg.requestedPermissions.add(name.intern());
+                    pkg.requestedPermissionsRequired.add(required ? Boolean.TRUE : Boolean.FALSE);
+                } else {
+                    if (pkg.requestedPermissionsRequired.get(index) != required) {
+                        outError[0] = "conflicting <uses-permission> entries";
+                        mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+                        return false;
+                    }
                 }
             }
         }
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index ec23f08..7f4ba4f 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -18,12 +18,25 @@
 
 import android.hardware.camera2.impl.CameraMetadataNative;
 
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 /**
  * The base class for camera controls and information.
  *
+ * <p>
  * This class defines the basic key/value map used for querying for camera
  * characteristics or capture results, and for setting camera request
  * parameters.
+ * </p>
+ *
+ * <p>
+ * All instances of CameraMetadata are immutable. The list of keys with {@link #getKeys()}
+ * never changes, nor do the values returned by any key with {@link #get} throughout
+ * the lifetime of the object.
+ * </p>
  *
  * @see CameraDevice
  * @see CameraManager
@@ -38,9 +51,14 @@
     }
 
     /**
-     * Get a camera metadata field value. The field definitions can be
+     * Get a camera metadata field value.
+     *
+     * <p>The field definitions can be
      * found in {@link CameraProperties}, {@link CaptureResult}, and
-     * {@link CaptureRequest}.
+     * {@link CaptureRequest}.</p>
+     *
+     * <p>Querying the value for the same key more than once will return a value
+     * which is equal to the previous queried value.</p>
      *
      * @throws IllegalArgumentException if the key was not valid
      *
@@ -49,6 +67,54 @@
      */
     public abstract <T> T get(Key<T> key);
 
+    /**
+     * Returns a list of the keys contained in this map.
+     *
+     * <p>The list returned is not modifiable, so any attempts to modify it will throw
+     * a {@code UnsupportedOperationException}.</p>
+     *
+     * <p>All values retrieved by a key from this list with {@link #get} are guaranteed to be
+     * non-{@code null}. Each key is only listed once in the list. The order of the keys
+     * is undefined.</p>
+     *
+     * @return List of the keys contained in this map.
+     */
+    public List<Key<?>> getKeys() {
+        return Collections.unmodifiableList(getKeysStatic(this.getClass(), this));
+    }
+
+    /**
+     * Return a list of all the Key<?> that are declared as a field inside of the class
+     * {@code type}.
+     *
+     * <p>
+     * Optionally, if {@code instance} is not null, then filter out any keys with null values.
+     * </p>
+     */
+    /*package*/ static ArrayList<Key<?>> getKeysStatic(Class<? extends CameraMetadata> type,
+            CameraMetadata instance) {
+        ArrayList<Key<?>> keyList = new ArrayList<Key<?>>();
+
+        Field[] fields = type.getDeclaredFields();
+        for (Field field : fields) {
+            if (field.getDeclaringClass().isAssignableFrom(Key.class)) {
+                Key<?> key;
+                try {
+                    key = (Key<?>) field.get(instance);
+                } catch (IllegalAccessException e) {
+                    throw new AssertionError("Can't get IllegalAccessException", e);
+                } catch (IllegalArgumentException e) {
+                    throw new AssertionError("Can't get IllegalArgumentException", e);
+                }
+                if (instance == null || instance.get(key) != null) {
+                    keyList.add(key);
+                }
+            }
+        }
+
+        return keyList;
+    }
+
     public static class Key<T> {
 
         private boolean mHasTag;
diff --git a/core/java/android/hardware/camera2/CameraProperties.java b/core/java/android/hardware/camera2/CameraProperties.java
index 45c009f..58a1ee3 100644
--- a/core/java/android/hardware/camera2/CameraProperties.java
+++ b/core/java/android/hardware/camera2/CameraProperties.java
@@ -18,6 +18,9 @@
 
 import android.hardware.camera2.impl.CameraMetadataNative;
 
+import java.util.Collections;
+import java.util.List;
+
 /**
  * <p>The properties describing a
  * {@link CameraDevice CameraDevice}.</p>
@@ -32,6 +35,8 @@
 public final class CameraProperties extends CameraMetadata {
 
     private final CameraMetadataNative mProperties;
+    private List<Key<?>> mAvailableRequestKeys;
+    private List<Key<?>> mAvailableResultKeys;
 
     /**
      * Takes ownership of the passed-in properties object
@@ -46,6 +51,75 @@
         return mProperties.get(key);
     }
 
+    /**
+     * Returns the list of keys supported by this {@link CameraDevice} for querying
+     * with a {@link CaptureRequest}.
+     *
+     * <p>The list returned is not modifiable, so any attempts to modify it will throw
+     * a {@code UnsupportedOperationException}.</p>
+     *
+     * <p>Each key is only listed once in the list. The order of the keys is undefined.</p>
+     *
+     * <p>Note that there is no {@code getAvailableCameraPropertiesKeys()} -- use
+     * {@link #getKeys()} instead.</p>
+     *
+     * @return List of keys supported by this CameraDevice for CaptureRequests.
+     */
+    public List<Key<?>> getAvailableCaptureRequestKeys() {
+        if (mAvailableRequestKeys == null) {
+            mAvailableRequestKeys = getAvailableKeyList(CaptureRequest.class);
+        }
+        return mAvailableRequestKeys;
+    }
+
+    /**
+     * Returns the list of keys supported by this {@link CameraDevice} for querying
+     * with a {@link CaptureResult}.
+     *
+     * <p>The list returned is not modifiable, so any attempts to modify it will throw
+     * a {@code UnsupportedOperationException}.</p>
+     *
+     * <p>Each key is only listed once in the list. The order of the keys is undefined.</p>
+     *
+     * <p>Note that there is no {@code getAvailableCameraPropertiesKeys()} -- use
+     * {@link #getKeys()} instead.</p>
+     *
+     * @return List of keys supported by this CameraDevice for CaptureResults.
+     */
+    public List<Key<?>> getAvailableCaptureResultKeys() {
+        if (mAvailableResultKeys == null) {
+            mAvailableResultKeys = getAvailableKeyList(CaptureResult.class);
+        }
+        return mAvailableResultKeys;
+    }
+
+    /**
+     * Returns the list of keys supported by this {@link CameraDevice} by metadataClass.
+     *
+     * <p>The list returned is not modifiable, so any attempts to modify it will throw
+     * a {@code UnsupportedOperationException}.</p>
+     *
+     * <p>Each key is only listed once in the list. The order of the keys is undefined.</p>
+     *
+     * @param metadataClass The subclass of CameraMetadata that you want to get the keys for.
+     *
+     * @return List of keys supported by this CameraDevice for metadataClass.
+     *
+     * @throws IllegalArgumentException if metadataClass is not a subclass of CameraMetadata
+     */
+    private <T extends CameraMetadata> List<Key<?>> getAvailableKeyList(Class<T> metadataClass) {
+
+        if (metadataClass.equals(CameraMetadata.class)) {
+            throw new AssertionError(
+                    "metadataClass must be a strict subclass of CameraMetadata");
+        } else if (!CameraMetadata.class.isAssignableFrom(metadataClass)) {
+            throw new AssertionError(
+                    "metadataClass must be a subclass of CameraMetadata");
+        }
+
+        return Collections.unmodifiableList(getKeysStatic(metadataClass, /*instance*/null));
+    }
+
     /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
      * The key entries below this point are generated from metadata
      * definitions in /system/media/camera/docs. Do not modify by hand or
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 4608ab9..3ec5ca0 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -176,7 +176,7 @@
      */
     public final static class Builder {
 
-        private CaptureRequest mRequest;
+        private final CaptureRequest mRequest;
 
         /**
          * Initialize the builder using the template; the request takes
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 3fcd2f9..377e78a 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -51,89 +51,6 @@
         return mResults.get(key);
     }
 
-    /**
-     * Describes a face detected in an image.
-     */
-    public static class Face {
-
-        /**
-         * <p>Bounds of the face. A rectangle relative to the sensor's
-         * {@link CameraProperties#SENSOR_INFO_ACTIVE_ARRAY_SIZE}, with (0,0)
-         * representing the top-left corner of the active array rectangle.</p>
-         */
-        public Rect getBounds() {
-            return mBounds;
-        }
-
-        /** <p>The confidence level for the detection of the face. The range is 1 to
-         * 100. 100 is the highest confidence.</p>
-         *
-         * <p>Depending on the device, even very low-confidence faces may be
-         * listed, so applications should filter out faces with low confidence,
-         * depending on the use case. For a typical point-and-shoot camera
-         * application that wishes to display rectangles around detected faces,
-         * filtering out faces with confidence less than 50 is recommended.</p>
-         *
-         */
-        public int getScore() {
-            return mScore;
-        }
-
-        /**
-         * An unique id per face while the face is visible to the tracker. If
-         * the face leaves the field-of-view and comes back, it will get a new
-         * id. This is an optional field, may not be supported on all devices.
-         * If not supported, id will always be set to -1. The optional fields
-         * are supported as a set. Either they are all valid, or none of them
-         * are.
-         */
-        public int getId() {
-            return mId;
-        }
-
-        /**
-         * The coordinates of the center of the left eye. The coordinates are in
-         * the same space as the ones for {@link #getBounds}. This is an
-         * optional field, may not be supported on all devices. If not
-         * supported, the value will always be set to null. The optional fields
-         * are supported as a set. Either they are all valid, or none of them
-         * are.
-         */
-        public Point getLeftEye() {
-            return mLeftEye;
-        }
-
-        /**
-         * The coordinates of the center of the right eye. The coordinates are
-         * in the same space as the ones for {@link #getBounds}.This is an
-         * optional field, may not be supported on all devices. If not
-         * supported, the value will always be set to null. The optional fields
-         * are supported as a set. Either they are all valid, or none of them
-         * are.
-         */
-        public Point getRightEye() {
-            return mRightEye;
-        }
-
-        /**
-         * The coordinates of the center of the mouth.  The coordinates are in
-         * the same space as the ones for {@link #getBounds}. This is an optional
-         * field, may not be supported on all devices. If not supported, the
-         * value will always be set to null. The optional fields are supported
-         * as a set. Either they are all valid, or none of them are.
-         */
-        public Point getMouth() {
-            return mMouth;
-        }
-
-        private Rect mBounds;
-        private int mScore;
-        private int mId;
-        private Point mLeftEye;
-        private Point mRightEye;
-        private Point mMouth;
-    }
-
     /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
      * The key entries below this point are generated from metadata
      * definitions in /system/media/camera/docs. Do not modify by hand or
@@ -1003,4 +920,19 @@
     /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
      * End generated code
      *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
+
+    /**
+     * <p>
+     * List of the {@link Face Faces} detected through camera face detection
+     * in this result.
+     * </p>
+     * <p>
+     * Only available if {@link #STATISTICS_FACE_DETECT_MODE} {@code !=}
+     * {@link CameraMetadata#STATISTICS_FACE_DETECT_MODE_OFF OFF}.
+     * </p>
+     *
+     * @see Face
+     */
+    public static final Key<Face[]> STATISTICS_FACES =
+            new Key<Face[]>("android.statistics.faces", Face[].class);
 }
diff --git a/core/java/android/hardware/camera2/Face.java b/core/java/android/hardware/camera2/Face.java
new file mode 100644
index 0000000..6bfc535
--- /dev/null
+++ b/core/java/android/hardware/camera2/Face.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.hardware.camera2;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+
+/**
+ * Describes a face detected in an image.
+ */
+public final class Face {
+
+    /**
+     * The ID is {@code -1} when the optional set of fields is unsupported.
+     *
+     * @see Face#Face(Rect, int)
+     * @see #getId()
+     */
+    public static final int ID_UNSUPPORTED = -1;
+
+    /**
+     * The minimum possible value for the confidence level.
+     *
+     * @see #getScore()
+     */
+    public static final int SCORE_MIN = 1;
+
+    /**
+     * The maximum possible value for the confidence level.
+     *
+     * @see #getScore()
+     */
+    public static final int SCORE_MAX = 100;
+
+    private final Rect mBounds;
+    private final int mScore;
+    private final int mId;
+    private final Point mLeftEye;
+    private final Point mRightEye;
+    private final Point mMouth;
+
+    /**
+     * Create a new face with all fields set.
+     *
+     * <p>The id, leftEyePosition, rightEyePosition, and mouthPosition are considered optional.
+     * If the id is {@value #ID_UNSUPPORTED} then the leftEyePosition, rightEyePosition, and
+     * mouthPositions are guaranteed to be {@code null}. Otherwise, each of leftEyePosition,
+     * rightEyePosition, and mouthPosition may be independently null or not-null.</p>
+     *
+     * @param bounds Bounds of the face.
+     * @param score Confidence level between {@value #SCORE_MIN}-{@value #SCORE_MAX}.
+     * @param id A unique ID per face visible to the tracker.
+     * @param leftEyePosition The position of the left eye.
+     * @param rightEyePosition The position of the right eye.
+     * @param mouthPosition The position of the mouth.
+     *
+     * @throws IllegalArgumentException
+     *             if bounds is {@code null},
+     *             or if the confidence is not in the range of
+     *             {@value #SCORE_MIN}-{@value #SCORE_MAX},
+     *             or if id is {@value #ID_UNSUPPORTED} and
+     *               leftEyePosition/rightEyePosition/mouthPosition aren't all null,
+     *             or else if id is negative.
+     *
+     * @hide
+     */
+    public Face(Rect bounds, int score, int id,
+            Point leftEyePosition, Point rightEyePosition, Point mouthPosition) {
+        checkNotNull("bounds", bounds);
+        if (score < SCORE_MIN || score > SCORE_MAX) {
+            throw new IllegalArgumentException("Confidence out of range");
+        } else if (id < 0 && id != ID_UNSUPPORTED) {
+            throw new IllegalArgumentException("Id out of range");
+        }
+        if (id == ID_UNSUPPORTED) {
+            checkNull("leftEyePosition", leftEyePosition);
+            checkNull("rightEyePosition", rightEyePosition);
+            checkNull("mouthPosition", mouthPosition);
+        }
+
+        mBounds = bounds;
+        mScore = score;
+        mId = id;
+        mLeftEye = leftEyePosition;
+        mRightEye = rightEyePosition;
+        mMouth = mouthPosition;
+    }
+
+    /**
+     * Create a new face without the optional fields.
+     *
+     * <p>The id, leftEyePosition, rightEyePosition, and mouthPosition are considered optional.
+     * If the id is {@value #ID_UNSUPPORTED} then the leftEyePosition, rightEyePosition, and
+     * mouthPositions are guaranteed to be {@code null}. Otherwise, each of leftEyePosition,
+     * rightEyePosition, and mouthPosition may be independently null or not-null.</p>
+     *
+     * @param bounds Bounds of the face.
+     * @param score Confidence level between {@value #SCORE_MIN}-{@value #SCORE_MAX}.
+     *
+     * @throws IllegalArgumentException
+     *             if bounds is {@code null},
+     *             or if the confidence is not in the range of
+     *             {@value #SCORE_MIN}-{@value #SCORE_MAX}.
+     *
+     * @hide
+     */
+    public Face(Rect bounds, int score) {
+        this(bounds, score, ID_UNSUPPORTED,
+                /*leftEyePosition*/null, /*rightEyePosition*/null, /*mouthPosition*/null);
+    }
+
+    /**
+     * Bounds of the face.
+     *
+     * <p>A rectangle relative to the sensor's
+     * {@link CameraProperties#SENSOR_INFO_ACTIVE_ARRAY_SIZE}, with (0,0)
+     * representing the top-left corner of the active array rectangle.</p>
+     *
+     * <p>There is no constraints on the the Rectangle value other than it
+     * is not-{@code null}.</p>
+     */
+    public Rect getBounds() {
+        return mBounds;
+    }
+
+    /**
+     * The confidence level for the detection of the face.
+     *
+     * <p>The range is {@value #SCORE_MIN} to {@value #SCORE_MAX}.
+     * {@value #SCORE_MAX} is the highest confidence.</p>
+     *
+     * <p>Depending on the device, even very low-confidence faces may be
+     * listed, so applications should filter out faces with low confidence,
+     * depending on the use case. For a typical point-and-shoot camera
+     * application that wishes to display rectangles around detected faces,
+     * filtering out faces with confidence less than half of {@value #SCORE_MAX}
+     * is recommended.</p>
+     *
+     * @see #SCORE_MAX
+     * @see #SCORE_MIN
+     */
+    public int getScore() {
+        return mScore;
+    }
+
+    /**
+     * An unique id per face while the face is visible to the tracker.
+     *
+     * <p>
+     * If the face leaves the field-of-view and comes back, it will get a new
+     * id.</p>
+     *
+     * <p>This is an optional field, may not be supported on all devices.
+     * If the id is {@value #ID_UNSUPPORTED} then the leftEyePosition, rightEyePosition, and
+     * mouthPositions are guaranteed to be {@code null}. Otherwise, each of leftEyePosition,
+     * rightEyePosition, and mouthPosition may be independently null or not-null.</p>
+     *
+     * <p>This value will either be {@value #ID_UNSUPPORTED} or
+     * otherwise greater than {@code 0}.</p>
+     *
+     * @see #ID_UNSUPPORTED
+     */
+    public int getId() {
+        return mId;
+    }
+
+    /**
+     * The coordinates of the center of the left eye.
+     *
+     * <p>The coordinates are in
+     * the same space as the ones for {@link #getBounds}. This is an
+     * optional field, may not be supported on all devices. If not
+     * supported, the value will always be set to null.
+     * This value will  always be null only if {@link #getId()} returns
+     * {@value #ID_UNSUPPORTED}.</p>
+     *
+     * @return The left eye position, or {@code null} if unknown.
+     */
+    public Point getLeftEyePosition() {
+        return mLeftEye;
+    }
+
+    /**
+     * The coordinates of the center of the right eye.
+     *
+     * <p>The coordinates are
+     * in the same space as the ones for {@link #getBounds}.This is an
+     * optional field, may not be supported on all devices. If not
+     * supported, the value will always be set to null.
+     * This value will  always be null only if {@link #getId()} returns
+     * {@value #ID_UNSUPPORTED}.</p>
+     *
+     * @return The right eye position, or {@code null} if unknown.
+     */
+    public Point getRightEyePosition() {
+        return mRightEye;
+    }
+
+    /**
+     * The coordinates of the center of the mouth.
+     *
+     * <p>The coordinates are in
+     * the same space as the ones for {@link #getBounds}. This is an optional
+     * field, may not be supported on all devices. If not
+     * supported, the value will always be set to null.
+     * This value will  always be null only if {@link #getId()} returns
+     * {@value #ID_UNSUPPORTED}.</p> them are.
+     * </p>
+     *
+     * @return The mouth position, or {@code null} if unknown.
+     */
+    public Point getMouthPosition() {
+        return mMouth;
+    }
+
+    /**
+     * Represent the Face as a string for debugging purposes.
+     */
+    @Override
+    public String toString() {
+        return String.format("{ bounds: %s, score: %s, id: %d, " +
+                "leftEyePosition: %s, rightEyePosition: %s, mouthPosition: %s }",
+                mBounds, mScore, mId, mLeftEye, mRightEye, mMouth);
+    }
+
+    private static void checkNotNull(String name, Object obj) {
+        if (obj == null) {
+            throw new IllegalArgumentException(name + " was required, but it was null");
+        }
+    }
+
+    private static void checkNull(String name, Object obj) {
+        if (obj != null) {
+            throw new IllegalArgumentException(name + " was required to be null, but it wasn't");
+        }
+    }
+}
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 020d7b6..c13438a 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -27,7 +27,6 @@
 import java.nio.ByteOrder;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Map;
 
 /**
  * Implementation of camera metadata marshal/unmarshal across Binder to
diff --git a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
index 2c05c58..d0b3ec4 100644
--- a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
+++ b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
@@ -19,6 +19,7 @@
 import static android.hardware.camera2.CameraAccessException.CAMERA_DISABLED;
 import static android.hardware.camera2.CameraAccessException.CAMERA_DISCONNECTED;
 import static android.hardware.camera2.CameraAccessException.CAMERA_IN_USE;
+import static android.hardware.camera2.CameraAccessException.MAX_CAMERAS_IN_USE;
 import static android.hardware.camera2.CameraAccessException.CAMERA_DEPRECATED_HAL;
 
 import android.os.DeadObjectException;
@@ -50,6 +51,7 @@
     public static final int EBUSY = -16;
     public static final int ENODEV = -19;
     public static final int EOPNOTSUPP = -95;
+    public static final int EDQUOT = -122;
 
     private static class CameraBinderDecoratorListener implements Decorator.DecoratorListener {
 
@@ -83,6 +85,9 @@
                     case EBUSY:
                         UncheckedThrow.throwAnyException(new CameraRuntimeException(
                                 CAMERA_IN_USE));
+                    case EDQUOT:
+                        UncheckedThrow.throwAnyException(new CameraRuntimeException(
+                                MAX_CAMERAS_IN_USE));
                     case ENODEV:
                         UncheckedThrow.throwAnyException(new CameraRuntimeException(
                                 CAMERA_DISCONNECTED));
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 2a18900..486e75a 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -227,9 +227,9 @@
     /**
      * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
      * <p>
-     * Setting this flag enables polling for Kovio technology.
+     * Setting this flag enables polling for NfcBarcode technology.
      */
-    public static final int FLAG_READER_KOVIO = 0x10;
+    public static final int FLAG_READER_NFC_BARCODE = 0x10;
 
     /**
      * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
diff --git a/core/java/android/print/IPrintManager.aidl b/core/java/android/print/IPrintManager.aidl
index d2ae5e6f..4e839c6 100644
--- a/core/java/android/print/IPrintManager.aidl
+++ b/core/java/android/print/IPrintManager.aidl
@@ -19,6 +19,7 @@
 import android.print.IPrinterDiscoveryObserver;
 import android.print.IPrintDocumentAdapter;
 import android.print.IPrintClient;
+import android.print.PrintJobId;
 import android.print.PrinterId;
 import android.print.PrintJobInfo;
 import android.print.PrintAttributes;
@@ -31,12 +32,12 @@
  */
 interface IPrintManager {
     List<PrintJobInfo> getPrintJobInfos(int appId, int userId);
-    PrintJobInfo getPrintJobInfo(int printJobId, int appId, int userId);
+    PrintJobInfo getPrintJobInfo(in PrintJobId printJobId, int appId, int userId);
     PrintJobInfo print(String printJobName, in IPrintClient client,
             in IPrintDocumentAdapter printAdapter, in PrintAttributes attributes,
             int appId, int userId);
-    void cancelPrintJob(int printJobId, int appId, int userId);
-    void restartPrintJob(int printJobId, int appId, int userId);
+    void cancelPrintJob(in PrintJobId printJobId, int appId, int userId);
+    void restartPrintJob(in PrintJobId printJobId, int appId, int userId);
 
     List<PrintServiceInfo> getEnabledPrintServices(int userId);
 
diff --git a/core/java/android/print/IPrintSpooler.aidl b/core/java/android/print/IPrintSpooler.aidl
index 0a77dab..291e81f 100644
--- a/core/java/android/print/IPrintSpooler.aidl
+++ b/core/java/android/print/IPrintSpooler.aidl
@@ -24,6 +24,8 @@
 import android.print.IPrintSpoolerCallbacks;
 import android.print.PrinterInfo;
 import android.print.PrintAttributes;
+import android.print.PrintJobId;
+import android.print.PrintJobInfo;
 
 /**
  * Interface for communication with the print spooler service.
@@ -33,17 +35,18 @@
  * @hide
  */
 oneway interface IPrintSpooler {
+    void removeObsoletePrintJobs();
+    void forgetPrintJobs(in List<PrintJobId> printJob);
     void getPrintJobInfos(IPrintSpoolerCallbacks callback, in ComponentName componentName,
             int state, int appId, int sequence);
-    void getPrintJobInfo(int printJobId, IPrintSpoolerCallbacks callback,
+    void getPrintJobInfo(in PrintJobId printJobId, IPrintSpoolerCallbacks callback,
             int appId, int sequence);
-    void createPrintJob(String printJobName, in IPrintClient client,
-            in IPrintDocumentAdapter printAdapter, in PrintAttributes attributes,
-            IPrintSpoolerCallbacks callback, int appId, int sequence);
-    void setPrintJobState(int printJobId, int status, String error,
+    void createPrintJob(in PrintJobInfo printJob, in IPrintClient client,
+            in IPrintDocumentAdapter printAdapter);
+    void setPrintJobState(in PrintJobId printJobId, int status, String stateReason,
             IPrintSpoolerCallbacks callback, int sequence);
-    void setPrintJobTag(int printJobId, String tag, IPrintSpoolerCallbacks callback,
+    void setPrintJobTag(in PrintJobId printJobId, String tag, IPrintSpoolerCallbacks callback,
             int sequence);
-    void writePrintJobData(in ParcelFileDescriptor fd, int printJobId);
+    void writePrintJobData(in ParcelFileDescriptor fd, in PrintJobId printJobId);
     void setClient(IPrintSpoolerClient client);
 }
diff --git a/core/java/android/print/IPrintSpoolerCallbacks.aidl b/core/java/android/print/IPrintSpoolerCallbacks.aidl
index 51b5439..45c5332 100644
--- a/core/java/android/print/IPrintSpoolerCallbacks.aidl
+++ b/core/java/android/print/IPrintSpoolerCallbacks.aidl
@@ -28,7 +28,6 @@
  */
 oneway interface IPrintSpoolerCallbacks {
     void onGetPrintJobInfosResult(in List<PrintJobInfo> printJob, int sequence);
-    void onCreatePrintJobResult(in PrintJobInfo printJob, int sequence);
     void onCancelPrintJobResult(boolean canceled, int sequence);
     void onSetPrintJobStateResult(boolean success, int sequence);
     void onSetPrintJobTagResult(boolean success, int sequence);
diff --git a/core/java/android/print/IPrinterDiscoveryObserver.aidl b/core/java/android/print/IPrinterDiscoveryObserver.aidl
index b558011..2be7b6b 100644
--- a/core/java/android/print/IPrinterDiscoveryObserver.aidl
+++ b/core/java/android/print/IPrinterDiscoveryObserver.aidl
@@ -18,6 +18,7 @@
 
 import android.print.PrinterId;
 import android.print.PrinterInfo;
+import android.content.pm.ParceledListSlice;
 
 /**
  * Interface for observing discovered printers by a discovery session.
@@ -25,6 +26,6 @@
  * @hide
  */
 oneway interface IPrinterDiscoveryObserver {
-    void onPrintersAdded(in List<PrinterInfo> printers);
-    void onPrintersRemoved(in List<PrinterId> printerIds);
+    void onPrintersAdded(in ParceledListSlice printers);
+    void onPrintersRemoved(in ParceledListSlice printerIds);
 }
diff --git a/core/java/android/print/PrintJob.java b/core/java/android/print/PrintJob.java
index 42bea6d..00ade07 100644
--- a/core/java/android/print/PrintJob.java
+++ b/core/java/android/print/PrintJob.java
@@ -22,8 +22,6 @@
  */
 public final class PrintJob {
 
-    private final int mId;
-
     private final PrintManager mPrintManager;
 
     private PrintJobInfo mCachedInfo;
@@ -31,7 +29,6 @@
     PrintJob(PrintJobInfo info, PrintManager printManager) {
         mCachedInfo = info;
         mPrintManager = printManager;
-        mId = info.getId();
     }
 
     /**
@@ -39,8 +36,8 @@
      *
      * @return The id.
      */
-    public int getId() {
-        return mId;
+    public PrintJobId getId() {
+        return mCachedInfo.getId();
     }
 
     /**
@@ -57,7 +54,7 @@
         if (isInImmutableState()) {
             return mCachedInfo;
         }
-        PrintJobInfo info = mPrintManager.getPrintJobInfo(mId);
+        PrintJobInfo info = mPrintManager.getPrintJobInfo(mCachedInfo.getId());
         if (info != null) {
             mCachedInfo = info;
         }
@@ -69,7 +66,7 @@
      */
     public void cancel() {
         if (!isInImmutableState()) {
-            mPrintManager.cancelPrintJob(mId);
+            mPrintManager.cancelPrintJob(mCachedInfo.getId());
         }
     }
 
@@ -91,11 +88,11 @@
             return false;
         }
         PrintJob other = (PrintJob) obj;
-        return mId == other.mId;
+        return mCachedInfo.getId().equals(other.mCachedInfo.getId());
     }
 
     @Override
     public int hashCode() {
-        return mId;
+        return mCachedInfo.getId().hashCode();
     }
 }
diff --git a/core/res/res/values-land/refs.xml b/core/java/android/print/PrintJobId.aidl
similarity index 75%
rename from core/res/res/values-land/refs.xml
rename to core/java/android/print/PrintJobId.aidl
index cda38cf..759f25f 100644
--- a/core/res/res/values-land/refs.xml
+++ b/core/java/android/print/PrintJobId.aidl
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+/**
  * Copyright (c) 2013, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,8 +12,8 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
-*/
--->
-<resources>
-    <item type="string" name="transient_navigation_confirmation">@string/transient_navigation_confirmation_long</item>
-</resources>
\ No newline at end of file
+ */
+
+package android.print;
+
+parcelable PrintJobId;
diff --git a/core/java/android/print/PrintJobId.java b/core/java/android/print/PrintJobId.java
new file mode 100644
index 0000000..01550e2
--- /dev/null
+++ b/core/java/android/print/PrintJobId.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.print;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import java.util.UUID;
+
+/**
+ * This class represents the id of a print job.
+ */
+public final class PrintJobId implements Parcelable {
+    private final String mValue;
+
+    /**
+     * Creates a new instance.
+     *
+     * @hide
+     */
+    public PrintJobId() {
+        this(UUID.randomUUID().toString());
+    }
+
+    /**
+     * Creates a new instance.
+     *
+     * @param value The internal value.
+     *
+     * @hide
+     */
+    public PrintJobId(String value) {
+        mValue = value;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((mValue != null) ? mValue.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        PrintJobId other = (PrintJobId) obj;
+        if (!TextUtils.equals(mValue, other.mValue)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeString(mValue);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Flattens this id to a string.
+     *
+     * @return The flattened id.
+     *
+     * @hide
+     */
+    public String flattenToString() {
+        return mValue;
+    }
+
+    /**
+     * Unflattens a print job id from a string.
+     *
+     * @string The string.
+     * @return The unflattened id, or null if the string is malformed.
+     *
+     * @hide
+     */
+    public static PrintJobId unflattenFromString(String string) {
+        return new PrintJobId(string);
+    }
+
+    public static final Parcelable.Creator<PrintJobId> CREATOR =
+            new Parcelable.Creator<PrintJobId>() {
+        @Override
+        public PrintJobId createFromParcel(Parcel parcel) {
+            return new PrintJobId(parcel.readString());
+        }
+
+        @Override
+        public PrintJobId[] newArray(int size) {
+            return new PrintJobId[size];
+        }
+    };
+}
diff --git a/core/java/android/print/PrintJobInfo.java b/core/java/android/print/PrintJobInfo.java
index b919ad6..502a9f2 100644
--- a/core/java/android/print/PrintJobInfo.java
+++ b/core/java/android/print/PrintJobInfo.java
@@ -56,8 +56,6 @@
      * <p>
      * Next valid states: {@link #STATE_QUEUED}
      * </p>
-     *
-     * @hide
      */
     public static final int STATE_CREATED = 1;
 
@@ -117,7 +115,7 @@
     public static final int STATE_CANCELED = 7;
 
     /** The unique print job id. */
-    private int mId;
+    private PrintJobId mId;
 
     /** The human readable print job label. */
     private String mLabel;
@@ -178,7 +176,7 @@
     }
 
     private PrintJobInfo(Parcel parcel) {
-        mId = parcel.readInt();
+        mId = parcel.readParcelable(null);
         mLabel = parcel.readString();
         mPrinterId = parcel.readParcelable(null);
         mPrinterName = parcel.readString();
@@ -208,7 +206,7 @@
      *
      * @return The id.
      */
-    public int getId() {
+    public PrintJobId getId() {
         return mId;
     }
 
@@ -219,7 +217,7 @@
      *
      * @hide
      */
-    public void setId(int id) {
+    public void setId(PrintJobId id) {
         this.mId = id;
     }
 
@@ -485,7 +483,7 @@
 
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeInt(mId);
+        parcel.writeParcelable(mId, flags);
         parcel.writeString(mLabel);
         parcel.writeParcelable(mPrinterId, flags);
         parcel.writeString(mPrinterName);
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
index 10cc771..5429155 100644
--- a/core/java/android/print/PrintManager.java
+++ b/core/java/android/print/PrintManager.java
@@ -36,7 +36,6 @@
 
 import libcore.io.IoUtils;
 
-import java.io.File;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -114,7 +113,7 @@
         return new PrintManager(mContext, mService, userId, APP_ID_ANY);
     }
 
-    PrintJobInfo getPrintJobInfo(int printJobId) {
+    PrintJobInfo getPrintJobInfo(PrintJobId printJobId) {
         try {
             return mService.getPrintJobInfo(printJobId, mAppId, mUserId);
         } catch (RemoteException re) {
@@ -148,7 +147,7 @@
         return Collections.emptyList();
     }
 
-    void cancelPrintJob(int printJobId) {
+    void cancelPrintJob(PrintJobId printJobId) {
         try {
             mService.cancelPrintJob(printJobId, mAppId, mUserId);
         } catch (RemoteException re) {
@@ -157,24 +156,6 @@
     }
 
     /**
-     * Creates a print job for printing a file with default print attributes.
-     *
-     * @param printJobName A name for the new print job.
-     * @param pdfFile The PDF file to print.
-     * @param documentInfo Information about the printed document.
-     * @param attributes The default print job attributes.
-     * @return The created print job on success or null on failure.
-     *
-     * @see PrintJob
-     */
-    public PrintJob print(String printJobName, File pdfFile, PrintDocumentInfo documentInfo,
-            PrintAttributes attributes) {
-        PrintFileDocumentAdapter documentAdapter = new PrintFileDocumentAdapter(
-                mContext, pdfFile, documentInfo);
-        return print(printJobName, documentAdapter, attributes);
-    }
-
-    /**
      * Creates a print job for printing a {@link PrintDocumentAdapter} with default print
      * attributes.
      *
diff --git a/core/java/android/print/PrinterDiscoverySession.java b/core/java/android/print/PrinterDiscoverySession.java
index 64249b4..c6dbc16 100644
--- a/core/java/android/print/PrinterDiscoverySession.java
+++ b/core/java/android/print/PrinterDiscoverySession.java
@@ -17,6 +17,7 @@
 package android.print;
 
 import android.content.Context;
+import android.content.pm.ParceledListSlice;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -270,20 +271,22 @@
         }
 
         @Override
-        public void onPrintersAdded(List<PrinterInfo> printers) {
+        @SuppressWarnings("rawtypes")
+        public void onPrintersAdded(ParceledListSlice printers) {
             PrinterDiscoverySession session = mWeakSession.get();
             if (session != null) {
                 session.mHandler.obtainMessage(MSG_PRINTERS_ADDED,
-                        printers).sendToTarget();
+                        printers.getList()).sendToTarget();
             }
         }
 
         @Override
-        public void onPrintersRemoved(List<PrinterId> printerIds) {
+        @SuppressWarnings("rawtypes")
+        public void onPrintersRemoved(ParceledListSlice printerIds) {
             PrinterDiscoverySession session = mWeakSession.get();
             if (session != null) {
                 session.mHandler.obtainMessage(MSG_PRINTERS_REMOVED,
-                        printerIds).sendToTarget();
+                        printerIds.getList()).sendToTarget();
             }
         }
     }
diff --git a/core/java/android/printservice/IPrintServiceClient.aidl b/core/java/android/printservice/IPrintServiceClient.aidl
index ad3c04f..c2dfc30 100644
--- a/core/java/android/printservice/IPrintServiceClient.aidl
+++ b/core/java/android/printservice/IPrintServiceClient.aidl
@@ -20,6 +20,8 @@
 import android.print.PrintJobInfo;
 import android.print.PrinterId;
 import android.print.PrinterInfo;
+import android.print.PrintJobId;
+import android.content.pm.ParceledListSlice;
 
 /**
  * The top-level interface from a print service to the system.
@@ -28,11 +30,11 @@
  */
 interface IPrintServiceClient {
     List<PrintJobInfo> getPrintJobInfos();
-    PrintJobInfo getPrintJobInfo(int printJobId);
-    boolean setPrintJobState(int printJobId, int state, String error);
-    boolean setPrintJobTag(int printJobId, String tag);
-    oneway void writePrintJobData(in ParcelFileDescriptor fd, int printJobId);
+    PrintJobInfo getPrintJobInfo(in PrintJobId printJobId);
+    boolean setPrintJobState(in PrintJobId printJobId, int state, String error);
+    boolean setPrintJobTag(in PrintJobId printJobId, String tag);
+    oneway void writePrintJobData(in ParcelFileDescriptor fd, in PrintJobId printJobId);
 
-    void onPrintersAdded(in List<PrinterInfo> printers);
-    void onPrintersRemoved(in List<PrinterId> printerIds);
+    void onPrintersAdded(in ParceledListSlice printers);
+    void onPrintersRemoved(in ParceledListSlice printerIds);
 }
diff --git a/core/java/android/printservice/PrintDocument.java b/core/java/android/printservice/PrintDocument.java
index 8292cfbc..e43f2a8 100644
--- a/core/java/android/printservice/PrintDocument.java
+++ b/core/java/android/printservice/PrintDocument.java
@@ -19,6 +19,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.print.PrintDocumentInfo;
+import android.print.PrintJobId;
 import android.util.Log;
 
 import java.io.IOException;
@@ -35,13 +36,13 @@
 
     private static final String LOG_TAG = "PrintDocument";
 
-    private final int mPrintJobId;
+    private final PrintJobId mPrintJobId;
 
     private final IPrintServiceClient mPrintServiceClient;
 
     private final PrintDocumentInfo mInfo;
 
-    PrintDocument(int printJobId, IPrintServiceClient printServiceClient,
+    PrintDocument(PrintJobId printJobId, IPrintServiceClient printServiceClient,
             PrintDocumentInfo info) {
         mPrintJobId = printJobId;
         mPrintServiceClient = printServiceClient;
diff --git a/core/java/android/printservice/PrintJob.java b/core/java/android/printservice/PrintJob.java
index 4ff7f0c..2fcae6b 100644
--- a/core/java/android/printservice/PrintJob.java
+++ b/core/java/android/printservice/PrintJob.java
@@ -17,6 +17,7 @@
 package android.printservice;
 
 import android.os.RemoteException;
+import android.print.PrintJobId;
 import android.print.PrintJobInfo;
 import android.text.TextUtils;
 import android.util.Log;
@@ -52,7 +53,7 @@
      *
      * @return The id.
      */
-    public int getId() {
+    public PrintJobId getId() {
         PrintService.throwIfNotCalledOnMainThread();
         return mCachedInfo.getId();
     }
@@ -312,12 +313,12 @@
             return false;
         }
         PrintJob other = (PrintJob) obj;
-        return (mCachedInfo.getId() == other.mCachedInfo.getId());
+        return (mCachedInfo.getId().equals(other.mCachedInfo.getId()));
     }
 
     @Override
     public int hashCode() {
-        return mCachedInfo.getId();
+        return mCachedInfo.getId().hashCode();
     }
 
     private boolean isInImmutableState() {
diff --git a/core/java/android/printservice/PrinterDiscoverySession.java b/core/java/android/printservice/PrinterDiscoverySession.java
index b0bf3da..17cb68f 100644
--- a/core/java/android/printservice/PrinterDiscoverySession.java
+++ b/core/java/android/printservice/PrinterDiscoverySession.java
@@ -16,6 +16,7 @@
 
 package android.printservice;
 
+import android.content.pm.ParceledListSlice;
 import android.os.RemoteException;
 import android.print.PrinterCapabilitiesInfo;
 import android.print.PrinterId;
@@ -80,8 +81,6 @@
 public abstract class PrinterDiscoverySession {
     private static final String LOG_TAG = "PrinterDiscoverySession";
 
-    private static final int MAX_ITEMS_PER_CALLBACK = 50;
-
     private static int sIdCounter = 0;
 
     private final int mId;
@@ -112,7 +111,11 @@
         // If some printers were added in the method that
         // created the session, send them over.
         if (!mPrinters.isEmpty()) {
-            sendAddedPrinters(mObserver, getPrinters());
+            try {
+                mObserver.onPrintersAdded(new ParceledListSlice<PrinterInfo>(getPrinters()));
+            } catch (RemoteException re) {
+                Log.e(LOG_TAG, "Error sending added printers", re);
+            }
         }
     }
 
@@ -184,7 +187,11 @@
 
             // Send the added printers, if such.
             if (addedPrinters != null) {
-                sendAddedPrinters(mObserver, addedPrinters);
+                try {
+                    mObserver.onPrintersAdded(new ParceledListSlice<PrinterInfo>(addedPrinters));
+                } catch (RemoteException re) {
+                    Log.e(LOG_TAG, "Error sending added printers", re);
+                }
             }
         } else {
             // Remember the last sent printers if needed.
@@ -203,27 +210,6 @@
         }
     }
 
-    private static void sendAddedPrinters(IPrintServiceClient observer,
-        List<PrinterInfo> printers) {
-        try {
-            final int printerCount = printers.size();
-            if (printerCount <= MAX_ITEMS_PER_CALLBACK) {
-                observer.onPrintersAdded(printers);
-            } else {
-                // Send the added printers in chunks avoiding the binder transaction limit.
-                final int transactionCount = (printerCount / MAX_ITEMS_PER_CALLBACK) + 1;
-                for (int i = 0; i < transactionCount; i++) {
-                    final int start = i * MAX_ITEMS_PER_CALLBACK;
-                    final int end = Math.min(start + MAX_ITEMS_PER_CALLBACK, printerCount);
-                    List<PrinterInfo> subPrinters = printers.subList(start, end);
-                    observer.onPrintersAdded(subPrinters);
-                }
-            }
-        } catch (RemoteException re) {
-            Log.e(LOG_TAG, "Error sending added printers", re);
-        }
-    }
-
     /**
      * Removes added printers. Removing an already removed or never added
      * printer has no effect. Removed printers can be added again. You can
@@ -261,7 +247,12 @@
 
             // Send the removed printers, if such.
             if (!removedPrinterIds.isEmpty()) {
-                sendRemovedPrinters(mObserver, removedPrinterIds);
+                try {
+                    mObserver.onPrintersRemoved(new ParceledListSlice<PrinterId>(
+                            removedPrinterIds));
+                } catch (RemoteException re) {
+                    Log.e(LOG_TAG, "Error sending removed printers", re);
+                }
             }
         } else {
             // Remember the last sent printers if needed.
@@ -278,26 +269,6 @@
         }
     }
 
-    private static void sendRemovedPrinters(IPrintServiceClient observer,
-            List<PrinterId> printerIds) {
-        try {
-            final int printerIdCount = printerIds.size();
-            if (printerIdCount <= MAX_ITEMS_PER_CALLBACK) {
-                observer.onPrintersRemoved(printerIds);
-            } else {
-                final int transactionCount = (printerIdCount / MAX_ITEMS_PER_CALLBACK) + 1;
-                for (int i = 0; i < transactionCount; i++) {
-                    final int start = i * MAX_ITEMS_PER_CALLBACK;
-                    final int end = Math.min(start + MAX_ITEMS_PER_CALLBACK, printerIdCount);
-                    List<PrinterId> subPrinterIds = printerIds.subList(start, end);
-                    observer.onPrintersRemoved(subPrinterIds);
-                }
-            }
-        } catch (RemoteException re) {
-            Log.e(LOG_TAG, "Error sending removed printers", re);
-        }
-    }
-
     private void sendOutOfDiscoveryPeriodPrinterChanges() {
         // Noting changed since the last discovery period - nothing to do.
         if (mLastSentPrinters == null || mLastSentPrinters.isEmpty()) {
@@ -319,7 +290,11 @@
 
         // Send the added printers, if such.
         if (addedPrinters != null) {
-            sendAddedPrinters(mObserver, addedPrinters);
+            try {
+                mObserver.onPrintersAdded(new ParceledListSlice<PrinterInfo>(addedPrinters));
+            } catch (RemoteException re) {
+                Log.e(LOG_TAG, "Error sending added printers", re);
+            }
         }
 
         // Determine the removed printers.
@@ -335,7 +310,11 @@
 
         // Send the removed printers, if such.
         if (removedPrinterIds != null) {
-            sendRemovedPrinters(mObserver, removedPrinterIds);
+            try {
+                mObserver.onPrintersRemoved(new ParceledListSlice<PrinterId>(removedPrinterIds));
+            } catch (RemoteException re) {
+                Log.e(LOG_TAG, "Error sending removed printers", re);
+            }
         }
 
         mLastSentPrinters = null;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c1c826c..c8312e3 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4365,6 +4365,9 @@
         /** @hide */
         public static final String BAR_SERVICE_COMPONENT = "bar_service_component";
 
+        /** @hide */
+        public static final String TRANSIENT_NAV_CONFIRMATIONS = "transient_nav_confirmations";
+
         /**
          * This are the settings to be backed up.
          *
diff --git a/core/java/android/transition/Fade.java b/core/java/android/transition/Fade.java
index 12e0d73..4cc2c42 100644
--- a/core/java/android/transition/Fade.java
+++ b/core/java/android/transition/Fade.java
@@ -91,6 +91,9 @@
             return null;
         }
         final ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", startAlpha, endAlpha);
+        if (DBG) {
+            Log.d(LOG_TAG, "Created animator " + anim);
+        }
         if (listener != null) {
             anim.addListener(listener);
             anim.addPauseListener(listener);
@@ -146,12 +149,41 @@
         final View endView = endValues.view;
         if (DBG) {
             View startView = (startValues != null) ? startValues.view : null;
-            Log.d(LOG_TAG, "Fade.onDisappear: startView, startVis, endView, endVis = " +
+            Log.d(LOG_TAG, "Fade.onAppear: startView, startVis, endView, endVis = " +
                     startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
         }
         // if alpha < 1, just fade it in from the current value
         if (endView.getAlpha() == 1.0f) {
             endView.setAlpha(0);
+            TransitionListener transitionListener = new TransitionListenerAdapter() {
+                boolean mCanceled = false;
+                float mPausedAlpha;
+
+                @Override
+                public void onTransitionCancel(Transition transition) {
+                    endView.setAlpha(1);
+                    mCanceled = true;
+                }
+
+                @Override
+                public void onTransitionEnd(Transition transition) {
+                    if (!mCanceled) {
+                        endView.setAlpha(1);
+                    }
+                }
+
+                @Override
+                public void onTransitionPause(Transition transition) {
+                    mPausedAlpha = endView.getAlpha();
+                    endView.setAlpha(1);
+                }
+
+                @Override
+                public void onTransitionResume(Transition transition) {
+                    endView.setAlpha(mPausedAlpha);
+                }
+            };
+            addListener(transitionListener);
         }
         return createAnimation(endView, endView.getAlpha(), 1, null);
     }
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index c588c6b..60b4708 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -1240,12 +1240,13 @@
                     View oldView = oldInfo.view;
                     TransitionValues newValues = mEndValues.viewValues != null ?
                             mEndValues.viewValues.get(oldView) : null;
+                    if (newValues == null) {
+                        newValues = mEndValues.idValues.get(oldView.getId());
+                    }
                     if (oldValues != null) {
                         // if oldValues null, then transition didn't care to stash values,
                         // and won't get canceled
-                        if (newValues == null) {
-                            cancel = true;
-                        } else {
+                        if (newValues != null) {
                             for (String key : oldValues.values.keySet()) {
                                 Object oldValue = oldValues.values.get(key);
                                 Object newValue = newValues.values.get(key);
@@ -1451,6 +1452,8 @@
         try {
             clone = (Transition) super.clone();
             clone.mAnimators = new ArrayList<Animator>();
+            clone.mStartValues = new TransitionValuesMaps();
+            clone.mEndValues = new TransitionValuesMaps();
         } catch (CloneNotSupportedException e) {}
 
         return clone;
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index 54d801e..44ca4e5 100644
--- a/core/java/android/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -22,6 +22,7 @@
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 
 /**
@@ -68,8 +69,9 @@
     ArrayMap<Scene, Transition> mSceneTransitions = new ArrayMap<Scene, Transition>();
     ArrayMap<Scene, ArrayMap<Scene, Transition>> mScenePairTransitions =
             new ArrayMap<Scene, ArrayMap<Scene, Transition>>();
-    private static ThreadLocal<ArrayMap<ViewGroup, ArrayList<Transition>>> sRunningTransitions =
-            new ThreadLocal<ArrayMap<ViewGroup, ArrayList<Transition>>>();
+    private static ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>>
+            sRunningTransitions =
+            new ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>>();
     private static ArrayList<ViewGroup> sPendingTransitions = new ArrayList<ViewGroup>();
 
 
@@ -184,20 +186,24 @@
     }
 
     private static ArrayMap<ViewGroup, ArrayList<Transition>> getRunningTransitions() {
-        ArrayMap<ViewGroup, ArrayList<Transition>> runningTransitions =
+        WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>> runningTransitions =
                 sRunningTransitions.get();
-        if (runningTransitions == null) {
-            runningTransitions = new ArrayMap<ViewGroup, ArrayList<Transition>>();
+        if (runningTransitions == null || runningTransitions.get() == null) {
+            ArrayMap<ViewGroup, ArrayList<Transition>> transitions =
+                    new ArrayMap<ViewGroup, ArrayList<Transition>>();
+            runningTransitions = new WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>(
+                    transitions);
             sRunningTransitions.set(runningTransitions);
         }
-        return runningTransitions;
+        return runningTransitions.get();
     }
 
     private static void sceneChangeRunTransition(final ViewGroup sceneRoot,
             final Transition transition) {
         if (transition != null) {
             final ViewTreeObserver observer = sceneRoot.getViewTreeObserver();
-            observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+            final ViewTreeObserver.OnPreDrawListener listener =
+                    new ViewTreeObserver.OnPreDrawListener() {
                 public boolean onPreDraw() {
                     sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
                     sPendingTransitions.remove(sceneRoot);
@@ -236,7 +242,8 @@
                     // values set on them again and avoid artifacts.
                     return false;
                 }
-            });
+            };
+            observer.addOnPreDrawListener(listener);
         }
     }
 
@@ -342,23 +349,19 @@
      * value of null causes the TransitionManager to use the default transition.
      */
     public static void beginDelayedTransition(final ViewGroup sceneRoot, Transition transition) {
-
-        // TEMPORARY: disabling delayed transitions until a fix for the various ActionBar-
-        // triggered artifacts is found
-
-//        if (!sPendingTransitions.contains(sceneRoot) && sceneRoot.isLaidOut()) {
-//            if (Transition.DBG) {
-//                Log.d(LOG_TAG, "beginDelayedTransition: root, transition = " +
-//                        sceneRoot + ", " + transition);
-//            }
-//            sPendingTransitions.add(sceneRoot);
-//            if (transition == null) {
-//                transition = sDefaultTransition;
-//            }
-//            final Transition finalTransition = transition.clone();
-//            sceneChangeSetup(sceneRoot, transition);
-//            Scene.setCurrentScene(sceneRoot, null);
-//            sceneChangeRunTransition(sceneRoot, finalTransition);
-//        }
+        if (!sPendingTransitions.contains(sceneRoot) && sceneRoot.isLaidOut()) {
+            if (Transition.DBG) {
+                Log.d(LOG_TAG, "beginDelayedTransition: root, transition = " +
+                        sceneRoot + ", " + transition);
+            }
+            sPendingTransitions.add(sceneRoot);
+            if (transition == null) {
+                transition = sDefaultTransition;
+            }
+            final Transition transitionClone = transition.clone();
+            sceneChangeSetup(sceneRoot, transitionClone);
+            Scene.setCurrentScene(sceneRoot, null);
+            sceneChangeRunTransition(sceneRoot, transitionClone);
+        }
     }
 }
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index 75d3e7c..f49821f 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -65,9 +65,6 @@
         ViewGroup endParent;
     }
 
-    // Temporary structure, used in calculating state in setup() and play()
-    private VisibilityInfo mTmpVisibilityInfo = new VisibilityInfo();
-
     @Override
     public String[] getTransitionProperties() {
         return sTransitionProperties;
@@ -161,7 +158,7 @@
 
     private VisibilityInfo getVisibilityChangeInfo(TransitionValues startValues,
             TransitionValues endValues) {
-        final VisibilityInfo visInfo = mTmpVisibilityInfo;
+        final VisibilityInfo visInfo = new VisibilityInfo();
         visInfo.visibilityChange = false;
         visInfo.fadeIn = false;
         if (startValues != null) {
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index 730c4eb..ad8b51d 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -992,6 +992,8 @@
                 mData = mDataCopy;
             }
             mDataCopy = null;
+            mAccess.mData.clear();
+            mAccess.mSize = 0;
         }
 
         int size() {
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 91c47d1..76b8579 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -30,6 +30,8 @@
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.AnticipateOvershootInterpolator;
 import android.view.animation.DecelerateInterpolator;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
@@ -41,6 +43,7 @@
     FrameLayout mContent;
     int mCount;
     final Handler mHandler = new Handler();
+    static final int BGCOLOR = 0xffed1d24;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -53,6 +56,7 @@
         Typeface light = Typeface.create("sans-serif-light", Typeface.NORMAL);
 
         mContent = new FrameLayout(this);
+        mContent.setBackgroundColor(0xC0000000);
         
         final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
                 FrameLayout.LayoutParams.WRAP_CONTENT,
@@ -64,13 +68,16 @@
         logo.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
         logo.setVisibility(View.INVISIBLE);
 
+        final View bg = new View(this);
+        bg.setBackgroundColor(BGCOLOR);
+        bg.setAlpha(0f);
+
         final TextView letter = new TextView(this);
 
         letter.setTypeface(bold);
         letter.setTextSize(300);
         letter.setTextColor(0xFFFFFFFF);
         letter.setGravity(Gravity.CENTER);
-        letter.setShadowLayer(12*metrics.density, 0, 0, 0xC085F985);
         letter.setText(String.valueOf(Build.VERSION.RELEASE).substring(0, 1));
 
         final int p = (int)(4 * metrics.density);
@@ -81,11 +88,11 @@
         tv.setPadding(p, p, p, p);
         tv.setTextColor(0xFFFFFFFF);
         tv.setGravity(Gravity.CENTER);
-        tv.setShadowLayer(4 * metrics.density, 0, 2 * metrics.density, 0x66000000);
         tv.setTransformationMethod(new AllCapsTransformationMethod(this));
         tv.setText("Android " + Build.VERSION.RELEASE);
         tv.setVisibility(View.INVISIBLE);
 
+        mContent.addView(bg);
         mContent.addView(letter, lp);
         mContent.addView(logo, lp);
 
@@ -96,24 +103,54 @@
         mContent.addView(tv, lp2);
 
         mContent.setOnClickListener(new View.OnClickListener() {
+            int clicks;
             @Override
             public void onClick(View v) {
-                if (logo.getVisibility() != View.VISIBLE) {
-                    letter.animate().alpha(0.25f).scaleY(0.75f).scaleX(0.75f).setDuration(2000)
-                            .start();
-                    logo.setAlpha(0f);
-                    logo.setVisibility(View.VISIBLE);
-                    logo.animate().alpha(1f).setDuration(1000).setStartDelay(500).start();
-                    tv.setAlpha(0f);
-                    tv.setVisibility(View.VISIBLE);
-                    tv.animate().alpha(1f).setDuration(1000).setStartDelay(1000).start();
+                clicks++;
+                if (clicks >= 6) {
+                    mContent.performLongClick();
+                    return;
                 }
+                letter.animate().cancel();
+                final float offset = (int)letter.getRotation() % 360;
+                letter.animate()
+                    .rotationBy((Math.random() > 0.5f ? 360 : -360) - offset)
+                    .setInterpolator(new DecelerateInterpolator())
+                    .setDuration(700).start();
             }
         });
 
         mContent.setOnLongClickListener(new View.OnLongClickListener() {
             @Override
             public boolean onLongClick(View v) {
+                if (logo.getVisibility() != View.VISIBLE) {
+                    bg.setScaleX(0.01f);
+                    bg.animate().alpha(1f).scaleX(1f).setStartDelay(500).start();
+                    letter.animate().alpha(0f).scaleY(0.5f).scaleX(0.5f)
+                            .rotationBy(360)
+                            .setInterpolator(new AccelerateInterpolator())
+                            .setDuration(1000)
+                            .start();
+                    logo.setAlpha(0f);
+                    logo.setVisibility(View.VISIBLE);
+                    logo.setScaleX(0.5f);
+                    logo.setScaleY(0.5f);
+                    logo.animate().alpha(1f).scaleX(1f).scaleY(1f)
+                        .setDuration(1000).setStartDelay(500)
+                        .setInterpolator(new AnticipateOvershootInterpolator())
+                        .start();
+                    tv.setAlpha(0f);
+                    tv.setVisibility(View.VISIBLE);
+                    tv.animate().alpha(1f).setDuration(1000).setStartDelay(1000).start();
+                    return true;
+                }
+                return false;
+            }
+        });
+
+        logo.setOnLongClickListener(new View.OnLongClickListener() {
+            @Override
+            public boolean onLongClick(View v) {
                 try {
                     startActivity(new Intent(Intent.ACTION_MAIN)
                         .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
index 07854e2..d3fe34e 100644
--- a/core/java/com/android/internal/app/ProcessStats.java
+++ b/core/java/com/android/internal/app/ProcessStats.java
@@ -24,6 +24,7 @@
 import android.text.format.DateFormat;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TimeUtils;
@@ -969,6 +970,7 @@
                 if (ps.isInUse()) {
                     uids.valueAt(iu).resetSafely(now);
                 } else {
+                    uids.valueAt(iu).makeDead();
                     uids.removeAt(iu);
                 }
             }
@@ -986,6 +988,7 @@
                     if (ps.isInUse() || ps.mCommonProcess.isInUse()) {
                         pkgState.mProcesses.valueAt(iproc).resetSafely(now);
                     } else {
+                        pkgState.mProcesses.valueAt(iproc).makeDead();
                         pkgState.mProcesses.removeAt(iproc);
                     }
                 }
@@ -2127,6 +2130,7 @@
         int mNumExcessiveCpu;
 
         boolean mMultiPackage;
+        boolean mDead;
 
         public long mTmpTotalTime;
 
@@ -2230,6 +2234,18 @@
             mNumExcessiveCpu = 0;
         }
 
+        void makeDead() {
+            mDead = true;
+        }
+
+        private void ensureNotDead() {
+            if (!mDead) {
+                return;
+            }
+            throw new IllegalStateException("ProcessState dead: name=" + mName
+                    + " pkg=" + mPackage + " uid=" + mUid + " common.name=" + mCommonProcess.mName);
+        }
+
         void writeToParcel(Parcel out, long now) {
             out.writeInt(mMultiPackage ? 1 : 0);
             out.writeInt(mDurationsTableSize);
@@ -2271,6 +2287,7 @@
         }
 
         public void makeActive() {
+            ensureNotDead();
             mActive = true;
         }
 
@@ -2279,7 +2296,8 @@
         }
 
         public boolean isInUse() {
-            return mActive || mNumActiveServices > 0 || mNumStartedServices > 0;
+            return mActive || mNumActiveServices > 0 || mNumStartedServices > 0
+                    || mCurState != STATE_NOTHING;
         }
 
         /**
@@ -2315,6 +2333,7 @@
         }
 
         void setState(int state, long now) {
+            ensureNotDead();
             if (mCurState != state) {
                 //Slog.i(TAG, "Setting state in " + mName + "/" + mPackage + ": " + state);
                 commitStateTime(now);
@@ -2392,6 +2411,7 @@
         }
 
         public void addPss(long pss, long uss, boolean always) {
+            ensureNotDead();
             if (!always) {
                 if (mLastPssState == mCurState && SystemClock.uptimeMillis()
                         < (mLastPssTime+(30*1000))) {
@@ -2453,6 +2473,7 @@
         }
 
         public void reportExcessiveWake(ArrayMap<String, ProcessState> pkgList) {
+            ensureNotDead();
             mCommonProcess.mNumExcessiveWake++;
             if (!mCommonProcess.mMultiPackage) {
                 return;
@@ -2464,6 +2485,7 @@
         }
 
         public void reportExcessiveCpu(ArrayMap<String, ProcessState> pkgList) {
+            ensureNotDead();
             mCommonProcess.mNumExcessiveCpu++;
             if (!mCommonProcess.mMultiPackage) {
                 return;
@@ -2489,9 +2511,17 @@
             return this;
         }
 
-        private ProcessState pullFixedProc(ArrayMap<String, ProcessState> pkgList,
-                int index) {
+        private ProcessState pullFixedProc(ArrayMap<String, ProcessState> pkgList, int index) {
             ProcessState proc = pkgList.valueAt(index);
+            if (mDead && proc.mCommonProcess != proc) {
+                // Somehow we try to continue to use a process state that is dead, because
+                // it was not being told it was active during the last commit.  We can recover
+                // from this by generating a fresh new state, but this is bad because we
+                // are losing whatever data we had in the old process state.
+                Log.wtf(TAG, "Pulling dead proc: name=" + mName + " pkg=" + mPackage
+                        + " uid=" + mUid + " common.name=" + mCommonProcess.mName);
+                proc = mStats.getProcessStateLocked(proc.mPackage, proc.mUid, proc.mName);
+            }
             if (proc.mMultiPackage) {
                 // The array map is still pointing to a common process state
                 // that is now shared across packages.  Update it to point to
diff --git a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
index 2d06b68..f773f59 100644
--- a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
+++ b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
@@ -159,17 +159,26 @@
 }
 
 
-static SkMemoryStream* adaptor_to_mem_stream(SkStream* adaptor) {
-    SkASSERT(adaptor != NULL);
-    SkDynamicMemoryWStream wStream;
-    const int bufferSize = 256 * 1024; // 256 KB, same as ViewStateSerializer.
-    uint8_t buffer[bufferSize];
-    do {
-        size_t bytesRead = adaptor->read(buffer, bufferSize);
-        wStream.write(buffer, bytesRead);
-    } while (!adaptor->isAtEnd());
-    SkAutoTUnref<SkData> data(wStream.copyToData());
-    return new SkMemoryStream(data.get());
+static SkMemoryStream* adaptor_to_mem_stream(SkStream* stream) {
+    SkASSERT(stream != NULL);
+    size_t bufferSize = 4096;
+    size_t streamLen = 0;
+    size_t len;
+    char* data = (char*)sk_malloc_throw(bufferSize);
+
+    while ((len = stream->read(data + streamLen,
+                               bufferSize - streamLen)) != 0) {
+        streamLen += len;
+        if (streamLen == bufferSize) {
+            bufferSize *= 2;
+            data = (char*)sk_realloc_throw(data, bufferSize);
+        }
+    }
+    data = (char*)sk_realloc_throw(data, streamLen);
+
+    SkMemoryStream* streamMem = new SkMemoryStream();
+    streamMem->setMemoryOwned(data, streamLen);
+    return streamMem;
 }
 
 SkStreamRewindable* CopyJavaInputStream(JNIEnv* env, jobject stream,
diff --git a/core/res/res/drawable-hdpi/stat_sys_adb_am.png b/core/res/res/drawable-hdpi/stat_sys_adb_am.png
index 0c13339..382557e 100644
--- a/core/res/res/drawable-hdpi/stat_sys_adb_am.png
+++ b/core/res/res/drawable-hdpi/stat_sys_adb_am.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_adb_am.png b/core/res/res/drawable-mdpi/stat_sys_adb_am.png
index f0a5089..4380035 100644
--- a/core/res/res/drawable-mdpi/stat_sys_adb_am.png
+++ b/core/res/res/drawable-mdpi/stat_sys_adb_am.png
Binary files differ
diff --git a/core/res/res/drawable-nodpi/platlogo.png b/core/res/res/drawable-nodpi/platlogo.png
index 4fd0e3c..6351c2d 100644
--- a/core/res/res/drawable-nodpi/platlogo.png
+++ b/core/res/res/drawable-nodpi/platlogo.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_adb_am.png b/core/res/res/drawable-xhdpi/stat_sys_adb_am.png
index 789a3f5..3222a76 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_adb_am.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_adb_am.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_adb_am.png b/core/res/res/drawable-xxhdpi/stat_sys_adb_am.png
index a36fa36..e01ad386 100644
--- a/core/res/res/drawable-xxhdpi/stat_sys_adb_am.png
+++ b/core/res/res/drawable-xxhdpi/stat_sys_adb_am.png
Binary files differ
diff --git a/core/res/res/layout/toast_bar.xml b/core/res/res/layout/toast_bar.xml
index b7443d5..a31d7cb 100644
--- a/core/res/res/layout/toast_bar.xml
+++ b/core/res/res/layout/toast_bar.xml
@@ -35,7 +35,7 @@
             android:paddingRight="16dp"
             android:singleLine="true"
             android:textColor="@android:color/white"
-            android:textSize="16sp" />
+            android:textSize="14sp" />
 
         <LinearLayout
             android:id="@android:id/button1"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 839f3e3..49b2bdc 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -481,10 +481,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Laat die program toe om laevlak-kenmerke van Wi-Fi-skerms te beheer."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"vang oudio-uitset vas"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Laat die program oudio-uitset vasvang en herlei."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Aktiveerwoord-opsporing"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Laat die program toe om oudio vir Aktiveerwoord-opsporing op te neem. Die opname kan in die agtergrond plaasvind, maar verhoed nie dat ander oudio opgeneem word nie (bv. Kameraopnemer)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"vang video-uitset vas"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Laat die program video-uitset vasvang en herlei."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"vang veilige video-uitset vas"</string>
@@ -552,12 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"verhoed foon om te slaap"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Laat die program toe om die tablet te keer om te slaap."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Laat die program toe om die foon te keer om te slaap."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"versend infrarooi"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Laat die program toe om die tablet se infrarooisender te gebruik."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Laat die program toe om die foon se infrarooisender te gebruik."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"skakel tablet aan of af"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"Sit foon aan of af"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Laat die program toe om die tablet aan en af te skakel."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 6c8c0c6..32123fb 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -481,10 +481,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"መተግበሪያው በዝቅተኛ ደረጃ ላይ ያሉ የWifi ማሳያዎችን እንዲቆጣጠር ይፈቅድለታል።"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"የድምጽ ውጽዓት ይቅረጹ"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"መተግበሪያው የድምጽ ውጽዓት እንዲቀርጽ እና አቅጣጫውን እንዲያዞር ያስችለዋል።"</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"ትኩስ ቃል ማወቅ"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"ትኩስ ቃል ለይቶ ለማወቅ ድምጽ እንዲቀርጽ ለመተግበሪያው ይፈቅድለታል። ቀረጻው በጀርባ ሊካሄድ ይችላል ነገር ግን ሌላ የድምጽ ቀረጻዎችን አይከለክልም (ለምሳሌ፣  የካሜራ መቅረጫ)።"</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"የቪዲዮ ውጽዓት ይቅረጹ"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"መተግበሪያው የቪዲዮ ውጽዓት እንዲቀርጽ እና አቅጣጫውን እንዲያዞር ያስችለዋል።"</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"ደህንነቱ የተጠበቀ የቪዲዮ ውጽዓት ይቅረጹ"</string>
@@ -552,12 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ስልክ ከማንቀላፋት ተከላከል"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ጡባዊውን ከመተኛት መከልከል ለመተግበሪያው ይፈቅዳሉ።"</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"ስልኩን ከመተኛት መከልከል ለመተግበሪያው ይፈቅዳሉ።"</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"ኢንፍራርድ አስተላልፍ"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"የጡባዊውን የኢንፍራሪድ አስተላላፊ እንዲጠቀም ለመተግበሪያው ይፈቅድለታል።"</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"የስልኩን የኢንፍራሪድ አስተላላፊ እንዲጠቀም ለመተግበሪያው ይፈቅድለታል።"</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ጡባዊ አብራ ወይም አጥፋ"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"ስልክ አብራ ወይም አጥፋ"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"ጡባዊ ተኮውን ለማብራት እና ለማጥፋት ለመተግበሪያው ይፈቅዳሉ።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index bd394d1..7f3e678 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"سعة تخزين الجهاز اللوحي ممتلئة! احذف بعض الملفات لإخلاء مساحة."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"سعة تخزين الهاتف ممتلئة. احذف بعض الملفات لإخلاء مساحة."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"قد تكون الشبكة مراقبة"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"بواسطة جهة خارجية غير معلومة"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"بواسطة <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"أنا"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"خيارات الجهاز اللوحي"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"خيارات الهاتف"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"للسماح للتطبيق بالتحكم في الميزات ذات المستوى المنخفض في شاشات Wi-Fi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"التقاط إخراج الصوت"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"السماح للتطبيق بالتقاط إخراج الصوت وإعادة توجيهه."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"اكتشاف الكلمة المهمة"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"للسماح للتطبيق بالتقاط الصوت لاكتشاف الكلمة المهمة. يمكن أن يتم الالتقاط في الخلفية ولكنه لا يمنع التقاط الأصوات الأخرى (على سبيل المثال، كاميرا الفيديو)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"التقاط إخراج الفيديو"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"السماح للتطبيق بالتقاط إخراج الفيديو وإعادة توجيهه."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"التقاط إخراج الفيديو الآمن"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"منع الهاتف من الدخول في وضع السكون"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"للسماح للتطبيق بمنع الجهاز اللوحي من الانتقال إلى وضع السكون."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"للسماح للتطبيق بمنع الهاتف من الانتقال إلى وضع السكون."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"إرسال الأشعة تحت الحمراء"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"للسماح للتطبيق باستخدام مرسل الأشعة تحت الحمراء الخاص بالجهاز اللوحي."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"للسماح للتطبيق باستخدام مرسل الأشعة تحت الحمراء الخاص بالهاتف."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"تشغيل الجهاز اللوحي أو إيقاف تشغيله"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"تشغيل الهاتف أو إيقاف تشغيله"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"للسماح للتطبيق بتشغيل الجهاز اللوحي أو إيقاف تشغيله."</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index f492ff5..040d274 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -481,10 +481,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Разрешава на приложението да контролира функциите от ниско ниво на дисплеите през WiFi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"записване на възпроизвеждания звук"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Разрешава на приложението да записва и пренасочва възпроизвеждания звук."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Откриване на активиращи думи"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Разрешава на приложението да записва звук с цел откриване на активиращи думи. Това може да става на заден план, но не пречи на записването на други звуци (напр. от видеокамерата)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"записване на възпроизвеждания образ"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Разрешава на приложението да записва и пренасочва възпроизвеждания образ."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"записване на защитеното възпроизвеждане на образ"</string>
@@ -552,12 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"предотвратява спящ режим на телефона"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Разрешава на приложението да предотвратява преминаването на таблета в спящ режим."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Разрешава на приложението да предотвратява преминаването на телефона в спящ режим."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"предаване чрез инфрачервени лъчи"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Разрешава на приложението да използва инфрачервения предавател на таблета."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Разрешава на приложението да използва инфрачервения предавател на телефона."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"включване или изключване на таблета"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"включване или изключване на телефона"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Разрешава на приложението да включва или изключва таблета."</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 6ea3299..a58f5b2 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -481,10 +481,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permet a l\'aplicació controlar les funcions de baix nivell de les pantalles Wi-Fi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"captura la sortida d\'àudio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Permet que l\'aplicació capturi i redirigeixi la sortida d\'àudio."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Detecció de paraules actives"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Permet que l\'aplicació capturi àudio per a la detecció de paraules actives. La captura es pot produir en segon pla però no evita altres captures d\'àudio (per exemple, de càmera de vídeo)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"captura la sortida de vídeo"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Permet que l\'aplicació capturi i redirigeixi la sortida de vídeo."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"captura la sortida de vídeo segur"</string>
@@ -552,12 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"impedir que el telèfon entri en mode de repòs"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permet que l\'aplicació impedeixi que la tauleta entri en repòs."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Permet que l\'aplicació impedeixi que el telèfon entri en repòs."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"transmissió d\'infraroigs"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Permet que l\'aplicació utilitzi el transmissor d\'infraroigs de la tauleta."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Permet que l\'aplicació utilitzi el transmissor d\'infraroigs del telèfon."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"activa o desactiva la tauleta"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"engegar o apagar el telèfon"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Permet que l\'aplicació encengui i apagui la tauleta."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 9822263..3a9da60 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Din tablets lager er fuldt. Slet nogle filer for at frigøre plads."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Telefonens lager er fuldt. Slet nogle filer for at frigøre plads."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Netværket kan være overvåget"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Af en ukendt tredjepart"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Af <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Mig"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Valgmuligheder for tabletcomputeren"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefonvalgmuligheder"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index cbea74f..8853b37 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Der Tablet-Speicher ist voll. Löschen Sie Dateien, um Speicherplatz freizugeben."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Der Handyspeicher ist voll! Löschen Sie Dateien, um Speicherplatz freizugeben."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Das Netzwerk wird möglicherweise überwacht."</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Von einem unbekannten Dritten"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Von <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Eigene"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tablet-Optionen"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefonoptionen"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Erlaubt der App, untergeordnete Funktionen von WLAN-Anzeigen zu steuern"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"Audioausgabe erfassen"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Ermöglicht der App die Erfassung und Weiterleitung von Audioausgaben"</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Hotword-Erkennung"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"App darf Audio für die Hotword-Erkennung erfassen. Dies kann im Hintergrund durchgeführt werden und beeinflusst die Erfassung von Audio über andere Funktionen (z. B. Camcorder) nicht."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"Videoausgabe erfassen"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Ermöglicht der App die Erfassung und Weiterleitung von Videoausgaben"</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"Sichere Videoausgabe erfassen"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"Ruhezustand deaktivieren"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Ermöglicht der App, den Ruhezustand des Tablets zu deaktivieren"</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Ermöglicht der App, den Ruhezustand des Telefons zu deaktivieren"</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"Infrarotübertragung"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"App darf das System zur Infrarotübertragung des Tablets verwenden."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"App darf das System zur Infrarotübertragung des Telefons verwenden."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"Tablet ein- oder ausschalten"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"Gerät ein- oder ausschalten"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Ermöglicht der App, das Tablet ein- oder auszuschalten"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index ca628bf..d0cd8da 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Ο αποθηκευτικός χώρος του tablet είναι πλήρης. Διαγράψτε μερικά αρχεία για να δημιουργήσετε ελεύθερο χώρο."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Ο αποθηκευτικός χώρος του τηλεφώνου είναι πλήρης. Διαγράψτε μερικά αρχεία για να δημιουργήσετε ελεύθερο χώρο."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Το δίκτυο ενδέχεται να παρακολουθείται"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Από ένα άγνωστο τρίτο μέρος"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Από <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Για εμένα"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Επιλογές tablet"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Επιλογές τηλεφώνου"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index a449835..d5ed353 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Tablet storage is full. Delete some files to free space."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Phone storage is full. Delete some files to free space."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Network may be monitored"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"By an unknown third party"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"By <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Me"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tablet options"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Phone options"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index a449835..d5ed353 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Tablet storage is full. Delete some files to free space."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Phone storage is full. Delete some files to free space."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Network may be monitored"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"By an unknown third party"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"By <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Me"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tablet options"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Phone options"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 29a3023..9222e70 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Se ha agotado el espacio de almacenamiento de la tablet. Elimina algunos archivos para liberar espacio."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Se ha agotado el espacio de almacenamiento del dispositivo. Elimina algunos archivos para liberar espacio."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Es posible que la red esté supervisada."</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Por un tercero desconocido"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Por <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Yo"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opciones de tablet"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Opciones de dispositivo"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 96d81d4..6191dc1 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Se ha agotado el espacio de almacenamiento del tablet. Elimina algunos archivos para liberar espacio."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Se ha agotado el espacio de almacenamiento del teléfono. Elimina algunos archivos para liberar espacio."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Es posible que la red esté supervisada"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"De un tercero desconocido"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"De <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Yo"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opciones del tablet"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Opciones del teléfono"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index fd1da20..8e93ec1 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Tahvelarvuti mäluruum on täis. Ruumi vabastamiseks kustutage mõned failid."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Telefonimälu on täis. Ruumi vabastamiseks kustutage mõned failid."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Võrku võidakse jälgida"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Tundmatu kolmas osapool:"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Domeen: <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Mina"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tahvelarvuti valikud"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefonivalikud"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Lubab rakendusel juhtida WiFi-ekraanide madala taseme funktsioone."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"heliväljundi jäädvustamine"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Lubab rakendusel jäädvustada ja ümber suunata heliväljundit."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Otsetee sõna tuvastamine"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Lubab rakendusel jäädvustada heli otsetee sõna tuvastamiseks. Jäädvustamine võib toimuda taustal, kuid see ei takista muud heli jäädvustamist (nt videokaameraga)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"videoväljundi jäädvustamine"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Lubab rakendusel jäädvustada ja ümber suunata videoväljundit."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"kaitstud videoväljundi jäädvustamine"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"väldi telefoni uinumist"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Võimaldab rakendusel vältida tahvelarvuti uinumist."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Võimaldab rakendusel vältida telefoni uinumist."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"infrapunaedastus"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Lubab rakendusel kasutada tahvelarvuti infrapunasaatjat."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Lubab rakendusel kasutada telefoni infrapunasaatjat."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"lülita tahvelarvuti sisse või välja"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"lülita telefon sisse või välja"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Võimaldab rakendusel tahvelarvutit sisse või välja lülitada."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 120f3ee..74c904f 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -481,10 +481,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"به برنامه اجازه می‌دهد که ویژگی‌های سطح پایین صفحه‌های نمایش Wi‑Fi را کنترل کند."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ضبط خروجی صدا"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"به برنامه امکان می‌دهد خروجی صدا را ضبط و هدایت کند."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"تشخیص کلیدگفته"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"به برنامه اجازه می‌دهد تا صدا را برای تشخیص کلیدگفته ضبط کند. ضبط صدا می‌تواند در پس‌زمینه رخ دهد اما از ضبط صداهای دیگر (مثلاً دوربین فیلمبرداری) جلوگیری نمی‌کند."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"ضبط خروجی ویدیو"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"به برنامه امکان می‌دهد خروجی ویدیو را ضبط و هدایت کند."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"ضبط خروجی ویدیوی ایمن"</string>
@@ -552,12 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ممانعت از به خواب رفتن تلفن"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"به برنامه اجازه می‎دهد تا از غیرفعال شدن رایانهٔ لوحی جلوگیری کند."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"به برنامه اجازه می‎دهد تا از غیرفعال شدن تلفن جلوگیری کند."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"ارسال مادون قرمز"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"به برنامه اجازه می‌دهد تا از فرستنده مادون قرمز رایانه لوحی استفاده کند."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"به برنامه اجازه می‌دهد تا از فرستنده مادون قرمز تلفن استفاده کند."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"روشن/خاموش کردن رایانهٔ لوحی"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"روشن/خاموش کردن تلفن"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"به برنامه اجازه می‎دهد رایانهٔ لوحی را روشن یا خاموش کند."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 98faa98..9c05971 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Tablet-laitteen tallennustila on täynnä. Vapauta tilaa poistamalla tiedostoja."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Puhelimen tallennustila on täynnä. Vapauta tilaa poistamalla tiedostoja."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Verkkoa saatetaan valvoa"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Valvoja on tuntematon kolmas osapuoli."</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Valvoja on <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>."</string>
     <string name="me" msgid="6545696007631404292">"Minä"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tablet-laitteen asetukset"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Puhelimen asetukset"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Antaa sovelluksen hallita wifi-näyttöjen matalan tason ominaisuuksia."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"äänentoiston kaappaus"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Antaa sovellukselle luvan äänentoiston kaappaamiseen ja uudelleenohjaamiseen."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Toimintosanan tunnistus"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Antaa sovelluksen siepata ääntä toimintosanojen tunnistusta varten. Sieppaus voi tapahtua taustalla, mutta se ei estä muita laitteita, kuten videokameraa, käyttämästä ääntä."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"videokuvan kaappaus"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Antaa sovellukselle luvan videokuvan kaappaamiseen ja uudelleenohjaamiseen"</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"suojatun videokuvan kaappaus"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"estä puhelinta menemästä virransäästötilaan"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Antaa sovelluksen estää tablet-laitetta siirtymästä virransäästötilaan."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Antaa sovelluksen estää puhelinta siirtymästä virransäästötilaan."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"infrapunalähetys"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Antaa sovelluksen käyttää tablet-laitteen infrapunalähetintä."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Antaa sovelluksen käyttää puhelimen infrapunalähetintä."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"käynnistä tai sammuta tablet-laite"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"sammutta tai käynnistä puhelin"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Antaa sovelluksen sammuttaa tai käynnistää tablet-laitteen."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 27ef5d7..563ed73 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"La mémoire de la tablette est pleine. Supprimez des fichiers pour libérer de l\'espace."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"La mémoire du téléphone est pleine. Veuillez supprimer des fichiers pour libérer de l\'espace."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Il est possible que le réseau soit surveillé."</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Par un tiers inconnu"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Par <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Moi"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Options de la tablette"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Options du téléphone"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permet à l\'application de contrôler les fonctionnalités de base des écrans Wi-Fi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"enregistrer les sorties audio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Autoriser l\'application à enregistrer et à rediriger les sorties audio"</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Détection de mot clé"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Permet à l\'application de capturer du contenu audio pour détecter des mots clés. L\'enregistrement peut se produire en arrière-plan, sans désactiver les autres services de capture audio (tels que ceux d\'un caméscope)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"enregistrer les sorties vidéo"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Autoriser l\'application à enregistrer et à rediriger les sorties vidéo"</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"enregistrer les sorties vidéo sécurisées"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"empêcher le téléphone de passer en mode veille"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permet à l\'application d\'empêcher la tablette de passer en mode veille."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Permet à l\'application d\'empêcher le téléphone de passer en mode veille."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"transmettre des signaux infrarouges"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Permet à l\'application d\'utiliser l\'émetteur infrarouge de la tablette."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Permet à l\'application d\'utiliser l\'émetteur infrarouge du téléphone."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"éteindre ou allumer la tablette"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"Éteindre ou allumer le téléphone"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Permet à l\'application d\'éteindre et d\'allumer la tablette."</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index e7e6518..8c18c58 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"टेबलेट संग्रहण भर गया है. स्‍थान रिक्त करने के लिए कुछ फ़ाइलें हटाएं."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"फ़ोन संग्रहण भर गया है. स्‍थान रिक्त करने के लिए कुछ फ़ाइलें हटाएं."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"नेटवर्क को मॉनिटर किया जा सकता है"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"किसी अज्ञात तृतीय पक्ष के द्वारा"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g> के द्वारा"</string>
     <string name="me" msgid="6545696007631404292">"मैं"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"टेबलेट विकल्‍प"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"फ़ोन विकल्‍प"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"एप्स को Wifi डिस्प्ले की निम्न-स्तर की सुविधाएं नियंत्रित करने देता है."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ऑडियो आउटपुट को कैप्‍चर करें"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"एप्‍स को ऑडियो आउटपुट को कैप्‍चर और रीडायरेक्‍ट करने देता है."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"हॉटवर्ड पहचान"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"एप्लिकेशन को हॉटवर्ड पहचान के लिए ऑडियो कैप्चर करने देती है. कैप्चर पृष्ठभूमि में हो सकता है लेकिन वह अन्य ऑडियो कैप्चर (उदा. कैमकॉर्डर) को नहीं रोकता."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"वीडियो आउटपुट को कैप्‍चर करें"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"एप्‍स को वीडियो आउटपुट को कैप्‍चर और रीडायरेक्‍ट करने देता है."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"सुरक्षित वीडियो आउटपुट को कैप्‍चर करें"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"फ़ोन को निष्‍क्रिय होने से रोकें"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"एप्स को टेबलेट को प्रयोग में नहीं हो जाने से रोकता है."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"एप्स को फ़ोन को प्रयोग में नहीं होने से रोकता है."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"इंफ़्रारेड संचारित करें"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"एप्लिकेशन को टेबलेट के इंफ़्रारेड ट्रांसमीटर का उपयोग करने देती है."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"एप्लिकेशन को फ़ोन के इंफ़्रारेड ट्रांसमीटर का उपयोग करने देती है."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"टेबलेट चालू या बंद करें"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"फ़ोन चालू या बंद करें"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"एप्‍स को टेबलेट चालू या बंद करने देता है."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index e839579..e9f5ed1 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Prostor za pohranu tabletnog računala pun je. Izbrišite nekoliko datoteka kako biste oslobodili prostor."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Prostor za pohranu na telefonu je pun. Izbrišite nekoliko datoteka kako biste oslobodili prostor."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Mreža se možda nadzire"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Od strane nepoznate treće strane"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Od strane domene <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Ja"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opcije tabletnog uređaja"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Opcije telefona"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Omogućuje aplikaciji upravljanje značajkama Wi-Fi zaslona niske razine."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"primanje audioizlaza"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Omogućuje aplikaciji primanje i preusmjeravanje audioizlaza."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Otkrivanje pokretača značajke"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Aplikaciji omogućuje snimanje zvuka radi otkrivanja pokretača značajke. Snimanje se može odvijati u pozadini, ali ne sprječava drugo snimanje zvuka (npr. kameru)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"primanje videoizlaza"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Omogućuje aplikaciji primanje i preusmjeravanje videoizlaza."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"primanje sigurnog videoizlaza"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"sprečava telefon da prijeđe u stanje mirovanja"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Aplikaciji omogućuje sprječavanje prelaska tabletnog računala u mirovanje."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Aplikaciji omogućuje da spriječi prelazak telefona u mirovanje."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"infracrveni prijenos"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Aplikaciji omogućuje upotrebu infracrvenog odašiljača tableta."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Aplikaciji omogućuje upotrebu infracrvenog odašiljača telefona."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"uključivanje ili isključivanje tabletnog uređaja"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"uključivanje ili isključivanje telefona"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Aplikaciji omogućuje uključivanje i isključivanje tabletnog računala."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index b313efb..8343bb3 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"A táblagép tárhelye tele van. Szabadítson fel helyet néhány fájl törlésével."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"A telefon tárhelye megtelt. Hely felszabadításához töröljön néhány fájlt."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Lehet, hogy a hálózat felügyelt"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Ismeretlen harmadik fél által"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Megfigyelő: <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Saját"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Táblagép beállításai"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefonbeállítások"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index d3b8762..97643c9 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Գրասալիկի պահոցը լիքն է: Ջնջեք մի քանի ֆայլ` տարածք ազատելու համար:"</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Հեռախոսի պահոցը լիքն է: Ջնջեք մի քանի ֆայլեր` տարածություն ազատելու համար:"</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Ցանցը կարող է վերահսկվել"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Անհայտ երրորդ կողմի կողմից"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g>-ի կողմից"</string>
     <string name="me" msgid="6545696007631404292">"Իմ"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Գրասալիկի ընտրանքները"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Հեռախոսի ընտրանքներ"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Թույլ է տալիս հավելվածին կառավարել WiFi ցուցադրիչների ցածր մակարդակի գործառույթները:"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"պահել աուդիո արտածումը"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Թույլ է տալիս ծրագրին պահել և վերահղել աուդիո արտածումը:"</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Թեժ բառի հայտնաբերում"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Հավելվածին թույլ է տալիս որսալ ձայնանյութը՝ թեժ բառի հայտնաբերման համար: Դա կարող է տեղի ունենալ հետնաշերտում, սակայն չի խանգարի այլ աուդիո ձայնագրություններին (օր.՝ Տեսախցիկից):"</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"պահել վիդեո արտածումը"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Թույլ է տալիս ծրագրին պահել և վերահղել վիդեո արտածումը:"</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"պահել անվտանգ վիդեո արտածումը"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"կանխել հեռախոսի քնի ռեժիմին անցնելը"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Թույլ է տալիս հավելվածին կանխել գրասալիկի` քնի ռեժիմին անցնելը:"</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Թույլ է տալիս հավելվածին կանխել հեռախոսի` քնի ռեժիմին անցնելը:"</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"փոխանցել ինֆրակարմիր հաղորդիչով"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Հավելվածին թույլ է տալիս օգտագործել գրասալիկի ինֆրակարմիր հաղորդիչը:"</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Հավելվածին թույլ է տալիս օգտագործել հեռախոսի ինֆրակարմիր հաղորդիչը:"</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"գրասալիկը միացնել կամ անջատել"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"հեռախոսը միացնել կամ անջատել"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Թույլ է տալիս հավելվածին միացնել կամ անջատել գրասալիկը:"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 078fb0c..6de81ac 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -481,10 +481,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Izinkan aplikasi mengontrol fitur tingkat rendah dari tampilan Wi-Fi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"tangkap keluaran audio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Memungkinkan aplikasi menangkap dan mengalihkan keluaran audio."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Deteksi kata cepat"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Memungkinkan aplikasi menangkap audio untuk deteksi Kata Cepat. Penangkapan dapat berlangsung di latar belakang namun tidak akan mencegah penangkapan audio yang lain (misalnya Perekam video)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"tangkap keluaran video"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Memungkinkan aplikasi menangkap dan mengalihkan keluaran video."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"tangkap keluaran video aman"</string>
@@ -552,12 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"mencegah ponsel menjadi tidak aktif"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Mengizinkan apl mencegah tablet tidur."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Mengizinkan apl mencegah ponsel tidur."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"pancarkan inframerah"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Memungkinkan aplikasi menggunakan pemancar inframerah tablet."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Memungkinkan aplikasi menggunakan pemancar inframerah ponsel."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"hidupkan atau matikan tablet"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"daya ponsel hidup atau mati"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Mengizinkan apl menyalakan atau mematikan tablet."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 613715b..5ae7c5f 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Spazio di archiviazione del tablet esaurito. Elimina alcuni file per liberare spazio."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Spazio di archiviazione del telefono esaurito. Elimina alcuni file per liberare spazio."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"La rete potrebbe essere monitorata"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Da una terza parte sconosciuta"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Da <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Io"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opzioni tablet"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Opzioni telefono"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index f01dd94..b9eecd0 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"שטח האחסון של הטבלט מלא. מחק קבצים כדי לפנות מקום."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"שטח האחסון של הטלפון מלא. מחק חלק מהקבצים כדי לפנות שטח."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ייתכן שהרשת מנוטרת"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"על ידי צד שלישי לא מוכר"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"על ידי <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"אני"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"אפשרויות טאבלט"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"אפשרויות טלפון"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"מאפשר לאפליקציה לשלוט בתכונות ברמה נמוכה של תצוגות Wi-Fi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"קליטת פלט אודיו"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"מאפשרת לאפליקציה לקלוט ולהפנות מחדש פלט אודיו."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"זיהוי של מילת הפעלה"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"מאפשרת לאפליקציה לקלוט אודיו עבור זיהוי של מילת הפעלה. פעולת הקליטה יכולה להתבצע ברקע, אבל לא מונעת קליטת אודיו אחרת (למשל, במצלמת הווידאו)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"קליטת פלט וידאו"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"מאפשרת לאפליקציה לקלוט ולהפנות מחדש פלט וידאו."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"קליטת פלט וידאו מאובטח"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"מניעת מעבר הטלפון למצב שינה"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"מאפשר ליישום למנוע מהטבלט לעבור למצב שינה."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"מאפשר ליישום למנוע מהטלפון לעבור למצב שינה."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"שידור באינפרא-אדום"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"מאפשרת לאפליקציה להשתמש במשדר האינפרא-אדום של הטאבלט."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"מאפשרת לאפליקציה להשתמש במשדר האינפרא-אדום של הטלפון."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"הפעלה או כיבוי של טאבלט"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"הפעל או כבה את הטלפון"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"מאפשר ליישום להפעיל או לכבות את הטבלט."</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 3ad4d5a..c2401bc 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -481,10 +481,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Wi-Fiディスプレイの低レベル機能を制御することをアプリに許可します。"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"音声出力のキャプチャ"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"音声出力のキャプチャとリダイレクトをアプリに許可します。"</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"注目ワード検出"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"注目ワード検出での音声キャプチャをアプリに許可します。キャプチャはバックグラウンドで発生しますが、その他の音声キャプチャ(例: ビデオ録画)を妨げることはありません。"</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"動画出力のキャプチャ"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"動画出力のキャプチャとリダイレクトをアプリに許可します。"</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"セキュリティ保護された動画出力のキャプチャ"</string>
@@ -552,12 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"端末のスリープを無効にする"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"タブレットのスリープを無効にすることをアプリに許可します。"</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"携帯端末のスリープを無効にすることをアプリに許可します。"</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"赤外線の送信"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"タブレットの赤外線送信機能の使用をアプリに許可します。"</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"携帯電話の赤外線送信機能の使用をアプリに許可します。"</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"タブレットの電源ON/OFF"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"電源のON/OFF"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"タブレットの電源のON/OFFをアプリに許可します。"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 56d18d3..e4e5f92 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -481,10 +481,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"აპს შეეძლება აკონტროლოს Wifi ეკრანების დაბალი დონის ფუნქციები."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"გამომავალი აუდიოს დაჭერა"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"საშუალებას აძლევს აპს დაიჭიროს და გადაამისამართოს გამომავალი აუდიო."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"ჯადოსნური სიტყვის პოვნა"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"საშუალებას აძლევს აპს ჩაიწეროს აუდიო ჯადოსნნური სიტყვების ამოცნობისათვის. ჩაწერა შესაძლოა განხორციელდეს ფონურად, თუმცა ხელს არ უშლის სხვა სახის აუდიოს ჩაწერას (მაგ. ვიდეოჩამწერიდან)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"გამომავალი ვიდეოს დაჭერა"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"საშუალებას აძლევს აპს დაიჭიროს და გადაამისამართოს გამომავალი ვიდეო."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"გამომავალი დაცული ვიდეოს დაჭერა"</string>
@@ -552,12 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ტელეფონის ძილის რეჟიმში გადასვლის აღკვეთა"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"აპს შეეძლება ხელი შეუშალოს ტაბლეტის დაძინებას."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"აპს შეეძლება ხელი შეუშალოს ტელეფონის დაძინებას."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"ინფრაწითელით გადაცემა"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"რთავს ნებას აპს გამოიყენოს ტაბლეტის ინფრაწითელი გადამცემი."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"რთავს ნებას აპს გამოიყენოს ტელეფონის ინფრაწითელი გადამცემი."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ტაბლეტის ჩართვა ან გამორთვა"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"ტელეფონის ჩართვა ან გამორთვა"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"აპს შეეძლება, ჩართოს ან გამორთოს ტაბლეტი."</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 4c131f5..f56d261 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"ឧបករណ៍​ផ្ទុក​នៃ​​កុំព្យូទ័រ​បន្ទះ​ពេញ។ លុប​ឯកសារ​មួយ​ចំនួន​។"</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"ឧបករណ៍​ផ្ទុក​ទូរស័ព្ទ​ពេញ! លុប​ឯកសារ​មួយ​ចំនួន​ដើម្បី​បង្កើន​ទំហំ។"</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"បណ្ដាញ​អាច​ត្រូវ​បាន​តាមដាន"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"ដោយ​ភាគី​ទីបី​ដែល​មិន​ស្គាល់"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"ដោយ <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"ខ្ញុំ"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ជម្រើស​កុំព្យូទ័រ​បន្ទះ"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"ជម្រើស​ទូរស័ព្ទ"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"ឲ្យ​កម្មវិធី​ពិនិត្យ​លក្ខណៈ​កម្រិត​ទាប​​នៃ​ការ​បង្ហាញ​វ៉ាយហ្វាយ។"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ចាប់​យក​លទ្ធផល​អូឌីយ៉ូ"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"​ឱ្យ​កម្មវិធី​ដើម្បី​ចាប់​យក​ និង​​ប្ដូរ​​ទិស​លទ្ធផល​អូឌីយ៉ូ​។"</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"ការ​រក​ឃើញ​ពាក្យ"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"ឲ្យ​កម្មវិធី​​ថត​អូឌីយ៉ូ​សម្រាប់​កា​រ​រក​ឃើញ​ពាក្យ។​ ការ​ថត​អាច​កើត​ឡើង​ក្នុង​ផ្ទៃ​ខាងក្រោយ​​ ប៉ុន្តែ​មិន​រារាំង​ការ​ថត​អូឌីយ៉ូ​ផ្សេង​ទេ (ឧ. ម៉ាស៊ីន​ថត​វីដេអូ)។"</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"ចាប់​យក​លទ្ធផល​វីដេអូ"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"ឲ្យ​កម្មវិធី​ចាប់​យក​ និង​ប្ដូរ​​ទិស​លទ្ធផល​វីដេអូ​។"</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"ចាប់​យក​លទ្ធផល​វីដេអូ​សុវត្ថិភាព"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ការ​ពារ​ទូរស័ព្ទ​មិន​ឲ្យ​ដេក"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ឲ្យ​​កម្មវិធី​ការពារ​កុំព្យូទ័រ​បន្ទះ​មិន​ឲ្យ​ដេក។"</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"ឲ្យ​កម្មវិធី​ការពារ​ទូរស័ព្ទ​មិន​ឲ្យ​ដេក។"</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"បញ្ជូន​អ៊ីនហ្វ្រា​រ៉េ​ដ"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"ឲ្យ​កម្មវិធី​ប្រើ​កម្មវិធី​បញ្ជូន​​អ៊ីនហ្វ្រា​រ៉េ​ដ​​របស់​កុំព្យូទ័រ​បន្ទះ។"</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"ឲ្យ​កម្មវិធី​ប្រើ​កម្មវិធី​បញ្ជូន​តាម​អ៊ីនហ្វ្រា​រ៉េ​ដ​​របស់​ទូរស័ព្ទ។"</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"បិទ/បើក​កុំព្យូទ័រ​បន្ទះ"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"បិទ/បើក​ទូរស័ព្ទ"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"ឲ្យ​កម្មវិធី​បិទ/បើក​កុំព្យូទ័រ​បន្ទះ។"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 21e343f..41e66ce 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -481,10 +481,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"앱이 Wi-Fi 디스플레이의 하위 수준 기능을 제어하도록 허용합니다."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"오디오 출력 캡처"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"앱이 오디오 출력을 캡처하고 리디렉션하도록 허용합니다."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"핫워드 감지"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"앱에서 핫워드 감지를 위해 오디오를 캡처하도록 허용합니다. 캡처는 백그라운드에서 수행될 수 있지만 다른 오디오 캡처를 차단하지 않습니다(예: 캠코더)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"동영상 출력 캡처"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"앱이 동영상 출력을 캡처하고 리디렉션하도록 허용합니다."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"안전한 동영상 출력 캡처"</string>
@@ -552,12 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"휴대전화가 절전 모드로 전환되지 않도록 설정"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"앱이 태블릿의 절전 모드 전환을 막도록 허용합니다."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"앱이 휴대전화의 절전 모드 전환을 막도록 허용합니다."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"적외선 전송"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"앱에서 태블릿의 적외선 송신기를 사용하도록 허용합니다."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"앱에서 휴대전화의 적외선 송신기를 사용하도록 허용합니다."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"태블릿 전원 켜고 끄기"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"휴대전화 전원 켜고 끄기"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"앱이 태블릿을 켜거나 끌 수 있도록 허용합니다."</string>
@@ -685,7 +680,7 @@
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"기기 전체 프록시 설정"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"정책이 사용 설정되어 있는 동안 사용될 기기 전체 프록시를 설정합니다. 첫 번째 기기 관리자가 설정한 전체 프록시만 유효합니다."</string>
     <string name="policylab_expirePassword" msgid="885279151847254056">"화면 잠금 비밀번호 만료 설정"</string>
-    <string name="policydesc_expirePassword" msgid="1729725226314691591">"화면 잠금 비밀번호 변경 빈도 설정"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"화면 잠금 비밀번호 변경 빈도를 설정합니다."</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"저장소 암호화 설정"</string>
     <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"저장한 애플리케이션 데이터를 암호화해야 합니다."</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"카메라 사용 안함"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index e8cd4e2..9d088f6 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"ພື້ນທີ່ຈັດເກັບຂໍ້ມູນໃນແທັບເລັດເຕັມ. ລຶບບາງໄຟລ໌ອອກເພື່ອເພີ່ມພື້ນທີ່ຫວ່າງ."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"ພື້ນທີ່ໃນໂທລະສັບເຕັມແລ້ວ. ກະລຸນາລຶບບາງໄຟລ໌ອອກເພື່ອເພີ່ມພື້ນທີ່ຫວ່າງ."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ການນຳໃຊ້ເຄືອຂ່າຍອາດມີການກວດສອບຕິດຕາມ"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"ໂດຍບຸກຄົນທີສາມທີ່ບໍ່ຮູ້ຈັກ"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"ໂດຍ <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"ຂ້າພະເຈົ້າ"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ໂຕເລືອກແທັບເລັດ"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"ໂຕເລືອກໂທລະສັບ"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"ອະນຸຍາດໃຫ້ແອັບຯ ຄວບຄຸມຄວາມສາມາດລະດັບຕໍ່າຂອງການສະແດງຜົນ Wifi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ບັນທຶກສຽງອອກ"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"ອະນຸຍາດໃຫ້ແອັບຯບັນທຶກ ແລະປ່ຽນເສັ້ນທາງການປ້ອນຂໍ້ມູນອອກຂອງສຽງ."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"ການກວດຫາ Hotword"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"ອະນຸຍາດໃຫ້ແອັບຯຈັບຂໍ້ມູນສຽງສຳລັບການກວດຈັບ Hotword. ການຈັບຂໍ້ມູນສາມາດເກີດຂຶ້ນໃນພື້ນຫຼັງໄດ້ ແຕ່ຈະບໍ່ໄປຂັດຂວາງການຈັບຂໍ້ມູນສຽງອື່ນໆ (ເຊັ່ນ: ກ້ອງວິດີໂອ)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"ບັນທຶກວິດີໂອອອກ"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"ອະນຸຍາດໃຫ້ແອັບຯບັນທຶກ ແລະປ່ຽນເສັ້ນທາງການປ້ອນຂໍ້ມູນອອກຂອງວິດີໂອ."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"ບັນທຶກວິດີໂອອອກຢ່າງປອດໄພ"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ຂັດຂວາງບໍ່ໃຫ້ໂທລະສັບປິດໜ້າຈໍ"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ອະນຸຍາດໃຫ້ແອັບຯ ປ້ອງກັນບໍ່ໃຫ້ປິດໜ້າຈໍແທັບເລັດ."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"ອະນຸຍາດໃຫ້ແອັບຯປ້ອງກັນບໍ່ໃຫ້ປິດໜ້າຈໍໂທລະສັບ."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"ສົ່ງອິນຟຣາເຣດ"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"ອະນຸຍາດໃຫ້ແອັບຯໃຊ້ການສົ່ງອິນຟຣາເຣດຂອງແທັບເລັດໄດ້."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"ອະນຸຍາດໃຫ້ແອັບຯໃຊ້ການສົ່ງອິນຟຣາເຣດຂອງໂທລະສັບໄດ້."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ເປີດ ຫຼືປິດແທັບເລັດ"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"ເປີດ ຫຼືປິດໂທລະສັບ"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"ອະນຸຍາດໃຫ້ແອັບຯເປີດ ຫຼືປິດແທັບເລັດ."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index ff2079a..c575a21 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Planšetinio kompiuterio atmintis pilna. Kad atlaisvintumėte vietos, ištrinkite kelis failus."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Telefono atmintis pilna. Ištrinkite kai kuriuos failus, kad atlaisvintumėte vietos."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Tinklas gali būti stebimas"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Nežinoma trečioji šalis"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Aš"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Planšetinio kompiuterio parinktys"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefono parinktys"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Leidžiama programai valdyti „Wi-Fi“ pateikčių žemo lygio funkcijas."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"fiksuoti garso išvestį"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Programai leidžiama fiksuoti ir peradresuoti garso išvestį."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Aktyvinamųjų žodžių aptikimas"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Programai leidžiama įrašyti garsą, kad būtų galima aptikti aktyvinamuosius žodžius. Įrašymas gali būti vykdomas fone, bet tai netrikdo kitų garso įrašymo veiksmų (pvz., įrašymo vaizdo kamera)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"fiksuoti vaizdo išvestį"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Programai leidžiama fiksuoti ir peradresuoti vaizdo išvestį."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"fiksuoti saugią vaizdo išvestį"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"neleisti telefonui snausti"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Leidžiama programai neleisti planšetiniam kompiuteriui užmigti."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Leidžiama programai neleisti telefonui užmigti."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"perduoti duomenis infraraudonaisiais spinduliais"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Programai leidžiama naudoti planšetinio kompiuterio infraraudonųjų spindulių perdavimo įrenginį."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Programai leidžiama naudoti telefono infraraudonųjų spindulių perdavimo įrenginį."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"įjungti arba išjungti planšetinį kompiuterį"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"telefono įjungimas ir išjungimas"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Leidžiama programai įjungti ar išjungti planšetinį kompiuterį."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 55dece8..0dda696 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Planšetdatora atmiņa ir pilna. Dzēsiet dažus failus, lai atbrīvotu vietu."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Tālruņa atmiņa ir pilna! Dzēsiet dažus failus, lai atbrīvotu vietu."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Iespējams, tīklā veiktās darbības tiek pārraudzītas."</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Nezināma trešā puse"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Domēns <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Man"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Planšetdatora opcijas"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Tālruņa opcijas"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Ļauj lietotnei kontrolēt zema līmeņa funkcijas Wi-Fi displejos."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"tvert audio izvadi"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Ļauj lietotnei tvert un novirzīt audio izvadi."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Īsinājumvārda noteikšana"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Ļauj lietotnei tvert audio īsinājumvārda noteikšanai. Tveršana var notikt fonā, taču tā neaizkavē citu audio (piemēram, videokameras audio) tveršanu."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"tvert video izvadi"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Ļauj lietotnei tvert un novirzīt video izvadi."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"tvert drošu video izvadi"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"novērst tālruņa pāriešanu miega režīmā"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Ļauj lietotnei novērst planšetdatora pāriešanu miega režīmā."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Ļauj lietotnei novērst tālruņa pāriešanu miega režīmā."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"pārraidīt infrasarkano staru signālu"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Ļauj lietotnei izmantot planšetdatora infrasarkano staru signāla raidītāju."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Ļauj lietotnei izmantot tālruņa infrasarkano staru signāla raidītāju."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ieslēgt vai izslēgt planšetdatoru"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"ieslēgt vai izslēgt tālruni"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Ļauj lietotnei ieslēgt vai izslēgt planšetdatoru."</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index e50854d..b456d3e 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Таблетийн сан дүүрсэн. Зай чөлөөлөх бол зарим файлыг устгана уу."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Утасны сан дүүрсэн. Зай чөлөөлөх бол зарим файлыг устгана уу."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Сүлжээ хянагдаж байж болзошгүй"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Тодорхойгүй гуравдагч талаас"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g>-с"</string>
     <string name="me" msgid="6545696007631404292">"Би"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Таблетын сонголтууд"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Утасны сонголт"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Апп нь Wifi дэлгэцний доод-төвшиний функцийг удирдах боломжтой."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"аудио гаралтыг барих"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Апп-т аудио гаралтыг барих, дахин чиглүүлэхийг зөвшөөрнө."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Хотворд таних"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Апп-д Хотворд илрүүлэхийн тулд аудиог бичихийг зөвшөөрнө. Бичилт далд хийгдэх бөгөөд бусад аудио бичилтэд (жнь. видео бичлэг) саад болохгүй."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"видео гаралтыг барих"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Апп-т видео гаралтыг барих, дахин чиглүүлэхийг зөвшөөрнө."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"найдвартай видео гаралтыг барих"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"утсыг унтуулахгүй байлгах"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Апп нь таблетыг унтахаас сэргийлэх боломжтой"</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Апп нь утсыг унтахаас сэргийлэх боломжтой"</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"хэт улаанаар дамжуулах"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Апп-д таблетын хэт улаан дамжуулагчийг ашиглахыг зөвшөөрнө."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Апп-д утасны хэт улаан дамжуулагчийг ашиглахыг зөвшөөрнө."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"таблетыг унтраах эсвэл асаах"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"утсыг унтраах эсвэл асаах"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Апп нь таблетыг асаах, унтраах боломжтой."</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 1fed75d..b266591 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -481,10 +481,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Membenarkan apl mengawal ciri tahap rendah paparan Wifi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"tangkap output audio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Membenarkan apl menangkap dan mengubah hala output audio."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Pengesanan sebutan laluan"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Benarkan apl merakam audio untuk pengesahan Sebutan Laluan. Rakaman ini boleh berlaku di latar belakang tetapi tidak menghalang rakaman audio lain (cth. Kamkorder)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"tangkap output video"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Membenarkan apl menangkap dan mengubah hala output video."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"tangkap output video selamat"</string>
@@ -552,12 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"halang telefon daripada tidur"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Membenarkan apl menghalang tablet daripada tidur."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Membenarkan apl menghalang telefon daripada tidur."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"hantar inframerah"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Membenarkan apl menggunakan pemancar inframerah tablet."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Membenarkan apl menggunakan pemancar inframerah telefon."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"menghidupkan atau mematikan kuasa tablet"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"kuasakan telefon hidup atau mati"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Membenarkan apl menghidupkan atau mematikan tablet."</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 625fb38..c0d58aa 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Nettbrettlageret er fullt. Slett noen filer for å frigjøre lagringsplass."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Telefonlageret er fullt. Slett noen filer for å frigjøre lagringsplass."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Nettverket blir muligens overvåket"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Av en ukjent tredjepart"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Av <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Meg"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Innstillinger for nettbrettet"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefoninnstillinger"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index bd45ddc..3a97f95 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Tabletgeheugen is vol. Verwijder enkele bestanden om ruimte vrij te maken."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Telefoongeheugen is vol. Verwijder enkele bestanden om ruimte vrij te maken."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Netwerk kan worden gecontroleerd"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Door een onbekende derde partij"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Door <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Ik"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tabletopties"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefoonopties"</string>
@@ -441,12 +439,12 @@
     <string name="permlab_writeContacts" msgid="5107492086416793544">"uw contacten aanpassen"</string>
     <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op uw tablet, inclusief de frequentie waarmee u heeft gebeld, gemaild of op andere manieren heeft gecommuniceerd met specifieke contacten. Met deze toestemming kunnen apps contactgegevens verwijderen."</string>
     <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op uw telefoon, inclusief de frequentie waarmee u heeft gebeld, gemaild of op andere manieren heeft gecommuniceerd met specifieke contacten. Met deze toestemming kunnen apps contactgegevens verwijderen."</string>
-    <string name="permlab_readCallLog" msgid="3478133184624102739">"oproeplogboek lezen"</string>
-    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Hiermee kan de app het oproeplogboek van uw tablet lezen, inclusief gegevens over inkomende en uitgaande oproepen. Met deze toestemming kunnen apps uw oproeploggegevens opslaan, en schadelijke apps kunnen logoproepgegevens zonder uw medeweten delen."</string>
-    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Hiermee kan de app het oproeplogboek van uw telefoon lezen, inclusief gegevens over inkomende en uitgaande oproepen. Met deze toestemming kunnen apps uw oproeploggegevens opslaan, en schadelijke apps kunnen logoproepgegevens zonder uw medeweten delen."</string>
-    <string name="permlab_writeCallLog" msgid="8552045664743499354">"oproeplogboek schrijven"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Toestaan dat de app het oproeplogboek van uw tablet aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee uw oproeplogboek wissen of aanpassen."</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Toestaan dat de app het oproeplogboek van uw telefoon aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee uw oproeplogboek wissen of aanpassen."</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"gesprekkenlijst lezen"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Hiermee kan de app het gesprekkenlijst van uw tablet lezen, inclusief gegevens over inkomende en uitgaande oproepen. Met deze toestemming kunnen apps uw oproeploggegevens opslaan, en schadelijke apps kunnen logoproepgegevens zonder uw medeweten delen."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Hiermee kan de app het gesprekkenlijst van uw telefoon lezen, inclusief gegevens over inkomende en uitgaande oproepen. Met deze toestemming kunnen apps uw oproeploggegevens opslaan, en schadelijke apps kunnen logoproepgegevens zonder uw medeweten delen."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"gesprekkenlijst schrijven"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Toestaan dat de app het gesprekkenlijst van uw tablet aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee uw gesprekkenlijst wissen of aanpassen."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Toestaan dat de app het gesprekkenlijst van uw telefoon aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee uw gesprekkenlijst wissen of aanpassen."</string>
     <string name="permlab_readProfile" msgid="4701889852612716678">"uw eigen contactkaart lezen"</string>
     <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Hiermee kan de app persoonlijke profielgegevens lezen die op uw apparaat zijn opgeslagen, zoals uw naam en contactgegevens. Dit betekent dat de app u kan identificeren en uw profielgegevens naar anderen kan verzenden."</string>
     <string name="permlab_writeProfile" msgid="907793628777397643">"uw eigen contactkaart aanpassen"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"De app toestaan minder belangrijke functies van wifi-displays te beheren."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"audio-uitvoer vastleggen"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Hiermee kan de app audio-uitvoer vastleggen en verwerken."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Detectie van hotwords"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Hiermee kan de app audio opnemen voor het detecteren van hotwords. Het opnemen kan op de achtergrond plaatsvinden, maar voorkomt niet dat andere audio wordt opgenomen (bijvoorbeeld in Camcorder)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"video-uitvoer vastleggen"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Hiermee kan de app video-uitvoer vastleggen en verwerken."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"beveiligde video-uitvoer vastleggen"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"voorkomen dat telefoon overschakelt naar slaapmodus"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Hiermee kan de app voorkomen dat de tablet overschakelt naar de slaapmodus."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Hiermee kan de app voorkomen dat de telefoon overschakelt naar de slaapmodus."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"infrarood verzenden"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Hiermee kan de app de infraroodzender van de tablet gebruiken."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Hiermee kan de app de infraroodzender van de telefoon gebruiken."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"tablet in- of uitschakelen"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"telefoon in- of uitschakelen"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Hiermee kan de app de tablet in- of uitschakelen."</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 8c7f072..3196373 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Pamięć tabletu jest pełna. Usuń niektóre pliki, aby zwolnić miejsce."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Pamięć telefonu jest pełna. Usuń niektóre pliki, aby zwolnić miejsce."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Sieć może być monitorowana"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Przez nieznaną firmę zewnętrzną"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Przez <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Ja"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opcje tabletu"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Opcje telefonu"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Zezwala aplikacji na zarządzanie niskopoziomowymi funkcjami wyświetlaczy Wi-Fi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"przechwyć wyjście audio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Zezwala aplikacji na przechwytywanie i przekierowywanie wyjścia audio."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Wykrywanie słów-kluczy"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Umożliwia aplikacji przechwytywanie dźwięku w celu wykrywania słów-kluczy. Może się to odbywać w tle i nie uniemożliwia innego przechwytywania dźwięku (np. z kamery)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"przechwyć wyjście wideo"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Zezwala aplikacji na przechwytywanie i przekierowywanie wyjścia wideo."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"przechwyć bezpieczne wyjście wideo"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"zapobieganie przejściu telefonu w stan uśpienia"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Pozwala aplikacji na zapobieganie przechodzeniu tabletu do trybu uśpienia."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Pozwala aplikacji na zapobieganie przechodzeniu telefonu w tryb uśpienia."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"przesyłanie w podczerwieni"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Zezwala aplikacji na używanie nadajnika podczerwieni w tablecie."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Zezwala aplikacji na używanie nadajnika podczerwieni w telefonie."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"włączenie lub wyłączenie tabletu"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"włączanie lub wyłączanie telefonu"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Pozwala aplikacji na włączanie i wyłączanie tabletu."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 4b6c7fa..3a86f55 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"O armazenamento do tablet está cheio. Exclua alguns arquivos para liberar espaço."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"O armazenamento do telefone está cheio. Exclua alguns arquivos para liberar espaço."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"A rede pode ser monitorada"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Por terceiros desconhecidos"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Por <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Eu"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opções do tablet"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Opções do telefone"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite que o aplicativo controle recursos de baixo nível de monitores Wi-Fi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"capturar saída de áudio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Permite que o aplicativo capture e redirecione a saída de áudio."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Detecção de hotwords"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Permite que o dispositivo capture áudio para a detecção de hotwords. A captura pode acontecer em segundo plano, mas não impede outras capturas de áudio (como por uma câmera de vídeo)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"capturar saída de vídeo"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Permite que o aplicativo capture e redirecione a saída de vídeo."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"capturar saída de vídeo segura"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"impedir modo de inatividade do telefone"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permite que o aplicativo impeça o tablet de entrar no modo de inatividade."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Permite que o aplicativo impeça o telefone de entrar no modo de inatividade."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"transmitir infravermelhos"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Permite que o aplicativo use o transmissor infravermelho do tablet."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Permite que o aplicativo use o transmissor infravermelho do telefone."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ligar ou desligar o tablet"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"ligar ou desligar o telefone"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Permite que o aplicativo ative ou desative o tablet."</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 75b0924..9842414 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -481,10 +481,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite aplicaţiei să controleze funcţiile de nivel redus ale afişajelor Wi-Fi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"să intercepteze ieșirea audio"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Permite aplicației să intercepteze și să redirecționeze ieșirea audio."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"detectarea expresiei de activare"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Activează captarea semnalului audio de către aplicație pentru detectarea expresiei de activare. Captarea poate avea loc în fundal, dar nu împiedică altă captare audio (de ex., cameră video)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"să intercepteze ieșirea video"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Permite aplicației să intercepteze și să redirecționeze ieșirea video."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"să intercepteze ieșirea video securizată"</string>
@@ -552,12 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"împiedicare intrare telefon în repaus"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permite aplicaţiei să împiedice intrarea tabletei în stare de repaus."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Permite aplicaţiei să împiedice intrarea telefonului în stare de repaus."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"transmisie prin infraroșii"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Permite aplicației să utilizeze transmițătorul prin infraroșii al tabletei."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Permite aplicației să utilizeze transmițătorul prin infraroșii al telefonului."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"pornire sau oprire computer tablet PC"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"telefon pornit sau oprit"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Permite aplicaţiei să pornească sau să oprească tableta."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index f710219..e96a40d 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -481,10 +481,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Приложение сможет управлять низкоуровневыми функциями экранов, подключенных через Wi-Fi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"захват аудиосигнала"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Приложение сможет захватывать и перенаправлять аудиосигнал."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"распознавать голосовые команды"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Приложение сможет анализировать звук для распознавания голосовых команд. Этот процесс выполняется в фоновом режиме и не мешает другим операциям (например, записи видеоролика)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"захват видеосигнала"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Приложение сможет захватывать и перенаправлять видеосигнал."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"захват защищенного видеосигнала"</string>
@@ -552,12 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"Отключение спящего режима"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Приложение сможет запрещать перевод планшетного ПК в спящий режим."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Приложение сможет запрещать перевод телефона в спящий режим."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"использовать инфракрасный передатчик"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Приложение сможет использовать инфракрасный передатчик планшетного ПК."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Приложение сможет использовать инфракрасный передатчик телефона."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"Включение/выключение планшета"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"Включение/выключение телефона"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Приложение сможет включать и выключать планшетный ПК."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 500ced4..d944031 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -481,10 +481,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Umožňuje aplikácii ovládať základné funkcie displejov cez siete Wi-Fi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"zachytiť výstup zvuku"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Umožňuje aplikácii zachytiť a presmerovať výstup zvuku."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Rozpoznanie kľúčových slov"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Umožňuje aplikácii zaznamenať zvuk s cieľom rozpoznať kľúčové slová. Záznam sa môže uskutočniť na pozadí a nebráni inému zaznamenávaniu zvuku (napríklad videokamerou)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"zachytiť výstup videa"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Umožňuje aplikácii zachytiť a presmerovať výstup videa."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"zachytiť zabezpečený výstup videa"</string>
@@ -552,12 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"zabránenie prechodu telefónu do režimu spánku"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Umožňuje aplikácii zabrániť prechodu tabletu do režimu spánku."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Umožňuje aplikácii zabrániť prechodu telefónu do režimu spánku."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"infračervený prenos"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Umožňuje aplikácii používať infračervený vysielač tabletu."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Umožňuje aplikácii používať infračervený vysielač telefónu."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"zapnutie a vypnutie tabletu"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"zapnutie a vypnutie telefónu"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Umožňuje aplikácii zapnúť a vypnúť tablet."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 1374366..b047c1a9 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Pomnilnik tabličnega računalnika je poln. Izbrišite nekaj datotek, da sprostite prostor."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Pomnilnik telefona je poln. Izbrišite nekaj datotek, da sprostite prostor."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Omrežje je lahko nadzorovano"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Neznana tretja oseba"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Nadzira: <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Jaz"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Možnosti tabličnega računalnika"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Možnosti telefona"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Omogoča aplikaciji nadzor osnovnih funkcij zaslonov Wi-Fi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"zajem avdioizhoda"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Omogoči aplikaciji, da zajame in preusmeri avdioizhod."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Zaznavanje sprožilnih besed"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Aplikaciji dovoljuje snemanje zvoka za zaznavanje sprožilnih besed. Snemanje je možno tudi v ozadju, ne preprečuje pa drugega snemanja zvoka (npr. z videokamero)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"zajem videoizhoda"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Omogoči aplikaciji, da zajame in preusmeri videoizhod."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"zajem varnega videoizhoda"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"preprečevanje prehoda v stanje pripravljenosti telefona"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Omogoča, da program prepreči prehod tabličnega računalnika v stanje pripravljenosti."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Programu omogoča, da v telefonu prepreči prehod v stanje pripravljenosti."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"prenašanje z infrardečim oddajnikom"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Aplikaciji dovoljuje uporabo infrardečega oddajnika tabličnega računalnika."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Aplikaciji dovoljuje uporabo infrardečega oddajnika telefona."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"vklop ali izklop tabličnega računalnika"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"vklop ali izklop telefona"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Programu omogoča vklop ali izklop tabličnega računalnika."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index f119865..7480afd 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Меморија таблета је пуна! Избришите неке датотеке да бисте ослободили простор."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Складиште телефона је пуно! Избришите неке датотеке како бисте ослободили простор."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Мрежа се можда надгледа"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Од стране непознате треће стране"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Од стране <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Ја"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Опције за таблет"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Опције телефона"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Дозвољава апликацији да контролише функције Wi-Fi екрана ниског нивоа."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"снимање аудио садржаја"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Дозвољава апликацији да снима и преусмерава аудио садржај."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Откривање актуелних речи"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Дозвољава апликацији да снима звук за откривање актуелних речи. Снимање може да се дешава у позадини, али не спречава друга снимања звука (нпр. камкордер)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"снимање видео садржаја"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Дозвољава апликацији да снима и преусмерава видео садржај."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"снимање безбедног видео садржаја"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"спречавање преласка телефона у стање спавања"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Дозвољава апликацији да спречи таблет да пређе у стање спавања."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Дозвољава апликацији да спречи телефон да пређе у стање спавања."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"пренос инфрацрвених зрака"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Дозвољава апликацији да користи одашиљач инфрацрвених зрака таблета."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Дозвољава апликацији да користи одашиљач инфрацрвених зрака телефона."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"укључивање или искључивање таблета"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"укључивање или искључивање телефона"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Дозвољава апликацији да укључује или искључује таблет."</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 40405ae..2c04831 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Pekdatorns lagringsutrymme är fullt. Ta bort några filer för att frigöra utrymme."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Mobilens lagringsutrymme är fullt. Ta bort några filer för att frigöra utrymme."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Nätverket kan vara övervakat"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Av en okänd tredje part"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Av <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Jag"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Alternativ för surfplattan"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefonalternativ"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 851e6b6..2049364 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Hifadhi ya kompyuta kibao imejaa. Futa baadhi ya faili ili kupata nafasi."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Hifadhi ya simu imejaa. Futa baadhi ya faili ili uweze kupata nafasi."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Mtandao unaweza kufuatiliwa"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Na mtu mwingine asiyejulikana"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Na <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Mimi"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Chaguo za kompyuta ndogo"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Machaguo ya simu"</string>
@@ -452,7 +450,7 @@
     <string name="permlab_writeProfile" msgid="907793628777397643">"rekebisha kadi yako mwenyewe ya mawasiliano"</string>
     <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Inaruhusu programu kubadilisha au kuongeza taarifa ya maelezo mafupi ya kibinafsi yaliyohifadhiwa kwenye kifaa chako, kama vile jina lako na taarifa ya anwani. Hii inamaanisha kuwa programu inaweza kukutambua na inaweza kutuma taarifa ya maelezo yako mafupi kwa wengine."</string>
     <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"soma mipasho yako wa kijamii"</string>
-    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Huruhusu programu kufikia na kupatanisha masasisho ya kijamii kutoka kwa marafiki zako. Kuwa makini wakati unashiriki taarifa -- hii huruhusu programu kusoma mawasiliano kati yako na marafiki zako kwenye mitandao ya jamii, bila kujali usiri. Kumbuka: idhini hii haiwezi kutekelezwa kwenye mitandao yote ya jamii."</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Huruhusu programu kufikia na kupatanisha masasisho ya kijamii kutoka kwa marafiki zako. Kuwa makini wakati unashiriki taarifa -- hii huruhusu programu kusoma mawasiliano kati yako na marafiki zako kwenye mitandao jamii, bila kujali usiri. Kumbuka: idhini hii haiwezi kutekelezwa kwenye mitandao yote ya jamii."</string>
     <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"andika kwa mipasho yako wa kijamii"</string>
     <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Huruhusu programu kuonyesha masasisho ya kijamii kutoka kwa marafiki zako. Kuwa makini wakati unashiriki taarifa -- hii inaruhusu programu kutoa ujumbe unaoweza kuonekana kuwa unatoka kwa rafiki. Kumbuka: idhini hii huenda usitekelezwe kwenye mitandao yote ya jamii."</string>
     <string name="permlab_readCalendar" msgid="5972727560257612398">"soma matukio ya kalenda pamoja na maelezo ya siri"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Inaruhusu programu kudhibiti vipengele vya kiwango cha chini vya maonyesho ya Wifi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"nasa sauti"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Inaruhusu programu kunasa na kuelekeza sauti kwingine."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Kutambua neno tekelezi"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Inaruhusu programu kunasa sauti kwa ajili ya utambuzi wa Neno tekelezi. Kunasa kunaweza kukafanyika chinichini lakini hakutazuia unasaji mwingine wa sauti (kwa mfano Kamkoda)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"nasa sauti ya video"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Inaruhusu programu kunasa na kuelekeza video kwingine."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"nasa sauti ya video kwa usalama"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"zuia simu dhidi ya kulala"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Inaruhusu programu kuzuia kompyuta kibao  kwenda kulala."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Inaruhusu programu kuzuia simu isiende kulala."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"sambaza infrared"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Inaruhusu programu kutumia transmita ya infrared ya kompyuta kibao."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Inaruhusu programu kutumia transmita ya infrared ya simu."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"Washa au zima kompyuta kibao"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"washa au zima simu"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Inaruhusu programu kuwasha au kuzima kompyuta kibao."</string>
diff --git a/core/res/res/values-sw600dp-port/refs.xml b/core/res/res/values-sw600dp-port/refs.xml
deleted file mode 100644
index cda38cf..0000000
--- a/core/res/res/values-sw600dp-port/refs.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (c) 2013, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
--->
-<resources>
-    <item type="string" name="transient_navigation_confirmation">@string/transient_navigation_confirmation_long</item>
-</resources>
\ No newline at end of file
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index a19ddaa..a0b0255 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"ที่จัดเก็บข้อมูลของแท็บเล็ตเต็ม ลบไฟล์บางไฟล์เพื่อเพิ่มพื้นที่ว่าง"</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"ที่เก็บข้อมูลโทรศัพท์เต็ม ลบบางไฟล์เพื่อเพิ่มที่ว่าง"</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"เครือข่ายอาจได้รับการตรวจสอบ"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"โดยบุคคลที่สามที่ไม่รู้จัก"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"โดย <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"ฉัน"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ตัวเลือกของแท็บเล็ต"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"ตัวเลือกโทรศัพท์"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"อนุญาตให้แอปควบคุมคุณลักษณะต่างๆ ในระดับล่างของการแสดงผลด้วย WiFi"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"บันทึกเอาต์พุตเสียง"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"อนุญาตให้แอปบันทึกและเปลี่ยนเส้นทางเอาต์พุตเสียง"</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"การตรวจหาคำที่นิยม"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"อนุญาตให้แอปเก็บเสียงสำหรับการตรวจหาคำที่นิยม การเก็บเสียงสามารถดำเนินการอยู่ในพื้นหลัง แต่ไม่เป็นการป้องกันการเก็บเสียงอื่นๆ (เช่น กล้องวิดีโอ)"</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"บันทึกเอาต์พุตวิดีโอ"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"อนุญาตให้แอปบันทึกและเปลี่ยนเส้นทางเอาต์พุตวิดีโอ"</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"บันทึกเอาต์พุตเสียงที่ปลอดภัย"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ป้องกันไม่ให้โทรศัพท์เข้าโหมดสลีป"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"อนุญาตให้แอปพลิเคชันป้องกันไม่ให้แท็บเล็ตเข้าสู่โหมดสลีป"</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"อนุญาตให้แอปพลิเคชันป้องกันไม่ให้โทรศัพท์เข้าสู่โหมดสลีป"</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"ส่งสัญญาณอินฟราเรด"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"อนุญาตให้แอปใช้ตัวส่งสัญญาณอินฟราเรดของแท็บเล็ต"</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"อนุญาตให้แอปใช้ตัวส่งสัญญาณอินฟราเรดของโทรศัพท์"</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"เปิดหรือปิดเครื่องแท็บเล็ต"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"เปิดหรือปิดโทรศัพท์"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"อนุญาตให้แอปพลิเคชันเปิดหรือปิดแท็บเล็ต"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index c357eb4..5b06737 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Puno na ang storage ng tablet. Magtanggal ng ilang file upang magbakante ng espasyo."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Puno na ang storage ng telepono. Magtanggal ng ilang file upang magbakante ng espasyo."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Maaaring sinusubaybayan ang network"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Ng isang di-kilalang third party"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Ng <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Ako"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Mga pagpipilian sa tablet"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Mga pagpipilian sa telepono"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Pinapayagan ang app na magkontrol ng mga tampok sa mababang antas ng mga dispay ng Wifi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"kumuha ng audio output"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Pinapayagan ang app na kumuha at mag-redirect ng audio output."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Paghahanap ng hotword"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Nagbibigay-daan sa app na kumuha ng audio na paghahanapan ng Hotword. Maaaring maisagawa sa background ang pagkuha, ngunit hindi nito pipigilan ang iba pang pagkuha ng audio (hal. Camcorder)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"kumuha ng video output"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Pinapayagan ang app na kumuha at mag-redirect ng video output."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"kumuha ng secure na video output"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"pigilan ang telepono mula sa paghinto"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Pinapayagan ang app na pigilan ang tablet mula sa pag-sleep."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Pinapayagan ang app na pigilan ang telepono mula sa pag-sleep."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"magpadala gamit ang infrared"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Nagbibigay-daan sa app na gamitin ang infrared transmitter ng tablet."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Nagbibigay-daan sa app na gamitin ang infrared transmitter ng telepono."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"i-on o i-off ang power tablet"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"i-on o i-off ang telepono"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Pinapayagan ang app na i-on o i-off ang tablet."</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 22a3eef..14f98d7 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -481,10 +481,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Uygulamaya kablosuz ekranların alt düzey özelliklerini kontrol etme izni verir."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ses çıkışını yakala"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Uygulamaya, ses çıkışını yakalayıp yönlendirme izni verir."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Önemli kelime algılama"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Uygulamaya, Özel kelime algılamak için ses yakalama izni verir. Ses yakalama işlemi arka planda yapılabilir, ancak diğer ses yakalama işlemlerini (ör. kameranın ses kaydını) engellemez."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"video çıkışını yakala"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Uygulamaya, video çıkışını yakalayıp yönlendirme izni verir."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"güvenli video çıkışını yakala"</string>
@@ -552,12 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"telefonun uykuya geçmesini önleme"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Uygulamaya, tabletin uykuya geçmesini önleme izni verir."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Uygulamaya, telefonun uykuya geçmesini önleme izni verir."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"kızı ötesi iletme"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Uygulamaya, tabletin kızıl ötesi vericisini kullanma izni verir."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Uygulamaya, telefonunun kızıl ötesi vericisini kullanma izni verir."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"tableti aç veya kapat"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"telefonu aç veya kapat"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Uygulamaya, tabletinizi açma veya kapatma izni verir."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 6a9677f..3ff9fd9 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Пам’ять планшетного ПК заповнено. Видаліть якісь файли, щоб звільнити місце."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Пам’ять телефону заповнено. Видаліть якісь файли, щоб звільнити місце."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Мережу можуть відстежувати"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Невідомою третьою стороною"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Доменом <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Я"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Парам. пристрою"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Параметри тел."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 954e52d..26e3f6e 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Bộ nhớ máy tính bảng đã đầy. Hãy xóa một số tệp để tạo thêm dung lượng."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Bộ nhớ điện thoại đã đầy. Hãy xóa một số tệp để tạo thêm dung lượng."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Mạng có thể được giám sát"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Bởi một bên thứ ba không xác định"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Bởi <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Tôi"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tùy chọn máy tính bảng"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Tùy chọn điện thoại"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Cho phép ứng dụng kiểm soát các tính năng cấp thấp của màn hình Wi-Fi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"thu thập dữ liệu đầu ra âm thanh"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Cho phép ứng dụng thu thập và chuyển hướng dữ liệu đầu ra âm thanh."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Phát hiện từ nóng"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Cho phép ứng dụng thu thập dữ liệu âm thanh để phát hiện từ nóng. Quá trình thu thập này có thể diễn ra trong nền nhưng không ngăn các hoạt động thu thập dữ liệu âm thanh khác (ví dụ: máy quay video)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"thu thập dữ liệu đầu ra video"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Cho phép ứng dụng thu thập và chuyển hướng dữ liệu đầu ra video."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"thu thập dữ liệu đầu ra video an toàn"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ngăn điện thoại chuyển sang chế độ ngủ"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Cho phép ứng dụng ngăn máy tính bảng chuyển sang chế độ ngủ."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Cho phép ứng dụng ngăn điện thoại chuyển sang chế độ ngủ."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"phát hồng ngoại"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Cho phép ứng dụng sử dụng bộ phát hồng ngoại của máy tính bảng."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Cho phép ứng dụng sử dụng bộ phát hồng ngoại của điện thoại."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"bật hoặc tắt máy tính bảng"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"bật hoặc tắt điện thoại"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Cho phép ứng dụng bật hoặc tắt máy tính bảng."</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index c765417..b250f14 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -481,10 +481,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"允许应用控制 WLAN 显示设备的基础功能。"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"捕获音频输出"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"允许该应用捕获和重定向音频输出。"</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"关键词检测"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"允许应用针对关键词检测捕获音频。捕获操作会在后台进行,但不会禁止使用其他音频捕获工具(例如摄像机)。"</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"捕获视频输出"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"允许该应用捕获和重定向视频输出。"</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"捕获安全视频输出"</string>
@@ -552,12 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"防止手机休眠"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"允许应用阻止平板电脑进入休眠状态。"</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"允许应用阻止手机进入休眠状态。"</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"发射红外线"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"允许应用使用平板电脑的红外线发射器。"</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"允许应用使用手机的红外线发射器。"</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"打开或关闭平板电脑"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"开机或关机"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"允许应用打开或关闭平板电脑。"</string>
@@ -652,7 +647,7 @@
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"允许应用访问所有用户的外部存储设备。"</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"访问缓存文件系统"</string>
     <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"允许应用读取和写入缓存文件系统。"</string>
-    <string name="permlab_use_sip" msgid="5986952362795870502">"拨打/接听互联网通话"</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"拨打/接听互联网电话"</string>
     <string name="permdesc_use_sip" msgid="4717632000062674294">"允许应用使用 SIP 服务拨打/接听互联网电话。"</string>
     <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"读取网络使用情况历史记录"</string>
     <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"允许应用读取特定网络和应用的网络使用情况历史记录。"</string>
@@ -695,7 +690,7 @@
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"住宅"</item>
     <item msgid="869923650527136615">"手机"</item>
-    <item msgid="7897544654242874543">"单位电话"</item>
+    <item msgid="7897544654242874543">"单位"</item>
     <item msgid="1103601433382158155">"单位传真"</item>
     <item msgid="1735177144948329370">"住宅传真"</item>
     <item msgid="603878674477207394">"寻呼机"</item>
@@ -703,8 +698,8 @@
     <item msgid="9192514806975898961">"自定义"</item>
   </string-array>
   <string-array name="emailAddressTypes">
-    <item msgid="8073994352956129127">"家庭"</item>
-    <item msgid="7084237356602625604">"单位"</item>
+    <item msgid="8073994352956129127">"个人"</item>
+    <item msgid="7084237356602625604">"工作"</item>
     <item msgid="1112044410659011023">"其他"</item>
     <item msgid="2374913952870110618">"自定义"</item>
   </string-array>
@@ -761,8 +756,8 @@
     <string name="eventTypeAnniversary" msgid="3876779744518284000">"周年纪念日"</string>
     <string name="eventTypeOther" msgid="7388178939010143077">"其他"</string>
     <string name="emailTypeCustom" msgid="8525960257804213846">"自定义"</string>
-    <string name="emailTypeHome" msgid="449227236140433919">"家用"</string>
-    <string name="emailTypeWork" msgid="3548058059601149973">"单位"</string>
+    <string name="emailTypeHome" msgid="449227236140433919">"个人"</string>
+    <string name="emailTypeWork" msgid="3548058059601149973">"工作"</string>
     <string name="emailTypeOther" msgid="2923008695272639549">"其他"</string>
     <string name="emailTypeMobile" msgid="119919005321166205">"手机"</string>
     <string name="postalTypeCustom" msgid="8903206903060479902">"自定义"</string>
@@ -1182,10 +1177,10 @@
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"无法连接到 WLAN"</string>
     <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" 互联网连接状况不佳。"</string>
-    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"WLAN Direct"</string>
-    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"启动 WLAN Direct。此操作将会关闭 WLAN 客户端/热点。"</string>
-    <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"无法启动 WLAN Direct。"</string>
-    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"已启用 WLAN Direct"</string>
+    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"WLAN 直连"</string>
+    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"启动 WLAN 直连。此操作将会关闭 WLAN 客户端/热点。"</string>
+    <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"无法启动 WLAN 直连。"</string>
+    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"已启用 WLAN 直连"</string>
     <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"通过触摸进行设置"</string>
     <string name="accept" msgid="1645267259272829559">"接受"</string>
     <string name="decline" msgid="2112225451706137894">"拒绝"</string>
@@ -1435,9 +1430,9 @@
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"修改"</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"流量使用警告"</string>
     <string name="data_usage_warning_body" msgid="2814673551471969954">"触摸可查看使用情况和设置。"</string>
-    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G 数据已停用"</string>
-    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G 数据已停用"</string>
-    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"移动数据已停用"</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G 数据网络已停用"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G 数据网络已停用"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"移动数据网络已停用"</string>
     <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"WLAN 数据网络已停用"</string>
     <string name="data_usage_limit_body" msgid="3317964706973601386">"触摸可启用。"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"已超出 2G-3G 数据流量限制"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 3b03aa5..e924d01 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"平板電腦的儲存空間已滿。請刪除一些檔案,以騰出可用空間。"</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"手機的儲存空間已滿。請刪除一些檔案,以騰出可用空間。"</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"網絡可能會受到監控"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"受到不明的第三方監控"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"受到 <xliff:g id="MANAGING_DOMAIN">%s</xliff:g> 監控"</string>
     <string name="me" msgid="6545696007631404292">"我本人"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"平板電腦選項"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"手機選項"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"允許應用程式控制 WiFi Display 的低階功能。"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"擷取音頻輸出"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"允許應用程式擷取及重新導向音頻輸出。"</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"啟動字詞偵測"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"允許應用程式擷取啟動字詞偵測的音頻。擷取操作可以在背景執行,但並未阻止其他音頻擷取 (例如攝錄機)。"</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"擷取視頻輸出"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"允許應用程式擷取及重新導向視頻輸出。"</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"擷取安全視頻輸出"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"防止手機進入休眠狀態"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"允許應用程式防止平板電腦進入休眠狀態。"</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"允許應用程式防止手機進入休眠狀態。"</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"傳送紅外線"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"允許應用程式使用平板電腦的紅外線傳送器。"</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"允許應用程式使用手機的紅外線傳送器。"</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"開啟或關閉平板電腦"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"開啟或關閉手機"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"允許應用程式開啟或關閉平板電腦。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index b26b989..7be248f 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"平板電腦的儲存空間已滿。請刪除一些檔案,以釋放出可用空間。"</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"手機儲存空間已滿。請刪除一些檔案,以釋放可用空間。"</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"網路可能會受到監控"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"受到不明的第三方監控"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"受到 <xliff:g id="MANAGING_DOMAIN">%s</xliff:g> 監控"</string>
     <string name="me" msgid="6545696007631404292">"我"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"平板電腦選項"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"電話選項"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"允許應用程式控制 Wi-Fi 顯示裝置的低階功能。"</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"擷取音訊輸出"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"允許應用程式擷取及重新導向音訊輸出。"</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"熱門字詞偵測"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"允許應用程式針對熱門字詞偵測擷取音訊。擷取作業可在背景執行,但並未禁止使用其他音訊擷取工具 (例如攝錄影機)。"</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"擷取視訊輸出"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"允許應用程式擷取及重新導向視訊輸出。"</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"擷取安全視訊輸出"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"防止手機進入待命狀態"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"允許應用程式防止平板電腦進入休眠狀態。"</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"允許應用程式防止手機進入休眠狀態。"</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"傳送紅外線"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"允許應用程式使用平板電腦的紅外線傳送器。"</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"允許應用程式使用手機的紅外線傳送器。"</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"開啟或關閉平板電腦"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"開啟或關閉電源"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"允許應用程式開啟或關閉平板電腦。"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 24006fd..f96b062 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -132,10 +132,8 @@
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Isilondolozi sethebhulethi sigcwele! Susa amanye amafayela ukukhulula isikhala."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Isilondolozi sefoni sigcwele! Susa amanye amafayela ukukhulula isikhala."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Inethiwekhi ingase inganyelwe"</string>
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Ngenkampani yangaphandle engaziwa"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Nge-<xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="me" msgid="6545696007631404292">"Mina"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Okukhethwa kukho kwethebhulethi"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Okukhethwa kukho kwefoni"</string>
@@ -481,10 +479,8 @@
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Uvumela uhlelo lokusebenza ukulawula izici zeleveli ephansi zokuboniswa kwe-Wi-Fi."</string>
     <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"shutha okukhipha umsindo"</string>
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Kuvumela uhlelo lokusebenza ukuba lushuthe futhi luqondise kabusha okukhipha umsindo."</string>
-    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
-    <skip />
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Ukutholwa kwe-Hotword"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Ivumela uhlelo lokusebenza ukuthi lishuthele umsindo ukutholwa kwe-Hotword. Ukushutha kungenzeka ngemuva kodwa akuvimbeli okunye ukushutha komsindo (isb. i-Camcorder)."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"shutha okokukhipha ividiyo"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Kuvumela uhlelo lokusebenza ukuba lushuthe futhi luqondise kabusha okukhipha ividiyo."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"shutha okukhipha ividiyo ephephile"</string>
@@ -552,12 +548,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"gwema ifoni ukuba ingalali"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Ivumela uhlelo lokusebenza ukuthi linqande ithebulethi yakho ukuthi ilale."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Ivumela uhlelo lokusebenza ukuthi inqande ucingo ukuthi lulale."</string>
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"hambisa okungabonwa ngeso"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Ivumela uhlelo lokusebenza ukuthi lusebenzise isihambisi esinombala ongabonwa ngeso wethebulethi."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Ivumela uhlelo lokusebenza ukuthi lusebenzise isihambisi esinombala ongabonwa ngeso wefoni."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"amandla efoni avuliwe noma avaliwe"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"amandla efoni avuliwe noma avaliwe"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Ivumela uhlelo lokusebenza ukuvala noma ukuvula ithebhulethi."</string>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index d2ada7a..80810d5 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1048,6 +1048,11 @@
         tag; often this is one of the {@link android.Manifest.permission standard
         system permissions}. -->
         <attr name="name" />
+        <!-- Optional: specify the maximum version of the Android OS for which the
+             application wishes to request the permission.  When running on a version
+             of Android higher than the number given here, the permission will not
+             be requested.  -->
+        <attr name="maxSdkVersion" format="integer" />
         <!--  Specify whether this permission is required for the application.
               The default is true, meaning the application requires the
               permission, and it must always be granted when it is installed.
@@ -1129,7 +1134,7 @@
              on.  You can use this to ensure your application is filtered out
              of later versions of the platform when you know you have
              incompatibility with them. -->
-        <attr name="maxSdkVersion" format="integer" />
+        <attr name="maxSdkVersion" />
     </declare-styleable>
     
     <!-- The <code>library</code> tag declares that this apk is providing itself
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d4b834a..2c1a3c1 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1241,4 +1241,8 @@
          To do this, add 21407 item to values-mcc214-mnc04/config.xml -->
     <string-array translatable="false" name="config_operatorConsideredNonRoaming">
     </string-array>
+
+    <!-- Threshold (in ms) under which a screen off / screen on will be considered a reset of the
+         transient navigation confirmation prompt.-->
+    <integer name="config_transient_navigation_confirmation_panic">5000</integer>
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index a03378e..98368a1 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4344,9 +4344,7 @@
     <!-- PIN entry dialog tells the user to not enter a PIN for a while. [CHAR LIMIT=none] -->
     <string name="restr_pin_try_later">Try again later</string>
 
-    <!-- Toast bar message when hiding the transient navigation bar [CHAR LIMIT=35] -->
-    <string name="transient_navigation_confirmation">Swipe edge of screen to reveal bar</string>
+    <!-- Toast bar message when hiding the transient navigation bar [CHAR LIMIT=45] -->
+    <string name="transient_navigation_confirmation">Swipe down from the top to exit full screen</string>
 
-    <!-- Longer version of toast bar message when hiding the transient navigation bar (if room) -->
-    <string name="transient_navigation_confirmation_long">Swipe from edge of screen to reveal system bar</string>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 4148f20..9cb0a37 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -301,6 +301,7 @@
   <java-symbol type="integer" name="config_ntpThreshold" />
   <java-symbol type="integer" name="config_ntpTimeout" />
   <java-symbol type="integer" name="config_toastDefaultGravity" />
+  <java-symbol type="integer" name="config_transient_navigation_confirmation_panic" />
   <java-symbol type="integer" name="config_wifi_framework_scan_interval" />
   <java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
   <java-symbol type="integer" name="config_wifi_scan_interval_p2p_connected" />
@@ -885,7 +886,6 @@
   <java-symbol type="string" name="write_fail_reason_cancelled" />
   <java-symbol type="string" name="write_fail_reason_cannot_write" />
   <java-symbol type="string" name="transient_navigation_confirmation" />
-  <java-symbol type="string" name="transient_navigation_confirmation_long" />
   <java-symbol type="string" name="ssl_ca_cert_noti_by_unknown" />
   <java-symbol type="string" name="ssl_ca_cert_noti_managed" />
   <java-symbol type="string" name="ssl_ca_cert_warning" />
diff --git a/core/tests/ConnectivityManagerTest/AndroidManifest.xml b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
index b76c8be..1649268 100644
--- a/core/tests/ConnectivityManagerTest/AndroidManifest.xml
+++ b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
@@ -23,13 +23,6 @@
          which is needed when building test cases. -->
     <application>
         <uses-library android:name="android.test.runner" />
-        <activity android:name="ConnectivityManagerTestActivity"
-          android:label="@string/app_name">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
     </application>
 
     <!--
@@ -87,4 +80,6 @@
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
     <uses-permission android:name="android.permission.INJECT_EVENTS" />
+    <uses-permission android:name="android.permission.DEVICE_POWER" />
+
 </manifest>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
index 0461c0b..b942eb6 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
@@ -32,13 +32,11 @@
 import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.RouteInfo;
-import android.util.Log;
 
 import java.io.InputStream;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 
 
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java
similarity index 88%
rename from core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
rename to core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java
index a0cb1bb..30eda75 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java
@@ -16,7 +16,7 @@
 
 package com.android.connectivitymanagertest;
 
-import android.app.Activity;
+import android.app.KeyguardManager;
 import android.content.Context;
 import android.content.BroadcastReceiver;
 import android.content.Intent;
@@ -26,21 +26,14 @@
 import android.net.NetworkInfo.State;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
-import android.os.Bundle;
 import android.os.Handler;
-import android.os.IPowerManager;
 import android.os.Message;
 import android.os.PowerManager;
-import android.os.ServiceManager;
 import android.os.SystemClock;
-import android.os.UserHandle;
-import android.provider.Settings;
+import android.test.InstrumentationTestCase;
 import android.util.Log;
 import android.view.KeyEvent;
-import android.widget.LinearLayout;
 
 import com.android.internal.util.AsyncChannel;
 
@@ -52,13 +45,17 @@
 
 
 /**
- * An activity registered with connectivity manager broadcast
- * provides network connectivity information and
- * can be used to set device states: Cellular, Wifi, Airplane mode.
+ * Base InstrumentationTestCase for Connectivity Manager (CM) test suite
+ *
+ * It registers connectivity manager broadcast and WiFi broadcast to provide
+ * network connectivity information, also provides a set of utility functions
+ * to modify and verify connectivity states.
+ *
+ * A CM test case should extend this base class.
  */
-public class ConnectivityManagerTestActivity extends Activity {
+public class ConnectivityManagerTestBase extends InstrumentationTestCase {
 
-    public static final String LOG_TAG = "ConnectivityManagerTestActivity";
+    public static final String LOG_TAG = "ConnectivityManagerTestBase";
     public static final int WAIT_FOR_SCAN_RESULT = 10 * 1000; //10 seconds
     public static final int WIFI_SCAN_TIMEOUT = 50 * 1000; // 50 seconds
     public static final int SHORT_TIMEOUT = 5 * 1000; // 5 seconds
@@ -94,14 +91,9 @@
     private Context mContext;
     public boolean scanResultAvailable = false;
 
-    /*
-     * Control Wifi States
-     */
+    /* Control Wifi States */
     public WifiManager mWifiManager;
-
-    /*
-     * Verify connectivity state
-     */
+    /* Verify connectivity state */
     public static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE + 1;
     NetworkState[] connectivityState = new NetworkState[NUM_NETWORK_TYPES];
 
@@ -208,26 +200,28 @@
         }
     }
 
-    public ConnectivityManagerTestActivity() {
+    @Override
+    public void setUp() throws Exception {
         mState = State.UNKNOWN;
         scanResultAvailable = false;
-    }
+        mContext = getInstrumentation().getContext();
 
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        log("onCreate, inst=" + Integer.toHexString(hashCode()));
+        // Get an instance of ConnectivityManager
+        mCM = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+        // Get an instance of WifiManager
+        mWifiManager =(WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
 
-        // Create a simple layout
-        LinearLayout contentView = new LinearLayout(this);
-        contentView.setOrientation(LinearLayout.VERTICAL);
-        setContentView(contentView);
-        setTitle("ConnectivityManagerTestActivity");
+        if (mWifiManager.isWifiApEnabled()) {
+            // if soft AP is enabled, disable it
+            mWifiManager.setWifiApEnabled(null, false);
+            log("Disable soft ap");
+        }
 
+        initializeNetworkStates();
 
         // register a connectivity receiver for CONNECTIVITY_ACTION;
         mConnectivityReceiver = new ConnectivityReceiver();
-        registerReceiver(mConnectivityReceiver,
+        mContext.registerReceiver(mConnectivityReceiver,
                 new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
 
         mWifiReceiver = new WifiReceiver();
@@ -238,28 +232,15 @@
         mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
         mIntentFilter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
         mIntentFilter.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
-        registerReceiver(mWifiReceiver, mIntentFilter);
+        mContext.registerReceiver(mWifiReceiver, mIntentFilter);
 
-        // Get an instance of ConnectivityManager
-        mCM = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
-        // Get an instance of WifiManager
-        mWifiManager =(WifiManager)getSystemService(Context.WIFI_SERVICE);
-        mContext = this;
-
-        if (mWifiManager.isWifiApEnabled()) {
-            // if soft AP is enabled, disable it
-            mWifiManager.setWifiApEnabled(null, false);
-            log("Disable soft ap");
-        }
-
-        initializeNetworkStates();
         log("Clear Wifi before we start the test.");
         removeConfiguredNetworksAndDisableWifi();
         mWifiRegexs = mCM.getTetherableWifiRegexs();
      }
 
     public List<WifiConfiguration> loadNetworkConfigurations() throws Exception {
-        InputStream in = getAssets().open(ACCESS_POINT_FILE);
+        InputStream in = mContext.getAssets().open(ACCESS_POINT_FILE);
         mParseHelper = new AccessPointParserHelper(in);
         return mParseHelper.getNetworkConfigurations();
     }
@@ -277,6 +258,12 @@
     public void recordNetworkState(int networkType, State networkState) {
         log("record network state for network " +  networkType +
                 ", state is " + networkState);
+        if (connectivityState == null) {
+             log("ConnectivityState is null");
+        }
+        if (connectivityState[networkType] == null) {
+             log("connectivityState[networkType] is null");
+        }
         connectivityState[networkType].recordState(networkState);
     }
 
@@ -503,7 +490,7 @@
     public void turnScreenOff() {
         log("Turn screen off");
         PowerManager pm =
-            (PowerManager) getSystemService(Context.POWER_SERVICE);
+            (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         pm.goToSleep(SystemClock.uptimeMillis());
     }
 
@@ -511,8 +498,13 @@
     public void turnScreenOn() {
         log("Turn screen on");
         PowerManager pm =
-                (PowerManager) getSystemService(Context.POWER_SERVICE);
+                (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         pm.wakeUp(SystemClock.uptimeMillis());
+        // disable lock screen
+        KeyguardManager km = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+        if (km.inKeyguardRestrictedInputMode()) {
+            sendKeys(KeyEvent.KEYCODE_MENU);
+        }
     }
 
     /**
@@ -607,7 +599,12 @@
             mWifiManager.setWifiEnabled(true);
             sleep(SHORT_TIMEOUT);
         }
+
         List<WifiConfiguration> wifiConfigList = mWifiManager.getConfiguredNetworks();
+        if (wifiConfigList == null) {
+            log("no configuration list is null");
+            return true;
+        }
         log("size of wifiConfigList: " + wifiConfigList.size());
         for (WifiConfiguration wifiConfig: wifiConfigList) {
             log("remove wifi configuration: " + wifiConfig.networkId);
@@ -656,57 +653,15 @@
     }
 
     @Override
-    protected void onDestroy() {
-        super.onDestroy();
-
+    public void tearDown() throws Exception{
         //Unregister receiver
         if (mConnectivityReceiver != null) {
-            unregisterReceiver(mConnectivityReceiver);
+          mContext.unregisterReceiver(mConnectivityReceiver);
         }
         if (mWifiReceiver != null) {
-            unregisterReceiver(mWifiReceiver);
+          mContext.unregisterReceiver(mWifiReceiver);
         }
-        log("onDestroy, inst=" + Integer.toHexString(hashCode()));
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-        mContext = this;
-        Bundle bundle = this.getIntent().getExtras();
-        if (bundle != null){
-            mPowerSsid = bundle.getString("power_ssid");
-        }
-    }
-    //A thread to set the device into airplane mode then turn on wifi.
-    Thread setDeviceWifiAndAirplaneThread = new Thread(new Runnable() {
-        public void run() {
-            mCM.setAirplaneMode(true);
-            connectToWifi(mPowerSsid);
-        }
-    });
-
-    //A thread to set the device into wifi
-    Thread setDeviceInWifiOnlyThread = new Thread(new Runnable() {
-        public void run() {
-            connectToWifi(mPowerSsid);
-        }
-    });
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        switch (keyCode) {
-            //This is a tricky way for the scripted monkey to
-            //set the device in wifi and wifi in airplane mode.
-            case KeyEvent.KEYCODE_1:
-                setDeviceWifiAndAirplaneThread.start();
-                break;
-
-            case KeyEvent.KEYCODE_2:
-                setDeviceInWifiOnlyThread.start();
-                break;
-        }
-        return super.onKeyDown(keyCode, event);
+        super.tearDown();
     }
 
     private void log(String message) {
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerUnitTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerUnitTestRunner.java
index 3a78f26..0e57a00 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerUnitTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerUnitTestRunner.java
@@ -16,10 +16,8 @@
 
 package com.android.connectivitymanagertest;
 
-import android.os.Bundle;
 import android.test.InstrumentationTestRunner;
 import android.test.InstrumentationTestSuite;
-import android.util.Log;
 import com.android.connectivitymanagertest.unit.WifiClientTest;
 import com.android.connectivitymanagertest.unit.WifiSoftAPTest;
 
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index 729e1d2..05462b4 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -24,31 +24,24 @@
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
 import android.provider.Settings;
-import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 
-import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
+import com.android.connectivitymanagertest.ConnectivityManagerTestBase;
 import com.android.connectivitymanagertest.ConnectivityManagerTestRunner;
 import com.android.connectivitymanagertest.NetworkState;
 
 public class ConnectivityManagerMobileTest extends
-        ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
-    private static final String LOG_TAG = "ConnectivityManagerMobileTest";
+        ConnectivityManagerTestBase {
+    private static final String TAG = "ConnectivityManagerMobileTest";
 
     private String mTestAccessPoint;
-    private ConnectivityManagerTestActivity cmActivity;
     private WakeLock wl;
     private boolean mWifiOnlyFlag;
 
-    public ConnectivityManagerMobileTest() {
-        super(ConnectivityManagerTestActivity.class);
-    }
-
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        cmActivity = getActivity();
         ConnectivityManagerTestRunner mRunner =
                 (ConnectivityManagerTestRunner)getInstrumentation();
         mTestAccessPoint = mRunner.mTestSsid;
@@ -62,12 +55,12 @@
         if (Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
                 Settings.Global.AIRPLANE_MODE_ON) == 1) {
             log("airplane is not disabled, disable it.");
-            cmActivity.mCM.setAirplaneMode(false);
+            mCM.setAirplaneMode(false);
         }
 
         if (!mWifiOnlyFlag) {
-            if (!cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
-                    ConnectivityManagerTestActivity.LONG_TIMEOUT)) {
+            if (!waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+                    State.CONNECTED, LONG_TIMEOUT)) {
                 // Note: When the test fails in setUp(), tearDown is not called. In that case,
                 // the activity is destroyed which blocks the next test at "getActivity()".
                 // tearDown() is called here to avoid that situation.
@@ -79,29 +72,22 @@
 
     @Override
     public void tearDown() throws Exception {
-        cmActivity.finish();
-        log("tear down ConnectivityManagerTestActivity");
         wl.release();
-        cmActivity.removeConfiguredNetworksAndDisableWifi();
-        // if airplane mode is set, disable it.
-        if (Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
-                Settings.Global.AIRPLANE_MODE_ON) == 1) {
-            log("disable airplane mode if it is enabled");
-            cmActivity.mCM.setAirplaneMode(false);
-        }
+        removeConfiguredNetworksAndDisableWifi();
+        mCM.setAirplaneMode(false);
         super.tearDown();
     }
 
     // help function to verify 3G connection
     public void verifyCellularConnection() {
-        NetworkInfo extraNetInfo = cmActivity.mCM.getActiveNetworkInfo();
+        NetworkInfo extraNetInfo = mCM.getActiveNetworkInfo();
         assertEquals("network type is not MOBILE", ConnectivityManager.TYPE_MOBILE,
                 extraNetInfo.getType());
         assertTrue("not connected to cellular network", extraNetInfo.isConnected());
     }
 
     private void log(String message) {
-        Log.v(LOG_TAG, message);
+        Log.v(TAG, message);
     }
 
     private void sleep(long sleeptime) {
@@ -115,46 +101,46 @@
     @LargeTest
     public void test3GToWifiNotification() {
         if (mWifiOnlyFlag) {
-            Log.v(LOG_TAG, this.getName() + " is excluded for wifi-only test");
+            Log.v(TAG, this.getName() + " is excluded for wifi-only test");
             return;
         }
         // Enable Wi-Fi to avoid initial UNKNOWN state
-        cmActivity.enableWifi();
-        sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+        enableWifi();
+        sleep(2 * SHORT_TIMEOUT);
 
         // Wi-Fi is disabled
-        cmActivity.disableWifi();
+        disableWifi();
 
-        assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
-                State.DISCONNECTED,  ConnectivityManagerTestActivity.LONG_TIMEOUT));
-        assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
-                State.CONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI,
+                State.DISCONNECTED, LONG_TIMEOUT));
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+                State.CONNECTED, LONG_TIMEOUT));
         // Wait for 10 seconds for broadcasts to be sent out
         sleep(10 * 1000);
 
         // As Wifi stays in DISCONNETED, Mobile statys in CONNECTED,
         // the connectivity manager will not broadcast any network connectivity event for Wifi
-        NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
-        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+        NetworkInfo networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+        setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
                 networkInfo.getState(), NetworkState.DO_NOTHING, State.CONNECTED);
-        networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
-        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+        networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
                 NetworkState.DO_NOTHING, State.DISCONNECTED);
         // Eanble Wifi without associating with any AP
-        cmActivity.enableWifi();
-        sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+        enableWifi();
+        sleep(2 * SHORT_TIMEOUT);
 
         // validate state and broadcast
-        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+        if (!validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
             log("the state for WIFI is changed");
             log("reason: " +
-                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+                    getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
             assertTrue("state validation fail", false);
         }
-        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+        if (!validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
             log("the state for MOBILE is changed");
             log("reason: " +
-                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+                    getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
             assertTrue("state validation fail", false);
         }
         // Verify that the device is still connected to MOBILE
@@ -168,40 +154,39 @@
         NetworkInfo networkInfo;
         if (!mWifiOnlyFlag) {
             //Prepare for connectivity verification
-            networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
-            cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+            networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+            setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
                     networkInfo.getState(), NetworkState.TO_DISCONNECTION, State.DISCONNECTED);
         }
-        networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
-        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+        networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
                 NetworkState.TO_CONNECTION, State.CONNECTED);
 
         // Enable Wifi and connect to a test access point
         assertTrue("failed to connect to " + mTestAccessPoint,
-                cmActivity.connectToWifi(mTestAccessPoint));
+                connectToWifi(mTestAccessPoint));
 
-        assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
-                ConnectivityManagerTestActivity.LONG_TIMEOUT));
+        assertTrue(waitForWifiState(WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
         log("wifi state is enabled");
-        assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                WIFI_CONNECTION_TIMEOUT));
         if (!mWifiOnlyFlag) {
-            assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
-                    State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+            assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+                    State.DISCONNECTED, LONG_TIMEOUT));
         }
 
         // validate states
-        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+        if (!validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
             log("Wifi state transition validation failed.");
             log("reason: " +
-                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+                    getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
             assertTrue(false);
         }
         if (!mWifiOnlyFlag) {
-            if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+            if (!validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
                 log("Mobile state transition validation failed.");
                 log("reason: " +
-                        cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+                        getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
                 assertTrue(false);
             }
         }
@@ -213,61 +198,59 @@
         assertNotNull("SSID is null", mTestAccessPoint);
         // Connect to mTestAccessPoint
         assertTrue("failed to connect to " + mTestAccessPoint,
-                cmActivity.connectToWifi(mTestAccessPoint));
-        assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
-                ConnectivityManagerTestActivity.LONG_TIMEOUT));
-        assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+                connectToWifi(mTestAccessPoint));
+        assertTrue(waitForWifiState(WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                WIFI_CONNECTION_TIMEOUT));
 
-        sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+        sleep(SHORT_TIMEOUT);
         // Disable Wifi
         log("Disable Wifi");
-        if (!cmActivity.disableWifi()) {
+        if (!disableWifi()) {
             log("disable Wifi failed");
             return;
         }
 
         // Wait for the Wifi state to be DISABLED
-        assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_DISABLED,
-                ConnectivityManagerTestActivity.LONG_TIMEOUT));
-        assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
-                State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+        assertTrue(waitForWifiState(WifiManager.WIFI_STATE_DISABLED, LONG_TIMEOUT));
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI,
+                State.DISCONNECTED, LONG_TIMEOUT));
         if (!mWifiOnlyFlag) {
-            assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
-                    State.CONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+            assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+                    State.CONNECTED, LONG_TIMEOUT));
         }
 
         NetworkInfo networkInfo;
         if (!mWifiOnlyFlag) {
             //Prepare for connectivity state verification
-            networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
-            cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+            networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+            setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
                                                   networkInfo.getState(), NetworkState.DO_NOTHING,
                                                   State.DISCONNECTED);
         }
-        networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
-        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+        networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
                 NetworkState.TO_CONNECTION, State.CONNECTED);
 
         // wait for 2 minutes before restart wifi
-        sleep(ConnectivityManagerTestActivity.WIFI_STOP_START_INTERVAL);
+        sleep(WIFI_STOP_START_INTERVAL);
         // Enable Wifi again
         log("Enable Wifi again");
-        cmActivity.enableWifi();
+        enableWifi();
 
         // Wait for Wifi to be connected and mobile to be disconnected
-        assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                WIFI_CONNECTION_TIMEOUT));
         if (!mWifiOnlyFlag) {
-            assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
-                    State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+            assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+                    State.DISCONNECTED, LONG_TIMEOUT));
         }
 
         // validate wifi states
-        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+        if (!validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
             log("Wifi state transition validation failed.");
             log("reason: " +
-                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+                    getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
             assertTrue(false);
         }
     }
@@ -279,48 +262,48 @@
 
         // connect to Wifi
         assertTrue("failed to connect to " + mTestAccessPoint,
-                cmActivity.connectToWifi(mTestAccessPoint));
+                connectToWifi(mTestAccessPoint));
 
-        assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                WIFI_CONNECTION_TIMEOUT));
 
         // Wait for a few seconds to avoid the state that both Mobile and Wifi is connected
-        sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+        sleep(SHORT_TIMEOUT);
 
         NetworkInfo networkInfo;
         if (!mWifiOnlyFlag) {
-            networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
-            cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+            networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+            setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
                                                   networkInfo.getState(),
                                                   NetworkState.TO_CONNECTION,
                                                   State.CONNECTED);
         }
-        networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
-        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+        networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
                 NetworkState.TO_DISCONNECTION, State.DISCONNECTED);
 
         // clear Wifi
-        cmActivity.removeConfiguredNetworksAndDisableWifi();
+        removeConfiguredNetworksAndDisableWifi();
 
-        assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
-                ConnectivityManagerTestActivity.LONG_TIMEOUT));
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI,
+                State.DISCONNECTED, LONG_TIMEOUT));
         if (!mWifiOnlyFlag) {
-            assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
-                    State.CONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+            assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+                    State.CONNECTED, LONG_TIMEOUT));
         }
 
         // validate states
-        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+        if (!validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
             log("Wifi state transition validation failed.");
             log("reason: " +
-                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+                    getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
             assertTrue(false);
         }
         if (!mWifiOnlyFlag) {
-            if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+            if (!validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
                 log("Mobile state transition validation failed.");
                 log("reason: " +
-                        cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+                        getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
                 assertTrue(false);
             }
         }
@@ -330,62 +313,62 @@
     @LargeTest
     public void testDataConnectionWith3GToAmTo3G() {
         if (mWifiOnlyFlag) {
-            Log.v(LOG_TAG, this.getName() + " is excluded for wifi-only test");
+            Log.v(TAG, this.getName() + " is excluded for wifi-only test");
             return;
         }
         //Prepare for state verification
-        NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
-        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+        NetworkInfo networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+        setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
                                               networkInfo.getState(),
                                               NetworkState.TO_DISCONNECTION,
                                               State.DISCONNECTED);
-        networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
         assertEquals(State.DISCONNECTED, networkInfo.getState());
 
         // Enable airplane mode
         log("Enable airplane mode");
-        cmActivity.mCM.setAirplaneMode(true);
-        sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+        mCM.setAirplaneMode(true);
+        sleep(SHORT_TIMEOUT);
 
-        networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
         assertEquals(State.DISCONNECTED, networkInfo.getState());
         // wait until mobile is turn off
-        assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
-                State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
-        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+                State.DISCONNECTED, LONG_TIMEOUT));
+        if (!validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
             log("Mobile state transition validation failed.");
             log("reason: " +
-                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+                    getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
             assertTrue(false);
         }
 
         // reset state recorder
-        networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
-        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+        networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+        setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
                                               networkInfo.getState(),
                                               NetworkState.TO_CONNECTION,
                                               State.CONNECTED);
-        networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
-        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+        networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
                 NetworkState.DO_NOTHING, State.DISCONNECTED);
 
         // disable airplane mode
-        cmActivity.mCM.setAirplaneMode(false);
+        mCM.setAirplaneMode(false);
 
-        assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
-                ConnectivityManagerTestActivity.LONG_TIMEOUT));
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+                State.CONNECTED, LONG_TIMEOUT));
 
         // Validate the state transition
-        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+        if (!validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
             log("Mobile state transition validation failed.");
             log("reason: " +
-                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+                    getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
             assertTrue(false);
         }
-        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+        if (!validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
           log("Wifi state transition validation failed.");
           log("reason: " +
-                  cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+                  getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
           assertTrue(false);
         }
     }
@@ -394,107 +377,107 @@
     @LargeTest
     public void testDataConnectionOverAMWithWifi() {
         if (mWifiOnlyFlag) {
-            Log.v(LOG_TAG, this.getName() + " is excluded for wifi-only test");
+            Log.v(TAG, this.getName() + " is excluded for wifi-only test");
             return;
         }
         assertNotNull("SSID is null", mTestAccessPoint);
         // Eanble airplane mode
         log("Enable airplane mode");
-        cmActivity.mCM.setAirplaneMode(true);
+        mCM.setAirplaneMode(true);
 
         NetworkInfo networkInfo;
         if (!mWifiOnlyFlag) {
-            assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
-                    State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
-            networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
-            cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+            assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+                    State.DISCONNECTED, LONG_TIMEOUT));
+            networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+            setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
                                                   networkInfo.getState(),
                                                   NetworkState.DO_NOTHING,
                                                   State.DISCONNECTED);
         }
-        networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
-        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+        networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
                                               NetworkState.TO_CONNECTION, State.CONNECTED);
 
         // Connect to Wifi
         assertTrue("failed to connect to " + mTestAccessPoint,
-                cmActivity.connectToWifi(mTestAccessPoint));
-        assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+                connectToWifi(mTestAccessPoint));
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                WIFI_CONNECTION_TIMEOUT));
 
         // validate state and broadcast
-        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+        if (!validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
             log("state validate for Wifi failed");
             log("reason: " +
-                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+                    getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
             assertTrue("State validation failed", false);
         }
         if (!mWifiOnlyFlag) {
-            if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+            if (!validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
                 log("state validation for Mobile failed");
                 log("reason: " +
-                        cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+                        getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
                 assertTrue("state validation failed", false);
             }
         }
-        cmActivity.mCM.setAirplaneMode(false);
+        mCM.setAirplaneMode(false);
     }
 
     // Test case 7: test connectivity while transit from Wifi->AM->Wifi
     @LargeTest
     public void testDataConnectionWithWifiToAMToWifi () {
         if (mWifiOnlyFlag) {
-            Log.v(LOG_TAG, this.getName() + " is excluded for wifi-only test");
+            Log.v(TAG, this.getName() + " is excluded for wifi-only test");
             return;
         }
         // Connect to mTestAccessPoint
         assertNotNull("SSID is null", mTestAccessPoint);
         // Connect to Wifi
         assertTrue("failed to connect to " + mTestAccessPoint,
-                cmActivity.connectToWifi(mTestAccessPoint));
+                connectToWifi(mTestAccessPoint));
 
-        assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                WIFI_CONNECTION_TIMEOUT));
 
         try {
-            Thread.sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+            Thread.sleep(SHORT_TIMEOUT);
         } catch (Exception e) {
             log("exception: " + e.toString());
         }
 
         // Enable airplane mode without clearing Wifi
-        cmActivity.mCM.setAirplaneMode(true);
+        mCM.setAirplaneMode(true);
 
-        assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
-                ConnectivityManagerTestActivity.LONG_TIMEOUT));
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI,
+                State.DISCONNECTED, LONG_TIMEOUT));
 
         try {
-            Thread.sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+            Thread.sleep(SHORT_TIMEOUT);
         } catch (Exception e) {
             log("exception: " + e.toString());
         }
 
         // Prepare for state validation
-        NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        NetworkInfo networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
         assertEquals(State.DISCONNECTED, networkInfo.getState());
-        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI,
+        setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI,
                 networkInfo.getState(), NetworkState.TO_CONNECTION, State.CONNECTED);
 
         // Disable airplane mode
-        cmActivity.mCM.setAirplaneMode(false);
+        mCM.setAirplaneMode(false);
 
-        assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                WIFI_CONNECTION_TIMEOUT));
         if (!mWifiOnlyFlag) {
-            assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
-                    State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+            assertTrue(waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+                    State.DISCONNECTED, LONG_TIMEOUT));
         }
 
         // validate the state transition
-        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+        if (!validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
             log("Wifi state transition validation failed.");
             log("reason: " +
-                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+                    getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
             assertTrue(false);
         }
     }
@@ -505,35 +488,33 @@
         assertNotNull("SSID is null", mTestAccessPoint);
         //Connect to mTestAccessPoint
         assertTrue("failed to connect to " + mTestAccessPoint,
-                cmActivity.connectToWifi(mTestAccessPoint));
-        assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
-                ConnectivityManagerTestActivity.LONG_TIMEOUT));
-        assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+                connectToWifi(mTestAccessPoint));
+        assertTrue(waitForWifiState(WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                WIFI_CONNECTION_TIMEOUT));
         assertNotNull("Not associated with any AP",
-                      cmActivity.mWifiManager.getConnectionInfo().getBSSID());
+                      mWifiManager.getConnectionInfo().getBSSID());
 
         try {
-            Thread.sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+            Thread.sleep(SHORT_TIMEOUT);
         } catch (Exception e) {
             log("exception: " + e.toString());
         }
 
         // Disconnect from the current AP
         log("disconnect from the AP");
-        if (!cmActivity.disconnectAP()) {
+        if (!disconnectAP()) {
             log("failed to disconnect from " + mTestAccessPoint);
         }
 
         // Verify the connectivity state for Wifi is DISCONNECTED
-        assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
-                ConnectivityManagerTestActivity.LONG_TIMEOUT));
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI,
+                State.DISCONNECTED, LONG_TIMEOUT));
 
-        if (!cmActivity.disableWifi()) {
+        if (!disableWifi()) {
             log("disable Wifi failed");
             return;
         }
-        assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_DISABLED,
-                ConnectivityManagerTestActivity.LONG_TIMEOUT));
+        assertTrue(waitForWifiState(WifiManager.WIFI_STATE_DISABLED, LONG_TIMEOUT));
     }
 }
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
index f12e62e..183f2a9 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
@@ -16,7 +16,7 @@
 
 package com.android.connectivitymanagertest.functional;
 
-import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
+import com.android.connectivitymanagertest.ConnectivityManagerTestBase;
 import com.android.connectivitymanagertest.WifiAssociationTestRunner;
 
 import android.content.Context;
@@ -32,7 +32,6 @@
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo.State;
 import android.test.suitebuilder.annotation.LargeTest;
-import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 
 /**
@@ -43,30 +42,22 @@
  * -w com.android.connectivitymanagertest/.WifiAssociationTestRunner"
  */
 public class WifiAssociationTest
-    extends ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
+        extends ConnectivityManagerTestBase {
     private static final String TAG = "WifiAssociationTest";
-    private ConnectivityManagerTestActivity mAct;
     private String mSsid = null;
     private String mPassword = null;
     private String mSecurityType = null;
     private String mFrequencyBand = null;
     private int mBand;
-    private WifiManager mWifiManager = null;
 
     enum SECURITY_TYPE {
         OPEN, WEP64, WEP128, WPA_TKIP, WPA2_AES
-    };
-
-    public WifiAssociationTest() {
-        super(ConnectivityManagerTestActivity.class);
     }
 
     @Override
     public void setUp() throws Exception {
         super.setUp();
         WifiAssociationTestRunner mRunner = (WifiAssociationTestRunner)getInstrumentation();
-        mWifiManager = (WifiManager) mRunner.getContext().getSystemService(Context.WIFI_SERVICE);
-        mAct = getActivity();
         Bundle arguments = mRunner.getArguments();
         mSecurityType = arguments.getString("security-type");
         mSsid = arguments.getString("ssid");
@@ -77,17 +68,15 @@
         assertNotNull("Ssid is empty", mSsid);
         validateFrequencyBand();
         // enable Wifi and verify wpa_supplicant is started
-        assertTrue("enable Wifi failed", mAct.enableWifi());
-        sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT,
-                "interrupted while waiting for WPA_SUPPLICANT to start");
-        WifiInfo mConnection = mAct.mWifiManager.getConnectionInfo();
+        assertTrue("enable Wifi failed", enableWifi());
+        sleep(2 * SHORT_TIMEOUT, "interrupted while waiting for WPA_SUPPLICANT to start");
+        WifiInfo mConnection = mWifiManager.getConnectionInfo();
         assertNotNull(mConnection);
-        assertTrue("wpa_supplicant is not started ", mAct.mWifiManager.pingSupplicant());
+        assertTrue("wpa_supplicant is not started ", mWifiManager.pingSupplicant());
     }
 
     @Override
     public void tearDown() throws Exception {
-        log("tearDown()");
         super.tearDown();
     }
 
@@ -107,16 +96,16 @@
     private void connectToWifi(WifiConfiguration config) {
         // step 1: connect to the test access point
         assertTrue("failed to associate with " + config.SSID,
-                mAct.connectToWifiWithConfiguration(config));
+                connectToWifiWithConfiguration(config));
 
         // step 2: verify Wifi state and network state;
         assertTrue("failed to connect with " + config.SSID,
-                mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
-                State.CONNECTED, ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+                waitForNetworkState(ConnectivityManager.TYPE_WIFI,
+                State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
 
         // step 3: verify the current connected network is the given SSID
-        assertNotNull("Wifi connection returns null", mAct.mWifiManager.getConnectionInfo());
-        assertTrue(config.SSID.contains(mAct.mWifiManager.getConnectionInfo().getSSID()));
+        assertNotNull("Wifi connection returns null", mWifiManager.getConnectionInfo());
+        assertTrue(config.SSID.contains(mWifiManager.getConnectionInfo().getSSID()));
     }
 
     private void sleep(long sometime, String errorMsg) {
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
index de0298e..ad73ee1 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
@@ -16,35 +16,19 @@
 
 package com.android.connectivitymanagertest.functional;
 
-import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
+import com.android.connectivitymanagertest.ConnectivityManagerTestBase;
 import com.android.connectivitymanagertest.ConnectivityManagerTestRunner;
 
-import android.R;
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.Intent;
 import android.content.Context;
-import android.content.res.Resources;
 import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiConfiguration.KeyMgmt;
-import android.net.wifi.WifiConfiguration.Status;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.net.ConnectivityManager;
-import android.net.DhcpInfo;
-import android.net.NetworkInfo;
 import android.net.NetworkInfo.State;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Settings;
 import android.test.suitebuilder.annotation.LargeTest;
-import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 
-import com.android.internal.util.AsyncChannel;
-
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -56,39 +40,25 @@
  *          -w com.android.connectivitymanagertest/.ConnectivityManagerTestRunner
  */
 public class WifiConnectionTest
-    extends ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
+    extends ConnectivityManagerTestBase {
     private static final String TAG = "WifiConnectionTest";
     private static final boolean DEBUG = false;
     private List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>();
-    private ConnectivityManagerTestActivity mAct;
-    private ConnectivityManagerTestRunner mRunner;
-    private WifiManager mWifiManager = null;
-    private Set<WifiConfiguration> enabledNetworks = null;
-
-    public WifiConnectionTest() {
-        super(ConnectivityManagerTestActivity.class);
-    }
 
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        mRunner = ((ConnectivityManagerTestRunner)getInstrumentation());
-        mWifiManager = (WifiManager) mRunner.getContext().getSystemService(Context.WIFI_SERVICE);
-
-        mAct = getActivity();
-
-        networks = mAct.loadNetworkConfigurations();
+        networks = loadNetworkConfigurations();
         if (DEBUG) {
             printNetworkConfigurations();
         }
 
         // enable Wifi and verify wpa_supplicant is started
-        assertTrue("enable Wifi failed", mAct.enableWifi());
-        sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT,
-                "interrupted while waiting for WPA_SUPPLICANT to start");
-        WifiInfo mConnection = mAct.mWifiManager.getConnectionInfo();
+        assertTrue("enable Wifi failed", enableWifi());
+        sleep(2 * SHORT_TIMEOUT, "interrupted while waiting for WPA_SUPPLICANT to start");
+        WifiInfo mConnection = mWifiManager.getConnectionInfo();
         assertNotNull(mConnection);
-        assertTrue("wpa_supplicant is not started ", mAct.mWifiManager.pingSupplicant());
+        assertTrue("wpa_supplicant is not started ", mWifiManager.pingSupplicant());
     }
 
     private void printNetworkConfigurations() {
@@ -101,8 +71,7 @@
 
     @Override
     public void tearDown() throws Exception {
-        log("tearDown()");
-        mAct.removeConfiguredNetworksAndDisableWifi();
+        removeConfiguredNetworksAndDisableWifi();
         super.tearDown();
     }
 
@@ -114,20 +83,20 @@
     private void connectToWifi(WifiConfiguration config) {
         // step 1: connect to the test access point
         assertTrue("failed to connect to " + config.SSID,
-                mAct.connectToWifiWithConfiguration(config));
+                connectToWifiWithConfiguration(config));
 
         // step 2: verify Wifi state and network state;
-        assertTrue(mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
-                State.CONNECTED, ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI,
+                State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
 
         // step 3: verify the current connected network is the given SSID
-        assertNotNull("Wifi connection returns null", mAct.mWifiManager.getConnectionInfo());
+        assertNotNull("Wifi connection returns null", mWifiManager.getConnectionInfo());
         if (DEBUG) {
             log("config.SSID = " + config.SSID);
-            log("mAct.mWifiManager.getConnectionInfo.getSSID()" +
-                    mAct.mWifiManager.getConnectionInfo().getSSID());
+            log("mWifiManager.getConnectionInfo.getSSID()" +
+                    mWifiManager.getConnectionInfo().getSSID());
         }
-        assertTrue(config.SSID.contains(mAct.mWifiManager.getConnectionInfo().getSSID()));
+        assertTrue(config.SSID.contains(mWifiManager.getConnectionInfo().getSSID()));
     }
 
     private void sleep(long sometime, String errorMsg) {
@@ -149,8 +118,7 @@
             log("-- START Wi-Fi connection test to : " + ssid + " --");
             connectToWifi(networks.get(i));
             // wait for 2 minutes between wifi stop and start
-            sleep(ConnectivityManagerTestActivity.WIFI_STOP_START_INTERVAL,
-                  "interruped while connected to wifi");
+            sleep(WIFI_STOP_START_INTERVAL, "interruped while connected to wifi");
             log("-- END Wi-Fi connection test to " + ssid + " -- ");
         }
     }
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
index 60595fb..790ca38 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
@@ -18,19 +18,13 @@
 
 
 import com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner;
-import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
+import com.android.connectivitymanagertest.ConnectivityManagerTestBase;
 
-import android.content.Context;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
 import android.net.wifi.WifiConfiguration.AuthAlgorithm;
 import android.net.wifi.WifiManager;
 import android.os.Environment;
-import android.os.IPowerManager;
-import android.os.PowerManager;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 
@@ -42,30 +36,24 @@
  * Stress the wifi driver as access point.
  */
 public class WifiApStress
-    extends ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
+    extends ConnectivityManagerTestBase {
     private final static String TAG = "WifiApStress";
     private static String NETWORK_ID = "AndroidAPTest";
     private static String PASSWD = "androidwifi";
     private final static String OUTPUT_FILE = "WifiStressTestOutput.txt";
-    private ConnectivityManagerTestActivity mAct;
     private int iterations;
     private BufferedWriter mOutputWriter = null;
     private int mLastIteration = 0;
     private boolean mWifiOnlyFlag;
 
-    public WifiApStress() {
-        super(ConnectivityManagerTestActivity.class);
-    }
-
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        mAct = getActivity();
         ConnectivityManagerStressTestRunner mRunner =
             (ConnectivityManagerStressTestRunner)getInstrumentation();
         iterations = mRunner.mSoftapIterations;
         mWifiOnlyFlag = mRunner.mWifiOnlyFlag;
-        mAct.turnScreenOn();
+        turnScreenOn();
     }
 
     @Override
@@ -92,30 +80,28 @@
         config.preSharedKey = PASSWD;
 
         // If Wifi is enabled, disable it
-        if (mAct.mWifiManager.isWifiEnabled()) {
-            mAct.disableWifi();
+        if (mWifiManager.isWifiEnabled()) {
+            disableWifi();
         }
         int i;
         for (i = 0; i < iterations; i++) {
             Log.v(TAG, "iteration: " + i);
             mLastIteration = i;
             // enable Wifi tethering
-            assertTrue(mAct.mWifiManager.setWifiApEnabled(config, true));
+            assertTrue(mWifiManager.setWifiApEnabled(config, true));
             // Wait for wifi ap state to be ENABLED
-            assertTrue(mAct.waitForWifiAPState(WifiManager.WIFI_AP_STATE_ENABLED,
-                    2 * ConnectivityManagerTestActivity.LONG_TIMEOUT));
+            assertTrue(waitForWifiAPState(WifiManager.WIFI_AP_STATE_ENABLED, 2 * LONG_TIMEOUT));
             // Wait for wifi tethering result
-            assertEquals(ConnectivityManagerTestActivity.SUCCESS,
-                    mAct.waitForTetherStateChange(2*ConnectivityManagerTestActivity.SHORT_TIMEOUT));
+            assertEquals(SUCCESS, waitForTetherStateChange(2 * SHORT_TIMEOUT));
             // Allow the wifi tethering to be enabled for 10 seconds
             try {
-                Thread.sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+                Thread.sleep(2 * SHORT_TIMEOUT);
             } catch (Exception e) {
                 fail("thread in sleep is interrupted");
             }
-            assertTrue("no uplink data connection after Wi-Fi tethering", mAct.pingTest(null));
+            assertTrue("no uplink data connection after Wi-Fi tethering", pingTest(null));
             // Disable soft AP
-            assertTrue(mAct.mWifiManager.setWifiApEnabled(config, false));
+            assertTrue(mWifiManager.setWifiApEnabled(config, false));
             // Wait for 30 seconds until Wi-Fi tethering is stopped
             try {
                 Thread.sleep(30 * 1000);
@@ -123,7 +109,7 @@
             } catch (Exception e) {
                 fail("thread in sleep is interrupted");
             }
-            assertFalse("Wi-Fi AP disable failed", mAct.mWifiManager.isWifiApEnabled());
+            assertFalse("Wi-Fi AP disable failed", mWifiManager.isWifiApEnabled());
         }
         if (i == iterations) {
             mLastIteration = iterations;
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index e3c7cc4..04ce4b7 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -29,12 +29,11 @@
 import android.os.PowerManager;
 import android.provider.Settings;
 import android.view.KeyEvent;
-import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 
 import com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner;
-import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
+import com.android.connectivitymanagertest.ConnectivityManagerTestBase;
 
 import java.io.BufferedWriter;
 import java.io.File;
@@ -50,7 +49,7 @@
  *                  -w com.android.connectivitymanagertest/.ConnectivityManagerStressTestRunner
  */
 public class WifiStressTest
-    extends ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
+        extends ConnectivityManagerTestBase {
     private final static String TAG = "WifiStressTest";
 
     /**
@@ -67,7 +66,6 @@
     private final static long WIFI_SHUTDOWN_DELAY = 2 * 60 * 1000;
 
     private final static String OUTPUT_FILE = "WifiStressTestOutput.txt";
-    private ConnectivityManagerTestActivity mAct;
     private int mReconnectIterations;
     private int mWifiSleepTime;
     private int mScanIterations;
@@ -77,15 +75,10 @@
     private BufferedWriter mOutputWriter = null;
     private boolean mWifiOnlyFlag;
 
-    public WifiStressTest() {
-        super(ConnectivityManagerTestActivity.class);
-    }
-
     @Override
     public void setUp() throws Exception {
         super.setUp();
 
-        mAct = getActivity();
         mRunner = (ConnectivityManagerStressTestRunner) getInstrumentation();
         mReconnectIterations = mRunner.mReconnectIterations;
         mSsid = mRunner.mReconnectSsid;
@@ -98,15 +91,14 @@
             mPassword, mScanIterations, mWifiSleepTime));
         mOutputWriter = new BufferedWriter(new FileWriter(new File(
                 Environment.getExternalStorageDirectory(), OUTPUT_FILE), true));
-        mAct.turnScreenOn();
-        if (!mAct.mWifiManager.isWifiEnabled()) {
+        turnScreenOn();
+        if (!mWifiManager.isWifiEnabled()) {
             log("Enable wi-fi before stress tests.");
-            if (!mAct.enableWifi()) {
+            if (!enableWifi()) {
                 tearDown();
                 fail("enable wifi failed.");
             }
-            sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT,
-                    "Interruped while waiting for wifi on");
+            sleep(SHORT_TIMEOUT, "Interruped while waiting for wifi on");
         }
     }
 
@@ -166,33 +158,32 @@
             writeOutput(String.format("ssid appear %d out of %d scan iterations",
                     ssidAppearInScanResultsCount, i));
             long startTime = System.currentTimeMillis();
-            mAct.scanResultAvailable = false;
-            assertTrue("start scan failed", mAct.mWifiManager.startScan());
+            scanResultAvailable = false;
+            assertTrue("start scan failed", mWifiManager.startScan());
             while (true) {
                 if ((System.currentTimeMillis() - startTime) >
-                ConnectivityManagerTestActivity.WIFI_SCAN_TIMEOUT) {
-                    fail("Wifi scanning takes more than " +
-                            ConnectivityManagerTestActivity.WIFI_SCAN_TIMEOUT + " ms");
+                WIFI_SCAN_TIMEOUT) {
+                    fail("Wifi scanning takes more than " + WIFI_SCAN_TIMEOUT + " ms");
                 }
-                synchronized(mAct) {
+                synchronized(this) {
                     try {
-                        mAct.wait(ConnectivityManagerTestActivity.WAIT_FOR_SCAN_RESULT);
+                        wait(WAIT_FOR_SCAN_RESULT);
                     } catch (InterruptedException e) {
                         e.printStackTrace();
                     }
-                    if (mAct.scanResultAvailable) {
+                    if (scanResultAvailable) {
                         long scanTime = (System.currentTimeMillis() - startTime);
                         scanTimeSum += scanTime;
                         break;
                     }
                 }
             }
-            if ((mAct.mWifiManager.getScanResults() == null) ||
-                    (mAct.mWifiManager.getScanResults().size() <= 0)) {
+            if ((mWifiManager.getScanResults() == null) ||
+                    (mWifiManager.getScanResults().size() <= 0)) {
                 fail("Scan results are empty ");
             }
 
-            List<ScanResult> netList = mAct.mWifiManager.getScanResults();
+            List<ScanResult> netList = mWifiManager.getScanResults();
             if (netList != null) {
                 log("size of scan result list: " + netList.size());
                 for (int s = 0; s < netList.size(); s++) {
@@ -244,13 +235,13 @@
         config.proxySettings = ProxySettings.NONE;
 
         assertTrue("Failed to connect to Wi-Fi network: " + mSsid,
-                mAct.connectToWifiWithConfiguration(config));
-        assertTrue(mAct.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
-                ConnectivityManagerTestActivity.SHORT_TIMEOUT));
-        assertTrue(mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+                connectToWifiWithConfiguration(config));
+        assertTrue(waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
+                SHORT_TIMEOUT));
+        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                WIFI_CONNECTION_TIMEOUT));
         // Run ping test to verify the data connection
-        assertTrue("Wi-Fi is connected, but no data connection.", mAct.pingTest(null));
+        assertTrue("Wi-Fi is connected, but no data connection.", pingTest(null));
 
         int i;
         long sum = 0;
@@ -263,33 +254,33 @@
             writeOutput(String.format("iteration %d out of %d",
                     i, mReconnectIterations));
             log("iteration: " + i);
-            mAct.turnScreenOff();
+            turnScreenOff();
             PowerManager pm =
                 (PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE);
             assertFalse(pm.isScreenOn());
             sleep(WIFI_IDLE_MS + WIFI_SHUTDOWN_DELAY, "Interruped while wait for wifi to be idle");
             assertTrue("Wait for Wi-Fi to idle timeout",
-                    mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
-                    6 * ConnectivityManagerTestActivity.SHORT_TIMEOUT));
+                    waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
+                    6 * SHORT_TIMEOUT));
             if (!mWifiOnlyFlag) {
                 // use long timeout as the pppd startup may take several retries.
                 assertTrue("Wait for cellular connection timeout",
-                        mAct.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
-                        2 * ConnectivityManagerTestActivity.LONG_TIMEOUT));
+                        waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
+                        2 * LONG_TIMEOUT));
             }
             sleep(mWifiSleepTime, "Interrupted while device is in sleep mode");
             // Verify the wi-fi is still off and data connection is on
             assertEquals("Wi-Fi is reconnected", State.DISCONNECTED,
-                    mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState());
+                    mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState());
 
             if (!mWifiOnlyFlag) {
                 assertEquals("Cellular connection is down", State.CONNECTED,
-                             mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState());
-                assertTrue("Mobile is connected, but no data connection.", mAct.pingTest(null));
+                             mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState());
+                assertTrue("Mobile is connected, but no data connection.", pingTest(null));
             }
 
             // Turn screen on again
-            mAct.turnScreenOn();
+            turnScreenOn();
             // Wait for 2 seconds for the lock screen
             sleep(2 * 1000, "wait 2 seconds for lock screen");
             // Disable lock screen by inject menu key event
@@ -298,16 +289,16 @@
             // Measure the time for Wi-Fi to get connected
             long startTime = System.currentTimeMillis();
             assertTrue("Wait for Wi-Fi enable timeout after wake up",
-                    mAct.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
-                    ConnectivityManagerTestActivity.SHORT_TIMEOUT));
+                    waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
+                    SHORT_TIMEOUT));
             assertTrue("Wait for Wi-Fi connection timeout after wake up",
-                    mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                    ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
+                    waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                    WIFI_CONNECTION_TIMEOUT));
             long connectionTime = System.currentTimeMillis() - startTime;
             sum += connectionTime;
             log("average reconnection time is: " + sum/(i+1));
 
-            assertTrue("Reconnect to Wi-Fi network, but no data connection.", mAct.pingTest(null));
+            assertTrue("Reconnect to Wi-Fi network, but no data connection.", pingTest(null));
         }
         if (i == mReconnectIterations) {
             writeOutput(String.format("iteration %d out of %d",
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java
index e44023b..7a9bc78 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java
@@ -20,9 +20,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.Context;
-import android.app.Instrumentation;
-import android.os.Handler;
-import android.os.Message;
 import android.net.NetworkInfo;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiConfiguration;
@@ -33,11 +30,8 @@
 import android.test.suitebuilder.annotation.LargeTest;
 import android.test.AndroidTestCase;
 
-import java.util.ArrayList;
 import java.util.List;
 
-import android.util.Log;
-
 /**
  * Test wifi client
  */
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiSoftAPTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiSoftAPTest.java
index 3f43e48..f202862 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiSoftAPTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiSoftAPTest.java
@@ -16,13 +16,7 @@
 
 package com.android.connectivitymanagertest.unit;
 
-import android.content.BroadcastReceiver;
-import android.content.Intent;
 import android.content.Context;
-import android.app.Instrumentation;
-import android.os.Handler;
-import android.os.Message;
-import android.net.ConnectivityManager;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
@@ -30,8 +24,6 @@
 import android.test.suitebuilder.annotation.LargeTest;
 import android.test.AndroidTestCase;
 
-import java.util.ArrayList;
-
 import android.util.Log;
 
 /**
diff --git a/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java b/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java
index ebecf2e3..a2e9ae8 100644
--- a/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java
+++ b/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java
@@ -83,8 +83,8 @@
 
         mImageReaderLock.lock();
         try {
-            mImageReader = new ImageReader(WIDTH, HEIGHT, PixelFormat.RGBA_8888, 2);
-            mImageReader.setImageAvailableListener(mImageListener, mHandler);
+            mImageReader = ImageReader.newInstance(WIDTH, HEIGHT, PixelFormat.RGBA_8888, 2);
+            mImageReader.setOnImageAvailableListener(mImageListener, mHandler);
             mSurface = mImageReader.getSurface();
         } finally {
             mImageReaderLock.unlock();
@@ -409,19 +409,11 @@
                 }
 
                 Log.d(TAG, "New image available from virtual display.");
-                Image image = reader.getNextImage();
+
+                // Get the latest buffer.
+                Image image = reader.acquireLatestImage();
                 if (image != null) {
                     try {
-                        // Get the latest buffer.
-                        for (;;) {
-                            Image nextImage = reader.getNextImage();
-                            if (nextImage == null) {
-                                break;
-                            }
-                            reader.releaseImage(image);
-                            image = nextImage;
-                        }
-
                         // Scan for colors.
                         int color = scanImage(image);
                         synchronized (this) {
@@ -431,7 +423,7 @@
                             }
                         }
                     } finally {
-                        reader.releaseImage(image);
+                        image.close();
                     }
                 }
             } finally {
diff --git a/docs/html/guide/topics/renderscript/compute.jd b/docs/html/guide/topics/renderscript/compute.jd
index 607d16e..14a1682 100644
--- a/docs/html/guide/topics/renderscript/compute.jd
+++ b/docs/html/guide/topics/renderscript/compute.jd
@@ -10,6 +10,11 @@
 
     <ol>
       <li><a href="#writing-an-rs-kernel">Writing a RenderScript Kernel</a></li>
+      <li><a href="#access-rs-apis">Accessing RenderScript Java APIs</a>
+        <ol>
+          <li><a href="#ide-setup">Setting Up Your Development Environment</a></li>
+        </ol>
+      </li>
       <li><a href="#using-rs-from-java">Using RenderScript from Java Code</a></li>
     </ol>
 
@@ -144,9 +149,85 @@
 beneficial on some architectures due to additional optimizations only available with relaxed
 precision (such as SIMD CPU instructions).</p>
 
+
+<h2 id="access-rs-apis">Accessing RenderScript Java APIs</h2>
+
+<p>When developing an Android application that uses RenderScript, you can access its Java API in
+  one of two ways. The APIs are available in the {@link android.renderscript} package
+  on devices running Android 3.0 (API level 11) and higher. These are the original APIs for
+  RenderScript. The APIs are also available as a Support Library in the
+  {@link android.support.v8.renderscript} package, which allow you to use them on devices running
+  Android 2.2 (API level 8) and higher.</p>
+
+<p>We strongly recommend using the Support Library APIs for accessing RenderScript because they
+  include the latest improvements to the RenderScript compute framework and provide a wider range
+  of device compatibility. Using the RenderScript APIs in the Support Library requires specific
+  setup procedures for your development environment, which is described in the next section.</p>
+
+
+<h3 id="ide-setup">Using the RenderScript Support Library APIs</h3>
+
+<p>In order to use the Support Library RenderScript APIs, you must configure your development
+  environment to be able to access them. The following Android SDK tools are required for using
+  these APIs:</p>
+
+<ul>
+  <li>Android SDK Tools revision 22.2 or higher</li>
+  <li>Android SDK Build-tools revision 18.1.0 or higher</li>
+</ul>
+
+<p>You can check and update the installed version of these tools in the
+  <a href="{@docRoot}tools/help/sdk-manager.html">Android SDK Manager</a>.</p>
+
+<p class="note">
+  <strong>Note:</strong> Use of Support Library RenderScript APIs is not currently supported with
+  Android Studio or Gradle-based builds.
+</p>
+
+<p>To use the Support Library RenderScript APIs in Eclipse:</p>
+
+<ol>
+  <li>Make sure you have the required Android SDK version and Build Tools version installed.</li>
+  <li>Open the {@code project.properties} file in the root folder of your application project.</li>
+  <li>Add the following lines to the file:
+<pre>
+renderscript.target=18
+renderscript.support.mode=true
+sdk.buildtools=18.1.0
+</pre>
+  </li>
+  <li>In your application classes that use RenderScript, add an import for the Support Library
+    classes:
+<pre>
+import android.support.v8.renderscript.*;
+</pre>
+  </li>
+</ol>
+
+<p>The {@code project.properties} settings listed above control specific behavior in the Android
+  build process:</p>
+
+<ul>
+  <li>{@code renderscript.target} - Specifies the bytecode version to be generated. We
+    recommend you set this value the highest available API level and set {@code
+    renderscript.support.mode} to {@code true}. Valid values for this setting are any integer value
+    from 11 to the most recently released API level. If your minimum SDK version specified in your
+    application manifest is set to a higher value, this value is ignored and the target value is set
+    to the minimum SDK version.</li>
+  <li>{@code renderscript.support.mode} - Specifies that the generated bytecode should fall
+    back to a compatible version if the device it is running on does not support the target version.
+    </li>
+  <li>{@code sdk.buildtools} - The version of the Android SDK build tools to use. This value
+    should be set to 18.1.0 or higher. If this option is not specified, the highest installed build
+    tools version is used. You should always set this value to ensure the consistency of builds
+    across development machines with different configurations.</li>
+</ul>
+
+
 <h2 id="using-rs-from-java">Using RenderScript from Java Code</h2>
 
-<p>Using RenderScript from Java code relies on the {@link android.renderscript} APIs. Most
+<p>Using RenderScript from Java code relies on the API classes located in the
+{@link android.renderscript} or the {@link android.support.v8.renderscript} package. Most
 applications follow the same basic usage patterns:</p>
 
 <ol>
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 4ea3752..0581435 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -5,43 +5,43 @@
 page.metaDescription=Download the official Android SDK to develop apps for Android-powered devices.
 
 
-sdk.linux32_bundle_download=adt-bundle-linux-x86-20130729.zip
-sdk.linux32_bundle_bytes=457716139
-sdk.linux32_bundle_checksum=b3686d10dc1cbceba1074404d4386283
+sdk.linux32_bundle_download=adt-bundle-linux-x86-20130911.zip
+sdk.linux32_bundle_bytes=474916528
+sdk.linux32_bundle_checksum=7eacc7124299ea99a8fa15c59123540f
 
-sdk.linux64_bundle_download=adt-bundle-linux-x86_64-20130729.zip
-sdk.linux64_bundle_bytes=458006784
-sdk.linux64_bundle_checksum=1fabcc3f772ba8b2fc194d6e0449da17
+sdk.linux64_bundle_download=adt-bundle-linux-x86_64-20130911.zip
+sdk.linux64_bundle_bytes=475207785
+sdk.linux64_bundle_checksum=daa5794a27be7c7fa708c3d28833b0d3
 
-sdk.mac64_bundle_download=adt-bundle-mac-x86_64-20130729.zip
-sdk.mac64_bundle_bytes=428792424
-sdk.mac64_bundle_checksum=6c42b9966abcfa8a75c0ee83d0d95882
+sdk.mac64_bundle_download=adt-bundle-mac-x86_64-20130911.zip
+sdk.mac64_bundle_bytes=448575446
+sdk.mac64_bundle_checksum=a1e0cbcc820ae734cfdf439c40811b4c
 
-sdk.win32_bundle_download=adt-bundle-windows-x86-20130729.zip
-sdk.win32_bundle_bytes=463931746
-sdk.win32_bundle_checksum=51faf4e5fdf9c5b4a176179a99ce3511
+sdk.win32_bundle_download=adt-bundle-windows-x86-20130911.zip
+sdk.win32_bundle_bytes=481794820
+sdk.win32_bundle_checksum=88a2f4f242aac44f4b1c53e6eccc8710
 
-sdk.win64_bundle_download=adt-bundle-windows-x86_64-20130729.zip
-sdk.win64_bundle_bytes=464064756
-sdk.win64_bundle_checksum=e8f05c1fddb8e609e880de23113c7426
+sdk.win64_bundle_download=adt-bundle-windows-x86_64-20130911.zip
+sdk.win64_bundle_bytes=481927327
+sdk.win64_bundle_checksum=e3fa9b7e38af9ed9ac0e99fce3c7026c
 
 
 
-sdk.linux_download=android-sdk_r22.0.5-linux.tgz
-sdk.linux_bytes=105641005
-sdk.linux_checksum=8201b10c21510f082c54f58a9bb082c8
+sdk.linux_download=android-sdk_r22.2-linux.tgz
+sdk.linux_bytes=100909403
+sdk.linux_checksum=2a3776839e823ba9acb7a87a3fe26e02
 
-sdk.mac_download=android-sdk_r22.0.5-macosx.zip
-sdk.mac_bytes=77225724
-sdk.mac_checksum=94f3cbe896c332b94ee0408ae610a4b8
+sdk.mac_download=android-sdk_r22.2-macosx.zip
+sdk.mac_bytes=74857114
+sdk.mac_checksum=9dfef6404e2f842c433073796aed8b7d
 
-sdk.win_download=android-sdk_r22.0.5-windows.zip
-sdk.win_bytes=113510621
-sdk.win_checksum=30695dffc41e0d7cf9ff948ab0c48920
+sdk.win_download=android-sdk_r22.2-windows.zip
+sdk.win_bytes=108790714
+sdk.win_checksum=1ac4c104378cd53049daa6c4458ec544
 
-sdk.win_installer=installer_r22.0.5-windows.exe
-sdk.win_installer_bytes=93505782
-sdk.win_installer_checksum=940849be19ac6151e3e35c8706c81d86
+sdk.win_installer=installer_r22.2-windows.exe
+sdk.win_installer_bytes=88788974
+sdk.win_installer_checksum=e5503fa059297d2b18475c086ac6e80c
 
 
 
diff --git a/docs/html/sdk/installing/installing-adt.jd b/docs/html/sdk/installing/installing-adt.jd
index bdc07d0..e038d20 100644
--- a/docs/html/sdk/installing/installing-adt.jd
+++ b/docs/html/sdk/installing/installing-adt.jd
@@ -1,8 +1,8 @@
 page.title=Installing the Eclipse Plugin
-adt.zip.version=22.0.5
-adt.zip.download=ADT-22.0.5.zip
-adt.zip.bytes=16839757
-adt.zip.checksum=1097fccf32063e3638a9d27aa0f295ca
+adt.zip.version=22.2.0
+adt.zip.download=ADT-22.2.0.zip
+adt.zip.bytes=14474195
+adt.zip.checksum=52892c9e3b1ad2d1e6edd50e48b2a127
 
 @jd:body
 
diff --git a/docs/html/tools/sdk/eclipse-adt.jd b/docs/html/tools/sdk/eclipse-adt.jd
index e9c514e..151707a 100644
--- a/docs/html/tools/sdk/eclipse-adt.jd
+++ b/docs/html/tools/sdk/eclipse-adt.jd
@@ -57,6 +57,44 @@
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>ADT 22.2</a> <em>(September 2013)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+<dl>
+  <dt>Dependencies:</dt>
+
+  <dd>
+    <ul>
+      <li>Java 1.6 or higher is required.</li>
+      <li>Eclipse Helios (Version 3.6.2) or higher is required.</li>
+      <li>This version of ADT is designed for use with
+        <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r22.2</a>.
+        If you haven't already installed SDK Tools r22.2 into your SDK, use the
+        Android SDK Manager to do so.</li>
+    </ul>
+  </dd>
+
+  <dt>General Notes:</dt>
+  <dd>
+    <ul>
+      <li>Updated build tools to allow use of RenderScript on older versions of Android
+       using new features in the
+       <a href="{@docRoot}tools/support-library/features.html#v8">Support Library</a>.</li>
+      <li>Reverted signing changes that sometimes trigger a signing verification problem on older
+        platforms.</li>
+      <li>Fixed problem with gradle export function for the Windows platform.</li>
+    </ul>
+  </dd>
+
+</dl>
+</div>
+</div>
+
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>ADT 22.0.5</a> <em>(July 2013)</em>
   </p>
 
@@ -78,7 +116,7 @@
   <dt>General Notes:</dt>
   <dd>
     <ul>
-      <li>Fixed Renderscript compilation issue for Windows platforms.</li>
+      <li>Fixed RenderScript compilation issue for Windows platforms.</li>
       <li>Updated <a href="{@docRoot}tools/help/systrace.html">Systrace</a> report generation
         in the Monitor and DDMS perspectives.</li>
     </ul>
@@ -113,7 +151,7 @@
   <dt>General Notes:</dt>
   <dd>
     <ul>
-      <li>Fixed problem with compiling Renderscript code.</li>
+      <li>Fixed problem with compiling RenderScript code.</li>
       <li>Improved Gradle export with better workflow and error reporting.</li>
       <li>Improved Gradle multi-module export feature.</li>
       <li>Updated build logic to force exporting of the classpath containers unless you are using
@@ -1005,7 +1043,7 @@
 <dt>Bug fixes:</dt>
 <dd>
 <ul>
-  <li>Fixed build issue when using Renderscript in projects that target API levels 11-13
+  <li>Fixed build issue when using RenderScript in projects that target API levels 11-13
     (<a href="http://code.google.com/p/android/issues/detail?id=21006">Issue 21006</a>).</li>
   <li>Fixed issue when creating projects from existing source code.</li>
   <li>Fixed issues in the SDK Manager
diff --git a/docs/html/tools/sdk/tools-notes.jd b/docs/html/tools/sdk/tools-notes.jd
index 4aef8a0..e8c4717 100644
--- a/docs/html/tools/sdk/tools-notes.jd
+++ b/docs/html/tools/sdk/tools-notes.jd
@@ -30,6 +30,54 @@
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>SDK Tools, Revision 22.2</a> <em>(September 2013)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <dl>
+    <dt>Dependencies:</dt>
+    <dd>
+      <ul>
+        <li>Android SDK Platform-tools revision 16 or later.</li>
+        <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is
+          designed for use with ADT 22.2 and later. If you haven't already, update your
+        <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 22.2.</li>
+        <li>If you are developing outside Eclipse, you must have
+          <a href="http://ant.apache.org/">Apache Ant</a> 1.8 or later.</li>
+      </ul>
+    </dd>
+
+    <dt>General Notes:</dt>
+    <dd>
+      <ul>
+        <li>Updated build tools to allow use of RenderScript on older versions of Android
+         using new features in the
+         <a href="{@docRoot}tools/support-library/features.html#v8">Support Library</a>.</li>
+        <li>Moved the Systrace tool to the {@code &gt;sdk&lt;/platform-tools/} directory. </li>
+        <li>Modified <a href="{@docRoot}tools/help/gltracer.html">Tracer for OpenGL ES</a> to
+          support OpenGL ES 3.0.</li>
+        <li>Lint
+          <ul>
+            <li>Fixed problem with lint not detecting custom namespaces.
+              (<a href="http://b.android.com/55673">Issue 55673</a>)</li>
+            <li>Fixed problem with the XML report including invalid characters.
+              (<a href="http://b.android.com/56205">Issue 56205</a>)</li>
+            <li>Fixed command-line execution of lint to work in headless mode to support execution
+              by build servers. (<a href="http://b.android.com/55820">Issue 55820</a>)</li>
+          </ul>
+        </li>
+        <li>Improved support for path names with spaces in the Windows command-line tools.</li>
+      </ul>
+    </dd>
+    </dl>
+  </div>
+</div>
+
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>SDK Tools, Revision 22.0.5</a> <em>(July 2013)</em>
   </p>
 
@@ -55,10 +103,10 @@
     <dt>General Notes:</dt>
     <dd>
       <ul>
-        <li>Fixed Renderscript compilation issue for Windows platforms with ant.</li>
+        <li>Fixed RenderScript compilation issue for Windows platforms with ant.</li>
         <li>Updated <a href="{@docRoot}tools/help/systrace.html">Systrace</a> to work with the
           Android 4.3 platform image.</li>
-        <li>Fixed packaging of Renderscript compiler.</li>
+        <li>Fixed packaging of RenderScript compiler.</li>
         <li>Build tools 18.0.0 is obsolete and 18.0.1 should be used instead.</li>
       </ul>
     </dd>
@@ -95,7 +143,7 @@
     <dt>General Notes:</dt>
     <dd>
       <ul>
-        <li>Fixed problem with compiling Renderscript code.</li>
+        <li>Fixed problem with compiling RenderScript code.</li>
       </ul>
     </dd>
     </dl>
@@ -274,17 +322,17 @@
           </ul>
         </li>
 
-        <li>Renderscript
+        <li>RenderScript
           <ul>
             <li>Added support for
               <a href="{@docRoot}guide/topics/renderscript/compute.html#filterscript">Filterscript</a>
               compilation.</li>
-            <li>Added new project setting to control the Renderscript compilation target separately
+            <li>Added new project setting to control the RenderScript compilation target separately
               from an Android project. Adding the following line to a {@code project.properties}
-              file causes Renderscript code to be compiled for Android API Level 17, while the
+              file causes RenderScript code to be compiled for Android API Level 17, while the
               containing application can target a different (lower) API level:
               <pre>renderscript.target = 17</pre>
-              Previously, the Renderscript compilation target was tied to the
+              Previously, the RenderScript compilation target was tied to the
               {@code android:minSdkVersion} setting in the manifest.
               (<a href="http://code.google.com/p/android/issues/detail?id=40487">Issue 40487</a>)
             </li>
@@ -483,7 +531,7 @@
         <li>Improved resize algorithm for better rendering on scaled emulator windows.</li>
         <li>Fixed a bug in the {@code lint} check for unprotected broadcast receivers to ignore
 unprotected receivers for default Android actions.</li>
-        <li>Fixed build issue for projects using Renderscript.</li>
+        <li>Fixed build issue for projects using RenderScript.</li>
         <li>Fixed memory leak in the emulator.</li>
       </ul>
     </dd>
@@ -823,7 +871,7 @@
     <li>Fixed emulator crash on Linux due to improper webcam detection
     (<a href="http://code.google.com/p/android/issues/detail?id=20952">Issue 20952</a>).</li>
     <li>Fixed emulator issue when using the <code>-wipe-data</code> argument.</li>
-    <li>Fixed build issue when using Renderscript in projects that target API levels 11-13
+    <li>Fixed build issue when using RenderScript in projects that target API levels 11-13
     (<a href="http://code.google.com/p/android/issues/detail?id=21006">Issue 21006</a>).</li>
     <li>Fixed issue when creating an AVD using the GoogleTV addon
     (<a href="http://code.google.com/p/android/issues/detail?id=20963">Issue 20963</a>).</li>
diff --git a/docs/html/tools/support-library/features.jd b/docs/html/tools/support-library/features.jd
index 8d25d96..65148bf 100644
--- a/docs/html/tools/support-library/features.jd
+++ b/docs/html/tools/support-library/features.jd
@@ -15,6 +15,7 @@
           <li><a href="#v7-mediarouter">v7 mediarouter library</a></li>
         </ol>
       </li>
+      <li><a href="#v8">v8 Support Library</a></li>
       <li><a href="#v13">v13 Support Library</a></li>
     </ol>
 
@@ -252,7 +253,7 @@
 where "18.0.0" is the minimum revision at which the library is available. For example:</p>
 
 <pre>
-com.android.support:support-v7-mediarouter:18.0.0
+com.android.support:mediarouter-v7:18.0.+
 </pre>
 
 <p class="caution">The v7 mediarouter library APIs introduced in Support Library
@@ -262,6 +263,24 @@
 developer preview</a>. </p>
 
 
+<h2 id="v8">v8 Support Library</h2>
+
+<p>This library is designed to be used with Android (API level 8) and higher. It adds support for
+  the <a href="{@docRoot}guide/topics/renderscript/compute.html">RenderScript</a> computation
+  framework. These APIs are included in the {@link android.support.v8.renderscript} package. You
+  should be aware that the steps for including these APIs in your application is <em>very
+  different</em> from other support library APIs. For more information about using these APIs
+  in your application, see the
+  <a href="{@docRoot}guide/topics/renderscript/compute.html#access-rs-apis">RenderScript</a>
+  developer guide.</p>
+
+<p class="note">
+  <strong>Note:</strong> Use of RenderScript with the support library is supported with the Android
+  Eclipse plugin and Ant build tools. It is <em>not currently</em> supported with Android Studio or
+  Gradle-based builds.
+</p>
+
+
 <h2 id="v13">v13 Support Library</h2>
 
 <p>This library is designed to be used for Android 3.2 (API level 13) and higher. It adds support
diff --git a/docs/html/tools/support-library/index.jd b/docs/html/tools/support-library/index.jd
index 06c7a3f..4ee8c12 100644
--- a/docs/html/tools/support-library/index.jd
+++ b/docs/html/tools/support-library/index.jd
@@ -58,6 +58,7 @@
 
 <p>This section provides details about the Support Library package releases.</p>
 
+
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img" alt=""
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index 9f442f5..a346e17 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -16,20 +16,19 @@
 
 package android.media;
 
-import android.graphics.ImageFormat;
 import java.nio.ByteBuffer;
 import java.lang.AutoCloseable;
 
 /**
  * <p>A single complete image buffer to use with a media source such as a
  * {@link MediaCodec} or a
- * {@link android.hardware.camera2.CameraDevice}.</p>
+ * {@link android.hardware.camera2.CameraDevice CameraDevice}.</p>
  *
  * <p>This class allows for efficient direct application access to the pixel
  * data of the Image through one or more
  * {@link java.nio.ByteBuffer ByteBuffers}. Each buffer is encapsulated in a
  * {@link Plane} that describes the layout of the pixel data in that plane. Due
- * to this direct access, and unlike the {@link android.graphics.Bitmap} class,
+ * to this direct access, and unlike the {@link android.graphics.Bitmap Bitmap} class,
  * Images are not directly usable as as UI resources.</p>
  *
  * <p>Since Images are often directly produced or consumed by hardware
@@ -40,19 +39,28 @@
  * from various media sources, not closing old Image objects will prevent the
  * availability of new Images once
  * {@link ImageReader#getMaxImages the maximum outstanding image count} is
- * reached.</p>
+ * reached. When this happens, the function acquiring new Images will typically
+ * throw an {@link IllegalStateException}.</p>
  *
  * @see ImageReader
  */
-public interface Image extends AutoCloseable {
+public abstract class Image implements AutoCloseable {
+    /**
+     * @hide
+     */
+    protected Image() {
+    }
+
     /**
      * Get the format for this image. This format determines the number of
      * ByteBuffers needed to represent the image, and the general layout of the
      * pixel data in each in ByteBuffer.
      *
+     * <p>
      * The format is one of the values from
-     * {@link android.graphics.ImageFormat}. The mapping between the formats and
-     * the planes is as follows:
+     * {@link android.graphics.ImageFormat ImageFormat}. The mapping between the
+     * formats and the planes is as follows:
+     * </p>
      *
      * <table>
      * <tr>
@@ -61,13 +69,14 @@
      *   <th>Layout details</th>
      * </tr>
      * <tr>
-     *   <td>{@link android.graphics.ImageFormat#JPEG}</td>
+     *   <td>{@link android.graphics.ImageFormat#JPEG JPEG}</td>
      *   <td>1</td>
      *   <td>Compressed data, so row and pixel strides are 0. To uncompress, use
-     *      {@link android.graphics.BitmapFactory#decodeByteArray}.</td>
+     *      {@link android.graphics.BitmapFactory#decodeByteArray BitmapFactory#decodeByteArray}.
+     *   </td>
      * </tr>
      * <tr>
-     *   <td>{@link android.graphics.ImageFormat#YUV_420_888}</td>
+     *   <td>{@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888}</td>
      *   <td>3</td>
      *   <td>A luminance plane followed by the Cb and Cr chroma planes.
      *     The chroma planes have half the width and height of the luminance
@@ -75,53 +84,60 @@
      *     Each plane has its own row stride and pixel stride.</td>
      * </tr>
      * <tr>
-     *   <td>{@link android.graphics.ImageFormat#RAW_SENSOR}</td>
+     *   <td>{@link android.graphics.ImageFormat#RAW_SENSOR RAW_SENSOR}</td>
      *   <td>1</td>
      *   <td>A single plane of raw sensor image data, with 16 bits per color
      *     sample. The details of the layout need to be queried from the source of
      *     the raw sensor data, such as
-     *     {@link android.hardware.camera2.CameraDevice}.
+     *     {@link android.hardware.camera2.CameraDevice CameraDevice}.
      *   </td>
      * </tr>
      * </table>
      *
      * @see android.graphics.ImageFormat
      */
-    public int getFormat();
+    public abstract int getFormat();
 
     /**
      * The width of the image in pixels. For formats where some color channels
      * are subsampled, this is the width of the largest-resolution plane.
      */
-    public int getWidth();
+    public abstract int getWidth();
 
     /**
      * The height of the image in pixels. For formats where some color channels
      * are subsampled, this is the height of the largest-resolution plane.
      */
-    public int getHeight();
+    public abstract int getHeight();
 
     /**
-     * Get the timestamp associated with this frame. The timestamp is measured
-     * in nanoseconds, and is monotonically increasing. However, the zero point
-     * and whether the timestamp can be compared against other sources of time
-     * or images depend on the source of this image.
+     * Get the timestamp associated with this frame.
+     * <p>
+     * The timestamp is measured in nanoseconds, and is monotonically
+     * increasing. However, the zero point and whether the timestamp can be
+     * compared against other sources of time or images depend on the source of
+     * this image.
+     * </p>
      */
-    public long getTimestamp();
+    public abstract long getTimestamp();
 
     /**
      * Get the array of pixel planes for this Image. The number of planes is
      * determined by the format of the Image.
      */
-    public Plane[] getPlanes();
+    public abstract Plane[] getPlanes();
 
     /**
-     * Free up this frame for reuse. After calling this method, calling any
-     * methods on this Image will result in an IllegalStateException, and
-     * attempting to read from ByteBuffers returned by an earlier
-     * {@code Plane#getBuffer} call will have undefined behavior.
+     * Free up this frame for reuse.
+     * <p>
+     * After calling this method, calling any methods on this {@code Image} will
+     * result in an {@link IllegalStateException}, and attempting to read from
+     * {@link ByteBuffer ByteBuffers} returned by an earlier
+     * {@link Plane#getBuffer} call will have undefined behavior.
+     * </p>
      */
-    public void close();
+    @Override
+    public abstract void close();
 
     /**
      * <p>A single color plane of image data.</p>
@@ -134,29 +150,41 @@
      *
      * @see #getFormat
      */
-    public interface Plane {
+    public static abstract class Plane {
         /**
-         * <p>The row stride for this color plane, in bytes.
+         * @hide
+         */
+        protected Plane() {
+        }
+
+        /**
+         * <p>The row stride for this color plane, in bytes.</p>
          *
          * <p>This is the distance between the start of two consecutive rows of
-         * pixels in the image.</p>
+         * pixels in the image. The row stride is always greater than 0.</p>
          */
-        public int getRowStride();
+        public abstract int getRowStride();
         /**
          * <p>The distance between adjacent pixel samples, in bytes.</p>
          *
          * <p>This is the distance between two consecutive pixel values in a row
          * of pixels. It may be larger than the size of a single pixel to
-         * account for interleaved image data or padded formats.</p>
+         * account for interleaved image data or padded formats.
+         * The pixel stride is always greater than 0.</p>
          */
-        public int getPixelStride();
+        public abstract int getPixelStride();
         /**
-         * <p>Get a set of direct {@link java.nio.ByteBuffer byte buffers}
+         * <p>Get a direct {@link java.nio.ByteBuffer ByteBuffer}
          * containing the frame data.</p>
          *
+         * <p>In particular, the buffer returned will always have
+         * {@link java.nio.ByteBuffer#isDirect isDirect} return {@code true}, so
+         * the underlying data could be mapped as a pointer in JNI without doing
+         * any copies with {@code GetDirectBufferAddress}.</p>
+         *
          * @return the byte buffer containing the image data for this plane.
          */
-        public ByteBuffer getBuffer();
+        public abstract ByteBuffer getBuffer();
     }
 
 }
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index b14a899..aee8362 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -40,41 +40,67 @@
  * <p>The image data is encapsulated in {@link Image} objects, and multiple such
  * objects can be accessed at the same time, up to the number specified by the
  * {@code maxImages} constructor parameter. New images sent to an ImageReader
- * through its Surface are queued until accessed through the
- * {@link #getNextImage} call. Due to memory limits, an image source will
+ * through its {@link Surface} are queued until accessed through the {@link #acquireLatestImage}
+ * or {@link #acquireNextImage} call. Due to memory limits, an image source will
  * eventually stall or drop Images in trying to render to the Surface if the
  * ImageReader does not obtain and release Images at a rate equal to the
  * production rate.</p>
  */
-public final class ImageReader implements AutoCloseable {
+public class ImageReader implements AutoCloseable {
+
+    /**
+     * Returned by nativeImageSetup when acquiring the image was successful.
+     */
+    private static final int ACQUIRE_SUCCESS = 0;
+    /**
+     * Returned by nativeImageSetup when we couldn't acquire the buffer,
+     * because there were no buffers available to acquire.
+     */
+    private static final int ACQUIRE_NO_BUFS = 1;
+    /**
+     * Returned by nativeImageSetup when we couldn't acquire the buffer
+     * because the consumer has already acquired {@maxImages} and cannot
+     * acquire more than that.
+     */
+    private static final int ACQUIRE_MAX_IMAGES = 2;
 
     /**
      * <p>Create a new reader for images of the desired size and format.</p>
      *
-     * <p>The maxImages parameter determines the maximum number of {@link Image}
-     * objects that can be be acquired from the ImageReader
+     * <p>The {@code maxImages} parameter determines the maximum number of {@link Image}
+     * objects that can be be acquired from the {@code ImageReader}
      * simultaneously. Requesting more buffers will use up more memory, so it is
      * important to use only the minimum number necessary for the use case.</p>
      *
      * <p>The valid sizes and formats depend on the source of the image
      * data.</p>
      *
-     * @param width the width in pixels of the Images that this reader will
-     * produce.
-     * @param height the height in pixels of the Images that this reader will
-     * produce.
-     * @param format the format of the Image that this reader will produce. This
-     * must be one of the {@link android.graphics.ImageFormat} or
-     * {@link android.graphics.PixelFormat} constants.
-     * @param maxImages the maximum number of images the user will want to
-     * access simultaneously. This should be as small as possible to limit
-     * memory use. Once maxImages Images are obtained by the user, one of them
-     * has to be released before a new Image will become available for access
-     * through getNextImage(). Must be greater than 0.
+     * @param width
+     *            The width in pixels of the Images that this reader will produce.
+     * @param height
+     *            The height in pixels of the Images that this reader will produce.
+     * @param format
+     *            The format of the Image that this reader will produce. This
+     *            must be one of the {@link android.graphics.ImageFormat} or
+     *            {@link android.graphics.PixelFormat} constants.
+     * @param maxImages
+     *            The maximum number of images the user will want to
+     *            access simultaneously. This should be as small as possible to limit
+     *            memory use. Once maxImages Images are obtained by the user, one of them
+     *            has to be released before a new Image will become available for access
+     *            through {@link #acquireLatestImage()} or {@link #acquireNextImage()}.
+     *            Must be greater than 0.
      *
      * @see Image
      */
-    public ImageReader(int width, int height, int format, int maxImages) {
+    public static ImageReader newInstance(int width, int height, int format, int maxImages) {
+        return new ImageReader(width, height, format, maxImages);
+    }
+
+    /**
+     * @hide
+     */
+    protected ImageReader(int width, int height, int format, int maxImages) {
         mWidth = width;
         mHeight = height;
         mFormat = format;
@@ -96,33 +122,79 @@
         mSurface = nativeGetSurface();
     }
 
+    /**
+     * The width of each {@link Image}, in pixels.
+     *
+     * <p>ImageReader guarantees that all Images acquired from ImageReader (for example, with
+     * {@link #acquireNextImage}) will have the same dimensions as specified in
+     * {@link #newInstance}.</p>
+     *
+     * @return the width of an Image
+     */
     public int getWidth() {
         return mWidth;
     }
 
+    /**
+     * The height of each {@link Image}, in pixels.
+     *
+     * <p>ImageReader guarantees that all Images acquired from ImageReader (for example, with
+     * {@link #acquireNextImage}) will have the same dimensions as specified in
+     * {@link #newInstance}.</p>
+     *
+     * @return the height of an Image
+     */
     public int getHeight() {
         return mHeight;
     }
 
+    /**
+     * The {@link ImageFormat image format} of each Image.
+     *
+     * <p>ImageReader guarantees that all {@link Image Images} acquired from ImageReader
+     *  (for example, with {@link #acquireNextImage}) will have the same format as specified in
+     * {@link #newInstance}.</p>
+     *
+     * @return the format of an Image
+     *
+     * @see ImageFormat
+     */
     public int getImageFormat() {
         return mFormat;
     }
 
+    /**
+     * Maximum number of images that can be acquired from the ImageReader by any time (for example,
+     * with {@link #acquireNextImage}).
+     *
+     * <p>An image is considered acquired after it's returned by a function from ImageReader, and
+     * until the Image is {@link Image#close closed} to release the image back to the ImageReader.
+     * </p>
+     *
+     * <p>Attempting to acquire more than {@code maxImages} concurrently will result in the
+     * acquire function throwing a {@link IllegalStateException}. Furthermore,
+     * while the max number of images have been acquired by the ImageReader user, the producer
+     * enqueueing additional images may stall until at least one image has been released. </p>
+     *
+     * @return Maximum number of images for this ImageReader.
+     *
+     * @see Image#close
+     */
     public int getMaxImages() {
         return mMaxImages;
     }
 
     /**
-     * <p>Get a Surface that can be used to produce Images for this
-     * ImageReader.</p>
+     * <p>Get a {@link Surface} that can be used to produce {@link Image Images} for this
+     * {@code ImageReader}.</p>
      *
-     * <p>Until valid image data is rendered into this Surface, the
-     * {@link #getNextImage} method will return {@code null}. Only one source
+     * <p>Until valid image data is rendered into this {@link Surface}, the
+     * {@link #acquireNextImage} method will return {@code null}. Only one source
      * can be producing data into this Surface at the same time, although the
-     * same Surface can be reused with a different API once the first source is
-     * disconnected from the Surface.</p>
+     * same {@link Surface} can be reused with a different API once the first source is
+     * disconnected from the {@link Surface}.</p>
      *
-     * @return A Surface to use for a drawing target for various APIs.
+     * @return A {@link Surface} to use for a drawing target for various APIs.
      */
     public Surface getSurface() {
         return mSurface;
@@ -130,41 +202,154 @@
 
     /**
      * <p>
-     * Get the next Image from the ImageReader's queue. Returns {@code null} if
-     * no new image is available.
+     * Acquire the latest {@link Image} from the ImageReader's queue, dropping older
+     * {@link Image images}. 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}.
+     * This operation will acquire all the images possible from the ImageReader,
+     * but {@link #close} all images that aren't the latest. This function is
+     * recommended to use over {@link #acquireNextImage} for most use-cases, as it's
+     * more suited for real-time processing.
+     * </p>
+     * <p>
+     * Note that {@link #getMaxImages maxImages} should be at least 2 for
+     * {@link #acquireLatestImage} to be any different than {@link #acquireNextImage} -
+     * discarding all-but-the-newest {@link Image} requires temporarily acquiring two
+     * {@link Image Images} at once. Or more generally, calling {@link #acquireLatestImage}
+     * with less than two images of margin, that is
+     * {@code (maxImages - currentAcquiredImages < 2)} will not discard as expected.
+     * </p>
+     * <p>
+     * This operation will fail by throwing an {@link IllegalStateException} if
+     * {@code maxImages} have been acquired with {@link #acquireLatestImage} or
+     * {@link #acquireNextImage}. In particular a sequence of {@link #acquireLatestImage}
+     * calls greater than {@link #getMaxImages} without calling {@link Image#close} in-between
+     * will exhaust the underlying queue. At such a time, {@link IllegalStateException}
+     * will be thrown until more images are
+     * released with {@link Image#close}.
      * </p>
      *
-     * @return a new frame of image data, or {@code null} if no image data is
-     *         available.
-     * @throws Surface.OutOfResourcesException if too many images are currently
-     *         acquired
+     * @return latest frame of image data, or {@code null} if no image data is available.
+     * @throws IllegalStateException if too many images are currently acquired
      */
-    public Image getNextImage() {
-        SurfaceImage si = new SurfaceImage();
-        if (nativeImageSetup(si)) {
-            // create SurfacePlane objects
-            si.createSurfacePlanes();
-            si.setImageValid(true);
-            return si;
+    public Image acquireLatestImage() {
+        Image image = acquireNextImage();
+        if (image == null) {
+            return null;
         }
-        return null;
+        try {
+            for (;;) {
+                Image next = acquireNextImageNoThrowISE();
+                if (next == null) {
+                    Image result = image;
+                    image = null;
+                    return result;
+                }
+                image.close();
+                image = next;
+            }
+        } finally {
+            if (image != null) {
+                image.close();
+            }
+        }
+    }
+
+    /**
+     * Don't throw IllegalStateException if there are too many images acquired.
+     *
+     * @return Image if acquiring succeeded, or null otherwise.
+     *
+     * @hide
+     */
+    public Image acquireNextImageNoThrowISE() {
+        SurfaceImage si = new SurfaceImage();
+        return acquireNextSurfaceImage(si) == ACQUIRE_SUCCESS ? si : null;
+    }
+
+    /**
+     * Attempts to acquire the next image from the underlying native implementation.
+     *
+     * <p>
+     * Note that unexpected failures will throw at the JNI level.
+     * </p>
+     *
+     * @param si A blank SurfaceImage.
+     * @return One of the {@code ACQUIRE_*} codes that determine success or failure.
+     *
+     * @see #ACQUIRE_MAX_IMAGES
+     * @see #ACQUIRE_NO_BUFS
+     * @see #ACQUIRE_SUCCESS
+     */
+    private int acquireNextSurfaceImage(SurfaceImage si) {
+
+        int status = nativeImageSetup(si);
+
+        switch (status) {
+            case ACQUIRE_SUCCESS:
+                si.createSurfacePlanes();
+                si.setImageValid(true);
+            case ACQUIRE_NO_BUFS:
+            case ACQUIRE_MAX_IMAGES:
+                break;
+            default:
+                throw new AssertionError("Unknown nativeImageSetup return code " + status);
+        }
+
+        return status;
+    }
+
+    /**
+     * <p>
+     * Acquire the next Image from the ImageReader's queue. Returns {@code null} if
+     * no new image is available.
+     * </p>
+     *
+     * <p><i>Warning:</i> Consider using {@link #acquireLatestImage()} instead, as it will
+     * automatically release older images, and allow slower-running processing routines to catch
+     * up to the newest frame. Usage of {@link #acquireNextImage} is recommended for
+     * batch/background processing. Incorrectly using this function can cause images to appear
+     * with an ever-increasing delay, followed by a complete stall where no new images seem to
+     * appear.
+     * </p>
+     *
+     * <p>
+     * This operation will fail by throwing an {@link IllegalStateException} if
+     * {@code maxImages} have been acquired with {@link #acquireNextImage} or
+     * {@link #acquireLatestImage}. In particular a sequence of {@link #acquireNextImage} or
+     * {@link #acquireLatestImage} calls greater than {@link #getMaxImages maxImages} without
+     * calling {@link Image#close} in-between will exhaust the underlying queue. At such a time,
+     * {@link IllegalStateException} will be thrown until more images are released with
+     * {@link Image#close}.
+     * </p>
+     *
+     * @return a new frame of image data, or {@code null} if no image data is available.
+     * @throws IllegalStateException if {@code maxImages} images are currently acquired
+     * @see #acquireLatestImage
+     */
+    public Image acquireNextImage() {
+        SurfaceImage si = new SurfaceImage();
+        int status = acquireNextSurfaceImage(si);
+
+        switch (status) {
+            case ACQUIRE_SUCCESS:
+                return si;
+            case ACQUIRE_NO_BUFS:
+                return null;
+            case ACQUIRE_MAX_IMAGES:
+                throw new IllegalStateException(
+                        String.format(
+                                "maxImages (%d) has already been acquired, " +
+                                "call #close before acquiring more.", mMaxImages));
+            default:
+                throw new AssertionError("Unknown nativeImageSetup return code " + status);
+        }
     }
 
     /**
      * <p>Return the frame to the ImageReader for reuse.</p>
      */
-    public void releaseImage(Image i) {
+    private void releaseImage(Image i) {
         if (! (i instanceof SurfaceImage) ) {
             throw new IllegalArgumentException(
                 "This image was not produced by an ImageReader");
@@ -183,13 +368,16 @@
     /**
      * Register a listener to be invoked when a new image becomes available
      * from the ImageReader.
-     * @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
+     * @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) {
+   public void setOnImageAvailableListener(OnImageAvailableListener listener, Handler handler) {
         mImageListener = listener;
 
         Looper looper;
@@ -206,12 +394,16 @@
 
     /**
      * Callback interface for being notified that a new image is available.
+     *
+     * <p>
      * The onImageAvailable is called per image basis, that is, callback fires for every new frame
      * available from ImageReader.
+     * </p>
      */
     public interface OnImageAvailableListener {
         /**
          * Callback that is called when a new image is available from ImageReader.
+         *
          * @param reader the ImageReader the callback is associated with.
          * @see ImageReader
          * @see Image
@@ -220,12 +412,17 @@
     }
 
     /**
-     * Free up all the resources associated with this ImageReader. After
-     * Calling this method, this ImageReader can not be used. calling
-     * any methods on this ImageReader and Images previously provided by {@link #getNextImage}
-     * will result in an IllegalStateException, and attempting to read from
-     * ByteBuffers returned by an earlier {@code Plane#getBuffer} call will
+     * Free up all the resources associated with this ImageReader.
+     *
+     * <p>
+     * After calling this method, this ImageReader can not be used. Calling
+     * any methods on this ImageReader and Images previously provided by
+     * {@link #acquireNextImage} or {@link #acquireLatestImage}
+     * will result in an {@link IllegalStateException}, and attempting to read from
+     * {@link ByteBuffer ByteBuffers} returned by an earlier
+     * {@link Image.Plane#getBuffer Plane#getBuffer} call will
      * have undefined behavior.
+     * </p>
      */
     @Override
     public void close() {
@@ -242,11 +439,14 @@
     }
 
     /**
-     * Only a subset of the formats defined in {@link android.graphics.ImageFormat} and
-     * {@link android.graphics.PixelFormat} are supported by ImageReader. When reading RGB
-     * data from a surface, the formats defined in {@link android.graphics.PixelFormat}
-     * can be used, when reading YUV, JPEG or raw sensor data ( for example, from camera
-     *  or video decoder), formats from {@link android.graphics.ImageFormat} are used.
+     * Only a subset of the formats defined in
+     * {@link android.graphics.ImageFormat ImageFormat} and
+     * {@link android.graphics.PixelFormat PixelFormat} are supported by
+     * ImageReader. When reading RGB data from a surface, the formats defined in
+     * {@link android.graphics.PixelFormat PixelFormat} can be used, when
+     * reading YUV, JPEG or raw sensor data (for example, from camera or video
+     * decoder), formats from {@link android.graphics.ImageFormat ImageFormat}
+     * are used.
      */
     private int getNumPlanesFromFormat() {
         switch (mFormat) {
@@ -308,7 +508,7 @@
      */
     private long mNativeContext;
 
-    private class SurfaceImage implements android.media.Image {
+    private class SurfaceImage extends android.media.Image {
         public SurfaceImage() {
             mIsImageValid = false;
         }
@@ -404,7 +604,7 @@
                 mPlanes[i] = nativeCreatePlane(i);
             }
         }
-        private class SurfacePlane implements android.media.Image.Plane {
+        private class SurfacePlane extends android.media.Image.Plane {
             // SurfacePlane instance is created by native code when a new SurfaceImage is created
             private SurfacePlane(int index, int rowStride, int pixelStride) {
                 mIndex = index;
@@ -479,9 +679,17 @@
     private synchronized native void nativeClose();
     private synchronized native void nativeReleaseImage(Image i);
     private synchronized native Surface nativeGetSurface();
-    private synchronized native boolean nativeImageSetup(Image i);
 
-    /*
+    /**
+     * @return A return code {@code ACQUIRE_*}
+     *
+     * @see #ACQUIRE_SUCCESS
+     * @see #ACQUIRE_NO_BUFS
+     * @see #ACQUIRE_MAX_IMAGES
+     */
+    private synchronized native int nativeImageSetup(Image i);
+
+    /**
      * We use a class initializer to allow the native code to cache some
      * field offsets.
      */
diff --git a/media/java/android/media/audiofx/AudioEffect.java b/media/java/android/media/audiofx/AudioEffect.java
index 52c0c2d..12f7bd9 100644
--- a/media/java/android/media/audiofx/AudioEffect.java
+++ b/media/java/android/media/audiofx/AudioEffect.java
@@ -120,6 +120,14 @@
             .fromString("58b4b260-8e06-11e0-aa8e-0002a5d5c51b");
 
     /**
+     * @hide
+     * CANDIDATE FOR PUBLIC API
+     * UUID for Loudness Enhancer
+     */
+    public static final UUID EFFECT_TYPE_LOUDNESS_ENHANCER = UUID
+              .fromString("fe3199be-aed0-413f-87bb-11260eb63cf1");
+
+    /**
      * Null effect UUID. Used when the UUID for effect type of
      * @hide
      */
diff --git a/media/java/android/media/audiofx/LoudnessEnhancer.java b/media/java/android/media/audiofx/LoudnessEnhancer.java
new file mode 100644
index 0000000..f6e3e6b
--- /dev/null
+++ b/media/java/android/media/audiofx/LoudnessEnhancer.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.audiofx;
+
+import android.media.AudioTrack;
+import android.media.MediaPlayer;
+import android.media.audiofx.AudioEffect;
+import android.util.Log;
+
+import java.util.StringTokenizer;
+
+
+/**
+ * @hide
+ * CANDIDATE FOR PUBLIC API
+ * LoudnessEnhancer is an audio effect for increasing audio loudness.
+ * The processing is parametrized by a target gain value, which determines the maximum amount
+ * by which an audio signal will be amplified; signals amplified outside of the sample
+ * range supported by the platform are compressed.
+ * An application creates a LoudnessEnhancer object to instantiate and control a
+ * this audio effect in the audio framework.
+ * To attach the LoudnessEnhancer to a particular AudioTrack or MediaPlayer,
+ * specify the audio session ID of this AudioTrack or MediaPlayer when constructing the effect
+ * (see {@link AudioTrack#getAudioSessionId()} and {@link MediaPlayer#getAudioSessionId()}).
+ */
+
+public class LoudnessEnhancer extends AudioEffect {
+
+    private final static String TAG = "LoudnessEnhancer";
+
+    // These parameter constants must be synchronized with those in
+    // /system/media/audio_effects/include/audio_effects/effect_loudnessenhancer.h
+    /**
+     * @hide
+     * CANDIDATE FOR PUBLIC API
+     * The maximum gain applied applied to the signal to process.
+     * It is expressed in millibels (100mB = 1dB) where 0mB corresponds to no amplification.
+     */
+    public static final int PARAM_TARGET_GAIN_MB = 0;
+
+    /**
+     * Registered listener for parameter changes.
+     */
+    private OnParameterChangeListener mParamListener = null;
+
+    /**
+     * Listener used internally to to receive raw parameter change events
+     * from AudioEffect super class
+     */
+    private BaseParameterListener mBaseParamListener = null;
+
+    /**
+     * Lock for access to mParamListener
+     */
+    private final Object mParamListenerLock = new Object();
+
+    /**
+     * @hide
+     * CANDIDATE FOR PUBLIC API
+     * Class constructor.
+     * @param audioSession system-wide unique audio session identifier. The LoudnessEnhancer
+     * will be attached to the MediaPlayer or AudioTrack in the same audio session.
+     *
+     * @throws java.lang.IllegalStateException
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     */
+    public LoudnessEnhancer(int audioSession)
+            throws IllegalStateException, IllegalArgumentException,
+                UnsupportedOperationException, RuntimeException {
+        super(EFFECT_TYPE_LOUDNESS_ENHANCER, EFFECT_TYPE_NULL, 0, audioSession);
+
+        if (audioSession == 0) {
+            Log.w(TAG, "WARNING: attaching a LoudnessEnhancer to global output mix is deprecated!");
+        }
+    }
+
+    /**
+     * @hide
+     * Class constructor.
+     * @param priority the priority level requested by the application for controlling the
+     * LoudnessEnhancer engine. As the same engine can be shared by several applications,
+     * this parameter indicates how much the requesting application needs control of effect
+     * parameters. The normal priority is 0, above normal is a positive number, below normal a
+     * negative number.
+     * @param audioSession system-wide unique audio session identifier. The LoudnessEnhancer
+     * will be attached to the MediaPlayer or AudioTrack in the same audio session.
+     *
+     * @throws java.lang.IllegalStateException
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     */
+    public LoudnessEnhancer(int priority, int audioSession)
+            throws IllegalStateException, IllegalArgumentException,
+                UnsupportedOperationException, RuntimeException {
+        super(EFFECT_TYPE_LOUDNESS_ENHANCER, EFFECT_TYPE_NULL, priority, audioSession);
+
+        if (audioSession == 0) {
+            Log.w(TAG, "WARNING: attaching a LoudnessEnhancer to global output mix is deprecated!");
+        }
+    }
+
+    /**
+     * @hide
+     * CANDIDATE FOR PUBLIC API
+     * Set the target gain for the audio effect.
+     * The target gain is the maximum value by which a sample value will be amplified when the
+     * effect is enabled.
+     * @param gainmB the effect target gain expressed in mB. 0mB corresponds to no amplification.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setTargetGain(int gainmB)
+            throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        checkStatus(setParameter(PARAM_TARGET_GAIN_MB, gainmB));
+    }
+
+    /**
+     * @hide
+     * CANDIDATE FOR PUBLIC API
+     * Return the target gain.
+     * @return the effect target gain expressed in mB.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public float getTargetGain()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        int[] value = new int[1];
+        checkStatus(getParameter(PARAM_TARGET_GAIN_MB, value));
+        return value[0];
+    }
+
+    /**
+     * @hide
+     * The OnParameterChangeListener interface defines a method called by the LoudnessEnhancer
+     * when a parameter value has changed.
+     */
+    public interface OnParameterChangeListener  {
+        /**
+         * @hide
+         * CANDIDATE FOR PUBLIC API
+         * Method called when a parameter value has changed. The method is called only if the
+         * parameter was changed by another application having the control of the same
+         * LoudnessEnhancer engine.
+         * @param effect the LoudnessEnhancer on which the interface is registered.
+         * @param param ID of the modified parameter. See {@link #PARAM_GENERIC_PARAM1} ...
+         * @param value the new parameter value.
+         */
+        void onParameterChange(LoudnessEnhancer effect, int param, int value);
+    }
+
+    /**
+     * Listener used internally to receive unformatted parameter change events from AudioEffect
+     * super class.
+     */
+    private class BaseParameterListener implements AudioEffect.OnParameterChangeListener {
+        private BaseParameterListener() {
+
+        }
+        public void onParameterChange(AudioEffect effect, int status, byte[] param, byte[] value) {
+            // only notify when the parameter was successfully change
+            if (status != AudioEffect.SUCCESS) {
+                return;
+            }
+            OnParameterChangeListener l = null;
+            synchronized (mParamListenerLock) {
+                if (mParamListener != null) {
+                    l = mParamListener;
+                }
+            }
+            if (l != null) {
+                int p = -1;
+                int v = Integer.MIN_VALUE;
+
+                if (param.length == 4) {
+                    p = byteArrayToInt(param, 0);
+                }
+                if (value.length == 4) {
+                    v = byteArrayToInt(value, 0);
+                }
+                if (p != -1 && v != Integer.MIN_VALUE) {
+                    l.onParameterChange(LoudnessEnhancer.this, p, v);
+                }
+            }
+        }
+    }
+
+    /**
+     * @hide
+     * Registers an OnParameterChangeListener interface.
+     * @param listener OnParameterChangeListener interface registered
+     */
+    public void setParameterListener(OnParameterChangeListener listener) {
+        synchronized (mParamListenerLock) {
+            if (mParamListener == null) {
+                mBaseParamListener = new BaseParameterListener();
+                super.setParameterListener(mBaseParamListener);
+            }
+            mParamListener = listener;
+        }
+    }
+
+    /**
+     * @hide
+     * The Settings class regroups the LoudnessEnhancer parameters. It is used in
+     * conjunction with the getProperties() and setProperties() methods to backup and restore
+     * all parameters in a single call.
+     */
+    public static class Settings {
+        public int targetGainmB;
+
+        public Settings() {
+        }
+
+        /**
+         * Settings class constructor from a key=value; pairs formatted string. The string is
+         * typically returned by Settings.toString() method.
+         * @throws IllegalArgumentException if the string is not correctly formatted.
+         */
+        public Settings(String settings) {
+            StringTokenizer st = new StringTokenizer(settings, "=;");
+            //int tokens = st.countTokens();
+            if (st.countTokens() != 3) {
+                throw new IllegalArgumentException("settings: " + settings);
+            }
+            String key = st.nextToken();
+            if (!key.equals("LoudnessEnhancer")) {
+                throw new IllegalArgumentException(
+                        "invalid settings for LoudnessEnhancer: " + key);
+            }
+            try {
+                key = st.nextToken();
+                if (!key.equals("targetGainmB")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                targetGainmB = Integer.parseInt(st.nextToken());
+             } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException("invalid value for key: " + key);
+            }
+        }
+
+        @Override
+        public String toString() {
+            String str = new String (
+                    "LoudnessEnhancer"+
+                    ";targetGainmB="+Integer.toString(targetGainmB)
+                    );
+            return str;
+        }
+    };
+
+
+    /**
+     * @hide
+     * Gets the LoudnessEnhancer properties. This method is useful when a snapshot of current
+     * effect settings must be saved by the application.
+     * @return a LoudnessEnhancer.Settings object containing all current parameters values
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public LoudnessEnhancer.Settings getProperties()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        Settings settings = new Settings();
+        int[] value = new int[1];
+        checkStatus(getParameter(PARAM_TARGET_GAIN_MB, value));
+        settings.targetGainmB = value[0];
+        return settings;
+    }
+
+    /**
+     * @hide
+     * Sets the LoudnessEnhancer properties. This method is useful when bass boost settings
+     * have to be applied from a previous backup.
+     * @param settings a LoudnessEnhancer.Settings object containing the properties to apply
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setProperties(LoudnessEnhancer.Settings settings)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        checkStatus(setParameter(PARAM_TARGET_GAIN_MB, settings.targetGainmB));
+    }
+}
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 94f20bc..a03dbf3 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -43,13 +43,16 @@
 
 using namespace android;
 
-static const char* const OutOfResourcesException =
-    "android/view/Surface$OutOfResourcesException";
-
 enum {
     IMAGE_READER_MAX_NUM_PLANES = 3,
 };
 
+enum {
+    ACQUIRE_SUCCESS = 0,
+    ACQUIRE_NO_BUFFERS = 1,
+    ACQUIRE_MAX_IMAGES = 2,
+};
+
 static struct {
     jfieldID mNativeContext;
     jmethodID postEventFromNative;
@@ -685,14 +688,14 @@
     ctx->returnLockedBuffer(buffer);
 }
 
-static jboolean ImageReader_imageSetup(JNIEnv* env, jobject thiz,
+static jint ImageReader_imageSetup(JNIEnv* env, jobject thiz,
                                              jobject image)
 {
     ALOGV("%s:", __FUNCTION__);
     JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz);
     if (ctx == NULL) {
         jniThrowRuntimeException(env, "ImageReaderContext is not initialized");
-        return false;
+        return -1;
     }
 
     CpuConsumer* consumer = ctx->getCpuConsumer();
@@ -700,27 +703,22 @@
     if (buffer == NULL) {
         ALOGW("Unable to acquire a lockedBuffer, very likely client tries to lock more than"
             " maxImages buffers");
-        jniThrowException(env, OutOfResourcesException,
-                  "Too many outstanding images, close existing images"
-                  " to be able to acquire more.");
-        return false;
+        return ACQUIRE_MAX_IMAGES;
     }
     status_t res = consumer->lockNextBuffer(buffer);
     if (res != NO_ERROR) {
         if (res != BAD_VALUE /*no buffers*/) {
             if (res == NOT_ENOUGH_DATA) {
-                jniThrowException(env, OutOfResourcesException,
-                          "Too many outstanding images, close existing images"
-                          " to be able to acquire more.");
+                return ACQUIRE_MAX_IMAGES;
             } else {
                 ALOGE("%s Fail to lockNextBuffer with error: %d ",
                       __FUNCTION__, res);
-                jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+                jniThrowExceptionFmt(env, "java/lang/AssertionError",
                           "Unknown error (%d) when we tried to lock buffer.",
                           res);
             }
         }
-        return false;
+        return ACQUIRE_NO_BUFFERS;
     }
 
     // Check if the left-top corner of the crop rect is origin, we currently assume this point is
@@ -730,7 +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;
+        return -1;
     }
 
     // Check if the producer buffer configurations match what ImageReader configured.
@@ -739,11 +737,9 @@
     int outputHeight = buffer->height;
 
     // Correct width/height when crop is set.
-    if (buffer->crop.getWidth() > 0) {
-        outputWidth = buffer->crop.getWidth() + 1;
-    }
-    if (buffer->crop.getHeight() > 0) {
-        outputHeight = buffer->crop.getHeight() + 1;
+    if (!buffer->crop.isEmpty()) {
+        outputWidth = buffer->crop.getWidth();
+        outputHeight = buffer->crop.getHeight();
     }
 
     int imageReaderWidth = ctx->getBufferWidth();
@@ -761,6 +757,7 @@
         jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
                 "Producer buffer size: %dx%d, doesn't match ImageReader configured size: %dx%d",
                 outputWidth, outputHeight, imageReaderWidth, imageReaderHeight);
+        return -1;
     }
 
     if (ctx->getBufferFormat() != buffer->format) {
@@ -777,14 +774,14 @@
                 buffer->format, ctx->getBufferFormat());
         jniThrowException(env, "java/lang/UnsupportedOperationException",
                 msg.string());
-        return false;
+        return -1;
     }
     // Set SurfaceImage instance member variables
     Image_setBuffer(env, image, buffer);
     env->SetLongField(image, gSurfaceImageClassInfo.mTimestamp,
             static_cast<jlong>(buffer->timestamp));
 
-    return true;
+    return ACQUIRE_SUCCESS;
 }
 
 static jobject ImageReader_getSurface(JNIEnv* env, jobject thiz)
@@ -855,7 +852,7 @@
     {"nativeInit",             "(Ljava/lang/Object;IIII)V",  (void*)ImageReader_init },
     {"nativeClose",            "()V",                        (void*)ImageReader_close },
     {"nativeReleaseImage",     "(Landroid/media/Image;)V",   (void*)ImageReader_imageRelease },
-    {"nativeImageSetup",       "(Landroid/media/Image;)Z",    (void*)ImageReader_imageSetup },
+    {"nativeImageSetup",       "(Landroid/media/Image;)I",    (void*)ImageReader_imageSetup },
     {"nativeGetSurface",       "()Landroid/view/Surface;",   (void*)ImageReader_getSurface },
 };
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java
index ecdc287..64b12b7 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java
@@ -49,6 +49,7 @@
         addMediaPlayerStateUnitTests(suite);
         addMediaScannerUnitTests(suite);
         addCameraUnitTests(suite);
+        addImageReaderTests(suite);
         return suite;
     }
 
@@ -65,6 +66,10 @@
         suite.addTestSuite(CameraMetadataTest.class);
     }
 
+    private void addImageReaderTests(TestSuite suite) {
+        suite.addTestSuite(ImageReaderTest.class);
+    }
+
     // Running all unit tests checking the state machine may be time-consuming.
     private void addMediaMetadataRetrieverStateUnitTests(TestSuite suite) {
         suite.addTestSuite(MediaMetadataRetrieverTest.class);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
index 2d26ac7..7b2a20e 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
@@ -61,6 +61,7 @@
     private SurfaceHolder mSurfaceHolder = null;
     private static final int NUM_STRESS_LOOP = 10;
     private static final int NUM_PLAYBACk_IN_EACH_LOOP = 20;
+    private static final int SHORT_WAIT = 2 * 1000; // 2 seconds
     private static final long MEDIA_STRESS_WAIT_TIME = 5000; //5 seconds
     private static final String MEDIA_MEMORY_OUTPUT =
         "/sdcard/mediaMemOutput.txt";
@@ -99,16 +100,17 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        //Insert a 2 second before launching the test activity. This is
+        //the workaround for the race condition of requesting the updated surface.
+        Thread.sleep(SHORT_WAIT);
+        getActivity();
         //Check if the device support the camcorder
-        CamcorderProfile mCamcorderProfile = CamcorderProfile.get(CAMERA_ID);
+        mCamcorderProfile = CamcorderProfile.get(CAMERA_ID);
         if (mCamcorderProfile != null) {
             mVideoWidth = mCamcorderProfile.videoFrameWidth;
             mVideoHeight = mCamcorderProfile.videoFrameHeight;
+            Log.v(TAG, "height = " + mVideoHeight + " width= " + mVideoWidth);
         }
-        //Insert a 2 second before launching the test activity. This is
-        //the workaround for the race condition of requesting the updated surface.
-        Thread.sleep(2000);
-        getActivity();
         if (MediaFrameworkPerfTestRunner.mGetNativeHeapDump)
             MediaTestUtil.getNativeHeapDump(this.getName() + "_before");
 
@@ -246,6 +248,8 @@
                 Thread.sleep(MEDIA_STRESS_WAIT_TIME);
                 mRecorder.stop();
                 mRecorder.release();
+                //Insert 2 seconds to make sure the camera released.
+                Thread.sleep(SHORT_WAIT);
             } catch (Exception e) {
                 Log.v("record video failed ", e.toString());
                 mRecorder.release();
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ImageReaderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ImageReaderTest.java
new file mode 100644
index 0000000..f6cd990
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ImageReaderTest.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mediaframeworktest.unit;
+
+import static org.mockito.Mockito.*;
+
+import android.graphics.ImageFormat;
+import android.media.Image;
+import android.media.Image.Plane;
+import android.media.ImageReader;
+import android.media.ImageReader.OnImageAvailableListener;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+public class ImageReaderTest extends AndroidTestCase {
+
+    private static final String TAG = "ImageReaderTest-unit";
+
+    private static final int DEFAULT_WIDTH = 640;
+    private static final int DEFAULT_HEIGHT = 480;
+    private static final int DEFAULT_FORMAT = ImageFormat.YUV_420_888;
+    private static final int DEFAULT_MAX_IMAGES = 3;
+
+    private ImageReader mReader;
+    private Image mImage1;
+    private Image mImage2;
+    private Image mImage3;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        /**
+         * Workaround for mockito and JB-MR2 incompatibility
+         *
+         * Avoid java.lang.IllegalArgumentException: dexcache == null
+         * https://code.google.com/p/dexmaker/issues/detail?id=2
+         */
+        System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
+
+        // TODO: refactor above into one of the test runners
+
+        mReader = spy(ImageReader.newInstance(DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
+                DEFAULT_MAX_IMAGES));
+        mImage1 = mock(Image.class);
+        mImage2 = mock(Image.class);
+        mImage3 = mock(Image.class);
+
+        /**
+         * Ensure rest of classes are mockable
+         */
+        {
+            mock(Plane.class);
+            mock(OnImageAvailableListener.class);
+        }
+
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mReader.close();
+
+        super.tearDown();
+    }
+
+    /**
+     * Return null when there is nothing in the image queue.
+     */
+    @SmallTest
+    public void testGetLatestImageEmpty() {
+        when(mReader.acquireNextImage()).thenReturn(null);
+        when(mReader.acquireNextImageNoThrowISE()).thenReturn(null);
+        assertEquals(null, mReader.acquireLatestImage());
+    }
+
+    /**
+     * Return the last image from the image queue, close up the rest.
+     */
+    @SmallTest
+    public void testGetLatestImage1() {
+        when(mReader.acquireNextImage()).thenReturn(mImage1);
+        when(mReader.acquireNextImageNoThrowISE()).thenReturn(null);
+        assertEquals(mImage1, mReader.acquireLatestImage());
+        verify(mImage1, never()).close();
+    }
+
+    /**
+     * Return the last image from the image queue, close up the rest.
+     */
+    @SmallTest
+    public void testGetLatestImage2() {
+        when(mReader.acquireNextImage()).thenReturn(mImage1);
+        when(mReader.acquireNextImageNoThrowISE()).thenReturn(mImage2).thenReturn(null);
+        assertEquals(mImage2, mReader.acquireLatestImage());
+        verify(mImage1, atLeastOnce()).close();
+        verify(mImage2, never()).close();
+    }
+
+    /**
+     * Return the last image from the image queue, close up the rest.
+     */
+    @SmallTest
+    public void testGetLatestImage3() {
+        when(mReader.acquireNextImage()).thenReturn(mImage1);
+        when(mReader.acquireNextImageNoThrowISE()).thenReturn(mImage2).
+                                                   thenReturn(mImage3).
+                                                   thenReturn(null);
+        assertEquals(mImage3, mReader.acquireLatestImage());
+        verify(mImage1, atLeastOnce()).close();
+        verify(mImage2, atLeastOnce()).close();
+        verify(mImage3, never()).close();
+    }
+
+    /**
+     * Return null if get a IllegalStateException with no images in the queue.
+     */
+    @SmallTest
+    public void testGetLatestImageTooManyBuffersAcquiredEmpty()  {
+        when(mReader.acquireNextImage()).thenThrow(new IllegalStateException());
+        try {
+            mReader.acquireLatestImage();
+            fail("Expected IllegalStateException to be thrown");
+        } catch(IllegalStateException e) {
+        }
+    }
+
+    /**
+     * All images are cleaned up when we get an unexpected Error.
+     */
+    @SmallTest
+    public void testGetLatestImageExceptionalError() {
+        when(mReader.acquireNextImage()).thenReturn(mImage1);
+        when(mReader.acquireNextImageNoThrowISE()).thenReturn(mImage2).
+                                                   thenReturn(mImage3).
+                                                   thenThrow(new OutOfMemoryError());
+        try {
+            mReader.acquireLatestImage();
+            fail("Impossible");
+        } catch(OutOfMemoryError e) {
+        }
+
+        verify(mImage1, atLeastOnce()).close();
+        verify(mImage2, atLeastOnce()).close();
+        verify(mImage3, atLeastOnce()).close();
+    }
+
+    /**
+     * All images are cleaned up when we get an unexpected RuntimeException.
+     */
+    @SmallTest
+    public void testGetLatestImageExceptionalRuntime() {
+
+        when(mReader.acquireNextImage()).thenReturn(mImage1);
+        when(mReader.acquireNextImageNoThrowISE()).thenReturn(mImage2).
+                                                   thenReturn(mImage3).
+                                                   thenThrow(new RuntimeException());
+        try {
+            mReader.acquireLatestImage();
+            fail("Impossible");
+        } catch(RuntimeException e) {
+        }
+
+        verify(mImage1, atLeastOnce()).close();
+        verify(mImage2, atLeastOnce()).close();
+        verify(mImage3, atLeastOnce()).close();
+    }
+}
diff --git a/media/tests/SoundPoolTest/AndroidManifest.xml b/media/tests/SoundPoolTest/AndroidManifest.xml
index 126276c..8a29052 100644
--- a/media/tests/SoundPoolTest/AndroidManifest.xml
+++ b/media/tests/SoundPoolTest/AndroidManifest.xml
@@ -8,4 +8,5 @@
             </intent-filter>
         </activity>
     </application>
+    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="8"/>
 </manifest>
diff --git a/media/tests/SoundPoolTest/src/com/android/SoundPoolTest.java b/media/tests/SoundPoolTest/src/com/android/SoundPoolTest.java
index 33db2dd..cc3306c 100644
--- a/media/tests/SoundPoolTest/src/com/android/SoundPoolTest.java
+++ b/media/tests/SoundPoolTest/src/com/android/SoundPoolTest.java
@@ -143,7 +143,7 @@
                 if (DEBUG) Log.d(LOG_TAG, "Stop note " + id);
                 sleep(50);
             }
-            if (DEBUG) Log.d(LOG_TAG, "End scale test");
+            if (DEBUG) Log.d(LOG_TAG, "End sounds test");
             return true;
         }
 
@@ -165,7 +165,7 @@
                 if (DEBUG) Log.d(LOG_TAG, "Stop note " + id);
                 sleep(50);
             }
-            if (DEBUG) Log.d(LOG_TAG, "End sounds test");
+            if (DEBUG) Log.d(LOG_TAG, "End scale test");
             return true;
         }
 
@@ -189,6 +189,7 @@
                 if (DEBUG) Log.d(LOG_TAG, "Change rate " + mScale[step]);
             }
             mSoundPool.stop(id);
+            if (DEBUG) Log.d(LOG_TAG, "Stop note " + id);
             if (DEBUG) Log.d(LOG_TAG, "End rate test");
             return true;
         }
@@ -205,34 +206,38 @@
                 Log.e(LOG_TAG, "Error occurred starting note");
                 return false;
             }
-            sleep(250);
+            sleep(1000);
 
             // play a low priority sound
-            int id = mSoundPool.play(mSounds[0], DEFAULT_VOLUME, DEFAULT_VOLUME,
+            int id = mSoundPool.play(mSounds[1], DEFAULT_VOLUME, DEFAULT_VOLUME,
                     LOW_PRIORITY, DEFAULT_LOOP, 1.0f);
-            if (id > 0) {
+            if (id != 0) {
                 Log.e(LOG_TAG, "Normal > Low priority test failed");
                 result = false;
                 mSoundPool.stop(id);
             } else {
-                Log.e(LOG_TAG, "Normal > Low priority test passed");
+                sleep(1000);
+                Log.i(LOG_TAG, "Normal > Low priority test passed");
             }
-            sleep(250);
 
             // play a high priority sound
-            id = mSoundPool.play(mSounds[0], DEFAULT_VOLUME, DEFAULT_VOLUME,
+            id = mSoundPool.play(mSounds[2], DEFAULT_VOLUME, DEFAULT_VOLUME,
                     HIGH_PRIORITY, DEFAULT_LOOP, 1.0f);
             if (id == 0) {
                 Log.e(LOG_TAG, "High > Normal priority test failed");
                 result = false;
             } else {
-                Log.e(LOG_TAG, "High > Normal priority test passed");
+                sleep(1000);
+                Log.i(LOG_TAG, "Stopping high priority");
+                mSoundPool.stop(id);
+                sleep(1000);
+                Log.i(LOG_TAG, "High > Normal priority test passed");
             }
-            sleep(250);
-            mSoundPool.stop(id);
 
             // stop normal note
+            Log.i(LOG_TAG, "Stopping normal priority");
             mSoundPool.stop(normalId);
+            sleep(1000);
 
             if (DEBUG) Log.d(LOG_TAG, "End priority test");
             return result;
@@ -250,17 +255,21 @@
                 Log.e(LOG_TAG, "Error occurred starting note");
                 return false;
             }
-            sleep(250);
+            sleep(2500);
 
             // pause and resume sound a few times
             for (int count = 0; count < 5; count++) {
+                if (DEBUG) Log.d(LOG_TAG, "Pause note " + id);
                 mSoundPool.pause(id);
-                sleep(250);
+                sleep(1000);
+                if (DEBUG) Log.d(LOG_TAG, "Resume note " + id);
                 mSoundPool.resume(id);
-                sleep(250);
+                sleep(1000);
             }
 
+            if (DEBUG) Log.d(LOG_TAG, "Stop note " + id);
             mSoundPool.stop(id);
+            sleep(1000);
 
             // play 5 sounds, forces one to be stolen
             int ids[] = new int[5];
@@ -272,18 +281,21 @@
                     Log.e(LOG_TAG, "Error occurred starting note");
                     return false;
                 }
-                sleep(250);
+                sleep(1000);
             }
 
             // pause and resume sound a few times
             for (int count = 0; count < 5; count++) {
+                if (DEBUG) Log.d(LOG_TAG, "autoPause");
                 mSoundPool.autoPause();
-                sleep(250);
+                sleep(1000);
+                if (DEBUG) Log.d(LOG_TAG, "autoResume");
                 mSoundPool.autoResume();
-                sleep(250);
+                sleep(1000);
             }
 
             for (int i = 0; i < 5; i++) {
+                if (DEBUG) Log.d(LOG_TAG, "Stop note " + ids[i]);
                 mSoundPool.stop(ids[i]);
             }
 
@@ -302,9 +314,9 @@
                 return false;
             }
 
-            // pan from left to right
+            // pan from right to left
             for (int count = 0; count < 101; count++) {
-                sleep(20);
+                sleep(50);
                 double radians = PI_OVER_2 * count / 100.0;
                 float leftVolume = (float) Math.sin(radians);
                 float rightVolume = (float) Math.cos(radians);
diff --git a/media/tests/audiotests/Android.mk b/media/tests/audiotests/Android.mk
new file mode 100644
index 0000000..69f0bb5
--- /dev/null
+++ b/media/tests/audiotests/Android.mk
@@ -0,0 +1,21 @@
+ifeq ($(TARGET_ARCH),arm)
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= shared_mem_test
+LOCAL_SRC_FILES := \
+		   shared_mem_test.cpp
+LOCAL_SHARED_LIBRARIES :=  \
+		libc \
+        libcutils \
+        libutils \
+        libbinder \
+        libhardware_legacy \
+		libmedia
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
+
+endif
diff --git a/media/tests/audiotests/shared_mem_test.cpp b/media/tests/audiotests/shared_mem_test.cpp
new file mode 100644
index 0000000..992c900
--- /dev/null
+++ b/media/tests/audiotests/shared_mem_test.cpp
@@ -0,0 +1,216 @@
+// Copyright 2008, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//
+#define LOG_NDEBUG 0
+#define LOG_TAG "shared_mem_test"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/properties.h>
+#include <media/AudioSystem.h>
+#include <media/AudioTrack.h>
+#include <math.h>
+
+#include "shared_mem_test.h"
+#include <binder/MemoryDealer.h>
+#include <binder/MemoryHeapBase.h>
+#include <binder/MemoryBase.h>
+#include <binder/ProcessState.h>
+
+
+#include <utils/Log.h>
+
+#include <fcntl.h>
+
+namespace android {
+
+/************************************************************
+*
+*    Constructor
+*
+************************************************************/
+AudioTrackTest::AudioTrackTest(void) {
+
+    InitSine();         // init sine table
+
+}
+
+
+/************************************************************
+*
+*
+************************************************************/
+void AudioTrackTest::Execute(void) {
+    if (Test01() == 0) {
+        ALOGD("01 passed\n");
+    } else {
+        ALOGD("01 failed\n");
+    }
+}
+
+/************************************************************
+*
+*    Shared memory test
+*
+************************************************************/
+#define BUF_SZ 44100
+
+int AudioTrackTest::Test01() {
+
+    sp<MemoryDealer> heap;
+    sp<IMemory> iMem;
+    uint8_t* p;
+
+    short smpBuf[BUF_SZ];
+    long rate = 44100;
+    unsigned long phi;
+    unsigned long dPhi;
+    long amplitude;
+    long freq = 1237;
+    float f0;
+
+    f0 = pow(2., 32.) * freq / (float)rate;
+    dPhi = (unsigned long)f0;
+    amplitude = 1000;
+    phi = 0;
+    Generate(smpBuf, BUF_SZ, amplitude, phi, dPhi);  // fill buffer
+
+    for (int i = 0; i < 1024; i++) {
+        heap = new MemoryDealer(1024*1024, "AudioTrack Heap Base");
+
+        iMem = heap->allocate(BUF_SZ*sizeof(short));
+
+        p = static_cast<uint8_t*>(iMem->pointer());
+        memcpy(p, smpBuf, BUF_SZ*sizeof(short));
+
+        sp<AudioTrack> track = new AudioTrack(AUDIO_STREAM_MUSIC,// stream type
+               rate,
+               AUDIO_FORMAT_PCM_16_BIT,// word length, PCM
+               AUDIO_CHANNEL_OUT_MONO,
+               iMem);
+
+        status_t status = track->initCheck();
+        if(status != NO_ERROR) {
+            track.clear();
+            ALOGD("Failed for initCheck()");
+            return -1;
+        }
+
+        // start play
+        ALOGD("start");
+        track->start();
+
+        usleep(20000);
+
+        ALOGD("stop");
+        track->stop();
+        iMem.clear();
+        heap.clear();
+        usleep(20000);
+    }
+
+    return 0;
+
+}
+
+/************************************************************
+*
+*    Generate a mono buffer
+*    Error is less than 3lsb
+*
+************************************************************/
+void AudioTrackTest::Generate(short *buffer, long bufferSz, long amplitude, unsigned long &phi, long dPhi)
+{
+    long pi13 = 25736;   // 2^13*pi
+    // fill buffer
+    for(int i0=0; i0<bufferSz; i0++) {
+        long sample;
+        long l0, l1;
+
+        buffer[i0] = ComputeSine( amplitude, phi);
+        phi += dPhi;
+    }
+}
+
+/************************************************************
+*
+*    Generate a sine
+*    Error is less than 3lsb
+*
+************************************************************/
+short AudioTrackTest::ComputeSine(long amplitude, long phi)
+{
+    long pi13 = 25736;   // 2^13*pi
+    long sample;
+    long l0, l1;
+
+    sample = (amplitude*sin1024[(phi>>22) & 0x3ff]) >> 15;
+    // correct with interpolation
+    l0 = (phi>>12) & 0x3ff;         // 2^20 * x / (2*pi)
+    l1 = (amplitude*sin1024[((phi>>22) + 256) & 0x3ff]) >> 15;    // 2^15*cosine
+    l0 = (l0 * l1) >> 10;
+    l0 = (l0 * pi13) >> 22;
+    sample = sample + l0;
+
+    return (short)sample;
+}
+
+
+/************************************************************
+*
+*    init sine table
+*
+************************************************************/
+void AudioTrackTest::InitSine(void) {
+    double phi = 0;
+    double dPhi = 2 * M_PI / SIN_SZ;
+    for(int i0 = 0; i0<SIN_SZ; i0++) {
+        long d0;
+
+        d0 = 32768. * sin(phi);
+        phi += dPhi;
+        if(d0 >= 32767) d0 = 32767;
+        if(d0 <= -32768) d0 = -32768;
+        sin1024[i0] = (short)d0;
+    }
+}
+
+/************************************************************
+*
+*    main in name space
+*
+************************************************************/
+int main() {
+    ProcessState::self()->startThreadPool();
+    AudioTrackTest *test;
+
+    test = new AudioTrackTest();
+    test->Execute();
+    delete test;
+
+    return 0;
+}
+
+}
+
+/************************************************************
+*
+*    global main
+*
+************************************************************/
+int main(int argc, char *argv[]) {
+
+    return android::main();
+}
diff --git a/media/tests/audiotests/shared_mem_test.h b/media/tests/audiotests/shared_mem_test.h
new file mode 100644
index 0000000..f495955
--- /dev/null
+++ b/media/tests/audiotests/shared_mem_test.h
@@ -0,0 +1,27 @@
+// Copyright 2008 The Android Open Source Project
+
+#ifndef AUDIOTRACKTEST_H_
+#define AUDIOTRACKTEST_H_
+
+namespace android {
+
+class AudioTrackTest{
+    public:
+        AudioTrackTest(void);
+        ~AudioTrackTest() {};
+
+        void Execute(void);
+        int Test01();
+
+        void Generate(short *buffer, long bufferSz, long amplitude, unsigned long &phi, long dPhi);
+        void InitSine();
+        short ComputeSine(long amplitude, long phi);
+
+        #define SIN_SZ    1024
+        short sin1024[SIN_SZ];           // sine table 2*pi = 1024
+};
+
+};
+
+
+#endif /*AUDIOTRACKTEST_H_*/
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
index 9319025..1e6954e 100644
--- a/packages/PrintSpooler/AndroidManifest.xml
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -44,7 +44,7 @@
     <uses-sdk android:minSdkVersion="18" android:targetSdkVersion="18"/>
 
     <application
-            android:allowClearUserData="false"
+            android:allowClearUserData="true"
             android:label="@string/app_label"
             android:allowBackup= "false"
             android:supportsRtl="true">
diff --git a/packages/PrintSpooler/res/values/strings.xml b/packages/PrintSpooler/res/values/strings.xml
index 21a4867..543c425 100644
--- a/packages/PrintSpooler/res/values/strings.xml
+++ b/packages/PrintSpooler/res/values/strings.xml
@@ -139,18 +139,20 @@
 
     <!-- Title of an application permission, listed so the user can choose whether they want
          to allow the application to do this. -->
-    <string name="permlab_accessAllPrintJobs">access all print jobs</string>
+    <string name="permlab_accessAllPrintJobs" translatable="false">access all print jobs</string>
     <!-- Description of an application permission, listed so the user can choose whether
          they want to allow the application to do this. -->
-    <string name="permdesc_accessAllPrintJobs">Allows the holder to access print jobs
-        created by another app. Should never be needed for normal apps.</string>
+    <string name="permdesc_accessAllPrintJobs" translatable="false">Allows the holder to access
+        print jobs created by another app. Should never be needed for normal apps.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want
          to allow the application to do this. -->
-    <string name="permlab_startPrintServiceConfigActivity">start print service configuration activities</string>
+    <string name="permlab_startPrintServiceConfigActivity" translatable="false">start print
+        service configuration activities</string>
     <!-- Description of an application permission, listed so the user can choose whether they
          want to allow the application to do this. -->
-    <string name="permdesc_startPrintServiceConfigActivity">Allows the holder to start the
-        configuration activities of a print service. Should never be needed for normal apps.</string>
+    <string name="permdesc_startPrintServiceConfigActivity" translatable="false">Allows the
+        holder to start the configuration activities of a print service. Should never be needed
+        for normal apps.</string>
 
 </resources>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java b/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java
index 43a751c..829fb06 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java
@@ -23,13 +23,13 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.AsyncTask;
-import android.os.Build;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.print.IPrintManager;
+import android.print.PrintJobId;
 import android.print.PrintJobInfo;
 import android.print.PrintManager;
 import android.text.TextUtils;
@@ -40,12 +40,13 @@
  * based on print job state transitions.
  */
 public class NotificationController {
-    public static final boolean DEBUG = true && Build.IS_DEBUGGABLE;
+    public static final boolean DEBUG = false;
 
     public static final String LOG_TAG = "NotificationController";
 
     private static final String INTENT_ACTION_CANCEL_PRINTJOB = "INTENT_ACTION_CANCEL_PRINTJOB";
     private static final String INTENT_ACTION_RESTART_PRINTJOB = "INTENT_ACTION_RESTART_PRINTJOB";
+
     private static final String INTENT_EXTRA_PRINTJOB_ID = "INTENT_EXTRA_PRINTJOB_ID";
     private static final String INTENT_EXTRA_PRINTJOB_LABEL = "INTENT_EXTRA_PRINTJOB_LABEL";
     private static final String INTENT_EXTRA_PRINTER_NAME = "INTENT_EXTRA_PRINTER_NAME";
@@ -61,8 +62,9 @@
 
     public void onPrintJobStateChanged(PrintJobInfo printJob) {
         if (DEBUG) {
-            Log.i(LOG_TAG, "onPrintJobStateChanged() printJobId: " + printJob.getId()
-                    + " state:" + PrintJobInfo.stateToString(printJob.getState()));
+            Log.i(LOG_TAG, "onPrintJobStateChanged() printJobId: "
+                    + printJob.getId().flattenToString() + " state:"
+                    + PrintJobInfo.stateToString(printJob.getState()));
         }
         switch (printJob.getState()) {
             case PrintJobInfo.STATE_QUEUED:
@@ -96,7 +98,7 @@
                 .setWhen(System.currentTimeMillis())
                 .setOngoing(true)
                 .setShowWhen(true);
-        mNotificationManager.notify(printJob.getId(), builder.build());
+        mNotificationManager.notify(printJob.getId().flattenToString(), 0, builder.build());
     }
 
     private void createFailedNotification(PrintJobInfo printJob) {
@@ -115,7 +117,7 @@
                 .setWhen(System.currentTimeMillis())
                 .setOngoing(true)
                 .setShowWhen(true);
-        mNotificationManager.notify(printJob.getId(), builder.build());
+        mNotificationManager.notify(printJob.getId().flattenToString(), 0, builder.build());
     }
 
     private void createBlockedNotification(PrintJobInfo printJob) {
@@ -132,25 +134,25 @@
                 .setWhen(System.currentTimeMillis())
                 .setOngoing(true)
                 .setShowWhen(true);
-        mNotificationManager.notify(printJob.getId(), builder.build());
+        mNotificationManager.notify(printJob.getId().flattenToString(), 0, builder.build());
     }
 
-    private void removeNotification(int printJobId) {
-        mNotificationManager.cancel(printJobId);
+    private void removeNotification(PrintJobId printJobId) {
+        mNotificationManager.cancel(printJobId.flattenToString(), 0);
     }
 
     private PendingIntent createCancelIntent(PrintJobInfo printJob) {
         Intent intent = new Intent(mContext, NotificationBroadcastReceiver.class);
-        intent.setAction(INTENT_ACTION_CANCEL_PRINTJOB + "_" + String.valueOf(printJob.getId()));
+        intent.setAction(INTENT_ACTION_CANCEL_PRINTJOB + "_" + printJob.getId().flattenToString());
         intent.putExtra(INTENT_EXTRA_PRINTJOB_ID, printJob.getId());
         intent.putExtra(INTENT_EXTRA_PRINTJOB_LABEL, printJob.getLabel());
         intent.putExtra(INTENT_EXTRA_PRINTER_NAME, printJob.getPrinterName());
         return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT);
     }
 
-    private PendingIntent createRestartIntent(int printJobId) {
+    private PendingIntent createRestartIntent(PrintJobId printJobId) {
         Intent intent = new Intent(mContext, NotificationBroadcastReceiver.class);
-        intent.setAction(INTENT_ACTION_RESTART_PRINTJOB + "_" + String.valueOf(printJobId));
+        intent.setAction(INTENT_ACTION_RESTART_PRINTJOB + "_" + printJobId.flattenToString());
         intent.putExtra(INTENT_EXTRA_PRINTJOB_ID, printJobId);
         return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT);
     }
@@ -162,17 +164,17 @@
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
             if (action != null && action.startsWith(INTENT_ACTION_CANCEL_PRINTJOB)) {
-                final int printJobId = intent.getExtras().getInt(INTENT_EXTRA_PRINTJOB_ID);
+                PrintJobId printJobId = intent.getExtras().getParcelable(INTENT_EXTRA_PRINTJOB_ID);
                 String printJobLabel = intent.getExtras().getString(INTENT_EXTRA_PRINTJOB_LABEL);
                 String printerName = intent.getExtras().getString(INTENT_EXTRA_PRINTER_NAME);
                 handleCancelPrintJob(context, printJobId, printJobLabel, printerName);
             } else if (action != null && action.startsWith(INTENT_ACTION_RESTART_PRINTJOB)) {
-                final int printJobId = intent.getExtras().getInt(INTENT_EXTRA_PRINTJOB_ID);
+                PrintJobId printJobId = intent.getExtras().getParcelable(INTENT_EXTRA_PRINTJOB_ID);
                 handleRestartPrintJob(context, printJobId);
             }
         }
 
-        private void handleCancelPrintJob(final Context context, final int printJobId,
+        private void handleCancelPrintJob(final Context context, final PrintJobId printJobId,
                 final String printJobLabel, final String printerName) {
             if (DEBUG) {
                 Log.i(LOG_TAG, "handleCancelPrintJob() printJobId:" + printJobId);
@@ -190,7 +192,7 @@
                     .setWhen(System.currentTimeMillis())
                     .setOngoing(true)
                     .setShowWhen(true);
-            notificationManager.notify(printJobId, builder.build());
+            notificationManager.notify(printJobId.flattenToString(), 0, builder.build());
 
             // Call into the print manager service off the main thread since
             // the print manager service may end up binding to the print spooler
@@ -226,7 +228,7 @@
             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
         }
 
-        private void handleRestartPrintJob(final Context context, final int printJobId) {
+        private void handleRestartPrintJob(final Context context, final PrintJobId printJobId) {
             if (DEBUG) {
                 Log.i(LOG_TAG, "handleRestartPrintJob() printJobId:" + printJobId);
             }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
index 14f60f1..4333aea 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
@@ -47,6 +47,7 @@
 import android.print.PrintAttributes.Resolution;
 import android.print.PrintDocumentAdapter;
 import android.print.PrintDocumentInfo;
+import android.print.PrintJobId;
 import android.print.PrintJobInfo;
 import android.print.PrintManager;
 import android.print.PrinterCapabilitiesInfo;
@@ -104,8 +105,7 @@
     private static final boolean DEBUG = true && Build.IS_DEBUGGABLE;
 
     public static final String EXTRA_PRINT_DOCUMENT_ADAPTER = "printDocumentAdapter";
-    public static final String EXTRA_PRINT_ATTRIBUTES = "printAttributes";
-    public static final String EXTRA_PRINT_JOB_ID = "printJobId";
+    public static final String EXTRA_PRINT_JOB = "printJob";
 
     public static final String INTENT_EXTRA_PRINTER_ID = "INTENT_EXTRA_PRINTER_ID";
 
@@ -163,7 +163,7 @@
     private Document mDocument;
     private PrintController mController;
 
-    private int mPrintJobId;
+    private PrintJobId mPrintJobId;
 
     private IBinder mIPrintDocumentAdapter;
 
@@ -175,17 +175,18 @@
 
         Bundle extras = getIntent().getExtras();
 
-        mPrintJobId = extras.getInt(EXTRA_PRINT_JOB_ID, -1);
-        if (mPrintJobId < 0) {
-            throw new IllegalArgumentException("Invalid print job id: " + mPrintJobId);
+        PrintJobInfo printJob = extras.getParcelable(EXTRA_PRINT_JOB);
+        if (printJob == null) {
+            throw new IllegalArgumentException("printJob cannot be null");
         }
 
+        mPrintJobId = printJob.getId();
         mIPrintDocumentAdapter = extras.getBinder(EXTRA_PRINT_DOCUMENT_ADAPTER);
         if (mIPrintDocumentAdapter == null) {
             throw new IllegalArgumentException("PrintDocumentAdapter cannot be null");
         }
 
-        PrintAttributes attributes = getIntent().getParcelableExtra(EXTRA_PRINT_ATTRIBUTES);
+        PrintAttributes attributes = printJob.getAttributes();
         if (attributes != null) {
             mCurrPrintAttributes.copyFrom(attributes);
         }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java
index 8580fcd..a6353f7 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java
@@ -37,6 +37,7 @@
 import android.print.PrintAttributes.MediaSize;
 import android.print.PrintAttributes.Resolution;
 import android.print.PrintDocumentInfo;
+import android.print.PrintJobId;
 import android.print.PrintJobInfo;
 import android.print.PrintManager;
 import android.print.PrinterId;
@@ -51,6 +52,8 @@
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.FastXmlSerializer;
 
+import libcore.io.IoUtils;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -63,8 +66,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import libcore.io.IoUtils;
-
 /**
  * Service for exposing some of the {@link PrintSpooler} functionality to
  * another process.
@@ -73,7 +74,7 @@
 
     private static final String LOG_TAG = "PrintSpoolerService";
 
-    private static final boolean DEBUG_PRINT_JOB_LIFECYCLE = false;
+    private static final boolean DEBUG_PRINT_JOB_LIFECYCLE = true;
 
     private static final boolean DEBUG_PERSISTENCE = false;
 
@@ -91,10 +92,6 @@
 
     private static PrintSpoolerService sInstance;
 
-    private static int sPrintJobIdCounter;
-
-    private Intent mStartPrintJobConfigActivityIntent;
-
     private IPrintSpoolerClient mClient;
 
     private HandlerCaller mHandlerCaller;
@@ -112,8 +109,6 @@
     @Override
     public void onCreate() {
         super.onCreate();
-        mStartPrintJobConfigActivityIntent = new Intent(PrintSpoolerService.this,
-                PrintJobConfigActivity.class);
         mHandlerCaller = new HandlerCaller(this, getMainLooper(),
                 new HandlerCallerCallback(), false);
 
@@ -147,7 +142,7 @@
             }
 
             @Override
-            public void getPrintJobInfo(int printJobId, IPrintSpoolerCallbacks callback,
+            public void getPrintJobInfo(PrintJobId printJobId, IPrintSpoolerCallbacks callback,
                     int appId, int sequence) throws RemoteException {
                 PrintJobInfo printJob = null;
                 try {
@@ -159,38 +154,28 @@
 
             @SuppressWarnings("deprecation")
             @Override
-            public void createPrintJob(String printJobName, IPrintClient client,
-                    IPrintDocumentAdapter printAdapter, PrintAttributes attributes,
-                    IPrintSpoolerCallbacks callback, int appId, int sequence)
-                    throws RemoteException {
-                PrintJobInfo printJob = null;
-                try {
-                    printJob = PrintSpoolerService.this.createPrintJob(
-                            printJobName, client, attributes, appId);
-                    if (printJob != null) {
-                        Intent intent = mStartPrintJobConfigActivityIntent;
-                        intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_DOCUMENT_ADAPTER,
-                                printAdapter.asBinder());
-                        intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_JOB_ID,
-                                printJob.getId());
-                        intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_ATTRIBUTES, attributes);
+            public void createPrintJob(PrintJobInfo printJob, IPrintClient client,
+                    IPrintDocumentAdapter printAdapter) throws RemoteException {
+                    PrintSpoolerService.this.createPrintJob(printJob);
 
-                        IntentSender sender = PendingIntent.getActivity(
-                                PrintSpoolerService.this, 0, intent, PendingIntent.FLAG_ONE_SHOT
-                                        | PendingIntent.FLAG_CANCEL_CURRENT).getIntentSender();
+                    Intent intent = new Intent(printJob.getId().flattenToString());
+                    intent.setClass(PrintSpoolerService.this, PrintJobConfigActivity.class);
+                    intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_DOCUMENT_ADAPTER,
+                            printAdapter.asBinder());
+                    intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_JOB, printJob);
 
-                        Message message = mHandlerCaller.obtainMessageOO(
-                                HandlerCallerCallback.MSG_START_PRINT_JOB_CONFIG_ACTIVITY,
-                                client, sender);
-                        mHandlerCaller.executeOrSendMessage(message);
-                    }
-                } finally {
-                    callback.onCreatePrintJobResult(printJob, sequence);
-                }
+                    IntentSender sender = PendingIntent.getActivity(
+                            PrintSpoolerService.this, 0, intent, PendingIntent.FLAG_ONE_SHOT
+                            | PendingIntent.FLAG_CANCEL_CURRENT).getIntentSender();
+
+                    Message message = mHandlerCaller.obtainMessageOO(
+                            HandlerCallerCallback.MSG_START_PRINT_JOB_CONFIG_ACTIVITY,
+                            client, sender);
+                    mHandlerCaller.executeOrSendMessage(message);
             }
 
             @Override
-            public void setPrintJobState(int printJobId, int state, String error,
+            public void setPrintJobState(PrintJobId printJobId, int state, String error,
                     IPrintSpoolerCallbacks callback, int sequece) throws RemoteException {
                 boolean success = false;
                 try {
@@ -202,7 +187,7 @@
             }
 
             @Override
-            public void setPrintJobTag(int printJobId, String tag,
+            public void setPrintJobTag(PrintJobId printJobId, String tag,
                     IPrintSpoolerCallbacks callback, int sequece) throws RemoteException {
                 boolean success = false;
                 try {
@@ -213,7 +198,7 @@
             }
 
             @Override
-            public void writePrintJobData(ParcelFileDescriptor fd, int printJobId) {
+            public void writePrintJobData(ParcelFileDescriptor fd, PrintJobId printJobId) {
                 PrintSpoolerService.this.writePrintJobData(fd, printJobId);
             }
 
@@ -223,6 +208,16 @@
                         HandlerCallerCallback.MSG_SET_CLIENT, client);
                 mHandlerCaller.executeOrSendMessage(message);
             }
+
+            @Override
+            public void removeObsoletePrintJobs() {
+                PrintSpoolerService.this.removeObsoletePrintJobs();
+            }
+
+            @Override
+            public void forgetPrintJobs(List<PrintJobId> printJobIds) {
+                PrintSpoolerService.this.forgetPrintJobs(printJobIds);
+            }
         };
     }
 
@@ -351,15 +346,16 @@
 
     private boolean isStateVisibleToUser(int state) {
         return (isActiveState(state) && (state == PrintJobInfo.STATE_FAILED
-                || state == PrintJobInfo.STATE_COMPLETED|| state == PrintJobInfo.STATE_CANCELED));
+                || state == PrintJobInfo.STATE_COMPLETED || state == PrintJobInfo.STATE_CANCELED
+                || state == PrintJobInfo.STATE_BLOCKED));
     }
 
-    public PrintJobInfo getPrintJobInfo(int printJobId, int appId) {
+    public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId) {
         synchronized (mLock) {
             final int printJobCount = mPrintJobs.size();
             for (int i = 0; i < printJobCount; i++) {
                 PrintJobInfo printJob = mPrintJobs.get(i);
-                if (printJob.getId() == printJobId
+                if (printJob.getId().equals(printJobId)
                         && (appId == PrintManager.APP_ID_ANY
                         || appId == printJob.getAppId())) {
                     return printJob;
@@ -369,20 +365,9 @@
         }
     }
 
-    public PrintJobInfo createPrintJob(String label, IPrintClient client,
-            PrintAttributes attributes, int appId) {
+    public void createPrintJob(PrintJobInfo printJob) {
         synchronized (mLock) {
-            final int printJobId = generatePrintJobIdLocked();
-            PrintJobInfo printJob = new PrintJobInfo();
-            printJob.setId(printJobId);
-            printJob.setAppId(appId);
-            printJob.setLabel(label);
-            printJob.setAttributes(attributes);
-            printJob.setState(PrintJobInfo.STATE_CREATED);
-
             addPrintJobLocked(printJob);
-
-            return printJob;
         }
     }
 
@@ -404,8 +389,7 @@
                     // decide whether to restart the job or just cancel it.
                     setPrintJobState(printJob.getId(), PrintJobInfo.STATE_FAILED,
                             getString(R.string.no_connection_to_printer));
-                }
-                    break;
+                } break;
             }
         }
     }
@@ -418,26 +402,7 @@
         }
     }
 
-    private int generatePrintJobIdLocked() {
-        int printJobId = sPrintJobIdCounter++;
-        while (isDuplicatePrintJobId(printJobId)) {
-            printJobId = sPrintJobIdCounter++;
-        }
-        return printJobId;
-    }
-
-    private boolean isDuplicatePrintJobId(int printJobId) {
-        final int printJobCount = mPrintJobs.size();
-        for (int j = 0; j < printJobCount; j++) {
-            PrintJobInfo printJob = mPrintJobs.get(j);
-            if (printJob.getId() == printJobId) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public void writePrintJobData(final ParcelFileDescriptor fd, final int printJobId) {
+    public void writePrintJobData(final ParcelFileDescriptor fd, final PrintJobId printJobId) {
         final PrintJobInfo printJob;
         synchronized (mLock) {
             printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
@@ -476,9 +441,9 @@
         }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
     }
 
-    public File generateFileForPrintJob(int printJobId) {
+    public File generateFileForPrintJob(PrintJobId printJobId) {
         return new File(getFilesDir(), "print_job_"
-                + printJobId + "." + PRINT_FILE_EXTENSION);
+                + printJobId.flattenToString() + "." + PRINT_FILE_EXTENSION);
     }
 
     private void addPrintJobLocked(PrintJobInfo printJob) {
@@ -488,16 +453,59 @@
         }
     }
 
-    private void removePrintJobLocked(PrintJobInfo printJob) {
-        if (mPrintJobs.remove(printJob)) {
-            generateFileForPrintJob(printJob.getId()).delete();
-            if (DEBUG_PRINT_JOB_LIFECYCLE) {
-                Slog.i(LOG_TAG, "[REMOVE] " + printJob);
+    private void forgetPrintJobs(List<PrintJobId> printJobIds) {
+        synchronized (mLock) {
+            boolean printJobsRemoved = false;
+            final int removedPrintJobCount = printJobIds.size();
+            for (int i = 0; i < removedPrintJobCount; i++) {
+                PrintJobId removedPrintJobId = printJobIds.get(i);
+                final int printJobCount = mPrintJobs.size();
+                for (int j = printJobCount - 1; j >= 0; j--) {
+                    PrintJobInfo printJob = mPrintJobs.get(j);
+                    if (removedPrintJobId.equals(printJob.getId())) {
+                        mPrintJobs.remove(j);
+                        printJobsRemoved = true;
+                        if (DEBUG_PRINT_JOB_LIFECYCLE) {
+                            Slog.i(LOG_TAG, "[FORGOT] " + printJob.getId().flattenToString());
+                        }
+                        removePrintJobFileLocked(printJob.getId());
+                    }
+                }
+            }
+            if (printJobsRemoved) {
+                mPersistanceManager.writeStateLocked();
             }
         }
     }
 
-    public boolean setPrintJobState(int printJobId, int state, String error) {
+    private void removeObsoletePrintJobs() {
+        synchronized (mLock) {
+            final int printJobCount = mPrintJobs.size();
+            for (int i = printJobCount - 1; i >= 0; i--) {
+                PrintJobInfo printJob = mPrintJobs.get(i);
+                if (isObsoleteState(printJob.getState())) {
+                    mPrintJobs.remove(i);
+                    if (DEBUG_PRINT_JOB_LIFECYCLE) {
+                        Slog.i(LOG_TAG, "[REMOVE] " + printJob.getId().flattenToString());
+                    }
+                    removePrintJobFileLocked(printJob.getId());
+                }
+            }
+            mPersistanceManager.writeStateLocked();
+        }
+    }
+
+    private void removePrintJobFileLocked(PrintJobId printJobId) {
+        File file = generateFileForPrintJob(printJobId);
+        if (file.exists()) {
+            file.delete();
+            if (DEBUG_PRINT_JOB_LIFECYCLE) {
+                Slog.i(LOG_TAG, "[REMOVE FILE FOR] " + printJobId.flattenToString());
+            }
+        }
+    }
+
+    public boolean setPrintJobState(PrintJobId printJobId, int state, String error) {
         boolean success = false;
 
         synchronized (mLock) {
@@ -516,7 +524,11 @@
                 switch (state) {
                     case PrintJobInfo.STATE_COMPLETED:
                     case PrintJobInfo.STATE_CANCELED:
-                        removePrintJobLocked(printJob);
+                        // Just remove the file but keep the print job info since
+                        // the app that created it may be holding onto the PrintJob
+                        // instance and query it for its most recent state. We will
+                        // remove the info for this job when told so by the system.
+                        removePrintJobFileLocked(printJob.getId());
                         // $fall-through$
 
                     case PrintJobInfo.STATE_FAILED: {
@@ -570,6 +582,11 @@
         return false;
     }
 
+    private boolean isObsoleteState(int printJobState) {
+        return (isTeminalState(printJobState)
+                || printJobState == PrintJobInfo.STATE_QUEUED);
+    }
+
     private boolean isActiveState(int printJobState) {
         return printJobState == PrintJobInfo.STATE_CREATED
                 || printJobState == PrintJobInfo.STATE_QUEUED
@@ -577,7 +594,12 @@
                 || printJobState == PrintJobInfo.STATE_BLOCKED;
     }
 
-    public boolean setPrintJobTag(int printJobId, String tag) {
+    private boolean isTeminalState(int printJobState) {
+        return printJobState == PrintJobInfo.STATE_COMPLETED
+                || printJobState == PrintJobInfo.STATE_CANCELED;
+    }
+
+    public boolean setPrintJobTag(PrintJobId printJobId, String tag) {
         synchronized (mLock) {
             PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
             if (printJob != null) {
@@ -599,7 +621,7 @@
         return false;
     }
 
-    public void setPrintJobCopiesNoPersistence(int printJobId, int copies) {
+    public void setPrintJobCopiesNoPersistence(PrintJobId printJobId, int copies) {
         synchronized (mLock) {
             PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
             if (printJob != null) {
@@ -608,7 +630,8 @@
         }
     }
 
-    public void setPrintJobPrintDocumentInfoNoPersistence(int printJobId, PrintDocumentInfo info) {
+    public void setPrintJobPrintDocumentInfoNoPersistence(PrintJobId printJobId,
+            PrintDocumentInfo info) {
         synchronized (mLock) {
             PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
             if (printJob != null) {
@@ -617,7 +640,8 @@
         }
     }
 
-    public void setPrintJobAttributesNoPersistence(int printJobId, PrintAttributes attributes) {
+    public void setPrintJobAttributesNoPersistence(PrintJobId printJobId,
+            PrintAttributes attributes) {
         synchronized (mLock) {
             PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
             if (printJob != null) {
@@ -626,7 +650,7 @@
         }
     }
 
-    public void setPrintJobPrinterNoPersistence(int printJobId, PrinterInfo printer) {
+    public void setPrintJobPrinterNoPersistence(PrintJobId printJobId, PrinterInfo printer) {
         synchronized (mLock) {
             PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
             if (printJob != null) {
@@ -636,7 +660,7 @@
         }
     }
 
-    public void setPrintJobPagesNoPersistence(int printJobId, PageRange[] pages) {
+    public void setPrintJobPagesNoPersistence(PrintJobId printJobId, PageRange[] pages) {
         synchronized (mLock) {
             PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
             if (printJob != null) {
@@ -759,15 +783,9 @@
                 for (int j = 0; j < printJobCount; j++) {
                     PrintJobInfo printJob = printJobs.get(j);
 
-                    final int state = printJob.getState();
-                    if (state < PrintJobInfo.STATE_QUEUED
-                            || state > PrintJobInfo.STATE_CANCELED) {
-                        continue;
-                    }
-
                     serializer.startTag(null, TAG_JOB);
 
-                    serializer.attribute(null, ATTR_ID, String.valueOf(printJob.getId()));
+                    serializer.attribute(null, ATTR_ID, printJob.getId().flattenToString());
                     serializer.attribute(null, ATTR_LABEL, printJob.getLabel().toString());
                     serializer.attribute(null, ATTR_STATE, String.valueOf(printJob.getState()));
                     serializer.attribute(null, ATTR_APP_ID, String.valueOf(printJob.getAppId()));
@@ -948,7 +966,8 @@
 
             PrintJobInfo printJob = new PrintJobInfo();
 
-            final int printJobId = Integer.parseInt(parser.getAttributeValue(null, ATTR_ID));
+            PrintJobId printJobId = PrintJobId.unflattenFromString(
+                    parser.getAttributeValue(null, ATTR_ID));
             printJob.setId(printJobId);
             String label = parser.getAttributeValue(null, ATTR_LABEL);
             printJob.setLabel(label);
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 5e198a2..fa5c769 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -189,6 +189,35 @@
             android:taskAffinity="com.android.systemui.net"
             android:excludeFromRecents="true" />
 
+        <!-- platform logo easter egg activity -->
+        <activity
+            android:name=".DessertCase"
+            android:exported="true"
+            android:label="@string/dessert_case"
+            android:theme="@android:style/Theme.Wallpaper.NoTitleBar.Fullscreen"
+            android:hardwareAccelerated="true"
+            android:launchMode="singleInstance"
+            android:excludeFromRecents="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="com.android.internal.category.PLATLOGO" />
+            </intent-filter>
+        </activity>
+
+        <!-- a gallery of delicious treats -->
+        <service
+            android:name=".DessertCaseDream"
+            android:exported="true"
+            android:label="@string/dessert_case"
+            android:enabled="false"
+            >
+            <intent-filter>
+                <action android:name="android.service.dreams.DreamService" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </service>
+
         <activity android:name=".Somnambulator"
             android:label="@string/start_dreams"
             android:icon="@mipmap/ic_launcher_dreams"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index bbfe383..7fdd308 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -431,8 +431,8 @@
     <!-- Description of the button in the phone-style notification panel that controls auto-rotation, when auto-rotation is off. [CHAR LIMIT=NONE] -->
     <string name="accessibility_rotation_lock_on_portrait">Screen is locked in portrait orientation.</string>
 
-    <!-- Name of the Jelly Bean platlogo screensaver -->
-    <string name="jelly_bean_dream_name">BeanFlinger</string>
+    <!-- Name of the K-release easter egg: a display case for all our tastiest desserts. [CHAR LIMIT=30] -->
+    <string name="dessert_case">Dessert Case</string>
 
     <!-- Name of the launcher shortcut icon that allows dreams to be started immediately [CHAR LIMIT=20] -->
     <string name="start_dreams">Daydream</string>
diff --git a/packages/SystemUI/src/com/android/systemui/DessertCase.java b/packages/SystemUI/src/com/android/systemui/DessertCase.java
new file mode 100644
index 0000000..b6424af0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/DessertCase.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.util.Slog;
+
+public class DessertCase extends Activity {
+
+    @Override
+    public void onStart() {
+        super.onStart();
+
+        Slog.v("DessertCase", "ACHIEVEMENT UNLOCKED");
+        PackageManager pm = getPackageManager();
+        pm.setComponentEnabledSetting(new ComponentName(this, DessertCaseDream.class),
+                PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
+
+        finish();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/DessertCaseDream.java b/packages/SystemUI/src/com/android/systemui/DessertCaseDream.java
new file mode 100644
index 0000000..022e4d8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/DessertCaseDream.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui;
+
+import android.service.dreams.DreamService;
+
+public class DessertCaseDream extends DreamService {
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        setInteractive(true);
+        setFullscreen(true);
+    }
+
+    @Override
+    public void onDreamingStarted() {
+        super.onDreamingStarted();
+    }
+
+    @Override
+    public void onDreamingStopped() {
+        super.onDreamingStopped();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index ada30ac..5ebd11e0 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -23,6 +23,7 @@
 import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
 import android.app.TaskStackBuilder;
+import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
@@ -698,6 +699,8 @@
                         new UserHandle(UserHandle.USER_CURRENT));
             } catch (SecurityException e) {
                 Log.e(TAG, "Recents does not have the permission to launch " + intent, e);
+            } catch (ActivityNotFoundException e) {
+                Log.e(TAG, "Error launching activity " + intent, e);
             }
         }
         if (usingDrawingCache) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 4683030..b56d7be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -424,7 +424,7 @@
                         mCurrentView.getWidth(), mCurrentView.getHeight(),
                         visibilityToString(mCurrentView.getVisibility())));
 
-        pw.println(String.format("      disabled=0x%08x vertical=%s hidden=%s low=%s menu=%s",
+        pw.println(String.format("      disabled=0x%08x vertical=%s menu=%s",
                         mDisabledFlags,
                         mVertical ? "true" : "false",
                         mShowMenu ? "true" : "false"));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index ceed30e..25ffbd4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -671,7 +671,7 @@
         alarmTile.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                startSettingsActivity(AlarmClock.ACTION_SET_ALARM);
+                startSettingsActivity(AlarmClock.ACTION_SHOW_ALARMS);
             }
         });
         mModel.addAlarmTile(alarmTile, new QuickSettingsModel.RefreshCallback() {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 8a285e3..0782cfb 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -34,7 +34,6 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -105,7 +104,6 @@
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.util.HashSet;
 
 import static android.view.WindowManager.LayoutParams.*;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
@@ -531,7 +529,7 @@
                     Settings.Secure.DEFAULT_INPUT_METHOD), false, this,
                     UserHandle.USER_ALL);
             resolver.registerContentObserver(Settings.System.getUriFor(
-                    ImmersiveModeTesting.ENABLED_SETTING), false, this,
+                    Settings.Secure.TRANSIENT_NAV_CONFIRMATIONS), false, this,
                     UserHandle.USER_ALL);
             updateSettings();
         }
@@ -947,9 +945,7 @@
                     }
                     @Override
                     public void onDebug() {
-                        if (ImmersiveModeTesting.enabled) {
-                            ImmersiveModeTesting.toggleForceImmersiveMode(mFocusedWindow, mContext);
-                        }
+                        // no-op
                     }
                 });
         mTransientNavigationConfirmation = new TransientNavigationConfirmation(mContext);
@@ -1168,8 +1164,9 @@
                 mHasSoftInput = hasSoftInput;
                 updateRotation = true;
             }
-            ImmersiveModeTesting.enabled = Settings.System.getIntForUser(resolver,
-                    ImmersiveModeTesting.ENABLED_SETTING, 0, UserHandle.USER_CURRENT) != 0;
+            if (mTransientNavigationConfirmation != null) {
+                mTransientNavigationConfirmation.loadSetting();
+            }
         }
         if (updateRotation) {
             updateRotation(true);
@@ -2819,7 +2816,7 @@
 
                 // If the status bar is hidden, we don't want to cause
                 // windows behind it to scroll.
-                if (mStatusBar.isVisibleLw() && !statusBarTransient && !statusBarTransparent) {
+                if (mStatusBar.isVisibleLw() && !statusBarTransient) {
                     // Status bar may go away, so the screen area it occupies
                     // is available to apps but just covering them when the
                     // status bar is visible.
@@ -3892,9 +3889,8 @@
             case KeyEvent.KEYCODE_POWER: {
                 result &= ~ACTION_PASS_TO_USER;
                 if (down) {
-                    if (isScreenOn && isTransientNavigationAllowed(mLastSystemUiFlags)) {
-                        mTransientNavigationConfirmation.unconfirmLastPackage();
-                    }
+                    mTransientNavigationConfirmation.onPowerKeyDown(isScreenOn, event.getDownTime(),
+                            isTransientNavigationAllowed(mLastSystemUiFlags));
                     if (isScreenOn && !mPowerKeyTriggered
                             && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
                         mPowerKeyTriggered = true;
@@ -4173,6 +4169,7 @@
                 }
                 if (sb) mStatusBarController.showTransient();
                 if (nb) mNavigationBarController.showTransient();
+                mTransientNavigationConfirmation.confirmCurrentPrompt();
                 updateSystemUiVisibilityLw();
             }
         }
@@ -5039,10 +5036,6 @@
     }
 
     private int updateSystemBarsLw(int oldVis, int vis) {
-        if (ImmersiveModeTesting.enabled) {
-            vis = ImmersiveModeTesting.applyForced(mFocusedWindow, vis);
-        }
-
         // prevent status bar interaction from clearing certain flags
         boolean statusBarHasFocus = mFocusedWindow.getAttrs().type == TYPE_STATUS_BAR;
         if (statusBarHasFocus) {
@@ -5086,8 +5079,7 @@
         boolean isTransientNav = isTransientNavigationAllowed(vis);
         if (mFocusedWindow != null && oldTransientNav != isTransientNav) {
             final String pkg = mFocusedWindow.getOwningPackage();
-            mTransientNavigationConfirmation.transientNavigationChanged(mCurrentUserId, pkg,
-                    isTransientNav);
+            mTransientNavigationConfirmation.transientNavigationChanged(pkg, isTransientNav);
         }
         vis = mNavigationBarController.updateVisibilityLw(isTransientNav, oldVis, vis);
 
@@ -5104,53 +5096,6 @@
                 && (vis & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0;
     }
 
-    // Temporary helper that allows testing immersive mode on existing apps
-    // TODO remove
-    private static final class ImmersiveModeTesting {
-        static String ENABLED_SETTING = "immersive_mode_testing_enabled";
-        static boolean enabled = false;
-        private static final HashSet<String> sForced = new HashSet<String>();
-
-        private static String parseActivity(WindowState win) {
-            if (win != null && win.getAppToken() != null) {
-                String str = win.getAppToken().toString();
-                int end = str.lastIndexOf(' ');
-                if (end > 0) {
-                    int start = str.lastIndexOf(' ', end - 1);
-                    if (start > -1) {
-                        return str.substring(start + 1, end);
-                    }
-                }
-            }
-            return null;
-        }
-
-        public static int applyForced(WindowState focused, int vis) {
-            if (sForced.contains(parseActivity(focused))) {
-                vis |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
-                       View.SYSTEM_UI_FLAG_FULLSCREEN |
-                       View.SYSTEM_UI_FLAG_IMMERSIVE;
-            }
-            return vis;
-        }
-
-        public static void toggleForceImmersiveMode(WindowState focused, Context context) {
-            String activity = parseActivity(focused);
-            if (activity != null) {
-                String action;
-                if (sForced.contains(activity)) {
-                    sForced.remove(activity);
-                    action = "Force immersive mode disabled";
-                } else {
-                    sForced.add(activity);
-                    action = "Force immersive mode enabled";
-                }
-                android.widget.Toast.makeText(context,
-                        action + " for " + activity, android.widget.Toast.LENGTH_SHORT).show();
-            }
-        }
-    }
-
     // Use this instead of checking config_showNavigationBar so that it can be consistently
     // overridden by qemu.hw.mainkeys in the emulator.
     @Override
diff --git a/policy/src/com/android/internal/policy/impl/TransientNavigationConfirmation.java b/policy/src/com/android/internal/policy/impl/TransientNavigationConfirmation.java
index 3c4f092..8613088 100644
--- a/policy/src/com/android/internal/policy/impl/TransientNavigationConfirmation.java
+++ b/policy/src/com/android/internal/policy/impl/TransientNavigationConfirmation.java
@@ -19,16 +19,20 @@
 import android.content.Context;
 import android.os.Handler;
 import android.os.Message;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Slog;
 import android.view.View;
 import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
 import android.view.animation.AnimationUtils;
 import android.widget.Toast;
 
 import com.android.internal.R;
 
+import java.util.Arrays;
+
 /**
  *  Helper to manage showing/hiding a confirmation prompt when the transient navigation bar
  *  is hidden.
@@ -39,16 +43,22 @@
 
     private final Context mContext;
     private final H mHandler;
-    private final ArraySet<String> mConfirmedUserPackages = new ArraySet<String>();
+    private final ArraySet<String> mConfirmedPackages = new ArraySet<String>();
     private final long mShowDelayMs;
+    private final long mPanicThresholdMs;
 
     private Toast mToast;
-    private String mLastUserPackage;
+    private String mLastPackage;
+    private String mPromptPackage;
+    private long mPanicTime;
+    private String mPanicPackage;
 
     public TransientNavigationConfirmation(Context context) {
         mContext = context;
         mHandler = new H();
         mShowDelayMs = getNavBarExitDuration() * 3;
+        mPanicThresholdMs = context.getResources()
+                .getInteger(R.integer.config_transient_navigation_confirmation_panic);
     }
 
     private long getNavBarExitDuration() {
@@ -56,44 +66,97 @@
         return exit != null ? exit.getDuration() : 0;
     }
 
-    public void transientNavigationChanged(int userId, String pkg, boolean isNavTransient) {
+    public void loadSetting() {
+        if (DEBUG) Slog.d(TAG, "loadSetting()");
+        mConfirmedPackages.clear();
+        String packages = null;
+        try {
+            packages = Settings.Secure.getStringForUser(mContext.getContentResolver(),
+                    Settings.Secure.TRANSIENT_NAV_CONFIRMATIONS,
+                    UserHandle.USER_CURRENT);
+            if (packages != null) {
+                mConfirmedPackages.addAll(Arrays.asList(packages.split(",")));
+                if (DEBUG) Slog.d(TAG, "Loaded mConfirmedPackages=" + mConfirmedPackages);
+            }
+        } catch (Throwable t) {
+            Slog.w(TAG, "Error loading confirmations, packages=" + packages, t);
+        }
+    }
+
+    private void saveSetting() {
+        if (DEBUG) Slog.d(TAG, "saveSetting()");
+        try {
+            final String packages = TextUtils.join(",", mConfirmedPackages);
+            Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                    Settings.Secure.TRANSIENT_NAV_CONFIRMATIONS,
+                    packages,
+                    UserHandle.USER_CURRENT);
+            if (DEBUG) Slog.d(TAG, "Saved packages=" + packages);
+        } catch (Throwable t) {
+            Slog.w(TAG, "Error saving confirmations, mConfirmedPackages=" + mConfirmedPackages, t);
+        }
+    }
+
+    public void transientNavigationChanged(String pkg, boolean isNavTransient) {
         if (pkg == null) {
             return;
         }
-        String userPkg = userId + ":" + pkg;
         mHandler.removeMessages(H.SHOW);
         if (isNavTransient) {
-            mLastUserPackage = userPkg;
-            if (!mConfirmedUserPackages.contains(userPkg)) {
-                if (DEBUG) Slog.d(TAG, "Showing transient navigation confirmation for " + userPkg);
-                mHandler.sendMessageDelayed(mHandler.obtainMessage(H.SHOW, userPkg), mShowDelayMs);
+            mLastPackage = pkg;
+            if (!mConfirmedPackages.contains(pkg)) {
+                mHandler.sendMessageDelayed(mHandler.obtainMessage(H.SHOW, pkg), mShowDelayMs);
             }
         } else {
-            mLastUserPackage = null;
-            if (DEBUG) Slog.d(TAG, "Hiding transient navigation confirmation for " + userPkg);
+            mLastPackage = null;
             mHandler.sendEmptyMessage(H.HIDE);
         }
     }
 
-    public void unconfirmLastPackage() {
-        if (mLastUserPackage != null) {
-            if (DEBUG) Slog.d(TAG, "Unconfirming transient navigation for " + mLastUserPackage);
-            mConfirmedUserPackages.remove(mLastUserPackage);
+    public void onPowerKeyDown(boolean isScreenOn, long time, boolean transientNavigationAllowed) {
+        if (mPanicPackage != null && !isScreenOn && (time - mPanicTime < mPanicThresholdMs)) {
+            // turning the screen back on within the panic threshold
+            unconfirmPackage(mPanicPackage);
+        }
+        if (isScreenOn && transientNavigationAllowed) {
+            // turning the screen off, remember if we were hiding the transient nav
+            mPanicTime = time;
+            mPanicPackage = mLastPackage;
+        } else {
+            mPanicTime = 0;
+            mPanicPackage = null;
+        }
+    }
+
+    public void confirmCurrentPrompt() {
+        mHandler.post(confirmAction(mPromptPackage));
+    }
+
+    private void unconfirmPackage(String pkg) {
+        if (pkg != null) {
+            if (DEBUG) Slog.d(TAG, "Unconfirming transient navigation for " + pkg);
+            mConfirmedPackages.remove(pkg);
+            saveSetting();
         }
     }
 
     private void handleHide() {
         if (mToast != null) {
+            if (DEBUG) Slog.d(TAG,
+                    "Hiding transient navigation confirmation for " + mPromptPackage);
             mToast.cancel();
             mToast = null;
         }
     }
 
-    private void handleShow(String userPkg) {
+    private void handleShow(String pkg) {
+        mPromptPackage = pkg;
+        if (DEBUG) Slog.d(TAG, "Showing transient navigation confirmation for " + pkg);
+
         // create the confirmation toast bar
         final int msg = R.string.transient_navigation_confirmation;
         mToast = Toast.makeBar(mContext, msg, Toast.LENGTH_INFINITE);
-        mToast.setAction(R.string.ok, confirmAction(userPkg));
+        mToast.setAction(R.string.ok, confirmAction(pkg));
 
         // we will be hiding the nav bar, so layout as if it's already hidden
         mToast.getView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
@@ -102,11 +165,15 @@
         mToast.show();
     }
 
-    private Runnable confirmAction(final String userPkg) {
+    private Runnable confirmAction(final String pkg) {
         return new Runnable() {
             @Override
             public void run() {
-                mConfirmedUserPackages.add(userPkg);
+                if (pkg != null && !mConfirmedPackages.contains(pkg)) {
+                    if (DEBUG) Slog.d(TAG, "Confirming transient navigation for " + pkg);
+                    mConfirmedPackages.add(pkg);
+                    saveSetting();
+                }
                 handleHide();
             }
         };
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index c4eb7a4..f3ebdb2 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -1305,9 +1305,6 @@
                 mTransports.put(name, transport);
             } else {
                 mTransports.remove(name);
-                if ((mCurrentTransport != null) && mCurrentTransport.equals(name)) {
-                    mCurrentTransport = null;
-                }
                 // Nothing further to do in the unregistration case
                 return;
             }
diff --git a/services/java/com/android/server/IdleMaintenanceService.java b/services/java/com/android/server/IdleMaintenanceService.java
index 584d4bc..b0a1aca 100644
--- a/services/java/com/android/server/IdleMaintenanceService.java
+++ b/services/java/com/android/server/IdleMaintenanceService.java
@@ -17,6 +17,7 @@
 package com.android.server;
 
 import android.app.Activity;
+import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
@@ -24,12 +25,13 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.Handler;
-import android.os.Looper;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
+import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.Log;
+import android.util.Slog;
 
 /**
  * This service observes the device state and when applicable sends
@@ -69,6 +71,9 @@
     private static final String ACTION_UPDATE_IDLE_MAINTENANCE_STATE =
         "com.android.server.IdleMaintenanceService.action.UPDATE_IDLE_MAINTENANCE_STATE";
 
+    private static final String ACTION_FORCE_IDLE_MAINTENANCE =
+        "com.android.server.IdleMaintenanceService.action.FORCE_IDLE_MAINTENANCE";
+
     private static final Intent sIdleMaintenanceStartIntent;
     static {
         sIdleMaintenanceStartIntent = new Intent(Intent.ACTION_IDLE_MAINTENANCE_START);
@@ -115,10 +120,10 @@
         mUpdateIdleMaintenanceStatePendingIntent = PendingIntent.getBroadcast(mContext, 0,
                 intent, PendingIntent.FLAG_UPDATE_CURRENT);
 
-        register(mContext.getMainLooper());
+        register(mHandler);
     }
 
-    public void register(Looper looper) {
+    public void register(Handler handler) {
         IntentFilter intentFilter = new IntentFilter();
 
         // Alarm actions.
@@ -136,7 +141,12 @@
         intentFilter.addAction(Intent.ACTION_DREAMING_STOPPED);
 
         mContext.registerReceiverAsUser(this, UserHandle.ALL,
-                intentFilter, null, new Handler(looper));
+                intentFilter, null, mHandler);
+
+        intentFilter = new IntentFilter();
+        intentFilter.addAction(ACTION_FORCE_IDLE_MAINTENANCE);
+        mContext.registerReceiverAsUser(this, UserHandle.ALL,
+                intentFilter, android.Manifest.permission.SET_ACTIVITY_WATCHER, mHandler);
     }
 
     private void scheduleUpdateIdleMaintenanceState(long delayMillis) {
@@ -149,7 +159,7 @@
         mAlarmService.cancel(mUpdateIdleMaintenanceStatePendingIntent);
     }
 
-    private void updateIdleMaintenanceState() {
+    private void updateIdleMaintenanceState(boolean noisy) {
         if (mIdleMaintenanceStarted) {
             // Idle maintenance can be interrupted by user activity, or duration
             // time out, or low battery.
@@ -170,9 +180,9 @@
                             getNextIdleMaintenanceIntervalStartFromNow());
                 }
             }
-        } else if (deviceStatePermitsIdleMaintenanceStart()
-                && lastUserActivityPermitsIdleMaintenanceStart()
-                && lastRunPermitsIdleMaintenanceStart()) {
+        } else if (deviceStatePermitsIdleMaintenanceStart(noisy)
+                && lastUserActivityPermitsIdleMaintenanceStart(noisy)
+                && lastRunPermitsIdleMaintenanceStart(noisy)) {
             // Now that we started idle maintenance, we should schedule another
             // update for the moment when the idle maintenance times out.
             scheduleUpdateIdleMaintenanceState(MAX_IDLE_MAINTENANCE_DURATION);
@@ -182,8 +192,8 @@
                     isBatteryCharging() ? 1 : 0);
             mLastIdleMaintenanceStartTimeMillis = SystemClock.elapsedRealtime();
             sendIdleMaintenanceStartIntent();
-        } else if (lastUserActivityPermitsIdleMaintenanceStart()) {
-             if (lastRunPermitsIdleMaintenanceStart()) {
+        } else if (lastUserActivityPermitsIdleMaintenanceStart(noisy)) {
+             if (lastRunPermitsIdleMaintenanceStart(noisy)) {
                 // The user does not use the device and we did not run maintenance in more
                 // than the min interval between runs, so schedule an update - maybe the
                 // battery will be charged latter.
@@ -204,6 +214,10 @@
 
     private void sendIdleMaintenanceStartIntent() {
         mWakeLock.acquire();
+        try {
+            ActivityManagerNative.getDefault().performIdleMaintenance();
+        } catch (RemoteException e) {
+        }
         mContext.sendOrderedBroadcastAsUser(sIdleMaintenanceStartIntent, UserHandle.ALL,
                 null, this, mHandler, Activity.RESULT_OK, null, null);
     }
@@ -214,25 +228,37 @@
                 null, this, mHandler, Activity.RESULT_OK, null, null);
     }
 
-    private boolean deviceStatePermitsIdleMaintenanceStart() {
+    private boolean deviceStatePermitsIdleMaintenanceStart(boolean noisy) {
         final int minBatteryLevel = isBatteryCharging()
                 ? MIN_BATTERY_LEVEL_IDLE_MAINTENANCE_START_CHARGING
                 : MIN_BATTERY_LEVEL_IDLE_MAINTENANCE_START_NOT_CHARGING;
-        return (mLastUserActivityElapsedTimeMillis != LAST_USER_ACTIVITY_TIME_INVALID
+        boolean allowed = (mLastUserActivityElapsedTimeMillis != LAST_USER_ACTIVITY_TIME_INVALID
                 && mBatteryService.getBatteryLevel() > minBatteryLevel);
+        if (!allowed && noisy) {
+            Slog.i("IdleMaintenance", "Idle maintenance not allowed due to power");
+        }
+        return allowed;
     }
 
-    private boolean lastUserActivityPermitsIdleMaintenanceStart() {
+    private boolean lastUserActivityPermitsIdleMaintenanceStart(boolean noisy) {
         // The last time the user poked the device is above the threshold.
-        return (mLastUserActivityElapsedTimeMillis != LAST_USER_ACTIVITY_TIME_INVALID
+        boolean allowed = (mLastUserActivityElapsedTimeMillis != LAST_USER_ACTIVITY_TIME_INVALID
                 && SystemClock.elapsedRealtime() - mLastUserActivityElapsedTimeMillis
                     > MIN_USER_INACTIVITY_IDLE_MAINTENANCE_START);
+        if (!allowed && noisy) {
+            Slog.i("IdleMaintenance", "Idle maintenance not allowed due to last user activity");
+        }
+        return allowed;
     }
 
-    private boolean lastRunPermitsIdleMaintenanceStart() {
+    private boolean lastRunPermitsIdleMaintenanceStart(boolean noisy) {
         // Enough time passed since the last maintenance run.
-        return SystemClock.elapsedRealtime() - mLastIdleMaintenanceStartTimeMillis
+        boolean allowed = SystemClock.elapsedRealtime() - mLastIdleMaintenanceStartTimeMillis
                 > MIN_IDLE_MAINTENANCE_INTERVAL_MILLIS;
+        if (!allowed && noisy) {
+            Slog.i("IdleMaintenance", "Idle maintenance not allowed due time since last");
+        }
+        return allowed;
     }
 
     private boolean lastUserActivityPermitsIdleMaintenanceRunning() {
@@ -266,7 +292,7 @@
             // next release. The only client for this for now is internal an holds
             // a wake lock correctly.
             if (mIdleMaintenanceStarted) {
-                updateIdleMaintenanceState();
+                updateIdleMaintenanceState(false);
             }
         } else if (Intent.ACTION_SCREEN_ON.equals(action)
                 || Intent.ACTION_DREAMING_STOPPED.equals(action)) {
@@ -276,7 +302,7 @@
             unscheduleUpdateIdleMaintenanceState();
             // If the screen went on/stopped dreaming, we know the user is using the
             // device which means that idle maintenance should be stopped if running.
-            updateIdleMaintenanceState();
+            updateIdleMaintenanceState(false);
         } else if (Intent.ACTION_SCREEN_OFF.equals(action)
                 || Intent.ACTION_DREAMING_STARTED.equals(action)) {
             mLastUserActivityElapsedTimeMillis = SystemClock.elapsedRealtime();
@@ -285,7 +311,12 @@
             // this timeout elapses since the device may go to sleep by then.
             scheduleUpdateIdleMaintenanceState(MIN_USER_INACTIVITY_IDLE_MAINTENANCE_START);
         } else if (ACTION_UPDATE_IDLE_MAINTENANCE_STATE.equals(action)) {
-            updateIdleMaintenanceState();
+            updateIdleMaintenanceState(false);
+        } else if (ACTION_FORCE_IDLE_MAINTENANCE.equals(action)) {
+            long now = SystemClock.elapsedRealtime() - 1;
+            mLastUserActivityElapsedTimeMillis = now - MIN_USER_INACTIVITY_IDLE_MAINTENANCE_START;
+            mLastIdleMaintenanceStartTimeMillis = now - MIN_IDLE_MAINTENANCE_INTERVAL_MILLIS;
+            updateIdleMaintenanceState(true);
         } else if (Intent.ACTION_IDLE_MAINTENANCE_START.equals(action)
                 || Intent.ACTION_IDLE_MAINTENANCE_END.equals(action)) {
             // We were holding a wake lock while broadcasting the idle maintenance
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index d38756f..ef50df7 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -217,8 +217,7 @@
             ServiceManager.addService("telephony.registry", telephonyRegistry);
 
             Slog.i(TAG, "Scheduling Policy");
-            ServiceManager.addService(Context.SCHEDULING_POLICY_SERVICE,
-                    new SchedulingPolicyService());
+            ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());
 
             AttributeCache.init(context);
 
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index b75eab4..37fbb13 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -299,11 +299,17 @@
         boolean addToStarting = false;
         if (!callerFg && r.app == null && mAm.mStartedUsers.get(r.userId) != null) {
             ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid);
-            if (proc == null || proc.curProcState >= ActivityManager.PROCESS_STATE_RECEIVER) {
+            if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
                 // If this is not coming from a foreground caller, then we may want
                 // to delay the start if there are already other background services
                 // that are starting.  This is to avoid process start spam when lots
                 // of applications are all handling things like connectivity broadcasts.
+                // We only do this for cached processes, because otherwise an application
+                // can have assumptions about calling startService() for a service to run
+                // in its own process, and for that process to not be killed before the
+                // service is started.  This is especially the case for receivers, which
+                // may start a service in onReceive() to do some additional work and have
+                // initialized some global state as part of that.
                 if (DEBUG_DELAYED_SERVICE) Slog.v(TAG, "Potential start delay of " + r + " in "
                         + proc);
                 if (r.delayed) {
@@ -324,7 +330,7 @@
             } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
                 // We slightly loosen when we will enqueue this new service as a background
                 // starting service we are waiting for, to also include processes that are
-                // currently running other services.
+                // currently running other services or receivers.
                 addToStarting = true;
                 if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Not delaying, but counting as bg: " + r);
             } else if (DEBUG_DELAYED_STATS) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index e208f10..2bac96e 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -172,7 +172,6 @@
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.File;
@@ -850,10 +849,39 @@
     int mNewNumServiceProcs = 0;
 
     /**
-     * System monitoring: number of processes that died since the last
-     * N procs were started.
+     * Allow the current computed overall memory level of the system to go down?
+     * This is set to false when we are killing processes for reasons other than
+     * memory management, so that the now smaller process list will not be taken as
+     * an indication that memory is tighter.
      */
-    int[] mProcDeaths = new int[20];
+    boolean mAllowLowerMemLevel = false;
+
+    /**
+     * The last computed memory level, for holding when we are in a state that
+     * processes are going away for other reasons.
+     */
+    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
+
+    /**
+     * The last total number of process we have, to determine if changes actually look
+     * like a shrinking number of process due to lower RAM.
+     */
+    int mLastNumProcesses;
+
+    /**
+     * The uptime of the last time we performed idle maintenance.
+     */
+    long mLastIdleTime = SystemClock.uptimeMillis();
+
+    /**
+     * Total time spent with RAM that has been added in the past since the last idle time.
+     */
+    long mLowRamTimeSinceLastIdle = 0;
+
+    /**
+     * If RAM is currently low, when that horrible situatin started.
+     */
+    long mLowRamStartTime = 0;
 
     /**
      * This is set if we had to do a delayed dexopt of an app before launching
@@ -978,17 +1006,18 @@
     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
-    static final int CLEAR_DNS_CACHE = 28;
-    static final int UPDATE_HTTP_PROXY = 29;
+    static final int CLEAR_DNS_CACHE_MSG = 28;
+    static final int UPDATE_HTTP_PROXY_MSG = 29;
     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
     static final int DISPATCH_PROCESSES_CHANGED = 31;
     static final int DISPATCH_PROCESS_DIED = 32;
-    static final int REPORT_MEM_USAGE = 33;
+    static final int REPORT_MEM_USAGE_MSG = 33;
     static final int REPORT_USER_SWITCH_MSG = 34;
     static final int CONTINUE_USER_SWITCH_MSG = 35;
     static final int USER_SWITCH_TIMEOUT_MSG = 36;
     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
-    static final int PERSIST_URI_GRANTS = 38;
+    static final int PERSIST_URI_GRANTS_MSG = 38;
+    static final int REQUEST_ALL_PSS_MSG = 39;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1169,7 +1198,7 @@
                     }
                 }
             } break;
-            case CLEAR_DNS_CACHE: {
+            case CLEAR_DNS_CACHE_MSG: {
                 synchronized (ActivityManagerService.this) {
                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
                         ProcessRecord r = mLruProcesses.get(i);
@@ -1183,7 +1212,7 @@
                     }
                 }
             } break;
-            case UPDATE_HTTP_PROXY: {
+            case UPDATE_HTTP_PROXY_MSG: {
                 ProxyProperties proxy = (ProxyProperties)msg.obj;
                 String host = "";
                 String port = "";
@@ -1369,7 +1398,7 @@
                 dispatchProcessDied(pid, uid);
                 break;
             }
-            case REPORT_MEM_USAGE: {
+            case REPORT_MEM_USAGE_MSG: {
                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
                 Thread thread = new Thread() {
                     @Override public void run() {
@@ -1583,10 +1612,14 @@
                 }
                 break;
             }
-            case PERSIST_URI_GRANTS: {
+            case PERSIST_URI_GRANTS_MSG: {
                 writeGrantedUriPermissions();
                 break;
             }
+            case REQUEST_ALL_PSS_MSG: {
+                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
+                break;
+            }
             }
         }
     };
@@ -1630,6 +1663,10 @@
                                 num++;
                                 proc.lastPssTime = SystemClock.uptimeMillis();
                                 proc.baseProcessTracker.addPss(pss, tmp[0], true);
+                                if (proc.initialIdlePss == 0) {
+                                    proc.initialIdlePss = pss;
+                                }
+                                proc.lastPss = pss;
                             }
                         }
                     }
@@ -2250,8 +2287,7 @@
         }
     }
 
-    final void updateLruProcessLocked(ProcessRecord app,
-            boolean oomAdj) {
+    final void updateLruProcessLocked(ProcessRecord app, boolean oomAdj) {
         mLruSeq++;
         updateLruProcessInternalLocked(app, 0);
 
@@ -2417,9 +2453,6 @@
 
         updateCpuStats();
 
-        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
-        mProcDeaths[0] = 0;
-
         try {
             int uid = app.uid;
 
@@ -3428,7 +3461,7 @@
                 }
             }
             if (doReport) {
-                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE, memInfos);
+                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
                 mHandler.sendMessage(msg);
             }
             scheduleAppGcsLocked();
@@ -3438,8 +3471,6 @@
     final void appDiedLocked(ProcessRecord app, int pid,
             IApplicationThread thread) {
 
-        mProcDeaths[0]++;
-
         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
         synchronized (stats) {
             stats.noteProcessDiedLocked(app.info.uid, pid);
@@ -3448,17 +3479,27 @@
         // Clean up already done if the process has been re-started.
         if (app.pid == pid && app.thread != null &&
                 app.thread.asBinder() == thread.asBinder()) {
-            if (!app.killedBackground) {
+            boolean doLowMem = app.instrumentationClass == null;
+            boolean doOomAdj = doLowMem;
+            if (!app.killedByAm) {
                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
                         + ") has died.");
+                mAllowLowerMemLevel = true;
+            } else {
+                // Note that we always want to do oom adj to update our state with the
+                // new number of procs.
+                mAllowLowerMemLevel = false;
+                doLowMem = false;
             }
             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
             if (DEBUG_CLEANUP) Slog.v(
                 TAG, "Dying app: " + app + ", pid: " + pid
                 + ", thread: " + thread.asBinder());
-            boolean doLowMem = app.instrumentationClass == null;
             handleAppDiedLocked(app, false, true);
 
+            if (doOomAdj) {
+                updateOomAdjLocked();
+            }
             if (doLowMem) {
                 doLowMemReportIfNeededLocked(app);
             }
@@ -3791,10 +3832,7 @@
 
         synchronized (this) {
             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
-                Slog.w(TAG, "Killing " + app + ": background ANR");
-                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
-                        app.processName, app.setAdj, "background ANR");
-                Process.killProcessQuiet(app.pid);
+                killUnneededProcessLocked(app, "background ANR");
                 return;
             }
 
@@ -3979,6 +4017,7 @@
                 for (int i=0; i<N; i++) {
                     removeProcessLocked(procs.get(i), false, true, "kill all background");
                 }
+                mAllowLowerMemLevel = true;
                 updateOomAdjLocked();
                 doLowMemReportIfNeededLocked(null);
             }
@@ -4478,10 +4517,9 @@
                 mPidsSelfLocked.remove(pid);
                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
             }
-            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
+            killUnneededProcessLocked(app, reason);
             handleAppDiedLocked(app, true, allowRestart);
             mLruProcesses.remove(app);
-            Process.killProcessQuiet(pid);
 
             if (app.persistent && !app.isolated) {
                 if (!callerWillRestart) {
@@ -4523,9 +4561,7 @@
             checkAppInLaunchingProvidersLocked(app, true);
             // Take care of any services that are waiting for the process.
             mServices.processStartTimedOutLocked(app);
-            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid,
-                    app.processName, app.setAdj, "start timeout");
-            Process.killProcessQuiet(pid);
+            killUnneededProcessLocked(app, "start timeout");
             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
                 Slog.w(TAG, "Unattached app died before backup, skipping");
                 try {
@@ -5769,8 +5805,8 @@
                 pi.packageName, targetPkg, targetUid, uri);
         final boolean persistChanged = perm.grantModes(modeFlags, persist, owner);
         if (persistChanged) {
-            mHandler.removeMessages(PERSIST_URI_GRANTS);
-            mHandler.obtainMessage(PERSIST_URI_GRANTS).sendToTarget();
+            mHandler.removeMessages(PERSIST_URI_GRANTS_MSG);
+            mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG).sendToTarget();
         }
     }
 
@@ -5994,8 +6030,8 @@
         }
 
         if (persistChanged) {
-            mHandler.removeMessages(PERSIST_URI_GRANTS);
-            mHandler.obtainMessage(PERSIST_URI_GRANTS).sendToTarget();
+            mHandler.removeMessages(PERSIST_URI_GRANTS_MSG);
+            mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG).sendToTarget();
         }
     }
 
@@ -6079,8 +6115,8 @@
         }
 
         if (persistChanged) {
-            mHandler.removeMessages(PERSIST_URI_GRANTS);
-            mHandler.obtainMessage(PERSIST_URI_GRANTS).sendToTarget();
+            mHandler.removeMessages(PERSIST_URI_GRANTS_MSG);
+            mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG).sendToTarget();
         }
     }
 
@@ -6508,6 +6544,16 @@
         }
     }
 
+    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
+        if (!pr.killedByAm) {
+            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
+            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
+                    pr.processName, pr.setAdj, reason);
+            pr.killedByAm = true;
+            Process.killProcessQuiet(pr.pid);
+        }
+    }
+
     private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
         mRecentTasks.remove(tr);
         mStackSupervisor.removeTask(tr);
@@ -6546,11 +6592,7 @@
             for (int i=0; i<procs.size(); i++) {
                 ProcessRecord pr = procs.get(i);
                 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
-                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
-                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
-                            pr.processName, pr.setAdj, "remove task");
-                    pr.killedBackground = true;
-                    Process.killProcessQuiet(pr.pid);
+                    killUnneededProcessLocked(pr, "remove task");
                 } else {
                     pr.waitingToKill = "remove task";
                 }
@@ -8401,13 +8443,9 @@
                     continue;
                 }
                 int adj = proc.setAdj;
-                if (adj >= worstType && !proc.killedBackground) {
-                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
-                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid,
-                            proc.processName, adj, reason);
+                if (adj >= worstType && !proc.killedByAm) {
+                    killUnneededProcessLocked(proc, reason);
                     killed = true;
-                    proc.killedBackground = true;
-                    Process.killProcessQuiet(pids[i]);
                 }
             }
         }
@@ -8449,13 +8487,9 @@
                 if (proc == null) continue;
 
                 final int adj = proc.setAdj;
-                if (adj > belowAdj && !proc.killedBackground) {
-                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
-                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId,
-                            proc.pid, proc.processName, adj, reason);
+                if (adj > belowAdj && !proc.killedByAm) {
+                    killUnneededProcessLocked(proc, reason);
                     killed = true;
-                    proc.killedBackground = true;
-                    Process.killProcessQuiet(pid);
                 }
             }
         }
@@ -8533,6 +8567,61 @@
         br.onReceive(mContext, intent);
     }
 
+    private long getLowRamTimeSinceIdle(long now) {
+        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
+    }
+
+    @Override
+    public void performIdleMaintenance() {
+        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Requires permission "
+                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
+        }
+
+        synchronized (this) {
+            final long now = SystemClock.uptimeMillis();
+            final long timeSinceLastIdle = now - mLastIdleTime;
+            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
+            mLastIdleTime = now;
+            mLowRamTimeSinceLastIdle = 0;
+            if (mLowRamStartTime != 0) {
+                mLowRamStartTime = now;
+            }
+
+            StringBuilder sb = new StringBuilder(128);
+            sb.append("Idle maintenance over ");
+            TimeUtils.formatDuration(timeSinceLastIdle, sb);
+            sb.append(" low RAM for ");
+            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
+            Slog.i(TAG, sb.toString());
+
+            // If at least 1/3 of our time since the last idle period has been spent
+            // with RAM low, then we want to kill processes.
+            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
+
+            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
+                ProcessRecord proc = mLruProcesses.get(i);
+                if (proc.notCachedSinceIdle) {
+                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
+                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
+                        if (doKilling && proc.initialIdlePss != 0
+                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
+                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
+                                    + " from " + proc.initialIdlePss + ")");
+                        }
+                    }
+                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
+                    proc.notCachedSinceIdle = true;
+                    proc.initialIdlePss = 0;
+                }
+            }
+
+            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
+            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
+        }
+    }
+
     public final void startRunning(String pkg, String cls, String action,
             String data) {
         synchronized(this) {
@@ -8967,10 +9056,7 @@
             }
             if (app.pid > 0 && app.pid != MY_PID) {
                 handleAppCrashLocked(app);
-                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
-                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
-                        app.processName, app.setAdj, "user's request after error");
-                Process.killProcessQuiet(app.pid);
+                killUnneededProcessLocked(app, "user request after error");
             }
         }
     }
@@ -10444,6 +10530,15 @@
                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
                         + " mNumServiceProcs=" + mNumServiceProcs
                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
+                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
+                        + " mLastMemoryLevel" + mLastMemoryLevel
+                        + " mLastNumProcesses" + mLastNumProcesses);
+                long now = SystemClock.uptimeMillis();
+                pw.print("  mLastIdleTime=");
+                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
+                        pw.print(" mLowRamSinceLastIdle=");
+                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
+                        pw.println();
             }
         }
 
@@ -11704,13 +11799,9 @@
                 if (!capp.persistent && capp.thread != null
                         && capp.pid != 0
                         && capp.pid != MY_PID) {
-                    Slog.i(TAG, "Kill " + capp.processName
-                            + " (pid " + capp.pid + "): provider " + cpr.info.name
-                            + " in dying process " + (proc != null ? proc.processName : "??"));
-                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid,
-                            capp.processName, capp.setAdj, "dying provider "
-                                    + cpr.name.toShortString());
-                    Process.killProcessQuiet(capp.pid);
+                    killUnneededProcessLocked(capp, "depends on provider "
+                            + cpr.name.flattenToShortString()
+                            + " in dying proc " + (proc != null ? proc.processName : "??"));
                 }
             } else if (capp.thread != null && conn.provider.provider != null) {
                 try {
@@ -12791,12 +12882,12 @@
         }
 
         if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
-            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
+            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
         }
 
         if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
             ProxyProperties proxy = intent.getParcelableExtra("proxy");
-            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
+            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
         }
 
         // Add to the sticky list if requested.
@@ -14527,26 +14618,18 @@
                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
                                 realtimeSince, wtimeUsed);
                     }
-                    Slog.w(TAG, "Excessive wake lock in " + app.processName
-                            + " (pid " + app.pid + "): held " + wtimeUsed
+                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
                             + " during " + realtimeSince);
-                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
-                            app.processName, app.setAdj, "excessive wake lock");
                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
-                    Process.killProcessQuiet(app.pid);
                 } else if (doCpuKills && uptimeSince > 0
                         && ((cputimeUsed*100)/uptimeSince) >= 50) {
                     synchronized (stats) {
                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
                                 uptimeSince, cputimeUsed);
                     }
-                    Slog.w(TAG, "Excessive CPU in " + app.processName
-                            + " (pid " + app.pid + "): used " + cputimeUsed
+                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
                             + " during " + uptimeSince);
-                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
-                            app.processName, app.setAdj, "excessive cpu");
                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
-                    Process.killProcessQuiet(app.pid);
                 } else {
                     app.lastWakeTime = wtime;
                     app.lastCpuTime = app.curCpuTime;
@@ -14593,11 +14676,7 @@
                     + " to " + app.curSchedGroup);
             if (app.waitingToKill != null &&
                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
-                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
-                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
-                        app.processName, app.setAdj, app.waitingToKill);
-                app.killedBackground = true;
-                Process.killProcessQuiet(app.pid);
+                killUnneededProcessLocked(app, app.waitingToKill);
                 success = false;
             } else {
                 if (true) {
@@ -14657,6 +14736,9 @@
                     "Proc state change of " + app.processName
                     + " to " + app.curProcState);
             app.setProcState = app.curProcState;
+            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
+                app.notCachedSinceIdle = false;
+            }
             if (!doingAll) {
                 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
             } else {
@@ -14783,7 +14865,7 @@
         int nextEmptyAdj = curEmptyAdj+2;
         for (int i=N-1; i>=0; i--) {
             ProcessRecord app = mLruProcesses.get(i);
-            if (!app.killedBackground && app.thread != null) {
+            if (!app.killedByAm && app.thread != null) {
                 app.procStateChanged = false;
                 final boolean wasKeeping = app.keeping;
                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
@@ -14858,34 +14940,19 @@
                         mNumCachedHiddenProcs++;
                         numCached++;
                         if (numCached > cachedProcessLimit) {
-                            Slog.i(TAG, "No longer want " + app.processName
-                                    + " (pid " + app.pid + "): cached #" + numCached);
-                            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
-                                    app.processName, app.setAdj, "too many background");
-                            app.killedBackground = true;
-                            Process.killProcessQuiet(app.pid);
+                            killUnneededProcessLocked(app, "cached #" + numCached);
                         }
                         break;
                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
                                 && app.lastActivityTime < oldTime) {
-                            Slog.i(TAG, "No longer want " + app.processName
-                                    + " (pid " + app.pid + "): empty for "
-                                    + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime)
-                                            / 1000) + "s");
-                            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
-                                    app.processName, app.setAdj, "old background process");
-                            app.killedBackground = true;
-                            Process.killProcessQuiet(app.pid);
+                            killUnneededProcessLocked(app, "empty for "
+                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
+                                    / 1000) + "s");
                         } else {
                             numEmpty++;
                             if (numEmpty > emptyProcessLimit) {
-                                Slog.i(TAG, "No longer want " + app.processName
-                                        + " (pid " + app.pid + "): empty #" + numEmpty);
-                                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
-                                        app.processName, app.setAdj, "too many background");
-                                app.killedBackground = true;
-                                Process.killProcessQuiet(app.pid);
+                                killUnneededProcessLocked(app, "empty #" + numEmpty);
                             }
                         }
                         break;
@@ -14901,16 +14968,11 @@
                     // definition not re-use the same process again, and it is
                     // good to avoid having whatever code was running in them
                     // left sitting around after no longer needed.
-                    Slog.i(TAG, "Isolated process " + app.processName
-                            + " (pid " + app.pid + ") no longer needed");
-                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
-                            app.processName, app.setAdj, "isolated not needed");
-                    app.killedBackground = true;
-                    Process.killProcessQuiet(app.pid);
+                    killUnneededProcessLocked(app, "isolated not needed");
                 }
 
                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
-                        && !app.killedBackground) {
+                        && !app.killedByAm) {
                     numTrimming++;
                 }
             }
@@ -14924,31 +14986,60 @@
         // are managing to keep around is less than half the maximum we desire;
         // if we are keeping a good number around, we'll let them use whatever
         // memory they want.
-        boolean allChanged;
+        final int numCachedAndEmpty = numCached + numEmpty;
+        int memFactor;
         if (numCached <= ProcessList.TRIM_CACHED_APPS
                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
-            final int numCachedAndEmpty = numCached + numEmpty;
+            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
+                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
+            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
+                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
+            } else {
+                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
+            }
+        } else {
+            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
+        }
+        // We always allow the memory level to go up (better).  We only allow it to go
+        // down if we are in a state where that is allowed, *and* the total number of processes
+        // has gone down since last time.
+        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
+                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
+                + " last=" + mLastNumProcesses);
+        if (memFactor > mLastMemoryLevel) {
+            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
+                memFactor = mLastMemoryLevel;
+                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
+            }
+        }
+        mLastMemoryLevel = memFactor;
+        mLastNumProcesses = mLruProcesses.size();
+        boolean allChanged = mProcessStats.setMemFactorLocked(
+                ProcessStats.ADJ_MEM_FACTOR_NORMAL, !mSleeping, now);
+        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
+        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
+            if (mLowRamStartTime == 0) {
+                mLowRamStartTime = now;
+            }
+            int step = 0;
+            int fgTrimLevel;
+            switch (memFactor) {
+                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
+                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
+                    break;
+                case ProcessStats.ADJ_MEM_FACTOR_LOW:
+                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
+                    break;
+                default:
+                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
+                    break;
+            }
             int factor = numTrimming/3;
             int minFactor = 2;
             if (mHomeProcess != null) minFactor++;
             if (mPreviousProcess != null) minFactor++;
             if (factor < minFactor) factor = minFactor;
-            int step = 0;
-            int fgTrimLevel;
-            int memFactor;
-            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
-                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
-                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
-            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
-                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
-                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
-            } else {
-                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
-                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
-            }
             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
-            allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
-            final int trackerMemFactor = mProcessStats.getMemFactorLocked();
             for (int i=N-1; i>=0; i--) {
                 ProcessRecord app = mLruProcesses.get(i);
                 if (allChanged || app.procStateChanged) {
@@ -14956,7 +15047,7 @@
                     app.procStateChanged = false;
                 }
                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
-                        && !app.killedBackground) {
+                        && !app.killedByAm) {
                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
                         try {
                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
@@ -15036,9 +15127,10 @@
                 }
             }
         } else {
-            allChanged = mProcessStats.setMemFactorLocked(
-                    ProcessStats.ADJ_MEM_FACTOR_NORMAL, !mSleeping, now);
-            final int trackerMemFactor = mProcessStats.getMemFactorLocked();
+            if (mLowRamStartTime != 0) {
+                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
+                mLowRamStartTime = 0;
+            }
             for (int i=N-1; i>=0; i--) {
                 ProcessRecord app = mLruProcesses.get(i);
                 if (allChanged || app.procStateChanged) {
@@ -15107,6 +15199,7 @@
                     if (app.pid > 0 && app.pid != MY_PID) {
                         EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
                                 app.processName, app.setAdj, "empty");
+                        app.killedByAm = true;
                         Process.killProcessQuiet(app.pid);
                     } else {
                         try {
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index e0eb2c4..f5d45b3 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1417,7 +1417,8 @@
                     final ActivityStack lastStack = getLastStack();
                     ActivityRecord curTop = lastStack == null?
                             null : lastStack.topRunningNonDelayedActivityLocked(notTop);
-                    if (curTop != null && curTop.task != intentActivity.task) {
+                    if (curTop != null && (curTop.task != intentActivity.task) ||
+                            curTop.task != lastStack.topTask()) {
                         r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
                         if (sourceRecord == null || (sourceStack.topActivity() != null &&
                                 sourceStack.topActivity().task == sourceRecord.task)) {
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 35e06b6..4fdacb3 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -66,6 +66,8 @@
     long lastPssTime;           // Last time we retrieved PSS data
     long nextPssTime;           // Next time we want to request PSS data
     long lastStateTime;         // Last time setProcState changed
+    long initialIdlePss;        // Initial memory pss of process for idle maintenance.
+    long lastPss;               // Last computed memory pss.
     int maxAdj;                 // Maximum OOM adjustment for this process
     int curRawAdj;              // Current OOM unlimited adjustment for this process
     int setRawAdj;              // Last set OOM unlimited adjustment for this process
@@ -82,6 +84,7 @@
     boolean serviceb;           // Process currently is on the service B list
     boolean keeping;            // Actively running code so don't kill due to that?
     boolean setIsForeground;    // Running foreground UI when last set?
+    boolean notCachedSinceIdle; // Has this process not been in a cached state since last idle?
     boolean hasActivities;      // Are there any activities running in this process?
     boolean hasClientActivities;  // Are there any client services with activities?
     boolean hasStartedServices; // Are there any started services running in this process?
@@ -92,7 +95,7 @@
     boolean pendingUiClean;     // Want to clean up resources from showing UI?
     boolean hasAboveClient;     // Bound using BIND_ABOVE_CLIENT, so want to be lower
     boolean bad;                // True if disabled in the bad process list
-    boolean killedBackground;   // True when proc has been killed due to too many bg
+    boolean killedByAm;         // True when proc has been killed by activity manager, not for RAM
     boolean procStateChanged;   // Keep track of whether we changed 'setAdj'.
     String waitingToKill;       // Process is waiting to be killed when in the bg; reason
     IBinder forcingToForeground;// Token that is forcing this process to be foreground
@@ -216,6 +219,11 @@
                 pw.print(" keeping="); pw.print(keeping);
                 pw.print(" cached="); pw.print(cached);
                 pw.print(" empty="); pw.println(empty);
+        if (notCachedSinceIdle) {
+            pw.print(prefix); pw.print("notCachedSinceIdle="); pw.print(notCachedSinceIdle);
+                    pw.print(" initialIdlePss="); pw.print(initialIdlePss);
+                    pw.print(" lastPss="); pw.println(lastPss);
+        }
         pw.print(prefix); pw.print("oom: max="); pw.print(maxAdj);
                 pw.print(" curRaw="); pw.print(curRawAdj);
                 pw.print(" setRaw="); pw.print(setRawAdj);
@@ -280,8 +288,8 @@
                 pw.print(" lastLowMemory=");
                 TimeUtils.formatDuration(lastLowMemory, now, pw);
                 pw.print(" reportLowMemory="); pw.println(reportLowMemory);
-        if (killedBackground || waitingToKill != null) {
-            pw.print(prefix); pw.print("killedBackground="); pw.print(killedBackground);
+        if (killedByAm || waitingToKill != null) {
+            pw.print(prefix); pw.print("killedByAm="); pw.print(killedByAm);
                     pw.print(" waitingToKill="); pw.println(waitingToKill);
         }
         if (debugging || crashing || crashDialog != null || notResponding
diff --git a/services/java/com/android/server/am/ProcessStatsService.java b/services/java/com/android/server/am/ProcessStatsService.java
index c180f6e..582e11e 100644
--- a/services/java/com/android/server/am/ProcessStatsService.java
+++ b/services/java/com/android/server/am/ProcessStatsService.java
@@ -445,7 +445,7 @@
     static private void dumpHelp(PrintWriter pw) {
         pw.println("Process stats (procstats) dump options:");
         pw.println("    [--checkin|-c|--csv] [--csv-screen] [--csv-proc] [--csv-mem]");
-        pw.println("    [--details] [--current] [--commit] [--write] [-h] [<package.name>]");
+        pw.println("    [--details] [--current] [--commit] [--reset] [--write] [-h] [<package.name>]");
         pw.println("  --checkin: perform a checkin: print and delete old committed states.");
         pw.println("  --c: print only state in checkin format.");
         pw.println("  --csv: output data suitable for putting in a spreadsheet.");
@@ -456,6 +456,7 @@
         pw.println("  --details: dump all execution details, not just summary.");
         pw.println("  --current: only dump current state.");
         pw.println("  --commit: commit current stats to disk and reset to start new stats.");
+        pw.println("  --reset: reset current stats, without committing.");
         pw.println("  --write: write current in-memory stats to disk.");
         pw.println("  --read: replace current stats with last-written stats.");
         pw.println("  -a: print everything.");
@@ -551,17 +552,29 @@
                 } else if ("--current".equals(arg)) {
                     currentOnly = true;
                 } else if ("--commit".equals(arg)) {
-                    mProcessStats.mFlags |= ProcessStats.FLAG_COMPLETE;
-                    writeStateLocked(true, true);
-                    pw.println("Process stats committed.");
+                    synchronized (mAm) {
+                        mProcessStats.mFlags |= ProcessStats.FLAG_COMPLETE;
+                        writeStateLocked(true, true);
+                        pw.println("Process stats committed.");
+                    }
+                    return;
+                } else if ("--reset".equals(arg)) {
+                    synchronized (mAm) {
+                        mProcessStats.resetSafely();
+                        pw.println("Process stats reset.");
+                    }
                     return;
                 } else if ("--write".equals(arg)) {
-                    writeStateSyncLocked();
-                    pw.println("Process stats written.");
+                    synchronized (mAm) {
+                        writeStateSyncLocked();
+                        pw.println("Process stats written.");
+                    }
                     return;
                 } else if ("--read".equals(arg)) {
-                    readLocked(mProcessStats, mFile);
-                    pw.println("Process stats read.");
+                    synchronized (mAm) {
+                        readLocked(mProcessStats, mFile);
+                        pw.println("Process stats read.");
+                    }
                     return;
                 } else if ("-h".equals(arg)) {
                     dumpHelp(pw);
diff --git a/services/java/com/android/server/print/PrintManagerService.java b/services/java/com/android/server/print/PrintManagerService.java
index c33bfb7..ddc5046 100644
--- a/services/java/com/android/server/print/PrintManagerService.java
+++ b/services/java/com/android/server/print/PrintManagerService.java
@@ -33,6 +33,7 @@
 import android.print.IPrintManager;
 import android.print.IPrinterDiscoveryObserver;
 import android.print.PrintAttributes;
+import android.print.PrintJobId;
 import android.print.PrintJobInfo;
 import android.print.PrinterId;
 import android.printservice.PrintServiceInfo;
@@ -70,30 +71,32 @@
         BackgroundThread.getHandler().post(new Runnable() {
             @Override
             public void run() {
+                final UserState userState;
                 synchronized (mLock) {
-                    UserState userState = getCurrentUserStateLocked();
+                    userState = getCurrentUserStateLocked();
                     userState.updateIfNeededLocked();
-                    userState.getSpoolerLocked().start();
                 }
+                // This is the first time we switch to this user after boot, so
+                // now is the time to remove obsolete print jobs since they
+                // are from the last boot and no application would query them.
+                userState.removeObsoletePrintJobs();
             }
         });
     }
 
     @Override
-    public PrintJobInfo print(String printJobName, IPrintClient client,
-            IPrintDocumentAdapter documentAdapter, PrintAttributes attributes, int appId,
-            int userId) {
+    public PrintJobInfo print(String printJobName, final IPrintClient client,
+            final IPrintDocumentAdapter documentAdapter, PrintAttributes attributes,
+            int appId, int userId) {
         final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
         final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
         final UserState userState;
-        final RemotePrintSpooler spooler;
         synchronized (mLock) {
             userState = getOrCreateUserStateLocked(resolvedUserId);
-            spooler = userState.getSpoolerLocked();
         }
         final long identity = Binder.clearCallingIdentity();
         try {
-            return spooler.createPrintJob(printJobName, client, documentAdapter,
+            return userState.print(printJobName, client, documentAdapter,
                     attributes, resolvedAppId);
         } finally {
             Binder.restoreCallingIdentity(identity);
@@ -105,95 +108,65 @@
         final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
         final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
         final UserState userState;
-        final RemotePrintSpooler spooler;
         synchronized (mLock) {
             userState = getOrCreateUserStateLocked(resolvedUserId);
-            spooler = userState.getSpoolerLocked();
         }
         final long identity = Binder.clearCallingIdentity();
         try {
-            return spooler.getPrintJobInfos(null, PrintJobInfo.STATE_ANY,
-                    resolvedAppId);
+            return userState.getPrintJobInfos(resolvedAppId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
     @Override
-    public PrintJobInfo getPrintJobInfo(int printJobId, int appId, int userId) {
+    public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId, int userId) {
         final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
         final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
         final UserState userState;
-        final RemotePrintSpooler spooler;
         synchronized (mLock) {
             userState = getOrCreateUserStateLocked(resolvedUserId);
-            spooler = userState.getSpoolerLocked();
         }
         final long identity = Binder.clearCallingIdentity();
         try {
-            return spooler.getPrintJobInfo(printJobId, resolvedAppId);
+            return userState.getPrintJobInfo(printJobId, resolvedAppId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
     @Override
-    public void cancelPrintJob(int printJobId, int appId, int userId) {
+    public void cancelPrintJob(PrintJobId printJobId, int appId, int userId) {
         final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
         final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
         final UserState userState;
-        final RemotePrintSpooler spooler;
         synchronized (mLock) {
             userState = getOrCreateUserStateLocked(resolvedUserId);
-            spooler = userState.getSpoolerLocked();
         }
         final long identity = Binder.clearCallingIdentity();
         try {
-            PrintJobInfo printJobInfo = spooler.getPrintJobInfo(printJobId, resolvedAppId);
-            if (printJobInfo == null) {
-                return;
-            }
-            if (printJobInfo.getState() != PrintJobInfo.STATE_FAILED) {
-                ComponentName printServiceName = printJobInfo.getPrinterId().getServiceName();
-                RemotePrintService printService = null;
-                synchronized (mLock) {
-                    printService = userState.getActiveServicesLocked().get(printServiceName);
-                }
-                if (printService == null) {
-                    return;
-                }
-                printService.onRequestCancelPrintJob(printJobInfo);
-            } else {
-                // If the print job is failed we do not need cooperation
-                // from the print service.
-                spooler.setPrintJobState(printJobId, PrintJobInfo.STATE_CANCELED, null);
-            }
+            userState.cancelPrintJob(printJobId, resolvedAppId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
     @Override
-    public void restartPrintJob(int printJobId, int appId, int userId) {
+    public void restartPrintJob(PrintJobId printJobId, int appId, int userId) {
         final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
         final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
-        final RemotePrintSpooler spooler;
+        final UserState userState;
         synchronized (mLock) {
-            spooler = getOrCreateUserStateLocked(resolvedUserId).getSpoolerLocked();
+            userState = getOrCreateUserStateLocked(resolvedUserId);
         }
         final long identity = Binder.clearCallingIdentity();
         try {
-            PrintJobInfo printJobInfo = getPrintJobInfo(printJobId, resolvedAppId, resolvedUserId);
-            if (printJobInfo == null || printJobInfo.getState() != PrintJobInfo.STATE_FAILED) {
-                return;
-            }
-            spooler.setPrintJobState(printJobId, PrintJobInfo.STATE_QUEUED, null);
+            userState.restartPrintJob(printJobId, resolvedAppId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
-
     @Override
     public List<PrintServiceInfo> getEnabledPrintServices(int userId) {
         final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
@@ -443,6 +416,7 @@
         // user changes
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
+        intentFilter.addAction(Intent.ACTION_USER_REMOVED);
 
         mContext.registerReceiverAsUser(new BroadcastReceiver() {
             @Override
@@ -471,15 +445,24 @@
     }
 
     private void switchUser(int newUserId) {
+        UserState userState;
         synchronized (mLock) {
             if (newUserId == mCurrentUserId) {
                 return;
             }
             mCurrentUserId = newUserId;
-            UserState userState = getCurrentUserStateLocked();
-            userState.updateIfNeededLocked();
-            userState.getSpoolerLocked().start();
+            userState = mUserStates.get(mCurrentUserId);
+            if (userState == null) {
+                userState = getCurrentUserStateLocked();
+                userState.updateIfNeededLocked();
+            } else {
+                userState.updateIfNeededLocked();
+            }
         }
+        // This is the first time we switch to this user after boot, so
+        // now is the time to remove obsolete print jobs since they
+        // are from the last boot and no application would query them.
+        userState.removeObsoletePrintJobs();
     }
 
     private void removeUser(int removedUserId) {
diff --git a/services/java/com/android/server/print/RemotePrintService.java b/services/java/com/android/server/print/RemotePrintService.java
index 8869cbe..a20973e 100644
--- a/services/java/com/android/server/print/RemotePrintService.java
+++ b/services/java/com/android/server/print/RemotePrintService.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.content.pm.ParceledListSlice;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
@@ -29,6 +30,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.print.PrintJobId;
 import android.print.PrintJobInfo;
 import android.print.PrintManager;
 import android.print.PrinterId;
@@ -690,7 +692,7 @@
         }
 
         @Override
-        public PrintJobInfo getPrintJobInfo(int printJobId) {
+        public PrintJobInfo getPrintJobInfo(PrintJobId printJobId) {
             RemotePrintService service = mWeakService.get();
             if (service != null) {
                 final long identity = Binder.clearCallingIdentity();
@@ -705,7 +707,7 @@
         }
 
         @Override
-        public boolean setPrintJobState(int printJobId, int state, String error) {
+        public boolean setPrintJobState(PrintJobId printJobId, int state, String error) {
             RemotePrintService service = mWeakService.get();
             if (service != null) {
                 final long identity = Binder.clearCallingIdentity();
@@ -719,7 +721,7 @@
         }
 
         @Override
-        public boolean setPrintJobTag(int printJobId, String tag) {
+        public boolean setPrintJobTag(PrintJobId printJobId, String tag) {
             RemotePrintService service = mWeakService.get();
             if (service != null) {
                 final long identity = Binder.clearCallingIdentity();
@@ -733,7 +735,7 @@
         }
 
         @Override
-        public void writePrintJobData(ParcelFileDescriptor fd, int printJobId) {
+        public void writePrintJobData(ParcelFileDescriptor fd, PrintJobId printJobId) {
             RemotePrintService service = mWeakService.get();
             if (service != null) {
                 final long identity = Binder.clearCallingIdentity();
@@ -746,13 +748,15 @@
         }
 
         @Override
-        public void onPrintersAdded(List<PrinterInfo> printers) {
+        @SuppressWarnings({"rawtypes", "unchecked"})
+        public void onPrintersAdded(ParceledListSlice printers) {
             RemotePrintService service = mWeakService.get();
             if (service != null) {
-                throwIfPrinterIdsForPrinterInfoTampered(service.mComponentName, printers);
+                List<PrinterInfo> addedPrinters = (List<PrinterInfo>) printers.getList();
+                throwIfPrinterIdsForPrinterInfoTampered(service.mComponentName, addedPrinters);
                 final long identity = Binder.clearCallingIdentity();
                 try {
-                    service.mCallbacks.onPrintersAdded(printers);
+                    service.mCallbacks.onPrintersAdded(addedPrinters);
                 } finally {
                     Binder.restoreCallingIdentity(identity);
                 }
@@ -760,13 +764,15 @@
         }
 
         @Override
-        public void onPrintersRemoved(List<PrinterId> printerIds) {
+        @SuppressWarnings({"rawtypes", "unchecked"})
+        public void onPrintersRemoved(ParceledListSlice printerIds) {
             RemotePrintService service = mWeakService.get();
             if (service != null) {
-                throwIfPrinterIdsTampered(service.mComponentName, printerIds);
+                List<PrinterId> removedPrinterIds = (List<PrinterId>) printerIds.getList();
+                throwIfPrinterIdsTampered(service.mComponentName, removedPrinterIds);
                 final long identity = Binder.clearCallingIdentity();
                 try {
-                    service.mCallbacks.onPrintersRemoved(printerIds);
+                    service.mCallbacks.onPrintersRemoved(removedPrinterIds);
                 } finally {
                     Binder.restoreCallingIdentity(identity);
                 }
diff --git a/services/java/com/android/server/print/RemotePrintSpooler.java b/services/java/com/android/server/print/RemotePrintSpooler.java
index 45469ac..1bde6d7 100644
--- a/services/java/com/android/server/print/RemotePrintSpooler.java
+++ b/services/java/com/android/server/print/RemotePrintSpooler.java
@@ -31,20 +31,20 @@
 import android.print.IPrintSpooler;
 import android.print.IPrintSpoolerCallbacks;
 import android.print.IPrintSpoolerClient;
-import android.print.PrintAttributes;
+import android.print.PrintJobId;
 import android.print.PrintJobInfo;
 import android.print.PrintManager;
 import android.util.Slog;
 import android.util.TimedRemoteCaller;
 
-import libcore.io.IoUtils;
-
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.List;
 import java.util.concurrent.TimeoutException;
 
+import libcore.io.IoUtils;
+
 /**
  * This represents the remote print spooler as a local object to the
  * PrintManagerSerivce. It is responsible to connecting to the remote
@@ -64,8 +64,6 @@
 
     private final GetPrintJobInfosCaller mGetPrintJobInfosCaller = new GetPrintJobInfosCaller();
 
-    private final CreatePrintJobCaller mCreatePrintJobCaller = new CreatePrintJobCaller();
-
     private final GetPrintJobInfoCaller mGetPrintJobInfoCaller = new GetPrintJobInfoCaller();
 
     private final SetPrintJobStateCaller mSetPrintJobStatusCaller = new SetPrintJobStateCaller();
@@ -132,16 +130,15 @@
         return null;
     }
 
-    public final PrintJobInfo createPrintJob(String printJobName, IPrintClient client,
-            IPrintDocumentAdapter documentAdapter, PrintAttributes attributes, int appId) {
+    public final void createPrintJob(PrintJobInfo printJob, IPrintClient client,
+            IPrintDocumentAdapter documentAdapter) {
         throwIfCalledOnMainThread();
         synchronized (mLock) {
             throwIfDestroyedLocked();
             mCanUnbind = false;
         }
         try {
-            return mCreatePrintJobCaller.createPrintJob(getRemoteInstanceLazy(),
-                    printJobName, client, documentAdapter, attributes, appId);
+            getRemoteInstanceLazy().createPrintJob(printJob, client, documentAdapter);
         } catch (RemoteException re) {
             Slog.e(LOG_TAG, "Error creating print job.", re);
         } catch (TimeoutException te) {
@@ -155,10 +152,9 @@
                 mLock.notifyAll();
             }
         }
-        return null;
     }
 
-    public final void writePrintJobData(ParcelFileDescriptor fd, int printJobId) {
+    public final void writePrintJobData(ParcelFileDescriptor fd, PrintJobId printJobId) {
         throwIfCalledOnMainThread();
         synchronized (mLock) {
             throwIfDestroyedLocked();
@@ -184,7 +180,7 @@
         }
     }
 
-    public final PrintJobInfo getPrintJobInfo(int printJobId, int appId) {
+    public final PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId) {
         throwIfCalledOnMainThread();
         synchronized (mLock) {
             throwIfDestroyedLocked();
@@ -209,7 +205,7 @@
         return null;
     }
 
-    public final boolean setPrintJobState(int printJobId, int state, String error) {
+    public final boolean setPrintJobState(PrintJobId printJobId, int state, String error) {
         throwIfCalledOnMainThread();
         synchronized (mLock) {
             throwIfDestroyedLocked();
@@ -234,7 +230,7 @@
         return false;
     }
 
-    public final boolean setPrintJobTag(int printJobId, String tag) {
+    public final boolean setPrintJobTag(PrintJobId printJobId, String tag) {
         throwIfCalledOnMainThread();
         synchronized (mLock) {
             throwIfDestroyedLocked();
@@ -259,19 +255,46 @@
         return false;
     }
 
-    public final void start() {
+    public final void removeObsoletePrintJobs() {
         throwIfCalledOnMainThread();
         synchronized (mLock) {
             throwIfDestroyedLocked();
             mCanUnbind = false;
         }
         try {
-            getRemoteInstanceLazy();
+            getRemoteInstanceLazy().removeObsoletePrintJobs();
+        } catch (RemoteException re) {
+            Slog.e(LOG_TAG, "Error removing obsolete print jobs .", re);
         } catch (TimeoutException te) {
-            Slog.e(LOG_TAG, "Error starting the spooler.", te);
+            Slog.e(LOG_TAG, "Error removing obsolete print jobs .", te);
         } finally {
             if (DEBUG) {
-                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] start()");
+                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier()
+                        + "] removeObsoletePrintJobs()");
+            }
+            synchronized (mLock) {
+                mCanUnbind = true;
+                mLock.notifyAll();
+            }
+        }
+    }
+
+    public final void forgetPrintJobs(List<PrintJobId> printJobIds) {
+        throwIfCalledOnMainThread();
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            mCanUnbind = false;
+        }
+        try {
+            getRemoteInstanceLazy().forgetPrintJobs(printJobIds);
+        } catch (RemoteException re) {
+            Slog.e(LOG_TAG, "Error forgeting print jobs", re);
+        } catch (TimeoutException te) {
+            Slog.e(LOG_TAG, "Error forgeting print jobs", te);
+        } finally {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier()
+                        + "] forgetPrintJobs()");
             }
             synchronized (mLock) {
                 mCanUnbind = true;
@@ -333,6 +356,9 @@
     }
 
     private void bindLocked() throws TimeoutException {
+        if (mRemoteInstance != null) {
+            return;
+        }
         if (DEBUG) {
             Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] bindLocked()");
         }
@@ -362,6 +388,9 @@
     }
 
     private void unbindLocked() {
+        if (mRemoteInstance == null) {
+            return;
+        }
         while (true) {
             if (mCanUnbind) {
                 if (DEBUG) {
@@ -452,29 +481,6 @@
         }
     }
 
-    private static final class CreatePrintJobCaller extends TimedRemoteCaller<PrintJobInfo> {
-        private final IPrintSpoolerCallbacks mCallback;
-
-        public CreatePrintJobCaller() {
-            super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS);
-            mCallback = new BasePrintSpoolerServiceCallbacks() {
-                @Override
-                public void onCreatePrintJobResult(PrintJobInfo printJob, int sequence) {
-                    onRemoteMethodResult(printJob, sequence);
-                }
-            };
-        }
-
-        public PrintJobInfo createPrintJob(IPrintSpooler target, String printJobName,
-                IPrintClient client, IPrintDocumentAdapter documentAdapter,
-                PrintAttributes attributes, int appId) throws RemoteException, TimeoutException {
-            final int sequence = onBeforeRemoteCall();
-            target.createPrintJob(printJobName, client, documentAdapter, attributes,
-                    mCallback, appId, sequence);
-            return getResultTimed(sequence);
-        }
-    }
-
     private static final class GetPrintJobInfoCaller extends TimedRemoteCaller<PrintJobInfo> {
         private final IPrintSpoolerCallbacks mCallback;
 
@@ -488,7 +494,7 @@
             };
         }
 
-        public PrintJobInfo getPrintJobInfo(IPrintSpooler target, int printJobId,
+        public PrintJobInfo getPrintJobInfo(IPrintSpooler target, PrintJobId printJobId,
                 int appId) throws RemoteException, TimeoutException {
             final int sequence = onBeforeRemoteCall();
             target.getPrintJobInfo(printJobId, mCallback, appId, sequence);
@@ -509,7 +515,7 @@
             };
         }
 
-        public boolean setPrintJobState(IPrintSpooler target, int printJobId,
+        public boolean setPrintJobState(IPrintSpooler target, PrintJobId printJobId,
                 int status, String error) throws RemoteException, TimeoutException {
             final int sequence = onBeforeRemoteCall();
             target.setPrintJobState(printJobId, status, error, mCallback, sequence);
@@ -530,7 +536,7 @@
             };
         }
 
-        public boolean setPrintJobTag(IPrintSpooler target, int printJobId,
+        public boolean setPrintJobTag(IPrintSpooler target, PrintJobId printJobId,
                 String tag) throws RemoteException, TimeoutException {
             final int sequence = onBeforeRemoteCall();
             target.setPrintJobTag(printJobId, tag, mCallback, sequence);
@@ -551,11 +557,6 @@
         }
 
         @Override
-        public void onCreatePrintJobResult(PrintJobInfo printJob, int sequence) {
-            /* do nothing */
-        }
-
-        @Override
         public void onCancelPrintJobResult(boolean canceled, int sequence) {
             /* do nothing */
         }
diff --git a/services/java/com/android/server/print/UserState.java b/services/java/com/android/server/print/UserState.java
index 7a56e6b..fd4a3a4 100644
--- a/services/java/com/android/server/print/UserState.java
+++ b/services/java/com/android/server/print/UserState.java
@@ -21,17 +21,24 @@
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.os.UserManager;
+import android.print.IPrintClient;
+import android.print.IPrintDocumentAdapter;
 import android.print.IPrinterDiscoveryObserver;
+import android.print.PrintAttributes;
+import android.print.PrintJobId;
 import android.print.PrintJobInfo;
 import android.print.PrintManager;
 import android.print.PrinterId;
@@ -46,6 +53,7 @@
 import android.util.Slog;
 
 import com.android.internal.R;
+import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.SomeArgs;
 import com.android.server.print.RemotePrintService.PrintServiceCallbacks;
 import com.android.server.print.RemotePrintSpooler.PrintSpoolerCallbacks;
@@ -56,7 +64,6 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 /**
@@ -68,8 +75,6 @@
 
     private static final boolean DEBUG = false;
 
-    private static final int MAX_ITEMS_PER_CALLBACK = 50;
-
     private static final char COMPONENT_NAME_SEPARATOR = ':';
 
     private final SimpleStringSplitter mStringColonSplitter =
@@ -87,6 +92,9 @@
     private final Set<ComponentName> mEnabledServices =
             new ArraySet<ComponentName>();
 
+    private final CreatedPrintJobTracker mCreatedPrintJobTracker =
+            new CreatedPrintJobTracker();
+
     private final Object mLock;
 
     private final Context mContext;
@@ -134,6 +142,79 @@
         }
     }
 
+    public void removeObsoletePrintJobs() {
+        mSpooler.removeObsoletePrintJobs();
+    }
+
+    public PrintJobInfo print(String printJobName, final IPrintClient client,
+            final IPrintDocumentAdapter documentAdapter, PrintAttributes attributes,
+            int appId) {
+        PrintJobId printJobId = new PrintJobId();
+
+        // Track this job so we can forget it when the creator dies.
+        if (!mCreatedPrintJobTracker.onPrintJobCreatedLocked(client.asBinder(), printJobId)) {
+            // Not adding a print job means the client is dead - done.
+            return null;
+        }
+
+        // Create print job place holder.
+        final PrintJobInfo printJob = new PrintJobInfo();
+        printJob.setId(printJobId);
+        printJob.setAppId(appId);
+        printJob.setLabel(printJobName);
+        printJob.setAttributes(attributes);
+        printJob.setState(PrintJobInfo.STATE_CREATED);
+
+        // Spin the spooler to add the job and show the config UI.
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... params) {
+                mSpooler.createPrintJob(printJob, client, documentAdapter);
+                return null;
+            }
+        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+
+        return printJob;
+    }
+
+    public List<PrintJobInfo> getPrintJobInfos(int appId) {
+        return mSpooler.getPrintJobInfos(null, PrintJobInfo.STATE_ANY, appId);
+    }
+
+    public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId) {
+        return mSpooler.getPrintJobInfo(printJobId, appId);
+    }
+
+    public void cancelPrintJob(PrintJobId printJobId, int appId) {
+        PrintJobInfo printJobInfo = mSpooler.getPrintJobInfo(printJobId, appId);
+        if (printJobInfo == null) {
+            return;
+        }
+        if (printJobInfo.getState() != PrintJobInfo.STATE_FAILED) {
+            ComponentName printServiceName = printJobInfo.getPrinterId().getServiceName();
+            RemotePrintService printService = null;
+            synchronized (mLock) {
+                printService = mActiveServices.get(printServiceName);
+            }
+            if (printService == null) {
+                return;
+            }
+            printService.onRequestCancelPrintJob(printJobInfo);
+        } else {
+            // If the print job is failed we do not need cooperation
+            // from the print service.
+            mSpooler.setPrintJobState(printJobId, PrintJobInfo.STATE_CANCELED, null);
+        }
+    }
+
+    public void restartPrintJob(PrintJobId printJobId, int appId) {
+        PrintJobInfo printJobInfo = getPrintJobInfo(printJobId, appId);
+        if (printJobInfo == null || printJobInfo.getState() != PrintJobInfo.STATE_FAILED) {
+            return;
+        }
+        mSpooler.setPrintJobState(printJobId, PrintJobInfo.STATE_QUEUED, null);
+    }
+
     public List<PrintServiceInfo> getEnabledPrintServices() {
         synchronized (mLock) {
             List<PrintServiceInfo> enabledServices = null;
@@ -328,18 +409,6 @@
         }
     }
 
-    public RemotePrintSpooler getSpoolerLocked() {
-        throwIfDestroyedLocked();
-        return mSpooler;
-    }
-
-    public Map<ComponentName, RemotePrintService> getActiveServicesLocked() {
-        synchronized(mLock) {
-            throwIfDestroyedLocked();
-            return mActiveServices;
-        }
-    }
-
     public Set<ComponentName> getEnabledServices() {
         synchronized(mLock) {
             throwIfDestroyedLocked();
@@ -593,13 +662,12 @@
         // just died. Do this off the main thread since we do to allow
         // calls into the spooler on the main thread.
         if (Looper.getMainLooper().isCurrentThread()) {
-            new AsyncTask<Void, Void, Void>() {
+            BackgroundThread.getHandler().post(new Runnable() {
                 @Override
-                protected Void doInBackground(Void... params) {
+                public void run() {
                     failActivePrintJobsForServiceInternal(serviceName);
-                    return null;
                 }
-            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+            });
         } else {
             failActivePrintJobsForServiceInternal(serviceName);
         }
@@ -1088,19 +1156,7 @@
         private void handlePrintersAdded(IPrinterDiscoveryObserver observer,
             List<PrinterInfo> printers) {
             try {
-                final int printerCount = printers.size();
-                if (printerCount <= MAX_ITEMS_PER_CALLBACK) {
-                    observer.onPrintersAdded(printers);
-                } else {
-                    // Send the added printers in chunks avoiding the binder transaction limit.
-                    final int transactionCount = (printerCount / MAX_ITEMS_PER_CALLBACK) + 1;
-                    for (int i = 0; i < transactionCount; i++) {
-                        final int start = i * MAX_ITEMS_PER_CALLBACK;
-                        final int end = Math.min(start + MAX_ITEMS_PER_CALLBACK, printerCount);
-                        List<PrinterInfo> subPrinters = printers.subList(start, end);
-                        observer.onPrintersAdded(subPrinters); 
-                    }
-                }
+                observer.onPrintersAdded(new ParceledListSlice<PrinterInfo>(printers));
             } catch (RemoteException re) {
                 Log.e(LOG_TAG, "Error sending added printers", re);
             }
@@ -1109,21 +1165,9 @@
         private void handlePrintersRemoved(IPrinterDiscoveryObserver observer,
             List<PrinterId> printerIds) {
             try {
-                final int printerCount = printerIds.size();
-                if (printerCount <= MAX_ITEMS_PER_CALLBACK) {
-                    observer.onPrintersRemoved(printerIds);
-                } else {
-                    // Send the added printers in chunks avoiding the binder transaction limit.
-                    final int transactionCount = (printerCount / MAX_ITEMS_PER_CALLBACK) + 1;
-                    for (int i = 0; i < transactionCount; i++) {
-                        final int start = i * MAX_ITEMS_PER_CALLBACK;
-                        final int end = Math.min(start + MAX_ITEMS_PER_CALLBACK, printerCount);
-                        List<PrinterId> subPrinterIds = printerIds.subList(start, end);
-                        observer.onPrintersRemoved(subPrinterIds);
-                    }
-               }
+                observer.onPrintersRemoved(new ParceledListSlice<PrinterId>(printerIds));
             } catch (RemoteException re) {
-                Log.e(LOG_TAG, "Error sending added printers", re);
+                Log.e(LOG_TAG, "Error sending removed printers", re);
             }
         }
 
@@ -1255,4 +1299,51 @@
             }
         }
     }
-}
\ No newline at end of file
+
+    private final class CreatedPrintJobTracker {
+        private final ArrayMap<IBinder, List<PrintJobId>> mCreatedPrintJobs =
+                new ArrayMap<IBinder, List<PrintJobId>>();
+
+        public boolean onPrintJobCreatedLocked(final IBinder creator, PrintJobId printJobId) {
+            try {
+                creator.linkToDeath(new DeathRecipient() {
+                    @Override
+                    public void binderDied() {
+                        creator.unlinkToDeath(this, 0);
+                        UserManager userManager = (UserManager) mContext.getSystemService(
+                                Context.USER_SERVICE);
+                        // If the death is a result of the user being removed, then
+                        // do nothing since the spooler data for this user will be
+                        // wiped and we cannot bind to the spooler at this point.
+                        if (userManager.getUserInfo(mUserId) == null) {
+                            return;
+                        }
+                        List<PrintJobId> printJobIds = null;
+                        synchronized (mLock) {
+                            printJobIds = mCreatedPrintJobs.remove(creator);
+                            if (printJobIds == null) {
+                                return;
+                            }
+                            printJobIds = new ArrayList<PrintJobId>(printJobIds);
+                        }
+                        if (printJobIds != null) {
+                            mSpooler.forgetPrintJobs(printJobIds);
+                        }
+                    }
+                }, 0);
+            } catch (RemoteException re) {
+                /* The process is already dead - we just failed. */
+                return false;
+            }
+            synchronized (mLock) {
+                List<PrintJobId> printJobIds = mCreatedPrintJobs.get(creator);
+                if (printJobIds == null) {
+                    printJobIds = new ArrayList<PrintJobId>();
+                    mCreatedPrintJobs.put(creator, printJobIds);
+                }
+                printJobIds.add(printJobId);
+            }
+            return true;
+        }
+    }
+}
diff --git a/services/java/com/android/server/wifi/WifiService.java b/services/java/com/android/server/wifi/WifiService.java
index 5a24ebb..bbcd01a 100644
--- a/services/java/com/android/server/wifi/WifiService.java
+++ b/services/java/com/android/server/wifi/WifiService.java
@@ -172,10 +172,16 @@
                 case WifiManager.CONNECT_NETWORK:
                 case WifiManager.SAVE_NETWORK: {
                     WifiConfiguration config = (WifiConfiguration) msg.obj;
-                    if (config.isValid()) {
+                    int networkId = msg.arg1;
+                    if (config != null && config.isValid()) {
+                        if (DBG) Slog.d(TAG, "Connect with config" + config);
+                        mWifiStateMachine.sendMessage(Message.obtain(msg));
+                    } else if (config == null
+                            && networkId != WifiConfiguration.INVALID_NETWORK_ID) {
+                        if (DBG) Slog.d(TAG, "Connect with networkId" + networkId);
                         mWifiStateMachine.sendMessage(Message.obtain(msg));
                     } else {
-                        Slog.d(TAG, "ClientHandler.handleMessage ignoring msg=" + msg);
+                        Slog.e(TAG, "ClientHandler.handleMessage ignoring invalid msg=" + msg);
                         if (msg.what == WifiManager.CONNECT_NETWORK) {
                             replyFailed(msg, WifiManager.CONNECT_NETWORK_FAILED);
                         } else {
@@ -582,7 +588,8 @@
      */
     public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
         enforceChangePermission();
-        if (wifiConfig.isValid()) {
+        // null wifiConfig is a meaningful input for CMD_SET_AP
+        if (wifiConfig == null || wifiConfig.isValid()) {
             mWifiController.obtainMessage(CMD_SET_AP, enabled ? 1 : 0, 0, wifiConfig).sendToTarget();
         } else {
             Slog.e(TAG, "Invalid WifiConfiguration");
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 2ce584b..2b3c9e2 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -355,7 +355,15 @@
      */
     public boolean isValid() {
         if (allowedKeyManagement.cardinality() > 1) {
-            return false;
+            if (allowedKeyManagement.cardinality() != 2) {
+                return false;
+            }
+            if (allowedKeyManagement.get(KeyMgmt.WPA_EAP) == false) {
+                return false;
+            }
+            if (allowedKeyManagement.get(KeyMgmt.IEEE8021X) == false) {
+                return false;
+            }
         }
 
         // TODO: Add more checks