Merge "Make outline and shadow APIs public"
diff --git a/Android.mk b/Android.mk
index d478a59..a57b3fa 100644
--- a/Android.mk
+++ b/Android.mk
@@ -275,9 +275,6 @@
 	telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl \
 	telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
 	telephony/java/com/android/internal/telephony/ITelephony.aidl \
-	telephony/java/com/android/internal/telephony/IThirdPartyCallListener.aidl \
-	telephony/java/com/android/internal/telephony/IThirdPartyCallProvider.aidl \
-	telephony/java/com/android/internal/telephony/IThirdPartyCallService.aidl \
 	telephony/java/com/android/internal/telephony/ISms.aidl \
 	telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
 	telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
@@ -576,7 +573,9 @@
                  -samplegroup Content \
                  -samplegroup Input \
                  -samplegroup Media \
+                 -samplegroup RenderScript \
                  -samplegroup Security \
+                 -samplegroup Sensors \
                  -samplegroup Testing \
                  -samplegroup UI \
                  -samplegroup Views
diff --git a/api/current.txt b/api/current.txt
index 448c247..6728823 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -7615,6 +7615,7 @@
     field public static final java.lang.String EXTRA_VERIFICATION_RESULT = "android.content.pm.extra.VERIFICATION_RESULT";
     field public static final java.lang.String FEATURE_APP_WIDGETS = "android.software.app_widgets";
     field public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency";
+    field public static final java.lang.String FEATURE_BACKUP = "android.software.backup";
     field public static final java.lang.String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
     field public static final java.lang.String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le";
     field public static final java.lang.String FEATURE_CAMERA = "android.hardware.camera";
@@ -7636,6 +7637,7 @@
     field public static final java.lang.String FEATURE_MICROPHONE = "android.hardware.microphone";
     field public static final java.lang.String FEATURE_NFC = "android.hardware.nfc";
     field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION = "android.hardware.nfc.hce";
+    field public static final java.lang.String FEATURE_PRINTING = "android.software.print";
     field public static final java.lang.String FEATURE_SCREEN_LANDSCAPE = "android.hardware.screen.landscape";
     field public static final java.lang.String FEATURE_SCREEN_PORTRAIT = "android.hardware.screen.portrait";
     field public static final java.lang.String FEATURE_SENSOR_ACCELEROMETER = "android.hardware.sensor.accelerometer";
@@ -10543,6 +10545,7 @@
     ctor public GradientDrawable();
     ctor public GradientDrawable(android.graphics.drawable.GradientDrawable.Orientation, int[]);
     method public void draw(android.graphics.Canvas);
+    method public float getGradientRadius();
     method public int getOpacity();
     method public android.graphics.drawable.GradientDrawable.Orientation getOrientation();
     method public boolean onStateChange(int[]);
@@ -11323,10 +11326,12 @@
     method public abstract int setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract int setRepeatingRequest(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract void stopRepeating() throws android.hardware.camera2.CameraAccessException;
+    field public static final int TEMPLATE_MANUAL = 6; // 0x6
     field public static final int TEMPLATE_PREVIEW = 1; // 0x1
     field public static final int TEMPLATE_RECORD = 3; // 0x3
     field public static final int TEMPLATE_STILL_CAPTURE = 2; // 0x2
     field public static final int TEMPLATE_VIDEO_SNAPSHOT = 4; // 0x4
+    field public static final int TEMPLATE_ZERO_SHUTTER_LAG = 5; // 0x5
   }
 
   public static abstract class CameraDevice.CaptureListener {
@@ -24566,32 +24571,6 @@
     field public static final int SIM_STATE_UNKNOWN = 0; // 0x0
   }
 
-  public class ThirdPartyCallListener {
-    ctor public ThirdPartyCallListener(com.android.internal.telephony.IThirdPartyCallListener);
-    method public void onCallEnded(int);
-    method public void onCallEstablished();
-    method public void onCallProviderAttached(android.telephony.ThirdPartyCallProvider);
-    method public void onRingingStarted();
-    field public static final int CALL_END_INCOMING_MISSED = 2; // 0x2
-    field public static final int CALL_END_NORMAL = 1; // 0x1
-    field public static final int CALL_END_OTHER = 3; // 0x3
-  }
-
-  public class ThirdPartyCallProvider {
-    ctor public ThirdPartyCallProvider();
-    method public void hangup();
-    method public void incomingCallAccept();
-    method public void mute(boolean);
-    method public void sendDtmf(char);
-  }
-
-  public class ThirdPartyCallService {
-    ctor public ThirdPartyCallService();
-    method public android.os.IBinder getBinder();
-    method public void incomingCallAttach(android.telephony.ThirdPartyCallListener, java.lang.String);
-    method public void outgoingCallInitiate(android.telephony.ThirdPartyCallListener, java.lang.String);
-  }
-
 }
 
 package android.telephony.cdma {
@@ -30261,8 +30240,13 @@
   public static final class AccessibilityNodeInfo.CollectionInfo {
     method public int getColumnCount();
     method public int getRowCount();
+    method public int getSelectionMode();
     method public boolean isHierarchical();
     method public static android.view.accessibility.AccessibilityNodeInfo.CollectionInfo obtain(int, int, boolean);
+    method public static android.view.accessibility.AccessibilityNodeInfo.CollectionInfo obtain(int, int, boolean, int);
+    field public static final int SELECTION_MODE_MULTIPLE = 2; // 0x2
+    field public static final int SELECTION_MODE_NONE = 0; // 0x0
+    field public static final int SELECTION_MODE_SINGLE = 1; // 0x1
   }
 
   public static final class AccessibilityNodeInfo.CollectionItemInfo {
@@ -30271,7 +30255,9 @@
     method public int getRowIndex();
     method public int getRowSpan();
     method public boolean isHeading();
+    method public boolean isSelected();
     method public static android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo obtain(int, int, int, int, boolean);
+    method public static android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo obtain(int, int, int, int, boolean, boolean);
   }
 
   public static final class AccessibilityNodeInfo.RangeInfo {
@@ -31683,6 +31669,7 @@
     method public void setRemoteViewsAdapter(android.content.Intent);
     method public void setScrollIndicators(android.view.View, android.view.View);
     method public void setScrollingCacheEnabled(boolean);
+    method public void setSelectionFromTop(int, int);
     method public void setSelector(int);
     method public void setSelector(android.graphics.drawable.Drawable);
     method public void setSmoothScrollbarEnabled(boolean);
@@ -32798,7 +32785,6 @@
     method public void setOverscrollHeader(android.graphics.drawable.Drawable);
     method public void setSelection(int);
     method public void setSelectionAfterHeaderView();
-    method public void setSelectionFromTop(int, int);
     method public void smoothScrollByOffset(int);
   }
 
@@ -34074,24 +34060,6 @@
 
 }
 
-package com.android.internal.telephony {
-
-  public abstract interface IThirdPartyCallListener implements android.os.IInterface {
-    method public abstract void onCallEnded(int) throws android.os.RemoteException;
-    method public abstract void onCallEstablished() throws android.os.RemoteException;
-    method public abstract void onCallProviderAttached(com.android.internal.telephony.IThirdPartyCallProvider) throws android.os.RemoteException;
-    method public abstract void onRingingStarted() throws android.os.RemoteException;
-  }
-
-  public abstract interface IThirdPartyCallProvider implements android.os.IInterface {
-    method public abstract void hangup() throws android.os.RemoteException;
-    method public abstract void incomingCallAccept() throws android.os.RemoteException;
-    method public abstract void mute(boolean) throws android.os.RemoteException;
-    method public abstract void sendDtmf(char) throws android.os.RemoteException;
-  }
-
-}
-
 package com.android.internal.util {
 
   public abstract interface Predicate {
diff --git a/cmds/idmap/Android.mk b/cmds/idmap/Android.mk
new file mode 100644
index 0000000..ffa83f2
--- /dev/null
+++ b/cmds/idmap/Android.mk
@@ -0,0 +1,28 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := idmap.cpp create.cpp scan.cpp inspect.cpp
+
+LOCAL_SHARED_LIBRARIES := liblog libutils libandroidfw
+
+LOCAL_MODULE := idmap
+
+LOCAL_C_INCLUDES := external/zlib
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_EXECUTABLE)
diff --git a/cmds/idmap/create.cpp b/cmds/idmap/create.cpp
new file mode 100644
index 0000000..ae35f7b
--- /dev/null
+++ b/cmds/idmap/create.cpp
@@ -0,0 +1,222 @@
+#include "idmap.h"
+
+#include <UniquePtr.h>
+#include <androidfw/AssetManager.h>
+#include <androidfw/ResourceTypes.h>
+#include <androidfw/ZipFileRO.h>
+#include <utils/String8.h>
+
+#include <fcntl.h>
+#include <sys/stat.h>
+
+using namespace android;
+
+namespace {
+    int get_zip_entry_crc(const char *zip_path, const char *entry_name, uint32_t *crc)
+    {
+        UniquePtr<ZipFileRO> zip(ZipFileRO::open(zip_path));
+        if (zip.get() == NULL) {
+            return -1;
+        }
+        ZipEntryRO entry = zip->findEntryByName(entry_name);
+        if (entry == NULL) {
+            return -1;
+        }
+        if (!zip->getEntryInfo(entry, NULL, NULL, NULL, NULL, NULL, (long*)crc)) {
+            return -1;
+        }
+        zip->releaseEntry(entry);
+        return 0;
+    }
+
+    int open_idmap(const char *path)
+    {
+        int fd = TEMP_FAILURE_RETRY(open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644));
+        if (fd == -1) {
+            ALOGD("error: open %s: %s\n", path, strerror(errno));
+            goto fail;
+        }
+        if (fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) {
+            ALOGD("error: fchmod %s: %s\n", path, strerror(errno));
+            goto fail;
+        }
+        if (TEMP_FAILURE_RETRY(flock(fd, LOCK_EX | LOCK_NB)) != 0) {
+            ALOGD("error: flock %s: %s\n", path, strerror(errno));
+            goto fail;
+        }
+
+        return fd;
+fail:
+        if (fd != -1) {
+            close(fd);
+            unlink(path);
+        }
+        return -1;
+    }
+
+    int write_idmap(int fd, const uint32_t *data, size_t size)
+    {
+        if (lseek(fd, SEEK_SET, 0) < 0) {
+            return -1;
+        }
+        size_t bytesLeft = size;
+        while (bytesLeft > 0) {
+            ssize_t w = TEMP_FAILURE_RETRY(write(fd, data + size - bytesLeft, bytesLeft));
+            if (w < 0) {
+                fprintf(stderr, "error: write: %s\n", strerror(errno));
+                return -1;
+            }
+            bytesLeft -= w;
+        }
+        return 0;
+    }
+
+    bool is_idmap_stale_fd(const char *target_apk_path, const char *overlay_apk_path, int idmap_fd)
+    {
+        static const size_t N = ResTable::IDMAP_HEADER_SIZE_BYTES;
+        struct stat st;
+        if (fstat(idmap_fd, &st) == -1) {
+            return true;
+        }
+        if (st.st_size < N) {
+            // file is empty or corrupt
+            return true;
+        }
+
+        char buf[N];
+        ssize_t bytesLeft = N;
+        if (lseek(idmap_fd, SEEK_SET, 0) < 0) {
+            return true;
+        }
+        for (;;) {
+            ssize_t r = TEMP_FAILURE_RETRY(read(idmap_fd, buf + N - bytesLeft, bytesLeft));
+            if (r < 0) {
+                return true;
+            }
+            bytesLeft -= r;
+            if (bytesLeft == 0) {
+                break;
+            }
+            if (r == 0) {
+                // "shouldn't happen"
+                return true;
+            }
+        }
+
+        uint32_t cached_target_crc, cached_overlay_crc;
+        String8 cached_target_path, cached_overlay_path;
+        if (!ResTable::getIdmapInfo(buf, N, &cached_target_crc, &cached_overlay_crc,
+                    &cached_target_path, &cached_overlay_path)) {
+            return true;
+        }
+
+        if (cached_target_path != target_apk_path) {
+            return true;
+        }
+        if (cached_overlay_path != overlay_apk_path) {
+            return true;
+        }
+
+        uint32_t actual_target_crc, actual_overlay_crc;
+        if (get_zip_entry_crc(target_apk_path, AssetManager::RESOURCES_FILENAME,
+				&actual_target_crc) == -1) {
+            return true;
+        }
+        if (get_zip_entry_crc(overlay_apk_path, AssetManager::RESOURCES_FILENAME,
+				&actual_overlay_crc) == -1) {
+            return true;
+        }
+
+        return cached_target_crc != actual_target_crc || cached_overlay_crc != actual_overlay_crc;
+    }
+
+    bool is_idmap_stale_path(const char *target_apk_path, const char *overlay_apk_path,
+            const char *idmap_path)
+    {
+        struct stat st;
+        if (stat(idmap_path, &st) == -1) {
+            // non-existing idmap is always stale; on other errors, abort idmap generation
+            return errno == ENOENT;
+        }
+
+        int idmap_fd = TEMP_FAILURE_RETRY(open(idmap_path, O_RDONLY));
+        if (idmap_fd == -1) {
+            return false;
+        }
+        bool is_stale = is_idmap_stale_fd(target_apk_path, overlay_apk_path, idmap_fd);
+        close(idmap_fd);
+        return is_stale;
+    }
+
+    int create_idmap(const char *target_apk_path, const char *overlay_apk_path,
+            uint32_t **data, size_t *size)
+    {
+        uint32_t target_crc, overlay_crc;
+        if (get_zip_entry_crc(target_apk_path, AssetManager::RESOURCES_FILENAME,
+				&target_crc) == -1) {
+            return -1;
+        }
+        if (get_zip_entry_crc(overlay_apk_path, AssetManager::RESOURCES_FILENAME,
+				&overlay_crc) == -1) {
+            return -1;
+        }
+
+        AssetManager am;
+        bool b = am.createIdmap(target_apk_path, overlay_apk_path, target_crc, overlay_crc,
+                data, size);
+        return b ? 0 : -1;
+    }
+
+    int create_and_write_idmap(const char *target_apk_path, const char *overlay_apk_path,
+            int fd, bool check_if_stale)
+    {
+        if (check_if_stale) {
+            if (!is_idmap_stale_fd(target_apk_path, overlay_apk_path, fd)) {
+                // already up to date -- nothing to do
+                return 0;
+            }
+        }
+
+        uint32_t *data = NULL;
+        size_t size;
+
+        if (create_idmap(target_apk_path, overlay_apk_path, &data, &size) == -1) {
+            return -1;
+        }
+
+        if (write_idmap(fd, data, size) == -1) {
+            free(data);
+            return -1;
+        }
+
+        free(data);
+        return 0;
+    }
+}
+
+int idmap_create_path(const char *target_apk_path, const char *overlay_apk_path,
+        const char *idmap_path)
+{
+    if (!is_idmap_stale_path(target_apk_path, overlay_apk_path, idmap_path)) {
+        // already up to date -- nothing to do
+        return EXIT_SUCCESS;
+    }
+
+    int fd = open_idmap(idmap_path);
+    if (fd == -1) {
+        return EXIT_FAILURE;
+    }
+
+    int r = create_and_write_idmap(target_apk_path, overlay_apk_path, fd, false);
+    close(fd);
+    if (r != 0) {
+        unlink(idmap_path);
+    }
+    return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+int idmap_create_fd(const char *target_apk_path, const char *overlay_apk_path, int fd)
+{
+    return create_and_write_idmap(target_apk_path, overlay_apk_path, fd, true) == 0 ?
+        EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/cmds/idmap/idmap.cpp b/cmds/idmap/idmap.cpp
new file mode 100644
index 0000000..46c0edc
--- /dev/null
+++ b/cmds/idmap/idmap.cpp
@@ -0,0 +1,237 @@
+#include "idmap.h"
+
+#include <private/android_filesystem_config.h> // for AID_SYSTEM
+
+#include <stdlib.h>
+#include <string.h>
+
+namespace {
+    const char *usage = "NAME\n\
+      idmap - create or display idmap files\n\
+\n\
+SYNOPSIS \n\
+      idmap --help \n\
+      idmap --fd target overlay fd \n\
+      idmap --path target overlay idmap \n\
+      idmap --scan dir-to-scan target-to-look-for target dir-to-hold-idmaps \n\
+      idmap --inspect idmap \n\
+\n\
+DESCRIPTION \n\
+      Idmap files play an integral part in the runtime resource overlay framework. An idmap \n\
+      file contains a mapping of resource identifiers between overlay package and its target \n\
+      package; this mapping is used during resource lookup. Idmap files also act as control \n\
+      files by their existence: if not present, the corresponding overlay package is ignored \n\
+      when the resource context is created. \n\
+\n\
+      Idmap files are stored in /data/resource-cache. For each pair (target package, overlay \n\
+      package), there exists exactly one idmap file, or none if the overlay should not be used. \n\
+\n\
+NOMENCLATURE \n\
+      target: the original, non-overlay, package. Each target package may be associated with \n\
+              any number of overlay packages. \n\
+\n\
+      overlay: an overlay package. Each overlay package is associated with exactly one target \n\
+               package, specified in the overlay's manifest using the <overlay target=\"...\"/> \n\
+               tag. \n\
+\n\
+OPTIONS \n\
+      --help: display this help \n\
+\n\
+      --fd: create idmap for target package 'target' (path to apk) and overlay package 'overlay' \n\
+            (path to apk); write results to file descriptor 'fd' (integer). This invocation \n\
+            version is intended to be used by a parent process with higher privileges to call \n\
+            idmap in a controlled way: the parent will open a suitable file descriptor, fork, \n\
+            drop its privileges and exec. This tool will continue execution without the extra \n\
+            privileges, but still have write access to a file it could not have opened on its \n\
+            own. \n\
+\n\
+      --path: create idmap for target package 'target' (path to apk) and overlay package \n\
+              'overlay' (path to apk); write results to 'idmap' (path). \n\
+\n\
+      --scan: non-recursively search directory 'dir-to-scan' (path) for overlay packages with \n\
+              target package 'target-to-look-for' (package name) present at 'target' (path to \n\
+              apk). For each overlay package found, create an idmap file in 'dir-to-hold-idmaps' \n\
+              (path). \n\
+\n\
+      --inspect: decode the binary format of 'idmap' (path) and display the contents in a \n\
+                 debug-friendly format. \n\
+\n\
+EXAMPLES \n\
+      Create an idmap file: \n\
+\n\
+      $ adb shell idmap --path /system/app/target.apk \\ \n\
+                               /vendor/overlay/overlay.apk \\ \n\
+                               /data/resource-cache/vendor@overlay@overlay.apk@idmap \n\
+\n\
+      Display an idmap file: \n\
+\n\
+      $ adb shell idmap --inspect /data/resource-cache/vendor@overlay@overlay.apk@idmap \n\
+      SECTION      ENTRY        VALUE      OFFSET    COMMENT \n\
+      IDMAP HEADER magic        0x706d6469 0x0 \n\
+                   base crc     0x484aa77f 0x1 \n\
+                   overlay crc  0x03c66fa5 0x2 \n\
+                   base path    .......... 0x03-0x42 /system/app/target.apk \n\
+                   overlay path .......... 0x43-0x82 /vendor/overlay/overlay.apk \n\
+      DATA HEADER  types count  0x00000003 0x83 \n\
+                   padding      0x00000000 0x84 \n\
+                   type offset  0x00000004 0x85      absolute offset 0x87, xml \n\
+                   type offset  0x00000007 0x86      absolute offset 0x8a, string \n\
+      DATA BLOCK   entry count  0x00000001 0x87 \n\
+                   entry offset 0x00000000 0x88 \n\
+                   entry        0x7f020000 0x89      xml/integer \n\
+      DATA BLOCK   entry count  0x00000002 0x8a \n\
+                   entry offset 0x00000000 0x8b \n\
+                   entry        0x7f030000 0x8c      string/str \n\
+                   entry        0x7f030001 0x8d      string/str2 \n\
+\n\
+      In this example, the overlay package provides three alternative resource values:\n\
+      xml/integer, string/str and string/str2.\n\
+\n\
+NOTES \n\
+      This tool and its expected invocation from installd is modelled on dexopt.";
+
+    bool verify_directory_readable(const char *path)
+    {
+        return access(path, R_OK | X_OK) == 0;
+    }
+
+    bool verify_directory_writable(const char *path)
+    {
+        return access(path, W_OK) == 0;
+    }
+
+    bool verify_file_readable(const char *path)
+    {
+        return access(path, R_OK) == 0;
+    }
+
+    bool verify_root_or_system()
+    {
+        uid_t uid = getuid();
+        gid_t gid = getgid();
+
+        return (uid == 0 && gid == 0) || (uid == AID_SYSTEM && gid == AID_SYSTEM);
+    }
+
+    int maybe_create_fd(const char *target_apk_path, const char *overlay_apk_path,
+            const char *idmap_str)
+    {
+        // anyone (not just root or system) may do --fd -- the file has
+        // already been opened by someone else on our behalf
+
+        char *endptr;
+        int idmap_fd = strtol(idmap_str, &endptr, 10);
+        if (*endptr != '\0') {
+            fprintf(stderr, "error: failed to parse file descriptor argument %s\n", idmap_str);
+            return -1;
+        }
+
+        if (!verify_file_readable(target_apk_path)) {
+            ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno));
+            return -1;
+        }
+
+        if (!verify_file_readable(overlay_apk_path)) {
+            ALOGD("error: failed to read apk %s: %s\n", overlay_apk_path, strerror(errno));
+            return -1;
+        }
+
+        return idmap_create_fd(target_apk_path, overlay_apk_path, idmap_fd);
+    }
+
+    int maybe_create_path(const char *target_apk_path, const char *overlay_apk_path,
+            const char *idmap_path)
+    {
+        if (!verify_root_or_system()) {
+            fprintf(stderr, "error: permission denied: not user root or user system\n");
+            return -1;
+        }
+
+        if (!verify_file_readable(target_apk_path)) {
+            ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno));
+            return -1;
+        }
+
+        if (!verify_file_readable(overlay_apk_path)) {
+            ALOGD("error: failed to read apk %s: %s\n", overlay_apk_path, strerror(errno));
+            return -1;
+        }
+
+        return idmap_create_path(target_apk_path, overlay_apk_path, idmap_path);
+    }
+
+    int maybe_scan(const char *overlay_dir, const char *target_package_name,
+            const char *target_apk_path, const char *idmap_dir)
+    {
+        if (!verify_root_or_system()) {
+            fprintf(stderr, "error: permission denied: not user root or user system\n");
+            return -1;
+        }
+
+        if (!verify_directory_readable(overlay_dir)) {
+            ALOGD("error: no read access to %s: %s\n", overlay_dir, strerror(errno));
+            return -1;
+        }
+
+        if (!verify_file_readable(target_apk_path)) {
+            ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno));
+            return -1;
+        }
+
+        if (!verify_directory_writable(idmap_dir)) {
+            ALOGD("error: no write access to %s: %s\n", idmap_dir, strerror(errno));
+            return -1;
+        }
+
+        return idmap_scan(overlay_dir, target_package_name, target_apk_path, idmap_dir);
+    }
+
+    int maybe_inspect(const char *idmap_path)
+    {
+        // anyone (not just root or system) may do --inspect
+        if (!verify_file_readable(idmap_path)) {
+            ALOGD("error: failed to read idmap %s: %s\n", idmap_path, strerror(errno));
+            return -1;
+        }
+        return idmap_inspect(idmap_path);
+    }
+}
+
+int main(int argc, char **argv)
+{
+#if 0
+    {
+        char buf[1024];
+        buf[0] = '\0';
+        for (int i = 0; i < argc; ++i) {
+            strncat(buf, argv[i], sizeof(buf) - 1);
+            strncat(buf, " ", sizeof(buf) - 1);
+        }
+        ALOGD("%s:%d: uid=%d gid=%d argv=%s\n", __FILE__, __LINE__, getuid(), getgid(), buf);
+    }
+#endif
+
+    if (argc == 2 && !strcmp(argv[1], "--help")) {
+        printf("%s\n", usage);
+        return 0;
+    }
+
+    if (argc == 5 && !strcmp(argv[1], "--fd")) {
+        return maybe_create_fd(argv[2], argv[3], argv[4]);
+    }
+
+    if (argc == 5 && !strcmp(argv[1], "--path")) {
+        return maybe_create_path(argv[2], argv[3], argv[4]);
+    }
+
+    if (argc == 6 && !strcmp(argv[1], "--scan")) {
+        return maybe_scan(argv[2], argv[3], argv[4], argv[5]);
+    }
+
+    if (argc == 3 && !strcmp(argv[1], "--inspect")) {
+        return maybe_inspect(argv[2]);
+    }
+
+    fprintf(stderr, "Usage: don't use this (cf dexopt usage).\n");
+    return EXIT_FAILURE;
+}
diff --git a/cmds/idmap/idmap.h b/cmds/idmap/idmap.h
new file mode 100644
index 0000000..f507dd8
--- /dev/null
+++ b/cmds/idmap/idmap.h
@@ -0,0 +1,34 @@
+#ifndef _IDMAP_H_
+#define _IDMAP_H_
+
+#define LOG_TAG "idmap"
+
+#include <utils/Log.h>
+
+#include <errno.h>
+#include <stdio.h>
+
+#ifndef TEMP_FAILURE_RETRY
+// Used to retry syscalls that can return EINTR.
+#define TEMP_FAILURE_RETRY(exp) ({         \
+    typeof (exp) _rc;                      \
+    do {                                   \
+        _rc = (exp);                       \
+    } while (_rc == -1 && errno == EINTR); \
+    _rc; })
+#endif
+
+int idmap_create_path(const char *target_apk_path, const char *overlay_apk_path,
+        const char *idmap_path);
+
+int idmap_create_fd(const char *target_apk_path, const char *overlay_apk_path, int fd);
+
+// Regarding target_package_name: the idmap_scan implementation should
+// be able to extract this from the manifest in target_apk_path,
+// simplifying the external API.
+int idmap_scan(const char *overlay_dir, const char *target_package_name,
+        const char *target_apk_path, const char *idmap_dir);
+
+int idmap_inspect(const char *idmap_path);
+
+#endif // _IDMAP_H_
diff --git a/cmds/idmap/inspect.cpp b/cmds/idmap/inspect.cpp
new file mode 100644
index 0000000..a59f5d3
--- /dev/null
+++ b/cmds/idmap/inspect.cpp
@@ -0,0 +1,291 @@
+#include "idmap.h"
+
+#include <androidfw/AssetManager.h>
+#include <androidfw/ResourceTypes.h>
+#include <utils/String8.h>
+
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+using namespace android;
+
+#define NEXT(b, i, o) do { if (buf.next(&i, &o) < 0) { return -1; } } while (0)
+
+namespace {
+    static const uint32_t IDMAP_MAGIC = 0x706d6469;
+    static const size_t PATH_LENGTH = 256;
+    static const uint32_t IDMAP_HEADER_SIZE = (3 + 2 * (PATH_LENGTH / sizeof(uint32_t)));
+
+    void printe(const char *fmt, ...);
+
+    class IdmapBuffer {
+        private:
+            char *buf_;
+            size_t len_;
+            mutable size_t pos_;
+        public:
+            IdmapBuffer() : buf_((char *)MAP_FAILED), len_(0), pos_(0) {}
+
+            ~IdmapBuffer() {
+                if (buf_ != MAP_FAILED) {
+                    munmap(buf_, len_);
+                }
+            }
+
+            int init(const char *idmap_path)
+            {
+                struct stat st;
+                int fd;
+
+                if (stat(idmap_path, &st) < 0) {
+                    printe("failed to stat idmap '%s': %s\n", idmap_path, strerror(errno));
+                    return -1;
+                }
+                len_ = st.st_size;
+                if ((fd = TEMP_FAILURE_RETRY(open(idmap_path, O_RDONLY))) < 0) {
+                    printe("failed to open idmap '%s': %s\n", idmap_path, strerror(errno));
+                    return -1;
+                }
+                if ((buf_ = (char*)mmap(NULL, len_, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) {
+                    close(fd);
+                    printe("failed to mmap idmap: %s\n", strerror(errno));
+                    return -1;
+                }
+                close(fd);
+                return 0;
+            }
+
+            int next(uint32_t *i, uint32_t *offset) const
+            {
+                if (!buf_) {
+                    printe("failed to read next uint32_t: buffer not initialized\n");
+                    return -1;
+                }
+                if (pos_ + 4 > len_) {
+                    printe("failed to read next uint32_t: end of buffer reached at pos=0x%08x\n",
+                            pos_);
+                    return -1;
+                }
+                *offset = pos_ / sizeof(uint32_t);
+                char a = buf_[pos_++];
+                char b = buf_[pos_++];
+                char c = buf_[pos_++];
+                char d = buf_[pos_++];
+                *i = (d << 24) | (c << 16) | (b << 8) | a;
+                return 0;
+            }
+
+            int nextPath(char *b, uint32_t *offset_start, uint32_t *offset_end) const
+            {
+                if (!buf_) {
+                    printe("failed to read next path: buffer not initialized\n");
+                    return -1;
+                }
+                if (pos_ + PATH_LENGTH > len_) {
+                    printe("failed to read next path: end of buffer reached at pos=0x%08x\n", pos_);
+                    return -1;
+                }
+                memcpy(b, buf_ + pos_, PATH_LENGTH);
+                *offset_start = pos_ / sizeof(uint32_t);
+                pos_ += PATH_LENGTH;
+                *offset_end = pos_ / sizeof(uint32_t) - 1;
+                return 0;
+            }
+    };
+
+    void printe(const char *fmt, ...)
+    {
+        va_list ap;
+
+        va_start(ap, fmt);
+        fprintf(stderr, "error: ");
+        vfprintf(stderr, fmt, ap);
+        va_end(ap);
+    }
+
+    void print_header()
+    {
+        printf("SECTION      ENTRY        VALUE      OFFSET    COMMENT\n");
+    }
+
+    void print(const char *section, const char *subsection, uint32_t value, uint32_t offset,
+            const char *fmt, ...)
+    {
+        va_list ap;
+
+        va_start(ap, fmt);
+        printf("%-12s %-12s 0x%08x 0x%-4x    ", section, subsection, value, offset);
+        vprintf(fmt, ap);
+        printf("\n");
+        va_end(ap);
+    }
+
+    void print_path(const char *section, const char *subsection, uint32_t offset_start,
+            uint32_t offset_end, const char *fmt, ...)
+    {
+        va_list ap;
+
+        va_start(ap, fmt);
+        printf("%-12s %-12s .......... 0x%02x-0x%02x ", section, subsection, offset_start,
+                offset_end);
+        vprintf(fmt, ap);
+        printf("\n");
+        va_end(ap);
+    }
+
+    int resource_metadata(const AssetManager& am, uint32_t res_id,
+            String8 *package, String8 *type, String8 *name)
+    {
+        const ResTable& rt = am.getResources();
+        struct ResTable::resource_name data;
+        if (!rt.getResourceName(res_id, false, &data)) {
+            printe("failed to get resource name id=0x%08x\n", res_id);
+            return -1;
+        }
+        if (package) {
+            *package = String8(String16(data.package, data.packageLen));
+        }
+        if (type) {
+            *type = String8(String16(data.type, data.typeLen));
+        }
+        if (name) {
+            *name = String8(String16(data.name, data.nameLen));
+        }
+        return 0;
+    }
+
+    int package_id(const AssetManager& am)
+    {
+        return (am.getResources().getBasePackageId(0)) << 24;
+    }
+
+    int parse_idmap_header(const IdmapBuffer& buf, AssetManager& am)
+    {
+        uint32_t i, o, e;
+        char path[PATH_LENGTH];
+
+        NEXT(buf, i, o);
+        if (i != IDMAP_MAGIC) {
+            printe("not an idmap file: actual magic constant 0x%08x does not match expected magic "
+                    "constant 0x%08x\n", i, IDMAP_MAGIC);
+            return -1;
+        }
+        print_header();
+        print("IDMAP HEADER", "magic", i, o, "");
+
+        NEXT(buf, i, o);
+        print("", "base crc", i, o, "");
+
+        NEXT(buf, i, o);
+        print("", "overlay crc", i, o, "");
+
+        if (buf.nextPath(path, &o, &e) < 0) {
+            // printe done from IdmapBuffer::nextPath
+            return -1;
+        }
+        print_path("", "base path", o, e, "%s", path);
+        if (!am.addAssetPath(String8(path), NULL)) {
+            printe("failed to add '%s' as asset path\n", path);
+            return -1;
+        }
+
+        if (buf.nextPath(path, &o, &e) < 0) {
+            // printe done from IdmapBuffer::nextPath
+            return -1;
+        }
+        print_path("", "overlay path", o, e, "%s", path);
+
+        return 0;
+    }
+
+    int parse_data_header(const IdmapBuffer& buf, const AssetManager& am, Vector<uint32_t>& types)
+    {
+        uint32_t i, o;
+        const uint32_t numeric_package = package_id(am);
+
+        NEXT(buf, i, o);
+        print("DATA HEADER", "types count", i, o, "");
+        const uint32_t N = i;
+
+        for (uint32_t j = 0; j < N; ++j) {
+            NEXT(buf, i, o);
+            if (i == 0) {
+                print("", "padding", i, o, "");
+            } else {
+                String8 type;
+                const uint32_t numeric_type = (j + 1) << 16;
+                const uint32_t res_id = numeric_package | numeric_type;
+                if (resource_metadata(am, res_id, NULL, &type, NULL) < 0) {
+                    // printe done from resource_metadata
+                    return -1;
+                }
+                print("", "type offset", i, o, "absolute offset 0x%02x, %s",
+                        i + IDMAP_HEADER_SIZE, type.string());
+                types.add(numeric_type);
+            }
+        }
+
+        return 0;
+    }
+
+    int parse_data_block(const IdmapBuffer& buf, const AssetManager& am, size_t numeric_type)
+    {
+        uint32_t i, o, n, id_offset;
+        const uint32_t numeric_package = package_id(am);
+
+        NEXT(buf, i, o);
+        print("DATA BLOCK", "entry count", i, o, "");
+        n = i;
+
+        NEXT(buf, i, o);
+        print("", "entry offset", i, o, "");
+        id_offset = i;
+
+        for ( ; n > 0; --n) {
+            String8 type, name;
+
+            NEXT(buf, i, o);
+            if (i == 0) {
+                print("", "padding", i, o, "");
+            } else {
+                uint32_t res_id = numeric_package | numeric_type | id_offset;
+                if (resource_metadata(am, res_id, NULL, &type, &name) < 0) {
+                    // printe done from resource_metadata
+                    return -1;
+                }
+                print("", "entry", i, o, "%s/%s", type.string(), name.string());
+            }
+            ++id_offset;
+        }
+
+        return 0;
+    }
+}
+
+int idmap_inspect(const char *idmap_path)
+{
+    IdmapBuffer buf;
+    if (buf.init(idmap_path) < 0) {
+        // printe done from IdmapBuffer::init
+        return EXIT_FAILURE;
+    }
+    AssetManager am;
+    if (parse_idmap_header(buf, am) < 0) {
+        // printe done from parse_idmap_header
+        return EXIT_FAILURE;
+    }
+    Vector<uint32_t> types;
+    if (parse_data_header(buf, am, types) < 0) {
+        // printe done from parse_data_header
+        return EXIT_FAILURE;
+    }
+    const size_t N = types.size();
+    for (size_t i = 0; i < N; ++i) {
+        if (parse_data_block(buf, am, types.itemAt(i)) < 0) {
+            // printe done from parse_data_block
+            return EXIT_FAILURE;
+        }
+    }
+    return EXIT_SUCCESS;
+}
diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp
new file mode 100644
index 0000000..c5fc941
--- /dev/null
+++ b/cmds/idmap/scan.cpp
@@ -0,0 +1,244 @@
+#include "idmap.h"
+
+#include <UniquePtr.h>
+#include <androidfw/ResourceTypes.h>
+#include <androidfw/StreamingZipInflater.h>
+#include <androidfw/ZipFileRO.h>
+#include <private/android_filesystem_config.h> // for AID_SYSTEM
+#include <utils/SortedVector.h>
+#include <utils/String16.h>
+#include <utils/String8.h>
+
+#include <dirent.h>
+
+#define NO_OVERLAY_TAG (-1000)
+
+using namespace android;
+
+namespace {
+    struct Overlay {
+        Overlay() {}
+        Overlay(const String8& a, const String8& i, int p) :
+            apk_path(a), idmap_path(i), priority(p) {}
+
+        bool operator<(Overlay const& rhs) const
+        {
+            // Note: order is reversed by design
+            return rhs.priority < priority;
+        }
+
+        String8 apk_path;
+        String8 idmap_path;
+        int priority;
+    };
+
+    bool writePackagesList(const char *filename, const SortedVector<Overlay>& overlayVector)
+    {
+        FILE* fout = fopen(filename, "w");
+        if (fout == NULL) {
+            return false;
+        }
+
+        for (size_t i = 0; i < overlayVector.size(); ++i) {
+            const Overlay& overlay = overlayVector[i];
+            fprintf(fout, "%s %s\n", overlay.apk_path.string(), overlay.idmap_path.string());
+        }
+
+        fclose(fout);
+
+        // Make file world readable since Zygote (running as root) will read
+        // it when creating the initial AssetManger object
+        const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // 0644
+        if (chmod(filename, mode) == -1) {
+            unlink(filename);
+            return false;
+        }
+
+        return true;
+    }
+
+    String8 flatten_path(const char *path)
+    {
+        String16 tmp(path);
+        tmp.replaceAll('/', '@');
+        return String8(tmp);
+    }
+
+    int mkdir_p(const String8& path, uid_t uid, gid_t gid)
+    {
+        static const mode_t mode =
+            S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH;
+        struct stat st;
+
+        if (stat(path.string(), &st) == 0) {
+            return 0;
+        }
+        if (mkdir_p(path.getPathDir(), uid, gid) < 0) {
+            return -1;
+        }
+        if (mkdir(path.string(), 0755) != 0) {
+            return -1;
+        }
+        if (chown(path.string(), uid, gid) == -1) {
+            return -1;
+        }
+        if (chmod(path.string(), mode) == -1) {
+            return -1;
+        }
+        return 0;
+    }
+
+    int parse_overlay_tag(const ResXMLTree& parser, const char *target_package_name)
+    {
+        const size_t N = parser.getAttributeCount();
+        String16 target;
+        int priority = -1;
+        for (size_t i = 0; i < N; ++i) {
+            size_t len;
+            String16 key(parser.getAttributeName(i, &len));
+            if (key == String16("targetPackage")) {
+                const uint16_t *p = parser.getAttributeStringValue(i, &len);
+                if (p) {
+                    target = String16(p, len);
+                }
+            } else if (key == String16("priority")) {
+                Res_value v;
+                if (parser.getAttributeValue(i, &v) == sizeof(Res_value)) {
+                    priority = v.data;
+                    if (priority < 0 || priority > 9999) {
+                        return -1;
+                    }
+                }
+            }
+        }
+        if (target == String16(target_package_name)) {
+            return priority;
+        }
+        return NO_OVERLAY_TAG;
+    }
+
+    int parse_manifest(const void *data, size_t size, const char *target_package_name)
+    {
+        ResXMLTree parser(data, size);
+        if (parser.getError() != NO_ERROR) {
+            ALOGD("%s failed to init xml parser, error=0x%08x\n", __FUNCTION__, parser.getError());
+            return -1;
+        }
+
+        ResXMLParser::event_code_t type;
+        do {
+            type = parser.next();
+            if (type == ResXMLParser::START_TAG) {
+                size_t len;
+                String16 tag(parser.getElementName(&len));
+                if (tag == String16("overlay")) {
+                    return parse_overlay_tag(parser, target_package_name);
+                }
+            }
+        } while (type != ResXMLParser::BAD_DOCUMENT && type != ResXMLParser::END_DOCUMENT);
+
+        return NO_OVERLAY_TAG;
+    }
+
+    int parse_apk(const char *path, const char *target_package_name)
+    {
+        UniquePtr<ZipFileRO> zip(ZipFileRO::open(path));
+        if (zip.get() == NULL) {
+            ALOGW("%s: failed to open zip %s\n", __FUNCTION__, path);
+            return -1;
+        }
+        ZipEntryRO entry;
+        if ((entry = zip->findEntryByName("AndroidManifest.xml")) == NULL) {
+            ALOGW("%s: failed to find entry AndroidManifest.xml\n", __FUNCTION__);
+            return -1;
+        }
+        size_t uncompLen = 0;
+        int method;
+        if (!zip->getEntryInfo(entry, &method, &uncompLen, NULL, NULL, NULL, NULL)) {
+            ALOGW("%s: failed to read entry info\n", __FUNCTION__);
+            return -1;
+        }
+        if (method != ZipFileRO::kCompressDeflated) {
+            ALOGW("%s: cannot handle zip compression method %d\n", __FUNCTION__, method);
+            return -1;
+        }
+        FileMap *dataMap = zip->createEntryFileMap(entry);
+        if (!dataMap) {
+            ALOGW("%s: failed to create FileMap\n", __FUNCTION__);
+            return -1;
+        }
+        char *buf = new char[uncompLen];
+        if (NULL == buf) {
+            ALOGW("%s: failed to allocate %d byte\n", __FUNCTION__, uncompLen);
+            dataMap->release();
+            return -1;
+        }
+        StreamingZipInflater inflater(dataMap, uncompLen);
+        if (inflater.read(buf, uncompLen) < 0) {
+            ALOGW("%s: failed to inflate %d byte\n", __FUNCTION__, uncompLen);
+            delete[] buf;
+            dataMap->release();
+            return -1;
+        }
+
+        int priority = parse_manifest(buf, uncompLen, target_package_name);
+        delete[] buf;
+        dataMap->release();
+        return priority;
+    }
+}
+
+int idmap_scan(const char *overlay_dir, const char *target_package_name,
+        const char *target_apk_path, const char *idmap_dir)
+{
+    String8 filename = String8(idmap_dir);
+    filename.appendPath("overlays.list");
+    if (unlink(filename.string()) != 0 && errno != ENOENT) {
+        return EXIT_FAILURE;
+    }
+
+    DIR *dir = opendir(overlay_dir);
+    if (dir == NULL) {
+        return EXIT_FAILURE;
+    }
+
+    SortedVector<Overlay> overlayVector;
+    struct dirent *dirent;
+    while ((dirent = readdir(dir)) != NULL) {
+        struct stat st;
+        char overlay_apk_path[PATH_MAX + 1];
+        snprintf(overlay_apk_path, PATH_MAX, "%s/%s", overlay_dir, dirent->d_name);
+        if (stat(overlay_apk_path, &st) < 0) {
+            continue;
+        }
+        if (!S_ISREG(st.st_mode)) {
+            continue;
+        }
+
+        int priority = parse_apk(overlay_apk_path, target_package_name);
+        if (priority < 0) {
+            continue;
+        }
+
+        String8 idmap_path(idmap_dir);
+        idmap_path.appendPath(flatten_path(overlay_apk_path + 1));
+        idmap_path.append("@idmap");
+
+        if (idmap_create_path(target_apk_path, overlay_apk_path, idmap_path.string()) != 0) {
+            ALOGE("error: failed to create idmap for target=%s overlay=%s idmap=%s\n",
+                    target_apk_path, overlay_apk_path, idmap_path.string());
+            continue;
+        }
+
+        Overlay overlay(String8(overlay_apk_path), idmap_path, priority);
+        overlayVector.add(overlay);
+    }
+
+    closedir(dir);
+
+    if (!writePackagesList(filename.string(), overlayVector)) {
+        return EXIT_FAILURE;
+    }
+
+    return EXIT_SUCCESS;
+}
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index d1ded10..9ad2e76 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -39,6 +39,7 @@
 import android.content.res.Resources;
 import android.net.Uri;
 import android.os.IUserManager;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -1011,6 +1012,27 @@
 
     public void runCreateUser() {
         String name;
+        int relatedUserId = -1;
+        int flags = 0;
+        String opt;
+        while ((opt = nextOption()) != null) {
+            if ("--relatedTo".equals(opt)) {
+                String optionData = nextOptionData();
+                if (optionData == null || !isNumber(optionData)) {
+                    System.err.println("Error: no USER_ID specified");
+                    showUsage();
+                    return;
+                } else {
+                    relatedUserId = Integer.parseInt(optionData);
+                }
+            } else if ("--managed".equals(opt)) {
+                flags |= UserInfo.FLAG_MANAGED_PROFILE;
+            } else {
+                System.err.println("Error: unknown option " + opt);
+                showUsage();
+                return;
+            }
+        }
         String arg = nextArg();
         if (arg == null) {
             System.err.println("Error: no user name specified.");
@@ -1018,7 +1040,16 @@
         }
         name = arg;
         try {
-            final UserInfo info = mUm.createUser(name, 0);
+            UserInfo info = null;
+            if (relatedUserId < 0) {
+                info = mUm.createUser(name, flags);
+            } else {
+                if (Process.myUid() != 0) {
+                    System.err.println("Error: not running as root.");
+                    return;
+                }
+                info = mUm.createRelatedUser(name, flags, relatedUserId);
+            }
             if (info != null) {
                 System.out.println("Success: created user id " + info.id);
             } else {
@@ -1530,7 +1561,7 @@
         System.err.println("       pm get-install-location");
         System.err.println("       pm set-permission-enforced PERMISSION [true|false]");
         System.err.println("       pm trim-caches DESIRED_FREE_SPACE");
-        System.err.println("       pm create-user USER_NAME");
+        System.err.println("       pm create-user [--relatedTo USER_ID] [--managed] USER_NAME");
         System.err.println("       pm remove-user USER_ID");
         System.err.println("       pm get-max-users");
         System.err.println("");
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 5239cc6..30c1e62 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1550,11 +1550,11 @@
     /**
      * Creates the top level resources for the given package.
      */
-    Resources getTopLevelResources(String resDir,
+    Resources getTopLevelResources(String resDir, String[] overlayDirs,
             int displayId, Configuration overrideConfiguration,
             LoadedApk pkgInfo) {
-        return mResourcesManager.getTopLevelResources(resDir, displayId, overrideConfiguration,
-                pkgInfo.getCompatibilityInfo(), null);
+        return mResourcesManager.getTopLevelResources(resDir, overlayDirs, displayId,
+                overrideConfiguration, pkgInfo.getCompatibilityInfo(), null);
     }
 
     final Handler getHandler() {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index b910ba5..6b48130 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -772,7 +772,7 @@
         }
         Resources r = mContext.mMainThread.getTopLevelResources(
                 app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir,
-                        Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo);
+                app.resourceDirs, Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo);
         if (r != null) {
             return r;
         }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 190ddb4..8d127c6 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1911,8 +1911,8 @@
         ContextImpl c = new ContextImpl();
         c.init(mPackageInfo, null, mMainThread);
         c.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
-                getDisplayId(), overrideConfiguration, mResources.getCompatibilityInfo(),
-                mActivityToken);
+                mPackageInfo.getOverlayDirs(), getDisplayId(), overrideConfiguration,
+                mResources.getCompatibilityInfo(), mActivityToken);
         return c;
     }
 
@@ -1929,7 +1929,7 @@
         context.mDisplay = display;
         DisplayAdjustments daj = getDisplayAdjustments(displayId);
         context.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
-                displayId, null, daj.getCompatibilityInfo(), null);
+                mPackageInfo.getOverlayDirs(), displayId, null, daj.getCompatibilityInfo(), null);
         return context;
     }
 
@@ -2041,7 +2041,8 @@
             mDisplayAdjustments.setCompatibilityInfo(compatInfo);
             mDisplayAdjustments.setActivityToken(activityToken);
             mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
-                    Display.DEFAULT_DISPLAY, null, compatInfo, activityToken);
+                    mPackageInfo.getOverlayDirs(), Display.DEFAULT_DISPLAY, null, compatInfo,
+                    activityToken);
         } else {
             mDisplayAdjustments.setCompatibilityInfo(packageInfo.getCompatibilityInfo());
             mDisplayAdjustments.setActivityToken(activityToken);
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 4239a5d..0115d1b 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -76,6 +76,7 @@
     final String mPackageName;
     private final String mAppDir;
     private final String mResDir;
+    private final String[] mOverlayDirs;
     private final String[] mSharedLibraries;
     private final String mDataDir;
     private final String mLibDir;
@@ -120,6 +121,7 @@
         final int myUid = Process.myUid();
         mResDir = aInfo.uid == myUid ? aInfo.sourceDir
                 : aInfo.publicSourceDir;
+        mOverlayDirs = aInfo.resourceDirs;
         if (!UserHandle.isSameUser(aInfo.uid, myUid) && !Process.isIsolated()) {
             aInfo.dataDir = PackageManager.getDataDirForUser(UserHandle.getUserId(myUid),
                     mPackageName);
@@ -159,6 +161,7 @@
         mPackageName = name;
         mAppDir = null;
         mResDir = null;
+        mOverlayDirs = null;
         mSharedLibraries = null;
         mDataDir = null;
         mDataDirFile = null;
@@ -471,6 +474,10 @@
         return mResDir;
     }
 
+    public String[] getOverlayDirs() {
+        return mOverlayDirs;
+    }
+
     public String getDataDir() {
         return mDataDir;
     }
@@ -485,7 +492,7 @@
 
     public Resources getResources(ActivityThread mainThread) {
         if (mResources == null) {
-            mResources = mainThread.getTopLevelResources(mResDir,
+            mResources = mainThread.getTopLevelResources(mResDir, mOverlayDirs,
                     Display.DEFAULT_DISPLAY, null, this);
         }
         return mResources;
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index d3b0763..d4de112 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -231,7 +231,7 @@
      * <p class="note">For security reasons, the {@link android.content.Intent}
      * you supply here should almost always be an <em>explicit intent</em>,
      * that is specify an explicit component to be delivered to through
-     * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
+     * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
      *
      * @param context The Context in which this PendingIntent should start
      * the activity.
@@ -262,7 +262,7 @@
      * <p class="note">For security reasons, the {@link android.content.Intent}
      * you supply here should almost always be an <em>explicit intent</em>,
      * that is specify an explicit component to be delivered to through
-     * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
+     * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
      *
      * @param context The Context in which this PendingIntent should start
      * the activity.
@@ -354,7 +354,7 @@
      * <p class="note">For security reasons, the {@link android.content.Intent} objects
      * you supply here should almost always be <em>explicit intents</em>,
      * that is specify an explicit component to be delivered to through
-     * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
+     * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
      *
      * @param context The Context in which this PendingIntent should start
      * the activity.
@@ -404,7 +404,7 @@
      * <p class="note">For security reasons, the {@link android.content.Intent} objects
      * you supply here should almost always be <em>explicit intents</em>,
      * that is specify an explicit component to be delivered to through
-     * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
+     * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
      *
      * @param context The Context in which this PendingIntent should start
      * the activity.
@@ -474,7 +474,7 @@
      * <p class="note">For security reasons, the {@link android.content.Intent}
      * you supply here should almost always be an <em>explicit intent</em>,
      * that is specify an explicit component to be delivered to through
-     * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
+     * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
      *
      * @param context The Context in which this PendingIntent should perform
      * the broadcast.
@@ -528,7 +528,7 @@
      * <p class="note">For security reasons, the {@link android.content.Intent}
      * you supply here should almost always be an <em>explicit intent</em>,
      * that is specify an explicit component to be delivered to through
-     * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
+     * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
      *
      * @param context The Context in which this PendingIntent should start
      * the service.
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index f55dba4..728f372 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -147,7 +147,7 @@
      * @param compatInfo the compability info. Must not be null.
      * @param token the application token for determining stack bounds.
      */
-    public Resources getTopLevelResources(String resDir, int displayId,
+    public Resources getTopLevelResources(String resDir, String[] overlayDirs, int displayId,
             Configuration overrideConfiguration, CompatibilityInfo compatInfo, IBinder token) {
         final float scale = compatInfo.applicationScale;
         ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfiguration, scale,
@@ -180,6 +180,12 @@
             return null;
         }
 
+        if (overlayDirs != null) {
+            for (String idmapPath : overlayDirs) {
+                assets.addOverlayPath(idmapPath);
+            }
+        }
+
         //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
         DisplayMetrics dm = getDisplayMetricsLocked(displayId);
         Configuration config;
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 40bdb73..0cc878e 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1690,16 +1690,16 @@
      * user. Also, this method must be called before the user has been used for the first time.
      * @param packageName the package name of the application to be registered as profile owner.
      * @param ownerName the human readable name of the organisation associated with this DPM.
+     * @param userHandle the userId to set the profile owner for.
      * @return whether the package was successfully registered as the profile owner.
      * @throws IllegalArgumentException if packageName is null, the package isn't installed, or
      *         the user has already been set up.
      */
-    public boolean setProfileOwner(String packageName, String ownerName)
+    public boolean setProfileOwner(String packageName, String ownerName, int userHandle)
             throws IllegalArgumentException {
         if (mService != null) {
             try {
-                return mService.setProfileOwner(packageName, ownerName,
-                        Process.myUserHandle().getIdentifier());
+                return mService.setProfileOwner(packageName, ownerName, userHandle);
             } catch (RemoteException re) {
                 Log.w(TAG, "Failed to set profile owner", re);
                 throw new IllegalArgumentException("Couldn't set profile owner.", re);
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index af1a6d5..785f2b4 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -227,6 +227,14 @@
     /** @hide */
     public String requiredAccountType;
 
+    /**
+     * What package, if any, this package will overlay.
+     *
+     * Package name of target package, or null.
+     * @hide
+     */
+    public String overlayTarget;
+
     public PackageInfo() {
     }
 
@@ -270,6 +278,7 @@
         dest.writeInt(requiredForAllUsers ? 1 : 0);
         dest.writeString(restrictedAccountType);
         dest.writeString(requiredAccountType);
+        dest.writeString(overlayTarget);
     }
 
     public static final Parcelable.Creator<PackageInfo> CREATOR
@@ -311,5 +320,6 @@
         requiredForAllUsers = source.readInt() != 0;
         restrictedAccountType = source.readString();
         requiredAccountType = source.readString();
+        overlayTarget = source.readString();
     }
 }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 0192a30..40d9606 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1257,6 +1257,20 @@
     public static final String FEATURE_TELEVISION = "android.hardware.type.television";
 
     /**
+     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+     * The device supports printing.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_PRINTING = "android.software.print";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+     * The device can perform backup and restore operations on installed applications.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_BACKUP = "android.software.backup";
+
+    /**
      * Action to external storage service to clean out removed apps.
      * @hide
      */
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 8a1fcd3..7fa9417 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -307,6 +307,7 @@
         }
         pi.restrictedAccountType = p.mRestrictedAccountType;
         pi.requiredAccountType = p.mRequiredAccountType;
+        pi.overlayTarget = p.mOverlayTarget;
         pi.firstInstallTime = firstInstallTime;
         pi.lastUpdateTime = lastUpdateTime;
         if ((flags&PackageManager.GET_GIDS) != 0) {
@@ -490,6 +491,11 @@
 
     public Package parsePackage(File sourceFile, String destCodePath,
             DisplayMetrics metrics, int flags) {
+        return parsePackage(sourceFile, destCodePath, metrics, flags, false);
+    }
+
+    public Package parsePackage(File sourceFile, String destCodePath,
+            DisplayMetrics metrics, int flags, boolean trustedOverlay) {
         mParseError = PackageManager.INSTALL_SUCCEEDED;
 
         mArchiveSourcePath = sourceFile.getPath();
@@ -542,7 +548,7 @@
         Exception errorException = null;
         try {
             // XXXX todo: need to figure out correct configuration.
-            pkg = parsePackage(res, parser, flags, errorText);
+            pkg = parsePackage(res, parser, flags, trustedOverlay, errorText);
         } catch (Exception e) {
             errorException = e;
             mParseError = PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
@@ -951,8 +957,8 @@
     }
 
     private Package parsePackage(
-        Resources res, XmlResourceParser parser, int flags, String[] outError)
-        throws XmlPullParserException, IOException {
+        Resources res, XmlResourceParser parser, int flags, boolean trustedOverlay,
+        String[] outError) throws XmlPullParserException, IOException {
         AttributeSet attrs = parser;
 
         mParseInstrumentationArgs = null;
@@ -1051,6 +1057,31 @@
                 if (!parseApplication(pkg, res, parser, attrs, flags, outError)) {
                     return null;
                 }
+            } else if (tagName.equals("overlay")) {
+                pkg.mTrustedOverlay = trustedOverlay;
+
+                sa = res.obtainAttributes(attrs,
+                        com.android.internal.R.styleable.AndroidManifestResourceOverlay);
+                pkg.mOverlayTarget = sa.getString(
+                        com.android.internal.R.styleable.AndroidManifestResourceOverlay_targetPackage);
+                pkg.mOverlayPriority = sa.getInt(
+                        com.android.internal.R.styleable.AndroidManifestResourceOverlay_priority,
+                        -1);
+                sa.recycle();
+
+                if (pkg.mOverlayTarget == null) {
+                    outError[0] = "<overlay> does not specify a target package";
+                    mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+                    return null;
+                }
+                if (pkg.mOverlayPriority < 0 || pkg.mOverlayPriority > 9999) {
+                    outError[0] = "<overlay> priority must be between 0 and 9999";
+                    mParseError =
+                        PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+                    return null;
+                }
+                XmlUtils.skipCurrentTag(parser);
+
             } else if (tagName.equals("keys")) {
                 if (!parseKeys(pkg, res, parser, attrs, outError)) {
                     return null;
@@ -3546,6 +3577,10 @@
          */
         public ManifestDigest manifestDigest;
 
+        public String mOverlayTarget;
+        public int mOverlayPriority;
+        public boolean mTrustedOverlay;
+
         /**
          * Data used to feed the KeySetManager
          */
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 276e19b..352825f 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -89,7 +89,7 @@
                 mNumRefs = 0;
                 incRefsLocked(this.hashCode());
             }
-            init();
+            init(false);
             if (localLOGV) Log.v(TAG, "New asset manager: " + this);
             ensureSystemAssets();
         }
@@ -112,7 +112,7 @@
                 incRefsLocked(this.hashCode());
             }
         }
-        init();
+        init(true);
         if (localLOGV) Log.v(TAG, "New asset manager: " + this);
     }
 
@@ -617,6 +617,16 @@
 
     private native final int addAssetPathNative(String path);
 
+     /**
+     * Add a set of assets to overlay an already added set of assets.
+     *
+     * This is only intended for application resources. System wide resources
+     * are handled before any Java code is executed.
+     *
+     * {@hide}
+     */
+    public native final int addOverlayPath(String idmapPath);
+
     /**
      * Add multiple sets of assets to the asset manager at once.  See
      * {@link #addAssetPath(String)} for more information.  Returns array of
@@ -754,7 +764,7 @@
     private native final int[] getArrayStringInfo(int arrayRes);
     /*package*/ native final int[] getArrayIntResource(int arrayRes);
 
-    private native final void init();
+    private native final void init(boolean isSystem);
     private native final void destroy();
 
     private final void incRefsLocked(long id) {
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index de00f71..da6ae56 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1625,7 +1625,7 @@
 
             String locale = null;
             if (mConfiguration.locale != null) {
-                locale = mConfiguration.locale.toLanguageTag();
+                locale = localeToLanguageTag(mConfiguration.locale);
             }
             int width, height;
             if (mMetrics.widthPixels >= mMetrics.heightPixels) {
@@ -1706,6 +1706,12 @@
         }
     }
 
+    // Locale.toLanguageTag() is not available in Java6. LayoutLib overrides
+    // this method to enable users to use Java6.
+    private String localeToLanguageTag(Locale locale) {
+        return locale.toLanguageTag();
+    }
+
     /**
      * Update the system resources configuration if they have previously
      * been initialized.
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 42880af..2c53f03 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -92,7 +92,6 @@
      * AE/AWB/AF should be on auto mode.
      *
      * @see #createCaptureRequest
-     * @hide
      */
     public static final int TEMPLATE_ZERO_SHUTTER_LAG = 5;
 
@@ -105,7 +104,6 @@
      * application depending on the intended use case.
      *
      * @see #createCaptureRequest
-     * @hide
      */
     public static final int TEMPLATE_MANUAL = 6;
 
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 408e532..dfde11b 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1329,7 +1329,7 @@
      * <p>Each channel's curve is defined by an array of control points:</p>
      * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} =
      * [ P0in, P0out, P1in, P1out, P2in, P2out, P3in, P3out, ..., PNin, PNout ]
-     * 2 &amp;lt;= N &amp;lt;= {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}</code></pre>
+     * 2 &lt;= N &lt;= {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}</code></pre>
      * <p>These are sorted in order of increasing <code>Pin</code>; it is always
      * guaranteed that input values 0.0 and 1.0 are included in the list to
      * define a complete mapping. For input values between control points,
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 345b52c..32526bd 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -1788,7 +1788,7 @@
      * <p>Each channel's curve is defined by an array of control points:</p>
      * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} =
      * [ P0in, P0out, P1in, P1out, P2in, P2out, P3in, P3out, ..., PNin, PNout ]
-     * 2 &amp;lt;= N &amp;lt;= {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}</code></pre>
+     * 2 &lt;= N &lt;= {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}</code></pre>
      * <p>These are sorted in order of increasing <code>Pin</code>; it is always
      * guaranteed that input values 0.0 and 1.0 are included in the list to
      * define a complete mapping. For input values between control points,
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 345ff82..dfba208 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -171,6 +171,10 @@
     private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
     private static final String DATA_CONNECTION_TIME_DATA = "dct";
     private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
+    private static final String WIFI_STATE_TIME_DATA = "wst";
+    private static final String WIFI_STATE_COUNT_DATA = "wsc";
+    private static final String BLUETOOTH_STATE_TIME_DATA = "bst";
+    private static final String BLUETOOTH_STATE_COUNT_DATA = "bsc";
     private static final String POWER_USE_SUMMARY_DATA = "pws";
     private static final String POWER_USE_ITEM_DATA = "pwi";
 
@@ -275,22 +279,22 @@
          */
         public abstract int getUid();
 
-        public abstract void noteWifiRunningLocked();
-        public abstract void noteWifiStoppedLocked();
-        public abstract void noteFullWifiLockAcquiredLocked();
-        public abstract void noteFullWifiLockReleasedLocked();
-        public abstract void noteWifiScanStartedLocked();
-        public abstract void noteWifiScanStoppedLocked();
-        public abstract void noteWifiBatchedScanStartedLocked(int csph);
-        public abstract void noteWifiBatchedScanStoppedLocked();
-        public abstract void noteWifiMulticastEnabledLocked();
-        public abstract void noteWifiMulticastDisabledLocked();
-        public abstract void noteAudioTurnedOnLocked();
-        public abstract void noteAudioTurnedOffLocked();
-        public abstract void noteVideoTurnedOnLocked();
-        public abstract void noteVideoTurnedOffLocked();
-        public abstract void noteActivityResumedLocked();
-        public abstract void noteActivityPausedLocked();
+        public abstract void noteWifiRunningLocked(long elapsedRealtime);
+        public abstract void noteWifiStoppedLocked(long elapsedRealtime);
+        public abstract void noteFullWifiLockAcquiredLocked(long elapsedRealtime);
+        public abstract void noteFullWifiLockReleasedLocked(long elapsedRealtime);
+        public abstract void noteWifiScanStartedLocked(long elapsedRealtime);
+        public abstract void noteWifiScanStoppedLocked(long elapsedRealtime);
+        public abstract void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtime);
+        public abstract void noteWifiBatchedScanStoppedLocked(long elapsedRealtime);
+        public abstract void noteWifiMulticastEnabledLocked(long elapsedRealtime);
+        public abstract void noteWifiMulticastDisabledLocked(long elapsedRealtime);
+        public abstract void noteAudioTurnedOnLocked(long elapsedRealtime);
+        public abstract void noteAudioTurnedOffLocked(long elapsedRealtime);
+        public abstract void noteVideoTurnedOnLocked(long elapsedRealtime);
+        public abstract void noteVideoTurnedOffLocked(long elapsedRealtime);
+        public abstract void noteActivityResumedLocked(long elapsedRealtime);
+        public abstract void noteActivityPausedLocked(long elapsedRealtime);
         public abstract long getWifiRunningTime(long batteryRealtime, int which);
         public abstract long getFullWifiLockTime(long batteryRealtime, int which);
         public abstract long getWifiScanTime(long batteryRealtime, int which);
@@ -549,8 +553,9 @@
         public static final int STATE_SENSOR_ON_FLAG = 1<<30;
         public static final int STATE_GPS_ON_FLAG = 1<<29;
         public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<28;
-        public static final int STATE_WIFI_SCAN_FLAG = 1<<29;
+        public static final int STATE_WIFI_SCAN_FLAG = 1<<27;
         public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<26;
+        public static final int STATE_MOBILE_RADIO_ACTIVE_FLAG = 1<<25;
         public static final int STATE_WIFI_RUNNING_FLAG = 1<<24;
         // These are on the lower bits used for the command; if they change
         // we need to write another int of data.
@@ -882,6 +887,15 @@
      */
     public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
 
+    /**
+     * Returns the time in microseconds that the mobile network has been active
+     * (in a high power state).
+     *
+     * {@hide}
+     */
+    public abstract long getMobileRadioActiveTime(long batteryRealtime, int which);
+
+
     public static final int DATA_CONNECTION_NONE = 0;
     public static final int DATA_CONNECTION_GPRS = 1;
     public static final int DATA_CONNECTION_EDGE = 2;
@@ -933,6 +947,7 @@
         new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock", "Wl"),
         new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan", "Ws"),
         new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast", "Wm"),
+        new BitDescription(HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG, "mobile_radio", "Pr"),
         new BitDescription(HistoryItem.STATE_WIFI_RUNNING_FLAG, "wifi_running", "Wr"),
         new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"),
         new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"),
@@ -983,6 +998,37 @@
      */
     public abstract long getGlobalWifiRunningTime(long batteryRealtime, int which);
 
+    public static final int WIFI_STATE_OFF = 0;
+    public static final int WIFI_STATE_OFF_SCANNING = 1;
+    public static final int WIFI_STATE_ON_NO_NETWORKS = 2;
+    public static final int WIFI_STATE_ON_DISCONNECTED = 3;
+    public static final int WIFI_STATE_ON_CONNECTED_STA = 4;
+    public static final int WIFI_STATE_ON_CONNECTED_P2P = 5;
+    public static final int WIFI_STATE_ON_CONNECTED_STA_P2P = 6;
+    public static final int WIFI_STATE_SOFT_AP = 7;
+
+    static final String[] WIFI_STATE_NAMES = {
+        "off", "scanning", "no_net", "disconn",
+        "sta", "p2p", "sta_p2p", "soft_ap"
+    };
+
+    public static final int NUM_WIFI_STATES = WIFI_STATE_SOFT_AP+1;
+
+    /**
+     * Returns the time in microseconds that WiFi has been running in the given state.
+     *
+     * {@hide}
+     */
+    public abstract long getWifiStateTime(int wifiState,
+            long batteryRealtime, int which);
+
+    /**
+     * Returns the number of times that WiFi has entered the given state.
+     *
+     * {@hide}
+     */
+    public abstract int getWifiStateCount(int wifiState, int which);
+
     /**
      * Returns the time in microseconds that bluetooth has been on while the device was
      * running on battery.
@@ -993,6 +1039,33 @@
     
     public abstract int getBluetoothPingCount();
 
+    public static final int BLUETOOTH_STATE_INACTIVE = 0;
+    public static final int BLUETOOTH_STATE_LOW = 1;
+    public static final int BLUETOOTH_STATE_MEDIUM = 2;
+    public static final int BLUETOOTH_STATE_HIGH = 3;
+
+    static final String[] BLUETOOTH_STATE_NAMES = {
+        "inactive", "low", "med", "high"
+    };
+
+    public static final int NUM_BLUETOOTH_STATES = BLUETOOTH_STATE_HIGH +1;
+
+    /**
+     * Returns the time in microseconds that Bluetooth has been running in the
+     * given active state.
+     *
+     * {@hide}
+     */
+    public abstract long getBluetoothStateTime(int bluetoothState,
+            long batteryRealtime, int which);
+
+    /**
+     * Returns the number of times that Bluetooth has entered the given active state.
+     *
+     * {@hide}
+     */
+    public abstract int getBluetoothStateCount(int bluetoothState, int which);
+
     public static final int NETWORK_MOBILE_RX_DATA = 0;
     public static final int NETWORK_MOBILE_TX_DATA = 1;
     public static final int NETWORK_WIFI_RX_DATA = 2;
@@ -1026,19 +1099,6 @@
     public abstract long getBatteryUptime(long curTime);
 
     /**
-     * @deprecated use getRadioDataUptime
-     */
-    public long getRadioDataUptimeMs() {
-        return getRadioDataUptime() / 1000;
-    }
-
-    /**
-     * Returns the time that the radio was on for data transfers.
-     * @return the uptime in microseconds while unplugged
-     */
-    public abstract long getRadioDataUptime();
-
-    /**
      * Returns the current battery realtime in microseconds.
      *
      * @param curTime the amount of elapsed realtime in microseconds.
@@ -1374,7 +1434,7 @@
                 wifiRunningTime / 1000, bluetoothOnTime / 1000,
                 mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes,
                 fullWakeLockTimeTotal, partialWakeLockTimeTotal,
-                getInputEventCount(which));
+                getInputEventCount(which), getMobileRadioActiveTime(batteryRealtime, which));
         
         // Dump screen brightness stats
         Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
@@ -1395,7 +1455,7 @@
             args[i] = getPhoneSignalStrengthCount(i, which);
         }
         dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
-        
+
         // Dump network type stats
         args = new Object[NUM_DATA_CONNECTION_TYPES];
         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
@@ -1406,9 +1466,31 @@
             args[i] = getPhoneDataConnectionCount(i, which);
         }
         dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
-        
+
+        // Dump wifi state stats
+        args = new Object[NUM_WIFI_STATES];
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            args[i] = getWifiStateTime(i, batteryRealtime, which) / 1000;
+        }
+        dumpLine(pw, 0 /* uid */, category, WIFI_STATE_TIME_DATA, args);
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            args[i] = getWifiStateCount(i, which);
+        }
+        dumpLine(pw, 0 /* uid */, category, WIFI_STATE_COUNT_DATA, args);
+
+        // Dump bluetooth state stats
+        args = new Object[NUM_BLUETOOTH_STATES];
+        for (int i=0; i<NUM_BLUETOOTH_STATES; i++) {
+            args[i] = getBluetoothStateTime(i, batteryRealtime, which) / 1000;
+        }
+        dumpLine(pw, 0 /* uid */, category, BLUETOOTH_STATE_TIME_DATA, args);
+        for (int i=0; i<NUM_BLUETOOTH_STATES; i++) {
+            args[i] = getBluetoothStateCount(i, which);
+        }
+        dumpLine(pw, 0 /* uid */, category, BLUETOOTH_STATE_COUNT_DATA, args);
+
         if (which == STATS_SINCE_UNPLUGGED) {
-            dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(), 
+            dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
                     getDischargeCurrentLevel());
         }
         
@@ -1906,9 +1988,8 @@
 
         sb.setLength(0);
         sb.append(prefix);
-        sb.append("  Radio data uptime when unplugged: ");
-        sb.append(getRadioDataUptime() / 1000);
-        sb.append(" ms");
+        sb.append("  Mobile radio active time: ");
+        formatTimeMs(sb, getMobileRadioActiveTime(batteryRealtime, which) / 1000);
         pw.println(sb.toString());
 
         sb.setLength(0);
@@ -1917,12 +1998,63 @@
                 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
                 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
                 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
-                sb.append("), Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
+                sb.append(")");
+        pw.println(sb.toString());
+
+        sb.setLength(0);
+        sb.append(prefix);
+        sb.append("  Wifi states:");
+        didOne = false;
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            final long time = getWifiStateTime(i, batteryRealtime, which);
+            if (time == 0) {
+                continue;
+            }
+            sb.append("\n    ");
+            didOne = true;
+            sb.append(WIFI_STATE_NAMES[i]);
+            sb.append(" ");
+            formatTimeMs(sb, time/1000);
+            sb.append("(");
+            sb.append(formatRatioLocked(time, whichBatteryRealtime));
+            sb.append(") ");
+            sb.append(getPhoneDataConnectionCount(i, which));
+            sb.append("x");
+        }
+        if (!didOne) sb.append(" (no activity)");
+        pw.println(sb.toString());
+
+        sb.setLength(0);
+        sb.append(prefix);
+                sb.append("  Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
                 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime));
                 sb.append(")");
         pw.println(sb.toString());
-        
-        pw.println(" ");
+
+        sb.setLength(0);
+        sb.append(prefix);
+        sb.append("  Bluetooth states:");
+        didOne = false;
+        for (int i=0; i<NUM_BLUETOOTH_STATES; i++) {
+            final long time = getBluetoothStateTime(i, batteryRealtime, which);
+            if (time == 0) {
+                continue;
+            }
+            sb.append("\n    ");
+            didOne = true;
+            sb.append(BLUETOOTH_STATE_NAMES[i]);
+            sb.append(" ");
+            formatTimeMs(sb, time/1000);
+            sb.append("(");
+            sb.append(formatRatioLocked(time, whichBatteryRealtime));
+            sb.append(") ");
+            sb.append(getPhoneDataConnectionCount(i, which));
+            sb.append("x");
+        }
+        if (!didOne) sb.append(" (no activity)");
+        pw.println(sb.toString());
+
+        pw.println();
 
         if (which == STATS_SINCE_UNPLUGGED) {
             if (getIsOnBattery()) {
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 0deaea6..c3f4807 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -1247,9 +1247,6 @@
         } else if (v instanceof Parcelable[]) {
             writeInt(VAL_PARCELABLEARRAY);
             writeParcelableArray((Parcelable[]) v, 0);
-        } else if (v instanceof Object[]) {
-            writeInt(VAL_OBJECTARRAY);
-            writeArray((Object[]) v);
         } else if (v instanceof int[]) {
             writeInt(VAL_INTARRAY);
             writeIntArray((int[]) v);
@@ -1259,12 +1256,20 @@
         } else if (v instanceof Byte) {
             writeInt(VAL_BYTE);
             writeInt((Byte) v);
-        } else if (v instanceof Serializable) {
-            // Must be last
-            writeInt(VAL_SERIALIZABLE);
-            writeSerializable((Serializable) v);
         } else {
-            throw new RuntimeException("Parcel: unable to marshal value " + v);
+            Class<?> clazz = v.getClass();
+            if (clazz.isArray() && clazz.getComponentType() == Object.class) {
+                // Only pure Object[] are written here, Other arrays of non-primitive types are
+                // handled by serialization as this does not record the component type.
+                writeInt(VAL_OBJECTARRAY);
+                writeArray((Object[]) v);
+            } else if (v instanceof Serializable) {
+                // Must be last
+                writeInt(VAL_SERIALIZABLE);
+                writeSerializable((Serializable) v);
+            } else {
+                throw new RuntimeException("Parcel: unable to marshal value " + v);
+            }
         }
     }
 
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index 51ba2f6..b97734e 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -642,12 +642,13 @@
                 return _result;
             }
 
-            public int changeEncryptionPassword(String password) throws RemoteException {
+            public int changeEncryptionPassword(int type, String password) throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
                 int _result;
                 try {
                     _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeInt(type);
                     _data.writeString(password);
                     mRemote.transact(Stub.TRANSACTION_changeEncryptionPassword, _data, _reply, 0);
                     _reply.readException();
@@ -677,6 +678,22 @@
                 return _result;
             }
 
+            public int getPasswordType() throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                int _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    mRemote.transact(Stub.TRANSACTION_getPasswordType, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
             public StorageVolume[] getVolumeList() throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
@@ -829,6 +846,8 @@
 
         static final int TRANSACTION_mkdirs = IBinder.FIRST_CALL_TRANSACTION + 34;
 
+        static final int TRANSACTION_getPasswordType = IBinder.FIRST_CALL_TRANSACTION + 36;
+
         /**
          * Cast an IBinder object into an IMountService interface, generating a
          * proxy if needed.
@@ -1130,8 +1149,9 @@
                 }
                 case TRANSACTION_changeEncryptionPassword: {
                     data.enforceInterface(DESCRIPTOR);
+                    int type = data.readInt();
                     String password = data.readString();
-                    int result = changeEncryptionPassword(password);
+                    int result = changeEncryptionPassword(type, password);
                     reply.writeNoException();
                     reply.writeInt(result);
                     return true;
@@ -1181,6 +1201,13 @@
                     reply.writeInt(result);
                     return true;
                 }
+                case TRANSACTION_getPasswordType: {
+                    data.enforceInterface(DESCRIPTOR);
+                    int result = getPasswordType();
+                    reply.writeNoException();
+                    reply.writeInt(result);
+                    return true;
+                }
             }
             return super.onTransact(code, data, reply, flags);
         }
@@ -1375,7 +1402,8 @@
     /**
      * Changes the encryption password.
      */
-    public int changeEncryptionPassword(String password) throws RemoteException;
+    public int changeEncryptionPassword(int type, String password)
+        throws RemoteException;
 
     /**
      * Verify the encryption password against the stored volume.  This method
@@ -1412,4 +1440,10 @@
      * external storage data or OBB directory belonging to calling app.
      */
     public int mkdirs(String callingPkg, String path) throws RemoteException;
+
+    /**
+     * Determines the type of the encryption password
+     * @return PasswordType
+     */
+    public int getPasswordType() throws RemoteException;
 }
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index f5e728d..68b91cb 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -645,4 +645,14 @@
         return Settings.Global.getLong(mResolver, Settings.Global.SYS_STORAGE_FULL_THRESHOLD_BYTES,
                 DEFAULT_FULL_THRESHOLD_BYTES);
     }
+
+    /// Consts to match the password types in cryptfs.h
+    /** @hide */
+    public static final int CRYPT_TYPE_PASSWORD = 0;
+    /** @hide */
+    public static final int CRYPT_TYPE_DEFAULT = 1;
+    /** @hide */
+    public static final int CRYPT_TYPE_PATTERN = 2;
+    /** @hide */
+    public static final int CRYPT_TYPE_PIN = 3;
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 9332578..76ada09 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3468,12 +3468,12 @@
             "lock_screen_owner_info_enabled";
 
         /**
-         * This preference enables expanding the notification panel even over a securely
-         * locked screen, showing only "public" notifications in this case.
+         * When set by a user, allows notifications to be shown atop a securely locked screen
+         * in their full "private" form (same as when the device is unlocked).
          * @hide
          */
-        public static final String LOCK_SCREEN_ALLOW_NOTIFICATIONS =
-                "lock_screen_allow_notifications";
+        public static final String LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS =
+                "lock_screen_allow_private_notifications";
 
         /**
          * The Logging ID (a unique 64-bit value) as a hex string.
@@ -6066,6 +6066,15 @@
          */
         public static final String POLICY_CONTROL = "policy_control";
 
+
+        /**
+         * This preference enables notification display even over a securely
+         * locked screen.
+         * @hide
+         */
+        public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS =
+                "lock_screen_show_notifications";
+
         /**
          * Settings to backup. This is here so that it's in the same place as the settings
          * keys and easy to update.
diff --git a/core/java/android/service/dreams/DreamManagerInternal.java b/core/java/android/service/dreams/DreamManagerInternal.java
new file mode 100644
index 0000000..17ea996
--- /dev/null
+++ b/core/java/android/service/dreams/DreamManagerInternal.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 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.service.dreams;
+
+/**
+ * Dream manager local system service interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class DreamManagerInternal {
+    /**
+     * Called by the power manager to start a dream.
+     */
+    public abstract void startDream();
+
+    /**
+     * Called by the power manager to stop a dream.
+     */
+    public abstract void stopDream();
+
+    /**
+     * Called by the power manager to determine whether a dream is running.
+     */
+    public abstract boolean isDreaming();
+}
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index 34274a6..b55cd6a 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -29,6 +29,7 @@
  */
 public class SpannableStringBuilder implements CharSequence, GetChars, Spannable, Editable,
         Appendable, GraphicsOperations {
+    private final static String TAG = "SpannableStringBuilder";
     /**
      * Create a new SpannableStringBuilder with empty contents
      */
@@ -436,10 +437,26 @@
     }
 
     // Documentation from interface
-    public SpannableStringBuilder replace(final int start, final int end,
+    public SpannableStringBuilder replace(int start, int end,
             CharSequence tb, int tbstart, int tbend) {
         checkRange("replace", start, end);
 
+        // Sanity check
+        if (start > end) {
+            Log.w(TAG, "Bad arguments to #replace : "
+                    + "start = " + start + ", end = " + end);
+            final int tmp = start;
+            start = end;
+            end = tmp;
+        }
+        if (tbstart > tbend) {
+            Log.w(TAG, "Bad arguments to #replace : "
+                    + "tbstart = " + tbstart + ", tbend = " + tbend);
+            final int tmp = tbstart;
+            tbstart = tbend;
+            tbend = tmp;
+        }
+
         int filtercount = mFilters.length;
         for (int i = 0; i < filtercount; i++) {
             CharSequence repl = mFilters[i].filter(tb, tbstart, tbend, this, start, end);
@@ -613,8 +630,9 @@
 
         // 0-length Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
         if (flagsStart == POINT && flagsEnd == MARK && start == end) {
-            if (send) Log.e("SpannableStringBuilder",
-                    "SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length");
+            if (send) {
+                Log.e(TAG, "SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length");
+            }
             // Silently ignore invalid spans when they are created from this class.
             // This avoids the duplication of the above test code before all the
             // calls to setSpan that are done in this class
diff --git a/core/java/android/util/JsonReader.java b/core/java/android/util/JsonReader.java
index f2a86c9..7d1c6c4 100644
--- a/core/java/android/util/JsonReader.java
+++ b/core/java/android/util/JsonReader.java
@@ -546,6 +546,9 @@
     public void skipValue() throws IOException {
         skipping = true;
         try {
+            if (!hasNext() || peek() == JsonToken.END_DOCUMENT) {
+                throw new IllegalStateException("No element left to skip");
+            }
             int count = 0;
             do {
                 JsonToken token = advance();
diff --git a/core/java/android/view/SurfaceSession.java b/core/java/android/view/SurfaceSession.java
index 0dfd94a..3cf5af4 100644
--- a/core/java/android/view/SurfaceSession.java
+++ b/core/java/android/view/SurfaceSession.java
@@ -24,11 +24,11 @@
  */
 public final class SurfaceSession {
     // Note: This field is accessed by native code.
-    private int mNativeClient; // SurfaceComposerClient*
+    private long mNativeClient; // SurfaceComposerClient*
 
-    private static native int nativeCreate();
-    private static native void nativeDestroy(int ptr);
-    private static native void nativeKill(int ptr);
+    private static native long nativeCreate();
+    private static native void nativeDestroy(long ptr);
+    private static native void nativeKill(long ptr);
 
     /** Create a new connection with the surface flinger. */
     public SurfaceSession() {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3513709..f10a271 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6166,7 +6166,7 @@
                 mPrivateFlags3 |= PFLAG3_FITTING_SYSTEM_WINDOWS;
                 return !dispatchApplyWindowInsets(new WindowInsets(insets)).hasInsets();
             } finally {
-                mPrivateFlags3 &= PFLAG3_FITTING_SYSTEM_WINDOWS;
+                mPrivateFlags3 &= ~PFLAG3_FITTING_SYSTEM_WINDOWS;
             }
         } else {
             // We're being called from the newer apply insets path.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index ef69948..11030d9 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -232,8 +232,6 @@
     InputStage mFirstInputStage;
     InputStage mFirstPostImeInputStage;
 
-    boolean mFlipControllerFallbackKeys;
-
     boolean mWindowAttributesChanged = false;
     int mWindowAttributesChangesFlag = 0;
 
@@ -370,8 +368,6 @@
         mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi;
         mFallbackEventHandler = PolicyManager.makeNewFallbackEventHandler(context);
         mChoreographer = Choreographer.getInstance();
-        mFlipControllerFallbackKeys =
-            context.getResources().getBoolean(R.bool.flip_controller_fallback_keys);
 
         PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         mAttachInfo.mScreenOn = powerManager.isScreenOn();
@@ -2930,9 +2926,6 @@
                 mView.dispatchConfigurationChanged(config);
             }
         }
-
-        mFlipControllerFallbackKeys =
-            mContext.getResources().getBoolean(R.bool.flip_controller_fallback_keys);
     }
 
     /**
@@ -4001,7 +3994,6 @@
         private final SyntheticJoystickHandler mJoystick = new SyntheticJoystickHandler();
         private final SyntheticTouchNavigationHandler mTouchNavigation =
                 new SyntheticTouchNavigationHandler();
-        private final SyntheticKeyHandler mKeys = new SyntheticKeyHandler();
 
         public SyntheticInputStage() {
             super(null);
@@ -4024,12 +4016,7 @@
                     mTouchNavigation.process(event);
                     return FINISH_HANDLED;
                 }
-            } else if (q.mEvent instanceof KeyEvent) {
-                if (mKeys.process((KeyEvent) q.mEvent)) {
-                    return FINISH_HANDLED;
-                }
             }
-
             return FORWARD;
         }
 
@@ -4854,71 +4841,6 @@
         };
     }
 
-    private KeyEvent getSyntheticFallbackKey(KeyEvent event) {
-        // In some locales (like Japan) controllers use B for confirm and A for back, rather
-        // than vice versa, so we need to special case this here since the input system itself
-        // is not locale-aware.
-        int keyCode;
-        switch(event.getKeyCode()) {
-            case KeyEvent.KEYCODE_BUTTON_A:
-            case KeyEvent.KEYCODE_BUTTON_C:
-            case KeyEvent.KEYCODE_BUTTON_X:
-            case KeyEvent.KEYCODE_BUTTON_Z:
-                keyCode = mFlipControllerFallbackKeys ?
-                    KeyEvent.KEYCODE_BACK : KeyEvent.KEYCODE_DPAD_CENTER;
-                break;
-            case KeyEvent.KEYCODE_BUTTON_B:
-            case KeyEvent.KEYCODE_BUTTON_Y:
-                keyCode = mFlipControllerFallbackKeys ?
-                    KeyEvent.KEYCODE_DPAD_CENTER : KeyEvent.KEYCODE_BACK;
-                break;
-            case KeyEvent.KEYCODE_BUTTON_THUMBL:
-            case KeyEvent.KEYCODE_BUTTON_THUMBR:
-            case KeyEvent.KEYCODE_BUTTON_START:
-            case KeyEvent.KEYCODE_BUTTON_1:
-            case KeyEvent.KEYCODE_BUTTON_2:
-            case KeyEvent.KEYCODE_BUTTON_3:
-            case KeyEvent.KEYCODE_BUTTON_4:
-            case KeyEvent.KEYCODE_BUTTON_5:
-            case KeyEvent.KEYCODE_BUTTON_6:
-            case KeyEvent.KEYCODE_BUTTON_7:
-            case KeyEvent.KEYCODE_BUTTON_8:
-            case KeyEvent.KEYCODE_BUTTON_9:
-            case KeyEvent.KEYCODE_BUTTON_10:
-            case KeyEvent.KEYCODE_BUTTON_11:
-            case KeyEvent.KEYCODE_BUTTON_12:
-            case KeyEvent.KEYCODE_BUTTON_13:
-            case KeyEvent.KEYCODE_BUTTON_14:
-            case KeyEvent.KEYCODE_BUTTON_15:
-            case KeyEvent.KEYCODE_BUTTON_16:
-                keyCode = KeyEvent.KEYCODE_DPAD_CENTER;
-                break;
-            case KeyEvent.KEYCODE_BUTTON_SELECT:
-            case KeyEvent.KEYCODE_BUTTON_MODE:
-                keyCode = KeyEvent.KEYCODE_MENU;
-            default:
-                return null;
-        }
-        return KeyEvent.obtain(event.getDownTime(), event.getEventTime(),
-                        event.getAction(), keyCode, event.getRepeatCount(), event.getMetaState(),
-                        event.getDeviceId(), event.getScanCode(),
-                        event.getFlags() | KeyEvent.FLAG_FALLBACK, event.getSource(), null);
-    }
-
-
-    final class SyntheticKeyHandler {
-
-        public boolean process(KeyEvent event) {
-            KeyEvent syntheticKey = getSyntheticFallbackKey(event);
-            if (syntheticKey != null) {
-                enqueueInputEvent(syntheticKey);
-                return true;
-            }
-            return false;
-        }
-
-    }
-
     /**
      * Returns true if the key is used for keyboard navigation.
      * @param keyEvent The key event.
@@ -5857,29 +5779,22 @@
             // Some fallback keys are decided by the ViewRoot as they might have special
             // properties (e.g. are locale aware). These take precedence over fallbacks defined by
             // the kcm.
-            KeyEvent fallbackEvent = getSyntheticFallbackKey(event);
+            final KeyCharacterMap kcm = event.getKeyCharacterMap();
+            final int keyCode = event.getKeyCode();
+            final int metaState = event.getMetaState();
 
-            if (fallbackEvent == null) {
-                final KeyCharacterMap kcm = event.getKeyCharacterMap();
-                final int keyCode = event.getKeyCode();
-                final int metaState = event.getMetaState();
-
-                // Check for fallback actions specified by the key character map.
-                KeyCharacterMap.FallbackAction fallbackAction =
-                        kcm.getFallbackAction(keyCode, metaState);
-                if (fallbackAction != null) {
-                    final int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK;
-                    fallbackEvent = KeyEvent.obtain(
-                            event.getDownTime(), event.getEventTime(),
-                            event.getAction(), fallbackAction.keyCode,
-                            event.getRepeatCount(), fallbackAction.metaState,
-                            event.getDeviceId(), event.getScanCode(),
-                            flags, event.getSource(), null);
-                    fallbackAction.recycle();
-
-                }
-            }
-            if (fallbackEvent != null) {
+            // Check for fallback actions specified by the key character map.
+            KeyCharacterMap.FallbackAction fallbackAction =
+                    kcm.getFallbackAction(keyCode, metaState);
+            if (fallbackAction != null) {
+                final int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK;
+                KeyEvent fallbackEvent = KeyEvent.obtain(
+                        event.getDownTime(), event.getEventTime(),
+                        event.getAction(), fallbackAction.keyCode,
+                        event.getRepeatCount(), fallbackAction.metaState,
+                        event.getDeviceId(), event.getScanCode(),
+                        flags, event.getSource(), null);
+                fallbackAction.recycle();
                 dispatchInputEvent(fallbackEvent);
             }
         }
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 7603305..4fdbc1e 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -2283,6 +2283,7 @@
             parcel.writeInt(mCollectionInfo.getRowCount());
             parcel.writeInt(mCollectionInfo.getColumnCount());
             parcel.writeInt(mCollectionInfo.isHierarchical() ? 1 : 0);
+            parcel.writeInt(mCollectionInfo.getSelectionMode());
         } else {
             parcel.writeInt(0);
         }
@@ -2294,6 +2295,7 @@
             parcel.writeInt(mCollectionItemInfo.getRowIndex());
             parcel.writeInt(mCollectionItemInfo.getRowSpan());
             parcel.writeInt(mCollectionItemInfo.isHeading() ? 1 : 0);
+            parcel.writeInt(mCollectionItemInfo.isSelected() ? 1 : 0);
         } else {
             parcel.writeInt(0);
         }
@@ -2420,7 +2422,8 @@
             mCollectionInfo = CollectionInfo.obtain(
                     parcel.readInt(),
                     parcel.readInt(),
-                    parcel.readInt() == 1);
+                    parcel.readInt() == 1,
+                    parcel.readInt());
         }
 
         if (parcel.readInt() == 1) {
@@ -2429,6 +2432,7 @@
                     parcel.readInt(),
                     parcel.readInt(),
                     parcel.readInt(),
+                    parcel.readInt() == 1,
                     parcel.readInt() == 1);
         }
     }
@@ -2786,6 +2790,15 @@
      * </p>
      */
     public static final class CollectionInfo {
+        /** Selection mode where items are not selectable. */
+        public static final int SELECTION_MODE_NONE = 0;
+
+        /** Selection mode where a single item may be selected. */
+        public static final int SELECTION_MODE_SINGLE = 1;
+
+        /** Selection mode where multiple items may be selected. */
+        public static final int SELECTION_MODE_MULTIPLE = 2;
+
         private static final int MAX_POOL_SIZE = 20;
 
         private static final SynchronizedPool<CollectionInfo> sPool =
@@ -2794,17 +2807,17 @@
         private int mRowCount;
         private int mColumnCount;
         private boolean mHierarchical;
+        private int mSelectionMode;
 
         /**
          * Obtains a pooled instance that is a clone of another one.
          *
          * @param other The instance to clone.
-         *
          * @hide
          */
         public static CollectionInfo obtain(CollectionInfo other) {
-            return CollectionInfo.obtain(other.mRowCount, other.mColumnCount,
-                    other.mHierarchical);
+            return CollectionInfo.obtain(other.mRowCount, other.mColumnCount, other.mHierarchical,
+                    other.mSelectionMode);
         }
 
         /**
@@ -2814,15 +2827,35 @@
          * @param columnCount The number of columns.
          * @param hierarchical Whether the collection is hierarchical.
          */
-        public static CollectionInfo obtain(int rowCount, int columnCount, boolean hierarchical) {
-            final CollectionInfo info = sPool.acquire();
+        public static CollectionInfo obtain(int rowCount, int columnCount,
+                boolean hierarchical) {
+            return obtain(rowCount, columnCount, hierarchical, SELECTION_MODE_NONE);
+        }
+
+        /**
+         * Obtains a pooled instance.
+         *
+         * @param rowCount The number of rows.
+         * @param columnCount The number of columns.
+         * @param hierarchical Whether the collection is hierarchical.
+         * @param selectionMode The collection's selection mode, one of:
+         *            <ul>
+         *            <li>{@link #SELECTION_MODE_NONE}
+         *            <li>{@link #SELECTION_MODE_SINGLE}
+         *            <li>{@link #SELECTION_MODE_MULTIPLE}
+         *            </ul>
+         */
+        public static CollectionInfo obtain(int rowCount, int columnCount,
+                boolean hierarchical, int selectionMode) {
+           final CollectionInfo info = sPool.acquire();
             if (info == null) {
-                return new CollectionInfo(rowCount, columnCount, hierarchical);
+                return new CollectionInfo(rowCount, columnCount, hierarchical, selectionMode);
             }
 
             info.mRowCount = rowCount;
             info.mColumnCount = columnCount;
             info.mHierarchical = hierarchical;
+            info.mSelectionMode = selectionMode;
             return info;
         }
 
@@ -2832,12 +2865,14 @@
          * @param rowCount The number of rows.
          * @param columnCount The number of columns.
          * @param hierarchical Whether the collection is hierarchical.
+         * @param selectionMode The collection's selection mode.
          */
-        private CollectionInfo(int rowCount, int columnCount,
-                boolean hierarchical) {
+        private CollectionInfo(int rowCount, int columnCount, boolean hierarchical,
+                int selectionMode) {
             mRowCount = rowCount;
             mColumnCount = columnCount;
             mHierarchical = hierarchical;
+            mSelectionMode = selectionMode;
         }
 
         /**
@@ -2868,6 +2903,20 @@
         }
 
         /**
+         * Gets the collection's selection mode.
+         *
+         * @return The collection's selection mode, one of:
+         *         <ul>
+         *         <li>{@link #SELECTION_MODE_NONE}
+         *         <li>{@link #SELECTION_MODE_SINGLE}
+         *         <li>{@link #SELECTION_MODE_MULTIPLE}
+         *         </ul>
+         */
+        public int getSelectionMode() {
+            return mSelectionMode;
+        }
+
+        /**
          * Recycles this instance.
          */
         void recycle() {
@@ -2879,6 +2928,7 @@
             mRowCount = 0;
             mColumnCount = 0;
             mHierarchical = false;
+            mSelectionMode = SELECTION_MODE_NONE;
         }
     }
 
@@ -2904,12 +2954,11 @@
          * Obtains a pooled instance that is a clone of another one.
          *
          * @param other The instance to clone.
-         *
          * @hide
          */
         public static CollectionItemInfo obtain(CollectionItemInfo other) {
-            return CollectionItemInfo.obtain(other.mRowIndex, other.mRowSpan,
-                    other.mColumnIndex, other.mColumnSpan, other.mHeading);
+            return CollectionItemInfo.obtain(other.mRowIndex, other.mRowSpan, other.mColumnIndex,
+                    other.mColumnSpan, other.mHeading, other.mSelected);
         }
 
         /**
@@ -2921,11 +2970,27 @@
          * @param columnSpan The number of columns the item spans.
          * @param heading Whether the item is a heading.
          */
-        public static CollectionItemInfo obtain(int rowIndex, int rowSpan, int columnIndex,
-                int columnSpan, boolean heading) {
+        public static CollectionItemInfo obtain(int rowIndex, int rowSpan,
+                int columnIndex, int columnSpan, boolean heading) {
+            return obtain(rowIndex, rowSpan, columnIndex, columnSpan, heading, false);
+        }
+
+        /**
+         * Obtains a pooled instance.
+         *
+         * @param rowIndex The row index at which the item is located.
+         * @param rowSpan The number of rows the item spans.
+         * @param columnIndex The column index at which the item is located.
+         * @param columnSpan The number of columns the item spans.
+         * @param heading Whether the item is a heading.
+         * @param selected Whether the item is selected.
+         */
+        public static CollectionItemInfo obtain(int rowIndex, int rowSpan,
+                int columnIndex, int columnSpan, boolean heading, boolean selected) {
             final CollectionItemInfo info = sPool.acquire();
             if (info == null) {
-                return new CollectionItemInfo(rowIndex, rowSpan, columnIndex, columnSpan, heading);
+                return new CollectionItemInfo(
+                        rowIndex, rowSpan, columnIndex, columnSpan, heading, selected);
             }
 
             info.mRowIndex = rowIndex;
@@ -2933,6 +2998,7 @@
             info.mColumnIndex = columnIndex;
             info.mColumnSpan = columnSpan;
             info.mHeading = heading;
+            info.mSelected = selected;
             return info;
         }
 
@@ -2941,6 +3007,7 @@
         private int mRowIndex;
         private int mColumnSpan;
         private int mRowSpan;
+        private boolean mSelected;
 
         /**
          * Creates a new instance.
@@ -2951,13 +3018,14 @@
          * @param columnSpan The number of columns the item spans.
          * @param heading Whether the item is a heading.
          */
-        private CollectionItemInfo(int rowIndex, int rowSpan,
-                int columnIndex, int columnSpan, boolean heading) {
+        private CollectionItemInfo(int rowIndex, int rowSpan, int columnIndex, int columnSpan,
+                boolean heading, boolean selected) {
             mRowIndex = rowIndex;
             mRowSpan = rowSpan;
             mColumnIndex = columnIndex;
             mColumnSpan = columnSpan;
             mHeading = heading;
+            mSelected = selected;
         }
 
         /**
@@ -3007,6 +3075,15 @@
         }
 
         /**
+         * Gets if the collection item is selected.
+         *
+         * @return If the item is selected.
+         */
+        public boolean isSelected() {
+            return mSelected;
+        }
+
+        /**
          * Recycles this instance.
          */
         void recycle() {
@@ -3020,6 +3097,7 @@
             mRowIndex = 0;
             mRowSpan = 0;
             mHeading = false;
+            mSelected = false;
         }
     }
 
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
index 97db84b..b4944be 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
@@ -312,18 +312,25 @@
                 }
             }
 
+            int disconnectedNodeCount = 0;
             // Check for disconnected nodes or ones from another window.
             for (int i = 0; i < mCacheImpl.size(); i++) {
                 AccessibilityNodeInfo info = mCacheImpl.valueAt(i);
                 if (!seen.contains(info)) {
                     if (info.getWindowId() == windowId) {
-                        Log.e(LOG_TAG, "Disconneced node: " + info);
+                        if (DEBUG) {
+                            Log.e(LOG_TAG, "Disconnected node: " + info);
+                        }
+                        disconnectedNodeCount++;
                     } else {
                         Log.e(LOG_TAG, "Node from: " + info.getWindowId() + " not from:"
                                 + windowId + " " + info);
                     }
                 }
             }
+            if (disconnectedNodeCount > 0) {
+                Log.e(LOG_TAG, String.format("Found %d disconnected nodes", disconnectedNodeCount));
+            }
         }
     }
 }
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 13febe9..93b95bf6e 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -36,6 +36,7 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.LongSparseArray;
+import android.util.MathUtils;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.StateSet;
@@ -60,6 +61,9 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.view.animation.LinearInterpolator;
 import android.view.inputmethod.BaseInputConnection;
@@ -418,7 +422,7 @@
     /**
      * Handles scrolling between positions within the list.
      */
-    PositionScroller mPositionScroller;
+    AbsPositionScroller mPositionScroller;
 
     /**
      * The offset in pixels form the top of the AdapterView to the top
@@ -1488,6 +1492,21 @@
         }
     }
 
+    int getSelectionModeForAccessibility() {
+        final int choiceMode = getChoiceMode();
+        switch (choiceMode) {
+            case CHOICE_MODE_NONE:
+                return CollectionInfo.SELECTION_MODE_NONE;
+            case CHOICE_MODE_SINGLE:
+                return CollectionInfo.SELECTION_MODE_SINGLE;
+            case CHOICE_MODE_MULTIPLE:
+            case CHOICE_MODE_MULTIPLE_MODAL:
+                return CollectionInfo.SELECTION_MODE_MULTIPLE;
+            default:
+                return CollectionInfo.SELECTION_MODE_NONE;
+        }
+    }
+
     @Override
     public boolean performAccessibilityAction(int action, Bundle arguments) {
         if (super.performAccessibilityAction(action, arguments)) {
@@ -4371,447 +4390,6 @@
         }
     }
 
-    class PositionScroller implements Runnable {
-        private static final int SCROLL_DURATION = 200;
-
-        private static final int MOVE_DOWN_POS = 1;
-        private static final int MOVE_UP_POS = 2;
-        private static final int MOVE_DOWN_BOUND = 3;
-        private static final int MOVE_UP_BOUND = 4;
-        private static final int MOVE_OFFSET = 5;
-
-        private int mMode;
-        private int mTargetPos;
-        private int mBoundPos;
-        private int mLastSeenPos;
-        private int mScrollDuration;
-        private final int mExtraScroll;
-
-        private int mOffsetFromTop;
-
-        PositionScroller() {
-            mExtraScroll = ViewConfiguration.get(mContext).getScaledFadingEdgeLength();
-        }
-
-        void start(final int position) {
-            stop();
-
-            if (mDataChanged) {
-                // Wait until we're back in a stable state to try this.
-                mPositionScrollAfterLayout = new Runnable() {
-                    @Override public void run() {
-                        start(position);
-                    }
-                };
-                return;
-            }
-
-            final int childCount = getChildCount();
-            if (childCount == 0) {
-                // Can't scroll without children.
-                return;
-            }
-
-            final int firstPos = mFirstPosition;
-            final int lastPos = firstPos + childCount - 1;
-
-            int viewTravelCount;
-            int clampedPosition = Math.max(0, Math.min(getCount() - 1, position));
-            if (clampedPosition < firstPos) {
-                viewTravelCount = firstPos - clampedPosition + 1;
-                mMode = MOVE_UP_POS;
-            } else if (clampedPosition > lastPos) {
-                viewTravelCount = clampedPosition - lastPos + 1;
-                mMode = MOVE_DOWN_POS;
-            } else {
-                scrollToVisible(clampedPosition, INVALID_POSITION, SCROLL_DURATION);
-                return;
-            }
-
-            if (viewTravelCount > 0) {
-                mScrollDuration = SCROLL_DURATION / viewTravelCount;
-            } else {
-                mScrollDuration = SCROLL_DURATION;
-            }
-            mTargetPos = clampedPosition;
-            mBoundPos = INVALID_POSITION;
-            mLastSeenPos = INVALID_POSITION;
-
-            postOnAnimation(this);
-        }
-
-        void start(final int position, final int boundPosition) {
-            stop();
-
-            if (boundPosition == INVALID_POSITION) {
-                start(position);
-                return;
-            }
-
-            if (mDataChanged) {
-                // Wait until we're back in a stable state to try this.
-                mPositionScrollAfterLayout = new Runnable() {
-                    @Override public void run() {
-                        start(position, boundPosition);
-                    }
-                };
-                return;
-            }
-
-            final int childCount = getChildCount();
-            if (childCount == 0) {
-                // Can't scroll without children.
-                return;
-            }
-
-            final int firstPos = mFirstPosition;
-            final int lastPos = firstPos + childCount - 1;
-
-            int viewTravelCount;
-            int clampedPosition = Math.max(0, Math.min(getCount() - 1, position));
-            if (clampedPosition < firstPos) {
-                final int boundPosFromLast = lastPos - boundPosition;
-                if (boundPosFromLast < 1) {
-                    // Moving would shift our bound position off the screen. Abort.
-                    return;
-                }
-
-                final int posTravel = firstPos - clampedPosition + 1;
-                final int boundTravel = boundPosFromLast - 1;
-                if (boundTravel < posTravel) {
-                    viewTravelCount = boundTravel;
-                    mMode = MOVE_UP_BOUND;
-                } else {
-                    viewTravelCount = posTravel;
-                    mMode = MOVE_UP_POS;
-                }
-            } else if (clampedPosition > lastPos) {
-                final int boundPosFromFirst = boundPosition - firstPos;
-                if (boundPosFromFirst < 1) {
-                    // Moving would shift our bound position off the screen. Abort.
-                    return;
-                }
-
-                final int posTravel = clampedPosition - lastPos + 1;
-                final int boundTravel = boundPosFromFirst - 1;
-                if (boundTravel < posTravel) {
-                    viewTravelCount = boundTravel;
-                    mMode = MOVE_DOWN_BOUND;
-                } else {
-                    viewTravelCount = posTravel;
-                    mMode = MOVE_DOWN_POS;
-                }
-            } else {
-                scrollToVisible(clampedPosition, boundPosition, SCROLL_DURATION);
-                return;
-            }
-
-            if (viewTravelCount > 0) {
-                mScrollDuration = SCROLL_DURATION / viewTravelCount;
-            } else {
-                mScrollDuration = SCROLL_DURATION;
-            }
-            mTargetPos = clampedPosition;
-            mBoundPos = boundPosition;
-            mLastSeenPos = INVALID_POSITION;
-
-            postOnAnimation(this);
-        }
-
-        void startWithOffset(int position, int offset) {
-            startWithOffset(position, offset, SCROLL_DURATION);
-        }
-
-        void startWithOffset(final int position, int offset, final int duration) {
-            stop();
-
-            if (mDataChanged) {
-                // Wait until we're back in a stable state to try this.
-                final int postOffset = offset;
-                mPositionScrollAfterLayout = new Runnable() {
-                    @Override public void run() {
-                        startWithOffset(position, postOffset, duration);
-                    }
-                };
-                return;
-            }
-
-            final int childCount = getChildCount();
-            if (childCount == 0) {
-                // Can't scroll without children.
-                return;
-            }
-
-            offset += getPaddingTop();
-
-            mTargetPos = Math.max(0, Math.min(getCount() - 1, position));
-            mOffsetFromTop = offset;
-            mBoundPos = INVALID_POSITION;
-            mLastSeenPos = INVALID_POSITION;
-            mMode = MOVE_OFFSET;
-
-            final int firstPos = mFirstPosition;
-            final int lastPos = firstPos + childCount - 1;
-
-            int viewTravelCount;
-            if (mTargetPos < firstPos) {
-                viewTravelCount = firstPos - mTargetPos;
-            } else if (mTargetPos > lastPos) {
-                viewTravelCount = mTargetPos - lastPos;
-            } else {
-                // On-screen, just scroll.
-                final int targetTop = getChildAt(mTargetPos - firstPos).getTop();
-                smoothScrollBy(targetTop - offset, duration, true);
-                return;
-            }
-
-            // Estimate how many screens we should travel
-            final float screenTravelCount = (float) viewTravelCount / childCount;
-            mScrollDuration = screenTravelCount < 1 ?
-                    duration : (int) (duration / screenTravelCount);
-            mLastSeenPos = INVALID_POSITION;
-
-            postOnAnimation(this);
-        }
-
-        /**
-         * Scroll such that targetPos is in the visible padded region without scrolling
-         * boundPos out of view. Assumes targetPos is onscreen.
-         */
-        void scrollToVisible(int targetPos, int boundPos, int duration) {
-            final int firstPos = mFirstPosition;
-            final int childCount = getChildCount();
-            final int lastPos = firstPos + childCount - 1;
-            final int paddedTop = mListPadding.top;
-            final int paddedBottom = getHeight() - mListPadding.bottom;
-
-            if (targetPos < firstPos || targetPos > lastPos) {
-                Log.w(TAG, "scrollToVisible called with targetPos " + targetPos +
-                        " not visible [" + firstPos + ", " + lastPos + "]");
-            }
-            if (boundPos < firstPos || boundPos > lastPos) {
-                // boundPos doesn't matter, it's already offscreen.
-                boundPos = INVALID_POSITION;
-            }
-
-            final View targetChild = getChildAt(targetPos - firstPos);
-            final int targetTop = targetChild.getTop();
-            final int targetBottom = targetChild.getBottom();
-            int scrollBy = 0;
-
-            if (targetBottom > paddedBottom) {
-                scrollBy = targetBottom - paddedBottom;
-            }
-            if (targetTop < paddedTop) {
-                scrollBy = targetTop - paddedTop;
-            }
-
-            if (scrollBy == 0) {
-                return;
-            }
-
-            if (boundPos >= 0) {
-                final View boundChild = getChildAt(boundPos - firstPos);
-                final int boundTop = boundChild.getTop();
-                final int boundBottom = boundChild.getBottom();
-                final int absScroll = Math.abs(scrollBy);
-
-                if (scrollBy < 0 && boundBottom + absScroll > paddedBottom) {
-                    // Don't scroll the bound view off the bottom of the screen.
-                    scrollBy = Math.max(0, boundBottom - paddedBottom);
-                } else if (scrollBy > 0 && boundTop - absScroll < paddedTop) {
-                    // Don't scroll the bound view off the top of the screen.
-                    scrollBy = Math.min(0, boundTop - paddedTop);
-                }
-            }
-
-            smoothScrollBy(scrollBy, duration);
-        }
-
-        void stop() {
-            removeCallbacks(this);
-        }
-
-        @Override
-        public void run() {
-            final int listHeight = getHeight();
-            final int firstPos = mFirstPosition;
-
-            switch (mMode) {
-            case MOVE_DOWN_POS: {
-                final int lastViewIndex = getChildCount() - 1;
-                final int lastPos = firstPos + lastViewIndex;
-
-                if (lastViewIndex < 0) {
-                    return;
-                }
-
-                if (lastPos == mLastSeenPos) {
-                    // No new views, let things keep going.
-                    postOnAnimation(this);
-                    return;
-                }
-
-                final View lastView = getChildAt(lastViewIndex);
-                final int lastViewHeight = lastView.getHeight();
-                final int lastViewTop = lastView.getTop();
-                final int lastViewPixelsShowing = listHeight - lastViewTop;
-                final int extraScroll = lastPos < mItemCount - 1 ?
-                        Math.max(mListPadding.bottom, mExtraScroll) : mListPadding.bottom;
-
-                final int scrollBy = lastViewHeight - lastViewPixelsShowing + extraScroll;
-                smoothScrollBy(scrollBy, mScrollDuration, true);
-
-                mLastSeenPos = lastPos;
-                if (lastPos < mTargetPos) {
-                    postOnAnimation(this);
-                }
-                break;
-            }
-
-            case MOVE_DOWN_BOUND: {
-                final int nextViewIndex = 1;
-                final int childCount = getChildCount();
-
-                if (firstPos == mBoundPos || childCount <= nextViewIndex
-                        || firstPos + childCount >= mItemCount) {
-                    return;
-                }
-                final int nextPos = firstPos + nextViewIndex;
-
-                if (nextPos == mLastSeenPos) {
-                    // No new views, let things keep going.
-                    postOnAnimation(this);
-                    return;
-                }
-
-                final View nextView = getChildAt(nextViewIndex);
-                final int nextViewHeight = nextView.getHeight();
-                final int nextViewTop = nextView.getTop();
-                final int extraScroll = Math.max(mListPadding.bottom, mExtraScroll);
-                if (nextPos < mBoundPos) {
-                    smoothScrollBy(Math.max(0, nextViewHeight + nextViewTop - extraScroll),
-                            mScrollDuration, true);
-
-                    mLastSeenPos = nextPos;
-
-                    postOnAnimation(this);
-                } else  {
-                    if (nextViewTop > extraScroll) {
-                        smoothScrollBy(nextViewTop - extraScroll, mScrollDuration, true);
-                    }
-                }
-                break;
-            }
-
-            case MOVE_UP_POS: {
-                if (firstPos == mLastSeenPos) {
-                    // No new views, let things keep going.
-                    postOnAnimation(this);
-                    return;
-                }
-
-                final View firstView = getChildAt(0);
-                if (firstView == null) {
-                    return;
-                }
-                final int firstViewTop = firstView.getTop();
-                final int extraScroll = firstPos > 0 ?
-                        Math.max(mExtraScroll, mListPadding.top) : mListPadding.top;
-
-                smoothScrollBy(firstViewTop - extraScroll, mScrollDuration, true);
-
-                mLastSeenPos = firstPos;
-
-                if (firstPos > mTargetPos) {
-                    postOnAnimation(this);
-                }
-                break;
-            }
-
-            case MOVE_UP_BOUND: {
-                final int lastViewIndex = getChildCount() - 2;
-                if (lastViewIndex < 0) {
-                    return;
-                }
-                final int lastPos = firstPos + lastViewIndex;
-
-                if (lastPos == mLastSeenPos) {
-                    // No new views, let things keep going.
-                    postOnAnimation(this);
-                    return;
-                }
-
-                final View lastView = getChildAt(lastViewIndex);
-                final int lastViewHeight = lastView.getHeight();
-                final int lastViewTop = lastView.getTop();
-                final int lastViewPixelsShowing = listHeight - lastViewTop;
-                final int extraScroll = Math.max(mListPadding.top, mExtraScroll);
-                mLastSeenPos = lastPos;
-                if (lastPos > mBoundPos) {
-                    smoothScrollBy(-(lastViewPixelsShowing - extraScroll), mScrollDuration, true);
-                    postOnAnimation(this);
-                } else {
-                    final int bottom = listHeight - extraScroll;
-                    final int lastViewBottom = lastViewTop + lastViewHeight;
-                    if (bottom > lastViewBottom) {
-                        smoothScrollBy(-(bottom - lastViewBottom), mScrollDuration, true);
-                    }
-                }
-                break;
-            }
-
-            case MOVE_OFFSET: {
-                if (mLastSeenPos == firstPos) {
-                    // No new views, let things keep going.
-                    postOnAnimation(this);
-                    return;
-                }
-
-                mLastSeenPos = firstPos;
-
-                final int childCount = getChildCount();
-                final int position = mTargetPos;
-                final int lastPos = firstPos + childCount - 1;
-
-                int viewTravelCount = 0;
-                if (position < firstPos) {
-                    viewTravelCount = firstPos - position + 1;
-                } else if (position > lastPos) {
-                    viewTravelCount = position - lastPos;
-                }
-
-                // Estimate how many screens we should travel
-                final float screenTravelCount = (float) viewTravelCount / childCount;
-
-                final float modifier = Math.min(Math.abs(screenTravelCount), 1.f);
-                if (position < firstPos) {
-                    final int distance = (int) (-getHeight() * modifier);
-                    final int duration = (int) (mScrollDuration * modifier);
-                    smoothScrollBy(distance, duration, true);
-                    postOnAnimation(this);
-                } else if (position > lastPos) {
-                    final int distance = (int) (getHeight() * modifier);
-                    final int duration = (int) (mScrollDuration * modifier);
-                    smoothScrollBy(distance, duration, true);
-                    postOnAnimation(this);
-                } else {
-                    // On-screen, just scroll.
-                    final int targetTop = getChildAt(position - firstPos).getTop();
-                    final int distance = targetTop - mOffsetFromTop;
-                    final int duration = (int) (mScrollDuration *
-                            ((float) Math.abs(distance) / getHeight()));
-                    smoothScrollBy(distance, duration, true);
-                }
-                break;
-            }
-
-            default:
-                break;
-            }
-        }
-    }
-
     /**
      * The amount of friction applied to flings. The default value
      * is {@link ViewConfiguration#getScrollFriction}.
@@ -4834,20 +4412,27 @@
     }
 
     /**
+     * Override this for better control over position scrolling.
+     */
+    AbsPositionScroller createPositionScroller() {
+        return new PositionScroller();
+    }
+
+    /**
      * Smoothly scroll to the specified adapter position. The view will
      * scroll such that the indicated position is displayed.
      * @param position Scroll to this adapter position.
      */
     public void smoothScrollToPosition(int position) {
         if (mPositionScroller == null) {
-            mPositionScroller = new PositionScroller();
+            mPositionScroller = createPositionScroller();
         }
         mPositionScroller.start(position);
     }
 
     /**
      * Smoothly scroll to the specified adapter position. The view will scroll
-     * such that the indicated position is displayed <code>offset</code> pixels from
+     * such that the indicated position is displayed <code>offset</code> pixels below
      * the top edge of the view. If this is impossible, (e.g. the offset would scroll
      * the first or last item beyond the boundaries of the list) it will get as close
      * as possible. The scroll will take <code>duration</code> milliseconds to complete.
@@ -4859,14 +4444,14 @@
      */
     public void smoothScrollToPositionFromTop(int position, int offset, int duration) {
         if (mPositionScroller == null) {
-            mPositionScroller = new PositionScroller();
+            mPositionScroller = createPositionScroller();
         }
         mPositionScroller.startWithOffset(position, offset, duration);
     }
 
     /**
      * Smoothly scroll to the specified adapter position. The view will scroll
-     * such that the indicated position is displayed <code>offset</code> pixels from
+     * such that the indicated position is displayed <code>offset</code> pixels below
      * the top edge of the view. If this is impossible, (e.g. the offset would scroll
      * the first or last item beyond the boundaries of the list) it will get as close
      * as possible.
@@ -4877,9 +4462,9 @@
      */
     public void smoothScrollToPositionFromTop(int position, int offset) {
         if (mPositionScroller == null) {
-            mPositionScroller = new PositionScroller();
+            mPositionScroller = createPositionScroller();
         }
-        mPositionScroller.startWithOffset(position, offset);
+        mPositionScroller.startWithOffset(position, offset, offset);
     }
 
     /**
@@ -4893,7 +4478,7 @@
      */
     public void smoothScrollToPosition(int position, int boundPosition) {
         if (mPositionScroller == null) {
-            mPositionScroller = new PositionScroller();
+            mPositionScroller = createPositionScroller();
         }
         mPositionScroller.start(position, boundPosition);
     }
@@ -6992,4 +6577,802 @@
             return null;
         }
     }
+
+    /**
+     * Returns the height of the view for the specified position.
+     *
+     * @param position the item position
+     * @return view height in pixels
+     */
+    int getHeightForPosition(int position) {
+        final int firstVisiblePosition = getFirstVisiblePosition();
+        final int childCount = getChildCount();
+        final int index = position - firstVisiblePosition;
+        if (index >= 0 && index < childCount) {
+            // Position is on-screen, use existing view.
+            final View view = getChildAt(index);
+            return view.getHeight();
+        } else {
+            // Position is off-screen, obtain & recycle view.
+            final View view = obtainView(position, mIsScrap);
+            view.measure(mWidthMeasureSpec, MeasureSpec.UNSPECIFIED);
+            final int height = view.getMeasuredHeight();
+            mRecycler.addScrapView(view, position);
+            return height;
+        }
+    }
+
+    /**
+     * Sets the selected item and positions the selection y pixels from the top edge
+     * of the ListView. (If in touch mode, the item will not be selected but it will
+     * still be positioned appropriately.)
+     *
+     * @param position Index (starting at 0) of the data item to be selected.
+     * @param y The distance from the top edge of the ListView (plus padding) that the
+     *        item will be positioned.
+     */
+    public void setSelectionFromTop(int position, int y) {
+        if (mAdapter == null) {
+            return;
+        }
+
+        if (!isInTouchMode()) {
+            position = lookForSelectablePosition(position, true);
+            if (position >= 0) {
+                setNextSelectedPositionInt(position);
+            }
+        } else {
+            mResurrectToPosition = position;
+        }
+
+        if (position >= 0) {
+            mLayoutMode = LAYOUT_SPECIFIC;
+            mSpecificTop = mListPadding.top + y;
+
+            if (mNeedSync) {
+                mSyncPosition = position;
+                mSyncRowId = mAdapter.getItemId(position);
+            }
+
+            if (mPositionScroller != null) {
+                mPositionScroller.stop();
+            }
+            requestLayout();
+        }
+    }
+
+    /**
+     * Abstract positon scroller used to handle smooth scrolling.
+     */
+    static abstract class AbsPositionScroller {
+        public abstract void start(int position);
+        public abstract void start(int position, int boundPosition);
+        public abstract void startWithOffset(int position, int offset);
+        public abstract void startWithOffset(int position, int offset, int duration);
+        public abstract void stop();
+    }
+
+    /**
+     * Default position scroller that simulates a fling.
+     */
+    class PositionScroller extends AbsPositionScroller implements Runnable {
+        private static final int SCROLL_DURATION = 200;
+
+        private static final int MOVE_DOWN_POS = 1;
+        private static final int MOVE_UP_POS = 2;
+        private static final int MOVE_DOWN_BOUND = 3;
+        private static final int MOVE_UP_BOUND = 4;
+        private static final int MOVE_OFFSET = 5;
+
+        private int mMode;
+        private int mTargetPos;
+        private int mBoundPos;
+        private int mLastSeenPos;
+        private int mScrollDuration;
+        private final int mExtraScroll;
+
+        private int mOffsetFromTop;
+
+        PositionScroller() {
+            mExtraScroll = ViewConfiguration.get(mContext).getScaledFadingEdgeLength();
+        }
+
+        @Override
+        public void start(final int position) {
+            stop();
+
+            if (mDataChanged) {
+                // Wait until we're back in a stable state to try this.
+                mPositionScrollAfterLayout = new Runnable() {
+                    @Override public void run() {
+                        start(position);
+                    }
+                };
+                return;
+            }
+
+            final int childCount = getChildCount();
+            if (childCount == 0) {
+                // Can't scroll without children.
+                return;
+            }
+
+            final int firstPos = mFirstPosition;
+            final int lastPos = firstPos + childCount - 1;
+
+            int viewTravelCount;
+            int clampedPosition = Math.max(0, Math.min(getCount() - 1, position));
+            if (clampedPosition < firstPos) {
+                viewTravelCount = firstPos - clampedPosition + 1;
+                mMode = MOVE_UP_POS;
+            } else if (clampedPosition > lastPos) {
+                viewTravelCount = clampedPosition - lastPos + 1;
+                mMode = MOVE_DOWN_POS;
+            } else {
+                scrollToVisible(clampedPosition, INVALID_POSITION, SCROLL_DURATION);
+                return;
+            }
+
+            if (viewTravelCount > 0) {
+                mScrollDuration = SCROLL_DURATION / viewTravelCount;
+            } else {
+                mScrollDuration = SCROLL_DURATION;
+            }
+            mTargetPos = clampedPosition;
+            mBoundPos = INVALID_POSITION;
+            mLastSeenPos = INVALID_POSITION;
+
+            postOnAnimation(this);
+        }
+
+        @Override
+        public void start(final int position, final int boundPosition) {
+            stop();
+
+            if (boundPosition == INVALID_POSITION) {
+                start(position);
+                return;
+            }
+
+            if (mDataChanged) {
+                // Wait until we're back in a stable state to try this.
+                mPositionScrollAfterLayout = new Runnable() {
+                    @Override public void run() {
+                        start(position, boundPosition);
+                    }
+                };
+                return;
+            }
+
+            final int childCount = getChildCount();
+            if (childCount == 0) {
+                // Can't scroll without children.
+                return;
+            }
+
+            final int firstPos = mFirstPosition;
+            final int lastPos = firstPos + childCount - 1;
+
+            int viewTravelCount;
+            int clampedPosition = Math.max(0, Math.min(getCount() - 1, position));
+            if (clampedPosition < firstPos) {
+                final int boundPosFromLast = lastPos - boundPosition;
+                if (boundPosFromLast < 1) {
+                    // Moving would shift our bound position off the screen. Abort.
+                    return;
+                }
+
+                final int posTravel = firstPos - clampedPosition + 1;
+                final int boundTravel = boundPosFromLast - 1;
+                if (boundTravel < posTravel) {
+                    viewTravelCount = boundTravel;
+                    mMode = MOVE_UP_BOUND;
+                } else {
+                    viewTravelCount = posTravel;
+                    mMode = MOVE_UP_POS;
+                }
+            } else if (clampedPosition > lastPos) {
+                final int boundPosFromFirst = boundPosition - firstPos;
+                if (boundPosFromFirst < 1) {
+                    // Moving would shift our bound position off the screen. Abort.
+                    return;
+                }
+
+                final int posTravel = clampedPosition - lastPos + 1;
+                final int boundTravel = boundPosFromFirst - 1;
+                if (boundTravel < posTravel) {
+                    viewTravelCount = boundTravel;
+                    mMode = MOVE_DOWN_BOUND;
+                } else {
+                    viewTravelCount = posTravel;
+                    mMode = MOVE_DOWN_POS;
+                }
+            } else {
+                scrollToVisible(clampedPosition, boundPosition, SCROLL_DURATION);
+                return;
+            }
+
+            if (viewTravelCount > 0) {
+                mScrollDuration = SCROLL_DURATION / viewTravelCount;
+            } else {
+                mScrollDuration = SCROLL_DURATION;
+            }
+            mTargetPos = clampedPosition;
+            mBoundPos = boundPosition;
+            mLastSeenPos = INVALID_POSITION;
+
+            postOnAnimation(this);
+        }
+
+        @Override
+        public void startWithOffset(int position, int offset) {
+            startWithOffset(position, offset, SCROLL_DURATION);
+        }
+
+        @Override
+        public void startWithOffset(final int position, int offset, final int duration) {
+            stop();
+
+            if (mDataChanged) {
+                // Wait until we're back in a stable state to try this.
+                final int postOffset = offset;
+                mPositionScrollAfterLayout = new Runnable() {
+                    @Override public void run() {
+                        startWithOffset(position, postOffset, duration);
+                    }
+                };
+                return;
+            }
+
+            final int childCount = getChildCount();
+            if (childCount == 0) {
+                // Can't scroll without children.
+                return;
+            }
+
+            offset += getPaddingTop();
+
+            mTargetPos = Math.max(0, Math.min(getCount() - 1, position));
+            mOffsetFromTop = offset;
+            mBoundPos = INVALID_POSITION;
+            mLastSeenPos = INVALID_POSITION;
+            mMode = MOVE_OFFSET;
+
+            final int firstPos = mFirstPosition;
+            final int lastPos = firstPos + childCount - 1;
+
+            int viewTravelCount;
+            if (mTargetPos < firstPos) {
+                viewTravelCount = firstPos - mTargetPos;
+            } else if (mTargetPos > lastPos) {
+                viewTravelCount = mTargetPos - lastPos;
+            } else {
+                // On-screen, just scroll.
+                final int targetTop = getChildAt(mTargetPos - firstPos).getTop();
+                smoothScrollBy(targetTop - offset, duration, true);
+                return;
+            }
+
+            // Estimate how many screens we should travel
+            final float screenTravelCount = (float) viewTravelCount / childCount;
+            mScrollDuration = screenTravelCount < 1 ?
+                    duration : (int) (duration / screenTravelCount);
+            mLastSeenPos = INVALID_POSITION;
+
+            postOnAnimation(this);
+        }
+
+        /**
+         * Scroll such that targetPos is in the visible padded region without scrolling
+         * boundPos out of view. Assumes targetPos is onscreen.
+         */
+        private void scrollToVisible(int targetPos, int boundPos, int duration) {
+            final int firstPos = mFirstPosition;
+            final int childCount = getChildCount();
+            final int lastPos = firstPos + childCount - 1;
+            final int paddedTop = mListPadding.top;
+            final int paddedBottom = getHeight() - mListPadding.bottom;
+
+            if (targetPos < firstPos || targetPos > lastPos) {
+                Log.w(TAG, "scrollToVisible called with targetPos " + targetPos +
+                        " not visible [" + firstPos + ", " + lastPos + "]");
+            }
+            if (boundPos < firstPos || boundPos > lastPos) {
+                // boundPos doesn't matter, it's already offscreen.
+                boundPos = INVALID_POSITION;
+            }
+
+            final View targetChild = getChildAt(targetPos - firstPos);
+            final int targetTop = targetChild.getTop();
+            final int targetBottom = targetChild.getBottom();
+            int scrollBy = 0;
+
+            if (targetBottom > paddedBottom) {
+                scrollBy = targetBottom - paddedBottom;
+            }
+            if (targetTop < paddedTop) {
+                scrollBy = targetTop - paddedTop;
+            }
+
+            if (scrollBy == 0) {
+                return;
+            }
+
+            if (boundPos >= 0) {
+                final View boundChild = getChildAt(boundPos - firstPos);
+                final int boundTop = boundChild.getTop();
+                final int boundBottom = boundChild.getBottom();
+                final int absScroll = Math.abs(scrollBy);
+
+                if (scrollBy < 0 && boundBottom + absScroll > paddedBottom) {
+                    // Don't scroll the bound view off the bottom of the screen.
+                    scrollBy = Math.max(0, boundBottom - paddedBottom);
+                } else if (scrollBy > 0 && boundTop - absScroll < paddedTop) {
+                    // Don't scroll the bound view off the top of the screen.
+                    scrollBy = Math.min(0, boundTop - paddedTop);
+                }
+            }
+
+            smoothScrollBy(scrollBy, duration);
+        }
+
+        @Override
+        public void stop() {
+            removeCallbacks(this);
+        }
+
+        @Override
+        public void run() {
+            final int listHeight = getHeight();
+            final int firstPos = mFirstPosition;
+
+            switch (mMode) {
+            case MOVE_DOWN_POS: {
+                final int lastViewIndex = getChildCount() - 1;
+                final int lastPos = firstPos + lastViewIndex;
+
+                if (lastViewIndex < 0) {
+                    return;
+                }
+
+                if (lastPos == mLastSeenPos) {
+                    // No new views, let things keep going.
+                    postOnAnimation(this);
+                    return;
+                }
+
+                final View lastView = getChildAt(lastViewIndex);
+                final int lastViewHeight = lastView.getHeight();
+                final int lastViewTop = lastView.getTop();
+                final int lastViewPixelsShowing = listHeight - lastViewTop;
+                final int extraScroll = lastPos < mItemCount - 1 ?
+                        Math.max(mListPadding.bottom, mExtraScroll) : mListPadding.bottom;
+
+                final int scrollBy = lastViewHeight - lastViewPixelsShowing + extraScroll;
+                smoothScrollBy(scrollBy, mScrollDuration, true);
+
+                mLastSeenPos = lastPos;
+                if (lastPos < mTargetPos) {
+                    postOnAnimation(this);
+                }
+                break;
+            }
+
+            case MOVE_DOWN_BOUND: {
+                final int nextViewIndex = 1;
+                final int childCount = getChildCount();
+
+                if (firstPos == mBoundPos || childCount <= nextViewIndex
+                        || firstPos + childCount >= mItemCount) {
+                    return;
+                }
+                final int nextPos = firstPos + nextViewIndex;
+
+                if (nextPos == mLastSeenPos) {
+                    // No new views, let things keep going.
+                    postOnAnimation(this);
+                    return;
+                }
+
+                final View nextView = getChildAt(nextViewIndex);
+                final int nextViewHeight = nextView.getHeight();
+                final int nextViewTop = nextView.getTop();
+                final int extraScroll = Math.max(mListPadding.bottom, mExtraScroll);
+                if (nextPos < mBoundPos) {
+                    smoothScrollBy(Math.max(0, nextViewHeight + nextViewTop - extraScroll),
+                            mScrollDuration, true);
+
+                    mLastSeenPos = nextPos;
+
+                    postOnAnimation(this);
+                } else  {
+                    if (nextViewTop > extraScroll) {
+                        smoothScrollBy(nextViewTop - extraScroll, mScrollDuration, true);
+                    }
+                }
+                break;
+            }
+
+            case MOVE_UP_POS: {
+                if (firstPos == mLastSeenPos) {
+                    // No new views, let things keep going.
+                    postOnAnimation(this);
+                    return;
+                }
+
+                final View firstView = getChildAt(0);
+                if (firstView == null) {
+                    return;
+                }
+                final int firstViewTop = firstView.getTop();
+                final int extraScroll = firstPos > 0 ?
+                        Math.max(mExtraScroll, mListPadding.top) : mListPadding.top;
+
+                smoothScrollBy(firstViewTop - extraScroll, mScrollDuration, true);
+
+                mLastSeenPos = firstPos;
+
+                if (firstPos > mTargetPos) {
+                    postOnAnimation(this);
+                }
+                break;
+            }
+
+            case MOVE_UP_BOUND: {
+                final int lastViewIndex = getChildCount() - 2;
+                if (lastViewIndex < 0) {
+                    return;
+                }
+                final int lastPos = firstPos + lastViewIndex;
+
+                if (lastPos == mLastSeenPos) {
+                    // No new views, let things keep going.
+                    postOnAnimation(this);
+                    return;
+                }
+
+                final View lastView = getChildAt(lastViewIndex);
+                final int lastViewHeight = lastView.getHeight();
+                final int lastViewTop = lastView.getTop();
+                final int lastViewPixelsShowing = listHeight - lastViewTop;
+                final int extraScroll = Math.max(mListPadding.top, mExtraScroll);
+                mLastSeenPos = lastPos;
+                if (lastPos > mBoundPos) {
+                    smoothScrollBy(-(lastViewPixelsShowing - extraScroll), mScrollDuration, true);
+                    postOnAnimation(this);
+                } else {
+                    final int bottom = listHeight - extraScroll;
+                    final int lastViewBottom = lastViewTop + lastViewHeight;
+                    if (bottom > lastViewBottom) {
+                        smoothScrollBy(-(bottom - lastViewBottom), mScrollDuration, true);
+                    }
+                }
+                break;
+            }
+
+            case MOVE_OFFSET: {
+                if (mLastSeenPos == firstPos) {
+                    // No new views, let things keep going.
+                    postOnAnimation(this);
+                    return;
+                }
+
+                mLastSeenPos = firstPos;
+
+                final int childCount = getChildCount();
+                final int position = mTargetPos;
+                final int lastPos = firstPos + childCount - 1;
+
+                int viewTravelCount = 0;
+                if (position < firstPos) {
+                    viewTravelCount = firstPos - position + 1;
+                } else if (position > lastPos) {
+                    viewTravelCount = position - lastPos;
+                }
+
+                // Estimate how many screens we should travel
+                final float screenTravelCount = (float) viewTravelCount / childCount;
+
+                final float modifier = Math.min(Math.abs(screenTravelCount), 1.f);
+                if (position < firstPos) {
+                    final int distance = (int) (-getHeight() * modifier);
+                    final int duration = (int) (mScrollDuration * modifier);
+                    smoothScrollBy(distance, duration, true);
+                    postOnAnimation(this);
+                } else if (position > lastPos) {
+                    final int distance = (int) (getHeight() * modifier);
+                    final int duration = (int) (mScrollDuration * modifier);
+                    smoothScrollBy(distance, duration, true);
+                    postOnAnimation(this);
+                } else {
+                    // On-screen, just scroll.
+                    final int targetTop = getChildAt(position - firstPos).getTop();
+                    final int distance = targetTop - mOffsetFromTop;
+                    final int duration = (int) (mScrollDuration *
+                            ((float) Math.abs(distance) / getHeight()));
+                    smoothScrollBy(distance, duration, true);
+                }
+                break;
+            }
+
+            default:
+                break;
+            }
+        }
+    }
+
+    /**
+     * Abstract position scroller that handles sub-position scrolling but has no
+     * understanding of layout.
+     */
+    abstract class AbsSubPositionScroller extends AbsPositionScroller {
+        private static final int DEFAULT_SCROLL_DURATION = 200;
+
+        private final SubScroller mSubScroller = new SubScroller();
+
+        /**
+         * The target offset in pixels between the top of the list and the top
+         * of the target position.
+         */
+        private int mOffset;
+
+        /**
+         * Scroll the minimum amount to get the target view entirely on-screen.
+         */
+        private void scrollToPosition(final int targetPosition, final boolean useOffset,
+                final int offset, final int boundPosition, final int duration) {
+            stop();
+
+            if (mDataChanged) {
+                // Wait until we're back in a stable state to try this.
+                mPositionScrollAfterLayout = new Runnable() {
+                    @Override
+                    public void run() {
+                        scrollToPosition(
+                                targetPosition, useOffset, offset, boundPosition, duration);
+                    }
+                };
+                return;
+            }
+
+            final int firstPosition = getFirstVisiblePosition();
+            final int lastPosition = firstPosition + getChildCount();
+            final int targetRow = getRowForPosition(targetPosition);
+            final int firstRow = getRowForPosition(firstPosition);
+            final int lastRow = getRowForPosition(lastPosition);
+            if (useOffset || targetRow <= firstRow) {
+                // Offset so the target row is top-aligned.
+                mOffset = offset;
+            } else if (targetRow >= lastRow - 1) {
+                // Offset so the target row is bottom-aligned.
+                final int listHeight = getHeight() - getPaddingTop() - getPaddingBottom();
+                mOffset = listHeight - getHeightForPosition(targetPosition);
+            } else {
+                // Don't scroll, target is entirely on-screen.
+                return;
+            }
+
+            float endSubRow = targetRow;
+            if (boundPosition != INVALID_POSITION) {
+                final int boundRow = getRowForPosition(boundPosition);
+                if (boundRow >= firstRow && boundRow < lastRow && boundRow != targetRow) {
+                    endSubRow = computeBoundSubRow(targetRow, boundRow);
+                }
+            }
+
+            final View firstChild = getChildAt(0);
+            if (firstChild == null) {
+                return;
+            }
+
+            final int firstChildHeight = firstChild.getHeight();
+            final float startOffsetRatio;
+            if (firstChildHeight == 0) {
+                startOffsetRatio = 1;
+            } else {
+                startOffsetRatio = -firstChild.getTop() / (float) firstChildHeight;
+            }
+
+            final float startSubRow = firstRow + startOffsetRatio;
+            if (startSubRow == endSubRow && mOffset == 0) {
+                // Don't scroll, target is already in position.
+                return;
+            }
+
+            mSubScroller.startScroll(startSubRow, endSubRow, duration);
+
+            postOnAnimation(mAnimationFrame);
+        }
+
+        private float computeBoundSubRow(int targetRow, int boundRow) {
+            // If the final offset is greater than 0, we're aiming above the
+            // suggested target row. Compute the actual target row and offset
+            // within that row by subtracting the height of each preceeding row.
+            int remainingOffset = mOffset;
+            int targetHeight = getHeightForRow(targetRow);
+            while (targetRow > 0 && remainingOffset > targetHeight) {
+                targetRow--;
+                remainingOffset -= targetHeight;
+                targetHeight = getHeightForRow(targetRow);
+            }
+
+            // Compute the offset within the actual target row.
+            final float targetOffsetRatio;
+            if (targetHeight == 0) {
+                targetOffsetRatio = 1;
+            } else {
+                targetOffsetRatio = remainingOffset / (float) targetHeight;
+            }
+
+            // The final offset has been accounted for, reset it.
+            final float targetSubRow = targetRow - targetOffsetRatio;
+            mOffset = 0;
+
+            if (targetSubRow >= boundRow) {
+                // End position would push the bound position above the list.
+                return boundRow;
+            }
+
+            // Compute the closest possible sub-position that wouldn't push the
+            // bound position's view further below the list.
+            final int listHeight = getHeight() - getPaddingTop() - getPaddingBottom();
+            final int boundHeight = getHeightForRow(boundRow);
+            int endRow = boundRow;
+            int totalHeight = boundHeight;
+            int endHeight;
+            do {
+                endRow--;
+                endHeight = getHeightForRow(endRow);
+                totalHeight += endHeight;
+            } while (totalHeight < listHeight && endRow > 0);
+
+            final float endOffsetRatio;
+            if (endHeight == 0) {
+                endOffsetRatio = 1;
+            } else {
+                endOffsetRatio = (totalHeight - listHeight) / (float) endHeight;
+            }
+
+            final float boundSubRow = endRow + endOffsetRatio;
+            return Math.max(boundSubRow, targetSubRow);
+        }
+
+        @Override
+        public void start(int position) {
+            scrollToPosition(position, false, 0, INVALID_POSITION, DEFAULT_SCROLL_DURATION);
+        }
+
+        @Override
+        public void start(int position, int boundPosition) {
+            scrollToPosition(position, false, 0, boundPosition, DEFAULT_SCROLL_DURATION);
+        }
+
+        @Override
+        public void startWithOffset(int position, int offset) {
+            scrollToPosition(position, true, offset, INVALID_POSITION, DEFAULT_SCROLL_DURATION);
+        }
+
+        @Override
+        public void startWithOffset(int position, int offset, int duration) {
+            scrollToPosition(position, true, offset, INVALID_POSITION, duration);
+        }
+
+        @Override
+        public void stop() {
+            removeCallbacks(mAnimationFrame);
+        }
+
+        /**
+         * Returns the height of a row, which is computed as the maximum height of
+         * the items in the row.
+         *
+         * @param row the row index
+         * @return row height in pixels
+         */
+        public abstract int getHeightForRow(int row);
+
+        /**
+         * Returns the row for the specified item position.
+         *
+         * @param position the item position
+         * @return the row index
+         */
+        public abstract int getRowForPosition(int position);
+
+        /**
+         * Returns the first item position within the specified row.
+         *
+         * @param row the row
+         * @return the position of the first item in the row
+         */
+        public abstract int getFirstPositionForRow(int row);
+
+        private void onAnimationFrame() {
+            final boolean shouldPost = mSubScroller.computePosition();
+            final float subRow = mSubScroller.getPosition();
+
+            final int row = (int) subRow;
+            final int position = getFirstPositionForRow(row);
+            if (position >= getCount()) {
+                // Invalid position, abort scrolling.
+                return;
+            }
+
+            final int rowHeight = getHeightForRow(row);
+            final int offset = (int) (rowHeight * (subRow - row));
+            final int addOffset = (int) (mOffset * mSubScroller.getInterpolatedValue());
+            setSelectionFromTop(position, -offset + addOffset);
+
+            if (shouldPost) {
+                postOnAnimation(mAnimationFrame);
+            }
+        }
+
+        private Runnable mAnimationFrame = new Runnable() {
+            @Override
+            public void run() {
+                onAnimationFrame();
+            }
+        };
+    }
+
+    /**
+     * Scroller capable of returning floating point positions.
+     */
+    static class SubScroller {
+        private final Interpolator mInterpolator;
+
+        private float mStartPosition;
+        private float mEndPosition;
+        private long mStartTime;
+        private long mDuration;
+
+        private float mPosition;
+        private float mInterpolatedValue;
+
+        public SubScroller() {
+            this(null);
+        }
+
+        public SubScroller(Interpolator interpolator) {
+            if (interpolator == null) {
+                mInterpolator = new AccelerateDecelerateInterpolator();
+            } else {
+                mInterpolator = interpolator;
+            }
+        }
+
+        public void startScroll(float startPosition, float endPosition, int duration) {
+            mStartPosition = startPosition;
+            mEndPosition = endPosition;
+            mDuration = duration;
+
+            mStartTime = AnimationUtils.currentAnimationTimeMillis();
+            mPosition = startPosition;
+            mInterpolatedValue = 0;
+        }
+
+        public boolean computePosition() {
+            final long elapsed = AnimationUtils.currentAnimationTimeMillis() - mStartTime;
+            final float value;
+            if (mDuration <= 0) {
+                value = 1;
+            } else {
+                value = MathUtils.constrain(elapsed / (float) mDuration, 0, 1);
+            }
+
+            mInterpolatedValue = mInterpolator.getInterpolation(value);
+            mPosition = (mEndPosition - mStartPosition) * mInterpolatedValue + mStartPosition;
+
+            return elapsed < mDuration;
+        }
+
+        public float getPosition() {
+            return mPosition;
+        }
+
+        public float getInterpolatedValue() {
+            return mInterpolatedValue;
+        }
+    }
 }
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index acd711d..6743002 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -35,6 +35,8 @@
 import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
 import android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo;
 import android.view.animation.GridLayoutAnimationController;
+import android.widget.AbsListView.AbsPositionScroller;
+import android.widget.ListView.ListViewPositionScroller;
 import android.widget.RemoteViews.RemoteView;
 
 import java.lang.annotation.Retention;
@@ -1027,6 +1029,11 @@
     }
 
     @Override
+    AbsPositionScroller createPositionScroller() {
+        return new GridViewPositionScroller();
+    }
+
+    @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         // Sets up mListPadding
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -2317,7 +2324,9 @@
 
         final int columnsCount = getNumColumns();
         final int rowsCount = getCount() / columnsCount;
-        final CollectionInfo collectionInfo = CollectionInfo.obtain(columnsCount, rowsCount, false);
+        final int selectionMode = getSelectionModeForAccessibility();
+        final CollectionInfo collectionInfo = CollectionInfo.obtain(
+                columnsCount, rowsCount, false, selectionMode);
         info.setCollectionInfo(collectionInfo);
     }
 
@@ -2344,7 +2353,38 @@
 
         final LayoutParams lp = (LayoutParams) view.getLayoutParams();
         final boolean isHeading = lp != null && lp.viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER;
-        final CollectionItemInfo itemInfo = CollectionItemInfo.obtain(column, 1, row, 1, isHeading);
+        final boolean isSelected = isItemChecked(position);
+        final CollectionItemInfo itemInfo = CollectionItemInfo.obtain(
+                column, 1, row, 1, isHeading, isSelected);
         info.setCollectionItemInfo(itemInfo);
     }
+
+    /**
+     * Sub-position scroller that understands the layout of a GridView.
+     */
+    class GridViewPositionScroller extends AbsSubPositionScroller {
+        @Override
+        public int getRowForPosition(int position) {
+            return position / mNumColumns;
+        }
+
+        @Override
+        public int getFirstPositionForRow(int row) {
+            return row * mNumColumns;
+        }
+
+        @Override
+        public int getHeightForRow(int row) {
+            final int firstRowPosition = row * mNumColumns;
+            final int lastRowPosition = Math.min(getCount(), firstRowPosition + mNumColumns);
+            int maxHeight = 0;
+            for (int i = firstRowPosition; i < lastRowPosition; i++) {
+                final int height = getHeightForPosition(i);
+                if (height > maxHeight) {
+                    maxHeight = height;
+                }
+            }
+            return maxHeight;
+        }
+    }
 }
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index c461723..cef2138 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1892,45 +1892,6 @@
     }
 
     /**
-     * Sets the selected item and positions the selection y pixels from the top edge
-     * of the ListView. (If in touch mode, the item will not be selected but it will
-     * still be positioned appropriately.)
-     *
-     * @param position Index (starting at 0) of the data item to be selected.
-     * @param y The distance from the top edge of the ListView (plus padding) that the
-     *        item will be positioned.
-     */
-    public void setSelectionFromTop(int position, int y) {
-        if (mAdapter == null) {
-            return;
-        }
-
-        if (!isInTouchMode()) {
-            position = lookForSelectablePosition(position, true);
-            if (position >= 0) {
-                setNextSelectedPositionInt(position);
-            }
-        } else {
-            mResurrectToPosition = position;
-        }
-
-        if (position >= 0) {
-            mLayoutMode = LAYOUT_SPECIFIC;
-            mSpecificTop = mListPadding.top + y;
-
-            if (mNeedSync) {
-                mSyncPosition = position;
-                mSyncRowId = mAdapter.getItemId(position);
-            }
-
-            if (mPositionScroller != null) {
-                mPositionScroller.stop();
-            }
-            requestLayout();
-        }
-    }
-
-    /**
      * Makes the item at the supplied position selected.
      * 
      * @param position the position of the item to select
@@ -3746,6 +3707,79 @@
     }
 
     @Override
+    int getHeightForPosition(int position) {
+        final int height = super.getHeightForPosition(position);
+        if (shouldAdjustHeightForDivider(position)) {
+            return height + mDividerHeight;
+        }
+        return height;
+    }
+
+    private boolean shouldAdjustHeightForDivider(int itemIndex) {
+        final int dividerHeight = mDividerHeight;
+        final Drawable overscrollHeader = mOverScrollHeader;
+        final Drawable overscrollFooter = mOverScrollFooter;
+        final boolean drawOverscrollHeader = overscrollHeader != null;
+        final boolean drawOverscrollFooter = overscrollFooter != null;
+        final boolean drawDividers = dividerHeight > 0 && mDivider != null;
+
+        if (drawDividers) {
+            final boolean fillForMissingDividers = isOpaque() && !super.isOpaque();
+            final int itemCount = mItemCount;
+            final int headerCount = mHeaderViewInfos.size();
+            final int footerLimit = (itemCount - mFooterViewInfos.size());
+            final boolean isHeader = (itemIndex < headerCount);
+            final boolean isFooter = (itemIndex >= footerLimit);
+            final boolean headerDividers = mHeaderDividersEnabled;
+            final boolean footerDividers = mFooterDividersEnabled;
+            if ((headerDividers || !isHeader) && (footerDividers || !isFooter)) {
+                final ListAdapter adapter = mAdapter;
+                if (!mStackFromBottom) {
+                    final boolean isLastItem = (itemIndex == (itemCount - 1));
+                    if (!drawOverscrollFooter || !isLastItem) {
+                        final int nextIndex = itemIndex + 1;
+                        // Draw dividers between enabled items, headers
+                        // and/or footers when enabled and requested, and
+                        // after the last enabled item.
+                        if (adapter.isEnabled(itemIndex) && (headerDividers || !isHeader
+                                && (nextIndex >= headerCount)) && (isLastItem
+                                || adapter.isEnabled(nextIndex) && (footerDividers || !isFooter
+                                                && (nextIndex < footerLimit)))) {
+                            return true;
+                        } else if (fillForMissingDividers) {
+                            return true;
+                        }
+                    }
+                } else {
+                    final int start = drawOverscrollHeader ? 1 : 0;
+                    final boolean isFirstItem = (itemIndex == start);
+                    if (!isFirstItem) {
+                        final int previousIndex = (itemIndex - 1);
+                        // Draw dividers between enabled items, headers
+                        // and/or footers when enabled and requested, and
+                        // before the first enabled item.
+                        if (adapter.isEnabled(itemIndex) && (headerDividers || !isHeader
+                                && (previousIndex >= headerCount)) && (isFirstItem ||
+                                adapter.isEnabled(previousIndex) && (footerDividers || !isFooter
+                                        && (previousIndex < footerLimit)))) {
+                            return true;
+                        } else if (fillForMissingDividers) {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    AbsPositionScroller createPositionScroller() {
+        return new ListViewPositionScroller();
+    }
+
+    @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
         event.setClassName(ListView.class.getName());
@@ -3757,7 +3791,8 @@
         info.setClassName(ListView.class.getName());
 
         final int count = getCount();
-        final CollectionInfo collectionInfo = CollectionInfo.obtain(1, count, false);
+        final int selectionMode = getSelectionModeForAccessibility();
+        final CollectionInfo collectionInfo = CollectionInfo.obtain(1, count, false, selectionMode);
         info.setCollectionInfo(collectionInfo);
     }
 
@@ -3768,7 +3803,29 @@
 
         final LayoutParams lp = (LayoutParams) view.getLayoutParams();
         final boolean isHeading = lp != null && lp.viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER;
-        final CollectionItemInfo itemInfo = CollectionItemInfo.obtain(0, 1, position, 1, isHeading);
+        final boolean isSelected = isItemChecked(position);
+        final CollectionItemInfo itemInfo = CollectionItemInfo.obtain(
+                0, 1, position, 1, isHeading, isSelected);
         info.setCollectionItemInfo(itemInfo);
     }
+
+    /**
+     * Sub-position scroller that understands the layout of a ListView.
+     */
+    class ListViewPositionScroller extends AbsSubPositionScroller {
+        @Override
+        public int getRowForPosition(int position) {
+            return position;
+        }
+
+        @Override
+        public int getFirstPositionForRow(int row) {
+            return row;
+        }
+
+        @Override
+        public int getHeightForRow(int row) {
+            return getHeightForPosition(row);
+        }
+    }
 }
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index bebe67f..90e80d3 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -748,14 +748,14 @@
         // measurement is code for, "we got an unspecified mode in the
         // RelativeLayout's measure spec."
         if (mySize < 0 && !mAllowBrokenMeasureSpecs) {
-            if (childSize >= 0) {
-                // The child specified an exact size.
-                childSpecSize = childSize;
-                childSpecMode = MeasureSpec.EXACTLY;
-            } else if (childStart >= 0 && childEnd >= 0) {
+            if (childStart >= 0 && childEnd >= 0) {
                 // Constraints fixed both edges, so child has an exact size.
                 childSpecSize = Math.max(0, childEnd - childStart);
                 childSpecMode = MeasureSpec.EXACTLY;
+            } else if (childSize >= 0) {
+                // The child specified an exact size.
+                childSpecSize = childSize;
+                childSpecMode = MeasureSpec.EXACTLY;
             } else {
                 // Allow the child to be whatever size it wants.
                 childSpecSize = 0;
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index b204dfd..1cda631 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -731,10 +731,14 @@
                 }
             }
 
-            if (scheduleOtherSpellCheck) {
+            if (scheduleOtherSpellCheck && wordStart <= end) {
                 // Update range span: start new spell check from last wordStart
                 setRangeSpan(editable, wordStart, end);
             } else {
+                if (DBG && scheduleOtherSpellCheck) {
+                    Log.w(TAG, "Trying to schedule spellcheck for invalid region, from "
+                            + wordStart + " to " + end);
+                }
                 removeRangeSpan(editable);
             }
 
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 65b79fc..e5cb16f 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -5809,6 +5809,7 @@
                 int end = text.partialEndOffset;
                 if (end > N) end = N;
                 removeParcelableSpans(content, start, end);
+                // If start > end, content.replace will swap them before using them.
                 content.replace(start, end, text.text);
             }
         }
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 9a04760..1155cbb 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -51,6 +51,7 @@
     void noteScreenOff();
     void noteInputEvent();
     void noteUserActivity(int uid, int event);
+    void noteDataConnectionActive(String label, boolean active);
     void notePhoneOn();
     void notePhoneOff();
     void notePhoneSignalStrength(in SignalStrength signalStrength);
@@ -61,8 +62,10 @@
     void noteWifiRunning(in WorkSource ws);
     void noteWifiRunningChanged(in WorkSource oldWs, in WorkSource newWs);
     void noteWifiStopped(in WorkSource ws);
+    void noteWifiState(int wifiState, String accessPoint);
     void noteBluetoothOn();
     void noteBluetoothOff();
+    void noteBluetoothState(int bluetoothState);
     void noteFullWifiLockAcquired(int uid);
     void noteFullWifiLockReleased(int uid);
     void noteWifiScanStarted(int uid);
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
index 4dd4a45..b1535e3 100644
--- a/core/java/com/android/internal/app/ProcessStats.java
+++ b/core/java/com/android/internal/app/ProcessStats.java
@@ -1018,7 +1018,7 @@
                     for (int iproc=pkgState.mProcesses.size()-1; iproc>=0; iproc--) {
                         final ProcessState ps = pkgState.mProcesses.valueAt(iproc);
                         if (ps.isInUse()) {
-                            pkgState.mProcesses.valueAt(iproc).resetSafely(now);
+                            ps.resetSafely(now);
                             ps.mCommonProcess.mTmpNumInUse++;
                             ps.mCommonProcess.mTmpFoundSubProc = ps;
                         } else {
@@ -1029,7 +1029,7 @@
                     for (int isvc=pkgState.mServices.size()-1; isvc>=0; isvc--) {
                         final ServiceState ss = pkgState.mServices.valueAt(isvc);
                         if (ss.isInUse()) {
-                            pkgState.mServices.valueAt(isvc).resetSafely(now);
+                            ss.resetSafely(now);
                         } else {
                             pkgState.mServices.removeAt(isvc);
                         }
@@ -3142,7 +3142,7 @@
         }
 
         public boolean isInUse() {
-            return mOwner != null;
+            return mOwner != null || mRestarting;
         }
 
         void add(ServiceState other) {
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index c22a5e9..8a15c99 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -640,7 +640,8 @@
         final long mobileTx = mStats.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, mStatsType);
         final long mobileData = mobileRx + mobileTx;
 
-        final long radioDataUptimeMs = mStats.getRadioDataUptime() / 1000;
+        final long radioDataUptimeMs
+                = mStats.getMobileRadioActiveTime(mBatteryRealtime, mStatsType) / 1000;
         final double mobilePps = radioDataUptimeMs != 0
                 ? mobileData / (double)radioDataUptimeMs
                 : (((double)MOBILE_BPS) / 8 / 2048);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 82dcbdb..155f062 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -55,11 +55,9 @@
 import com.android.internal.util.JournaledFile;
 import com.google.android.collect.Sets;
 
-import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
-import java.io.FileReader;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -88,7 +86,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS'
 
     // Current on-disk Parcel version
-    private static final int VERSION = 79 + (USE_OLD_HISTORY ? 1000 : 0);
+    private static final int VERSION = 84 + (USE_OLD_HISTORY ? 1000 : 0);
 
     // Maximum number of items we will record in the history.
     private static final int MAX_HISTORY_ITEMS = 2000;
@@ -273,9 +271,18 @@
     boolean mGlobalWifiRunning;
     StopwatchTimer mGlobalWifiRunningTimer;
 
+    int mWifiState = -1;
+    final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES];
+
     boolean mBluetoothOn;
     StopwatchTimer mBluetoothOnTimer;
 
+    int mBluetoothState = -1;
+    final StopwatchTimer[] mBluetoothStateTimer = new StopwatchTimer[NUM_BLUETOOTH_STATES];
+
+    boolean mMobileRadioActive;
+    StopwatchTimer mMobileRadioActiveTimer;
+
     /** Bluetooth headset object */
     BluetoothHeadset mBtHeadset;
 
@@ -310,9 +317,6 @@
 
     long mLastWriteTime = 0; // Milliseconds
 
-    private long mRadioDataUptime;
-    private long mRadioDataStart;
-
     private int mBluetoothPingCount;
     private int mBluetoothPingStart = -1;
 
@@ -1164,10 +1168,9 @@
                     + " mAcquireTime=" + mAcquireTime);
         }
 
-        void startRunningLocked(BatteryStatsImpl stats) {
+        void startRunningLocked(BatteryStatsImpl stats, long elapsedRealtime) {
             if (mNesting++ == 0) {
-                mUpdateTime = stats.getBatteryRealtimeLocked(
-                        SystemClock.elapsedRealtime() * 1000);
+                mUpdateTime = stats.getBatteryRealtimeLocked(elapsedRealtime * 1000);
                 if (mTimerPool != null) {
                     // Accumulate time to all currently active timers before adding
                     // this new one to the pool.
@@ -1190,7 +1193,7 @@
             return mNesting > 0;
         }
 
-        void stopRunningLocked(BatteryStatsImpl stats) {
+        void stopRunningLocked(BatteryStatsImpl stats, long elapsedRealtime) {
             // Ignore attempt to stop a timer that isn't running
             if (mNesting == 0) {
                 return;
@@ -1203,8 +1206,8 @@
                     // Remove this timer from the active pool
                     mTimerPool.remove(this);
                 } else {
-                    final long realtime = SystemClock.elapsedRealtime() * 1000;
-                    final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
+                    final long batteryRealtime = stats.getBatteryRealtimeLocked(
+                            elapsedRealtime * 1000);
                     mNesting = 1;
                     mTotalTime = computeRunTimeLocked(batteryRealtime);
                     mNesting = 0;
@@ -1432,44 +1435,6 @@
         return kwlt;
     }
 
-    /**
-     * Radio uptime in microseconds when transferring data. This value is very approximate.
-     * @return
-     */
-    private long getCurrentRadioDataUptime() {
-        try {
-            File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
-            if (!awakeTimeFile.exists()) return 0;
-            BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
-            String line = br.readLine();
-            br.close();
-            return Long.parseLong(line) * 1000;
-        } catch (NumberFormatException nfe) {
-            // Nothing
-        } catch (IOException ioe) {
-            // Nothing
-        }
-        return 0;
-    }
-
-    /**
-     * @deprecated use getRadioDataUptime
-     */
-    public long getRadioDataUptimeMs() {
-        return getRadioDataUptime() / 1000;
-    }
-
-    /**
-     * Returns the duration that the cell radio was up for data transfers.
-     */
-    public long getRadioDataUptime() {
-        if (mRadioDataStart == -1) {
-            return mRadioDataUptime;
-        } else {
-            return getCurrentRadioDataUptime() - mRadioDataStart;
-        }
-    }
-
     private int getCurrentBluetoothPingCount() {
         if (mBtHeadset != null) {
             List<BluetoothDevice> deviceList = mBtHeadset.getConnectedDevices();
@@ -1520,14 +1485,16 @@
     }
 
     // Part of initial delta int that specifies the time delta.
-    static final int DELTA_TIME_MASK = 0xfffff;
-    static final int DELTA_TIME_LONG = 0xfffff;   // The delta is a following long
-    static final int DELTA_TIME_INT = 0xffffe;    // The delta is a following int
-    static final int DELTA_TIME_ABS = 0xffffd;    // Following is an entire abs update.
+    static final int DELTA_TIME_MASK = 0x7ffff;
+    static final int DELTA_TIME_LONG = 0x7ffff;   // The delta is a following long
+    static final int DELTA_TIME_INT = 0x7fffe;    // The delta is a following int
+    static final int DELTA_TIME_ABS = 0x7fffd;    // Following is an entire abs update.
     // Flag in delta int: a new battery level int follows.
-    static final int DELTA_BATTERY_LEVEL_FLAG   = 0x00100000;
+    static final int DELTA_BATTERY_LEVEL_FLAG   = 0x00080000;
     // Flag in delta int: a new full state and battery status int follows.
-    static final int DELTA_STATE_FLAG           = 0x00200000;
+    static final int DELTA_STATE_FLAG           = 0x00100000;
+    // Flag in delta int: a new full state2 int follows.
+    static final int DELTA_STATE2_FLAG          = 0x00200000;
     // Flag in delta int: contains a wakelock tag.
     static final int DELTA_WAKELOCK_FLAG        = 0x00400000;
     // Flag in delta int: contains an event description.
@@ -1963,10 +1930,6 @@
             mUnpluggables.get(i).unplug(elapsedRealtime, batteryUptime, batteryRealtime);
         }
 
-        // Track radio awake time
-        mRadioDataStart = getCurrentRadioDataUptime();
-        mRadioDataUptime = 0;
-
         // Track bt headset ping count
         mBluetoothPingStart = getCurrentBluetoothPingCount();
         mBluetoothPingCount = 0;
@@ -1977,10 +1940,6 @@
             mUnpluggables.get(i).plug(elapsedRealtime, batteryUptime, batteryRealtime);
         }
 
-        // Track radio awake time
-        mRadioDataUptime = getRadioDataUptime();
-        mRadioDataStart = -1;
-
         // Track bt headset ping count
         mBluetoothPingCount = getBluetoothPingCount();
         mBluetoothPingStart = -1;
@@ -2049,6 +2008,7 @@
     public void noteStartWakeLocked(int uid, int pid, String name, int type,
             boolean unimportantForLogging) {
         uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         if (type == WAKE_TYPE_PARTIAL) {
             // Only care about partial wake locks, since full wake locks
             // will be canceled when the user puts the screen to sleep.
@@ -2060,7 +2020,7 @@
                 mHistoryCur.wakelockTag.string = name;
                 mHistoryCur.wakelockTag.uid = uid;
                 mWakeLockImportant = !unimportantForLogging;
-                addHistoryRecordLocked(SystemClock.elapsedRealtime());
+                addHistoryRecordLocked(elapsedRealtime);
             } else if (!mWakeLockImportant && !unimportantForLogging) {
                 if (mHistoryLastWritten.wakelockTag != null) {
                     // We'll try to update the last tag.
@@ -2068,7 +2028,7 @@
                     mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
                     mHistoryCur.wakelockTag.string = name;
                     mHistoryCur.wakelockTag.uid = uid;
-                    addHistoryRecordLocked(SystemClock.elapsedRealtime());
+                    addHistoryRecordLocked(elapsedRealtime);
                 }
                 mWakeLockImportant = true;
             }
@@ -2079,19 +2039,20 @@
                 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
                 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
             }
-            getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type);
+            getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime);
         }
     }
 
     public void noteStopWakeLocked(int uid, int pid, String name, int type) {
         uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         if (type == WAKE_TYPE_PARTIAL) {
             mWakeLockNesting--;
             if (mWakeLockNesting == 0) {
                 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
                 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
                         + Integer.toHexString(mHistoryCur.states));
-                addHistoryRecordLocked(SystemClock.elapsedRealtime());
+                addHistoryRecordLocked(elapsedRealtime);
             }
         }
         if (uid >= 0) {
@@ -2099,7 +2060,7 @@
                 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
                 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
             }
-            getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type);
+            getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime);
         }
     }
 
@@ -2256,64 +2217,70 @@
 
     public void noteStartSensorLocked(int uid, int sensor) {
         uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         if (mSensorNesting == 0) {
             mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
         }
         mSensorNesting++;
-        getUidStatsLocked(uid).noteStartSensor(sensor);
+        getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime);
     }
 
     public void noteStopSensorLocked(int uid, int sensor) {
         uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         mSensorNesting--;
         if (mSensorNesting == 0) {
             mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
         }
-        getUidStatsLocked(uid).noteStopSensor(sensor);
+        getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime);
     }
 
     int mGpsNesting;
 
     public void noteStartGpsLocked(int uid) {
         uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         if (mGpsNesting == 0) {
             mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
         }
         mGpsNesting++;
-        getUidStatsLocked(uid).noteStartGps();
+        getUidStatsLocked(uid).noteStartGps(elapsedRealtime);
     }
 
     public void noteStopGpsLocked(int uid) {
         uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         mGpsNesting--;
         if (mGpsNesting == 0) {
             mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
         }
-        getUidStatsLocked(uid).noteStopGps();
+        getUidStatsLocked(uid).noteStopGps(elapsedRealtime);
     }
 
     public void noteScreenOnLocked() {
         if (!mScreenOn) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
             mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
             mScreenOn = true;
-            mScreenOnTimer.startRunningLocked(this);
+            mScreenOnTimer.startRunningLocked(this, elapsedRealtime);
             if (mScreenBrightnessBin >= 0) {
-                mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
+                mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this,
+                        elapsedRealtime);
             }
 
             // Fake a wake lock, so we consider the device waked as long
@@ -2329,14 +2296,16 @@
 
     public void noteScreenOffLocked() {
         if (mScreenOn) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
             mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
             mScreenOn = false;
-            mScreenOnTimer.stopRunningLocked(this);
+            mScreenOnTimer.stopRunningLocked(this, elapsedRealtime);
             if (mScreenBrightnessBin >= 0) {
-                mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
+                mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this,
+                        elapsedRealtime);
             }
 
             noteStopWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
@@ -2354,16 +2323,18 @@
         if (bin < 0) bin = 0;
         else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
         if (mScreenBrightnessBin != bin) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
             mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
                     | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
             if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
             if (mScreenOn) {
                 if (mScreenBrightnessBin >= 0) {
-                    mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
+                    mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this,
+                            elapsedRealtime);
                 }
-                mScreenBrightnessTimer[bin].startRunningLocked(this);
+                mScreenBrightnessTimer[bin].startRunningLocked(this, elapsedRealtime);
             }
             mScreenBrightnessBin = bin;
         }
@@ -2378,35 +2349,60 @@
         getUidStatsLocked(uid).noteUserActivityLocked(event);
     }
 
+    public void noteDataConnectionActive(String label, boolean active) {
+        try {
+            int type = Integer.parseInt(label);
+            if (ConnectivityManager.isNetworkTypeMobile(type)) {
+                final long elapsedRealtime = SystemClock.elapsedRealtime();
+                if (mMobileRadioActive != active) {
+                    if (active) mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
+                    else mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
+                    if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
+                            + Integer.toHexString(mHistoryCur.states));
+                    addHistoryRecordLocked(elapsedRealtime);
+                    mMobileRadioActive = active;
+                    if (active) mMobileRadioActiveTimer.startRunningLocked(this, elapsedRealtime);
+                    else mMobileRadioActiveTimer.stopRunningLocked(this, elapsedRealtime);
+                }
+            }
+        } catch (NumberFormatException e) {
+            Slog.w(TAG, "Bad data connection label: " + label, e);
+            return;
+        }
+    }
+
     public void notePhoneOnLocked() {
         if (!mPhoneOn) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
             mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
             mPhoneOn = true;
-            mPhoneOnTimer.startRunningLocked(this);
+            mPhoneOnTimer.startRunningLocked(this, elapsedRealtime);
         }
     }
 
     public void notePhoneOffLocked() {
         if (mPhoneOn) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
             mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
             mPhoneOn = false;
-            mPhoneOnTimer.stopRunningLocked(this);
+            mPhoneOnTimer.stopRunningLocked(this, elapsedRealtime);
         }
     }
 
     void stopAllSignalStrengthTimersLocked(int except) {
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
             if (i == except) {
                 continue;
             }
             while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
-                mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
+                mPhoneSignalStrengthsTimer[i].stopRunningLocked(this, elapsedRealtime);
             }
         }
     }
@@ -2424,26 +2420,28 @@
         return state;
     }
 
-    private void updateAllPhoneStateLocked(int state, int simState, int bin) {
+    private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) {
         boolean scanning = false;
         boolean newHistory = false;
 
         mPhoneServiceStateRaw = state;
         mPhoneSimStateRaw = simState;
-        mPhoneSignalStrengthBinRaw = bin;
+        mPhoneSignalStrengthBinRaw = strengthBin;
+
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
 
         if (simState == TelephonyManager.SIM_STATE_ABSENT) {
             // In this case we will always be STATE_OUT_OF_SERVICE, so need
             // to infer that we are scanning from other data.
             if (state == ServiceState.STATE_OUT_OF_SERVICE
-                    && bin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+                    && strengthBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
                 state = ServiceState.STATE_IN_SERVICE;
             }
         }
 
         // If the phone is powered off, stop all timers.
         if (state == ServiceState.STATE_POWER_OFF) {
-            bin = -1;
+            strengthBin = -1;
 
         // If we are in service, make sure the correct signal string timer is running.
         } else if (state == ServiceState.STATE_IN_SERVICE) {
@@ -2453,13 +2451,13 @@
         // bin and have the scanning bit set.
         } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
             scanning = true;
-            bin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+            strengthBin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
             if (!mPhoneSignalScanningTimer.isRunningLocked()) {
                 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
                 newHistory = true;
                 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
                         + Integer.toHexString(mHistoryCur.states));
-                mPhoneSignalScanningTimer.startRunningLocked(this);
+                mPhoneSignalScanningTimer.startRunningLocked(this, elapsedRealtime);
             }
         }
 
@@ -2470,7 +2468,7 @@
                 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
                         + Integer.toHexString(mHistoryCur.states));
                 newHistory = true;
-                mPhoneSignalScanningTimer.stopRunningLocked(this);
+                mPhoneSignalScanningTimer.stopRunningLocked(this, elapsedRealtime);
             }
         }
 
@@ -2483,27 +2481,29 @@
             mPhoneServiceState = state;
         }
 
-        if (mPhoneSignalStrengthBin != bin) {
+        if (mPhoneSignalStrengthBin != strengthBin) {
             if (mPhoneSignalStrengthBin >= 0) {
-                mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
+                mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this,
+                        elapsedRealtime);
             }
-            if (bin >= 0) {
-                if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
-                    mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
+            if (strengthBin >= 0) {
+                if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) {
+                    mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(this,
+                            elapsedRealtime);
                 }
                 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
-                        | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
-                if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: "
+                        | (strengthBin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
+                if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: "
                         + Integer.toHexString(mHistoryCur.states));
                 newHistory = true;
             } else {
                 stopAllSignalStrengthTimersLocked(-1);
             }
-            mPhoneSignalStrengthBin = bin;
+            mPhoneSignalStrengthBin = strengthBin;
         }
 
         if (newHistory) {
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
         }
     }
 
@@ -2577,105 +2577,113 @@
         }
         if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
         if (mPhoneDataConnectionType != bin) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
             mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
                     | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
             if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
             if (mPhoneDataConnectionType >= 0) {
-                mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
+                mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this,
+                        elapsedRealtime);
             }
             mPhoneDataConnectionType = bin;
-            mPhoneDataConnectionsTimer[bin].startRunningLocked(this);
+            mPhoneDataConnectionsTimer[bin].startRunningLocked(this, elapsedRealtime);
         }
     }
 
     public void noteWifiOnLocked() {
         if (!mWifiOn) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
             mHistoryCur.states |= HistoryItem.STATE_WIFI_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
             mWifiOn = true;
-            mWifiOnTimer.startRunningLocked(this);
+            mWifiOnTimer.startRunningLocked(this, elapsedRealtime);
         }
     }
 
     public void noteWifiOffLocked() {
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         if (mWifiOn) {
             mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
             mWifiOn = false;
-            mWifiOnTimer.stopRunningLocked(this);
+            mWifiOnTimer.stopRunningLocked(this, elapsedRealtime);
         }
         if (mWifiOnUid >= 0) {
-            getUidStatsLocked(mWifiOnUid).noteWifiStoppedLocked();
+            getUidStatsLocked(mWifiOnUid).noteWifiStoppedLocked(elapsedRealtime);
             mWifiOnUid = -1;
         }
     }
 
     public void noteAudioOnLocked(int uid) {
         uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         if (!mAudioOn) {
             mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
                     + Integer.toHexString(mHistoryCur.states));
             addHistoryRecordLocked(SystemClock.elapsedRealtime());
             mAudioOn = true;
-            mAudioOnTimer.startRunningLocked(this);
+            mAudioOnTimer.startRunningLocked(this, elapsedRealtime);
         }
-        getUidStatsLocked(uid).noteAudioTurnedOnLocked();
+        getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime);
     }
 
     public void noteAudioOffLocked(int uid) {
         uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         if (mAudioOn) {
             mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
                     + Integer.toHexString(mHistoryCur.states));
             addHistoryRecordLocked(SystemClock.elapsedRealtime());
             mAudioOn = false;
-            mAudioOnTimer.stopRunningLocked(this);
+            mAudioOnTimer.stopRunningLocked(this, elapsedRealtime);
         }
-        getUidStatsLocked(uid).noteAudioTurnedOffLocked();
+        getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime);
     }
 
     public void noteVideoOnLocked(int uid) {
         uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         if (!mVideoOn) {
             mHistoryCur.states |= HistoryItem.STATE_VIDEO_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
                     + Integer.toHexString(mHistoryCur.states));
             addHistoryRecordLocked(SystemClock.elapsedRealtime());
             mVideoOn = true;
-            mVideoOnTimer.startRunningLocked(this);
+            mVideoOnTimer.startRunningLocked(this, elapsedRealtime);
         }
-        getUidStatsLocked(uid).noteVideoTurnedOnLocked();
+        getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime);
     }
 
     public void noteVideoOffLocked(int uid) {
         uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         if (mVideoOn) {
             mHistoryCur.states &= ~HistoryItem.STATE_VIDEO_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
                     + Integer.toHexString(mHistoryCur.states));
             addHistoryRecordLocked(SystemClock.elapsedRealtime());
             mVideoOn = false;
-            mVideoOnTimer.stopRunningLocked(this);
+            mVideoOnTimer.stopRunningLocked(this, elapsedRealtime);
         }
-        getUidStatsLocked(uid).noteVideoTurnedOffLocked();
+        getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime);
     }
 
     public void noteActivityResumedLocked(int uid) {
         uid = mapUid(uid);
-        getUidStatsLocked(uid).noteActivityResumedLocked();
+        getUidStatsLocked(uid).noteActivityResumedLocked(SystemClock.elapsedRealtime());
     }
 
     public void noteActivityPausedLocked(int uid) {
         uid = mapUid(uid);
-        getUidStatsLocked(uid).noteActivityPausedLocked();
+        getUidStatsLocked(uid).noteActivityPausedLocked(SystemClock.elapsedRealtime());
     }
 
     public void noteVibratorOnLocked(int uid, long durationMillis) {
@@ -2690,16 +2698,17 @@
 
     public void noteWifiRunningLocked(WorkSource ws) {
         if (!mGlobalWifiRunning) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
             mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
                     + Integer.toHexString(mHistoryCur.states));
             addHistoryRecordLocked(SystemClock.elapsedRealtime());
             mGlobalWifiRunning = true;
-            mGlobalWifiRunningTimer.startRunningLocked(this);
+            mGlobalWifiRunningTimer.startRunningLocked(this, elapsedRealtime);
             int N = ws.size();
             for (int i=0; i<N; i++) {
                 int uid = mapUid(ws.get(i));
-                getUidStatsLocked(uid).noteWifiRunningLocked();
+                getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
             }
         } else {
             Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
@@ -2708,15 +2717,16 @@
 
     public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
         if (mGlobalWifiRunning) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
             int N = oldWs.size();
             for (int i=0; i<N; i++) {
                 int uid = mapUid(oldWs.get(i));
-                getUidStatsLocked(uid).noteWifiStoppedLocked();
+                getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
             }
             N = newWs.size();
             for (int i=0; i<N; i++) {
                 int uid = mapUid(newWs.get(i));
-                getUidStatsLocked(uid).noteWifiRunningLocked();
+                getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
             }
         } else {
             Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
@@ -2725,41 +2735,69 @@
 
     public void noteWifiStoppedLocked(WorkSource ws) {
         if (mGlobalWifiRunning) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
             mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
             mGlobalWifiRunning = false;
-            mGlobalWifiRunningTimer.stopRunningLocked(this);
+            mGlobalWifiRunningTimer.stopRunningLocked(this, elapsedRealtime);
             int N = ws.size();
             for (int i=0; i<N; i++) {
                 int uid = mapUid(ws.get(i));
-                getUidStatsLocked(uid).noteWifiStoppedLocked();
+                getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
             }
         } else {
             Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
         }
     }
 
+    public void noteWifiStateLocked(int wifiState, String accessPoint) {
+        if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState);
+        if (mWifiState != wifiState) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            if (mWifiState >= 0) {
+                mWifiStateTimer[mWifiState].stopRunningLocked(this, elapsedRealtime);
+            }
+            mWifiState = wifiState;
+            mWifiStateTimer[wifiState].startRunningLocked(this, elapsedRealtime);
+        }
+    }
+
     public void noteBluetoothOnLocked() {
         if (!mBluetoothOn) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
             mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
             mBluetoothOn = true;
-            mBluetoothOnTimer.startRunningLocked(this);
+            mBluetoothOnTimer.startRunningLocked(this, elapsedRealtime);
         }
     }
 
     public void noteBluetoothOffLocked() {
         if (mBluetoothOn) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
             mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
             mBluetoothOn = false;
-            mBluetoothOnTimer.stopRunningLocked(this);
+            mBluetoothOnTimer.stopRunningLocked(this, elapsedRealtime);
+        }
+    }
+
+    public void noteBluetoothStateLocked(int bluetoothState) {
+        if (DEBUG) Log.i(TAG, "Bluetooth state -> " + bluetoothState);
+        if (mBluetoothState != bluetoothState) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            if (mBluetoothState >= 0) {
+                mBluetoothStateTimer[mBluetoothState].stopRunningLocked(this,
+                        elapsedRealtime);
+            }
+            mBluetoothState = bluetoothState;
+            mBluetoothStateTimer[bluetoothState].startRunningLocked(this, elapsedRealtime);
         }
     }
 
@@ -2767,88 +2805,96 @@
 
     public void noteFullWifiLockAcquiredLocked(int uid) {
         uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         if (mWifiFullLockNesting == 0) {
             mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
         }
         mWifiFullLockNesting++;
-        getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked();
+        getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime);
     }
 
     public void noteFullWifiLockReleasedLocked(int uid) {
         uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         mWifiFullLockNesting--;
         if (mWifiFullLockNesting == 0) {
             mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
         }
-        getUidStatsLocked(uid).noteFullWifiLockReleasedLocked();
+        getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime);
     }
 
     int mWifiScanNesting = 0;
 
     public void noteWifiScanStartedLocked(int uid) {
         uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         if (mWifiScanNesting == 0) {
             mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
         }
         mWifiScanNesting++;
-        getUidStatsLocked(uid).noteWifiScanStartedLocked();
+        getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime);
     }
 
     public void noteWifiScanStoppedLocked(int uid) {
         uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         mWifiScanNesting--;
         if (mWifiScanNesting == 0) {
             mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
         }
-        getUidStatsLocked(uid).noteWifiScanStoppedLocked();
+        getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime);
     }
 
     public void noteWifiBatchedScanStartedLocked(int uid, int csph) {
         uid = mapUid(uid);
-        getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime);
     }
 
     public void noteWifiBatchedScanStoppedLocked(int uid) {
         uid = mapUid(uid);
-        getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked();
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime);
     }
 
     int mWifiMulticastNesting = 0;
 
     public void noteWifiMulticastEnabledLocked(int uid) {
         uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         if (mWifiMulticastNesting == 0) {
             mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
         }
         mWifiMulticastNesting++;
-        getUidStatsLocked(uid).noteWifiMulticastEnabledLocked();
+        getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime);
     }
 
     public void noteWifiMulticastDisabledLocked(int uid) {
         uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         mWifiMulticastNesting--;
         if (mWifiMulticastNesting == 0) {
             mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime);
         }
-        getUidStatsLocked(uid).noteWifiMulticastDisabledLocked();
+        getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime);
     }
 
     public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
@@ -2971,6 +3017,10 @@
         return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
     }
 
+    @Override public long getMobileRadioActiveTime(long batteryRealtime, int which) {
+        return mMobileRadioActiveTimer.getTotalTimeLocked(batteryRealtime, which);
+    }
+
     @Override public long getWifiOnTime(long batteryRealtime, int which) {
         return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
     }
@@ -2979,10 +3029,30 @@
         return mGlobalWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
     }
 
+    @Override public long getWifiStateTime(int wifiState,
+            long batteryRealtime, int which) {
+        return mWifiStateTimer[wifiState].getTotalTimeLocked(
+                batteryRealtime, which);
+    }
+
+    @Override public int getWifiStateCount(int wifiState, int which) {
+        return mWifiStateTimer[wifiState].getCountLocked(which);
+    }
+
     @Override public long getBluetoothOnTime(long batteryRealtime, int which) {
         return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which);
     }
 
+    @Override public long getBluetoothStateTime(int bluetoothState,
+            long batteryRealtime, int which) {
+        return mBluetoothStateTimer[bluetoothState].getTotalTimeLocked(
+                batteryRealtime, which);
+    }
+
+    @Override public int getBluetoothStateCount(int bluetoothState, int which) {
+        return mBluetoothStateTimer[bluetoothState].getCountLocked(which);
+    }
+
     @Override
     public long getNetworkActivityBytes(int type, int which) {
         if (type >= 0 && type < mNetworkByteActivityCounters.length) {
@@ -3115,67 +3185,67 @@
         }
 
         @Override
-        public void noteWifiRunningLocked() {
+        public void noteWifiRunningLocked(long elapsedRealtime) {
             if (!mWifiRunning) {
                 mWifiRunning = true;
                 if (mWifiRunningTimer == null) {
                     mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
                             mWifiRunningTimers, mUnpluggables);
                 }
-                mWifiRunningTimer.startRunningLocked(BatteryStatsImpl.this);
+                mWifiRunningTimer.startRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
             }
         }
 
         @Override
-        public void noteWifiStoppedLocked() {
+        public void noteWifiStoppedLocked(long elapsedRealtime) {
             if (mWifiRunning) {
                 mWifiRunning = false;
-                mWifiRunningTimer.stopRunningLocked(BatteryStatsImpl.this);
+                mWifiRunningTimer.stopRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
             }
         }
 
         @Override
-        public void noteFullWifiLockAcquiredLocked() {
+        public void noteFullWifiLockAcquiredLocked(long elapsedRealtime) {
             if (!mFullWifiLockOut) {
                 mFullWifiLockOut = true;
                 if (mFullWifiLockTimer == null) {
                     mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
                             mFullWifiLockTimers, mUnpluggables);
                 }
-                mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
+                mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
             }
         }
 
         @Override
-        public void noteFullWifiLockReleasedLocked() {
+        public void noteFullWifiLockReleasedLocked(long elapsedRealtime) {
             if (mFullWifiLockOut) {
                 mFullWifiLockOut = false;
-                mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
+                mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
             }
         }
 
         @Override
-        public void noteWifiScanStartedLocked() {
+        public void noteWifiScanStartedLocked(long elapsedRealtime) {
             if (!mWifiScanStarted) {
                 mWifiScanStarted = true;
                 if (mWifiScanTimer == null) {
                     mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
                             mWifiScanTimers, mUnpluggables);
                 }
-                mWifiScanTimer.startRunningLocked(BatteryStatsImpl.this);
+                mWifiScanTimer.startRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
             }
         }
 
         @Override
-        public void noteWifiScanStoppedLocked() {
+        public void noteWifiScanStoppedLocked(long elapsedRealtime) {
             if (mWifiScanStarted) {
                 mWifiScanStarted = false;
-                mWifiScanTimer.stopRunningLocked(BatteryStatsImpl.this);
+                mWifiScanTimer.stopRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
             }
         }
 
         @Override
-        public void noteWifiBatchedScanStartedLocked(int csph) {
+        public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtime) {
             int bin = 0;
             while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS) {
                 csph = csph >> 3;
@@ -3186,41 +3256,41 @@
 
             if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
                 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
-                        stopRunningLocked(BatteryStatsImpl.this);
+                        stopRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
             }
             mWifiBatchedScanBinStarted = bin;
             if (mWifiBatchedScanTimer[bin] == null) {
                 makeWifiBatchedScanBin(bin, null);
             }
-            mWifiBatchedScanTimer[bin].startRunningLocked(BatteryStatsImpl.this);
+            mWifiBatchedScanTimer[bin].startRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
         }
 
         @Override
-        public void noteWifiBatchedScanStoppedLocked() {
+        public void noteWifiBatchedScanStoppedLocked(long elapsedRealtime) {
             if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
                 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
-                        stopRunningLocked(BatteryStatsImpl.this);
+                        stopRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
                 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
             }
         }
 
         @Override
-        public void noteWifiMulticastEnabledLocked() {
+        public void noteWifiMulticastEnabledLocked(long elapsedRealtime) {
             if (!mWifiMulticastEnabled) {
                 mWifiMulticastEnabled = true;
                 if (mWifiMulticastTimer == null) {
                     mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
                             mWifiMulticastTimers, mUnpluggables);
                 }
-                mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
+                mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
             }
         }
 
         @Override
-        public void noteWifiMulticastDisabledLocked() {
+        public void noteWifiMulticastDisabledLocked(long elapsedRealtime) {
             if (mWifiMulticastEnabled) {
                 mWifiMulticastEnabled = false;
-                mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
+                mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
             }
         }
 
@@ -3233,19 +3303,20 @@
         }
 
         @Override
-        public void noteAudioTurnedOnLocked() {
+        public void noteAudioTurnedOnLocked(long elapsedRealtime) {
             if (!mAudioTurnedOn) {
                 mAudioTurnedOn = true;
-                createAudioTurnedOnTimerLocked().startRunningLocked(BatteryStatsImpl.this);
+                createAudioTurnedOnTimerLocked().startRunningLocked(BatteryStatsImpl.this,
+                        elapsedRealtime);
             }
         }
 
         @Override
-        public void noteAudioTurnedOffLocked() {
+        public void noteAudioTurnedOffLocked(long elapsedRealtime) {
             if (mAudioTurnedOn) {
                 mAudioTurnedOn = false;
                 if (mAudioTurnedOnTimer != null) {
-                    mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
+                    mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
                 }
             }
         }
@@ -3259,19 +3330,20 @@
         }
 
         @Override
-        public void noteVideoTurnedOnLocked() {
+        public void noteVideoTurnedOnLocked(long elapsedRealtime) {
             if (!mVideoTurnedOn) {
                 mVideoTurnedOn = true;
-                createVideoTurnedOnTimerLocked().startRunningLocked(BatteryStatsImpl.this);
+                createVideoTurnedOnTimerLocked().startRunningLocked(BatteryStatsImpl.this,
+                        elapsedRealtime);
             }
         }
 
         @Override
-        public void noteVideoTurnedOffLocked() {
+        public void noteVideoTurnedOffLocked(long elapsedRealtime) {
             if (mVideoTurnedOn) {
                 mVideoTurnedOn = false;
                 if (mVideoTurnedOnTimer != null) {
-                    mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
+                    mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
                 }
             }
         }
@@ -3285,15 +3357,16 @@
         }
 
         @Override
-        public void noteActivityResumedLocked() {
+        public void noteActivityResumedLocked(long elapsedRealtime) {
             // We always start, since we want multiple foreground PIDs to nest
-            createForegroundActivityTimerLocked().startRunningLocked(BatteryStatsImpl.this);
+            createForegroundActivityTimerLocked().startRunningLocked(BatteryStatsImpl.this,
+                    elapsedRealtime);
         }
 
         @Override
-        public void noteActivityPausedLocked() {
+        public void noteActivityPausedLocked(long elapsedRealtime) {
             if (mForegroundActivityTimer != null) {
-                mForegroundActivityTimer.stopRunningLocked(BatteryStatsImpl.this);
+                mForegroundActivityTimer.stopRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
             }
         }
 
@@ -4870,28 +4943,28 @@
             return t;
         }
 
-        public void noteStartWakeLocked(int pid, String name, int type) {
+        public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtime) {
             StopwatchTimer t = getWakeTimerLocked(name, type);
             if (t != null) {
-                t.startRunningLocked(BatteryStatsImpl.this);
+                t.startRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
             }
             if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
                 Pid p = getPidStatsLocked(pid);
                 if (p.mWakeStart == 0) {
-                    p.mWakeStart = SystemClock.elapsedRealtime();
+                    p.mWakeStart = elapsedRealtime;
                 }
             }
         }
 
-        public void noteStopWakeLocked(int pid, String name, int type) {
+        public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtime) {
             StopwatchTimer t = getWakeTimerLocked(name, type);
             if (t != null) {
-                t.stopRunningLocked(BatteryStatsImpl.this);
+                t.stopRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
             }
             if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
                 Pid p = mPids.get(pid);
                 if (p != null && p.mWakeStart != 0) {
-                    p.mWakeSum += SystemClock.elapsedRealtime() - p.mWakeStart;
+                    p.mWakeSum += elapsedRealtime - p.mWakeStart;
                     p.mWakeStart = 0;
                 }
             }
@@ -4911,32 +4984,32 @@
             }
         }
 
-        public void noteStartSensor(int sensor) {
+        public void noteStartSensor(int sensor, long elapsedRealtime) {
             StopwatchTimer t = getSensorTimerLocked(sensor, true);
             if (t != null) {
-                t.startRunningLocked(BatteryStatsImpl.this);
+                t.startRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
             }
         }
 
-        public void noteStopSensor(int sensor) {
+        public void noteStopSensor(int sensor, long elapsedRealtime) {
             // Don't create a timer if one doesn't already exist
             StopwatchTimer t = getSensorTimerLocked(sensor, false);
             if (t != null) {
-                t.stopRunningLocked(BatteryStatsImpl.this);
+                t.stopRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
             }
         }
 
-        public void noteStartGps() {
+        public void noteStartGps(long elapsedRealtime) {
             StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
             if (t != null) {
-                t.startRunningLocked(BatteryStatsImpl.this);
+                t.startRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
             }
         }
 
-        public void noteStopGps() {
+        public void noteStopGps(long elapsedRealtime) {
             StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
             if (t != null) {
-                t.stopRunningLocked(BatteryStatsImpl.this);
+                t.stopRunningLocked(BatteryStatsImpl.this, elapsedRealtime);
             }
         }
 
@@ -4966,9 +5039,16 @@
             mNetworkByteActivityCounters[i] = new LongSamplingCounter(mUnpluggables);
             mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mUnpluggables);
         }
+        mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mUnpluggables);
         mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables);
         mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables);
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            mWifiStateTimer[i] = new StopwatchTimer(null, -600-i, null, mUnpluggables);
+        }
         mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mUnpluggables);
+        for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
+            mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i, null, mUnpluggables);
+        }
         mAudioOnTimer = new StopwatchTimer(null, -6, null, mUnpluggables);
         mVideoOnTimer = new StopwatchTimer(null, -7, null, mUnpluggables);
         mOnBattery = mOnBatteryInternal = false;
@@ -5225,9 +5305,16 @@
             mNetworkByteActivityCounters[i].reset(false);
             mNetworkPacketActivityCounters[i].reset(false);
         }
+        mMobileRadioActiveTimer.reset(this, false);
         mWifiOnTimer.reset(this, false);
         mGlobalWifiRunningTimer.reset(this, false);
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            mWifiStateTimer[i].reset(this, false);
+        }
         mBluetoothOnTimer.reset(this, false);
+        for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
+            mBluetoothStateTimer[i].reset(this, false);
+        }
 
         for (int i=0; i<mUidStats.size(); i++) {
             if (mUidStats.valueAt(i).reset()) {
@@ -6119,12 +6206,20 @@
             mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
             mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
         }
+        mMobileRadioActive = false;
+        mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
         mWifiOn = false;
         mWifiOnTimer.readSummaryFromParcelLocked(in);
         mGlobalWifiRunning = false;
         mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            mWifiStateTimer[i].readSummaryFromParcelLocked(in);
+        }
         mBluetoothOn = false;
         mBluetoothOnTimer.readSummaryFromParcelLocked(in);
+        for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
+            mBluetoothStateTimer[i].readSummaryFromParcelLocked(in);
+        }
 
         int NKW = in.readInt();
         if (NKW > 10000) {
@@ -6340,9 +6435,16 @@
             mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
             mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
         }
+        mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL);
         mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
         mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
+        }
         mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+        for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
+            mBluetoothStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
+        }
 
         out.writeInt(mKernelWakelockStats.size());
         for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
@@ -6574,12 +6676,22 @@
             mNetworkByteActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in);
             mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in);
         }
+        mMobileRadioActive = false;
+        mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mUnpluggables, in);
         mWifiOn = false;
         mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
         mGlobalWifiRunning = false;
         mGlobalWifiRunningTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            mWifiStateTimer[i] = new StopwatchTimer(null, -600-i,
+                    null, mUnpluggables, in);
+        }
         mBluetoothOn = false;
         mBluetoothOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
+        for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
+            mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i,
+                    null, mUnpluggables, in);
+        }
         mUptime = in.readLong();
         mUptimeStart = in.readLong();
         mLastUptime = 0;
@@ -6604,9 +6716,6 @@
         mDischargeAmountScreenOffSinceCharge = in.readInt();
         mLastWriteTime = in.readLong();
 
-        mRadioDataUptime = in.readLong();
-        mRadioDataStart = -1;
-
         mBluetoothPingCount = in.readInt();
         mBluetoothPingStart = -1;
 
@@ -6685,9 +6794,16 @@
             mNetworkByteActivityCounters[i].writeToParcel(out);
             mNetworkPacketActivityCounters[i].writeToParcel(out);
         }
+        mMobileRadioActiveTimer.writeToParcel(out, batteryRealtime);
         mWifiOnTimer.writeToParcel(out, batteryRealtime);
         mGlobalWifiRunningTimer.writeToParcel(out, batteryRealtime);
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            mWifiStateTimer[i].writeToParcel(out, batteryRealtime);
+        }
         mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
+        for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
+            mBluetoothStateTimer[i].writeToParcel(out, batteryRealtime);
+        }
         out.writeLong(mUptime);
         out.writeLong(mUptimeStart);
         out.writeLong(mRealtime);
@@ -6709,9 +6825,6 @@
         out.writeInt(mDischargeAmountScreenOffSinceCharge);
         out.writeLong(mLastWriteTime);
 
-        // Write radio uptime for data
-        out.writeLong(getRadioDataUptime());
-
         out.writeInt(getBluetoothPingCount());
 
         if (inclUids) {
@@ -6786,12 +6899,22 @@
                 pr.println("*** Data connection type #" + i + ":");
                 mPhoneDataConnectionsTimer[i].logState(pr, "  ");
             }
+            pr.println("*** Mobile network active timer:");
+            mMobileRadioActiveTimer.logState(pr, "  ");
             pr.println("*** Wifi timer:");
             mWifiOnTimer.logState(pr, "  ");
             pr.println("*** WifiRunning timer:");
             mGlobalWifiRunningTimer.logState(pr, "  ");
+            for (int i=0; i<NUM_WIFI_STATES; i++) {
+                pr.println("*** Wifi state #" + i + ":");
+                mWifiStateTimer[i].logState(pr, "  ");
+            }
             pr.println("*** Bluetooth timer:");
             mBluetoothOnTimer.logState(pr, "  ");
+            for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
+                pr.println("*** Bluetooth active type #" + i + ":");
+                mBluetoothStateTimer[i].logState(pr, "  ");
+            }
         }
         super.dumpLocked(context, pw, isUnpluggedOnly, reqUid, historyOnly);
     }
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 4f3b5b3..f9a1f89 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -224,9 +224,37 @@
                 ZygoteInit.setCloseOnExec(serverPipeFd, true);
             }
 
+            /**
+             * In order to avoid leaking descriptors to the Zygote child,
+             * the native code must close the two Zygote socket descriptors
+             * in the child process before it switches from Zygote-root to
+             * the UID and privileges of the application being launched.
+             *
+             * In order to avoid "bad file descriptor" errors when the
+             * two LocalSocket objects are closed, the Posix file
+             * descriptors are released via a dup2() call which closes
+             * the socket and substitutes an open descriptor to /dev/null.
+             */
+
+            int [] fdsToClose = { -1, -1 };
+
+            FileDescriptor fd = mSocket.getFileDescriptor();
+
+            if (fd != null) {
+                fdsToClose[0] = fd.getInt$();
+            }
+
+            fd = ZygoteInit.getServerSocketFileDescriptor();
+
+            if (fd != null) {
+                fdsToClose[1] = fd.getInt$();
+            }
+
+            fd = null;
+
             pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                     parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
-                    parsedArgs.niceName);
+                    parsedArgs.niceName, fdsToClose);
         } catch (IOException ex) {
             logAndPrintError(newStderr, "Exception creating pipe", ex);
         } catch (ErrnoException ex) {
@@ -814,6 +842,12 @@
             FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
             throws ZygoteInit.MethodAndArgsCaller {
 
+        /**
+         * By the time we get here, the native code has closed the two actual Zygote
+         * socket connections, and substituted /dev/null in their place.  The LocalSocket
+         * objects still need to be closed properly.
+         */
+
         closeSocket();
         ZygoteInit.closeServerSocket();
 
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 9dc9116..bf62745 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -207,6 +207,16 @@
         sServerSocket = null;
     }
 
+    /**
+     * Return the server socket's underlying file descriptor, so that
+     * ZygoteConnection can pass it to the native code for proper
+     * closure after a child process is forked off.
+     */
+
+    static FileDescriptor getServerSocketFileDescriptor() {
+        return sServerSocket.getFileDescriptor();
+    }
+
     private static final int UNPRIVILEGED_UID = 9999;
     private static final int UNPRIVILEGED_GID = 9999;
 
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 3419f15..f5c18f5 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -30,10 +30,12 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.storage.IMountService;
+import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.Slog;
 import android.view.IWindowManager;
 import android.view.View;
 import android.widget.Button;
@@ -498,6 +500,13 @@
             getLockSettings().setLockPattern(patternToString(pattern), getCurrentOrCallingUserId());
             DevicePolicyManager dpm = getDevicePolicyManager();
             if (pattern != null) {
+
+                int userHandle = getCurrentOrCallingUserId();
+                if (userHandle == UserHandle.USER_OWNER) {
+                    String stringPattern = patternToString(pattern);
+                    updateEncryptionPassword(StorageManager.CRYPT_TYPE_PATTERN, stringPattern);
+                }
+
                 setBoolean(PATTERN_EVER_CHOSEN_KEY, true);
                 if (!isFallback) {
                     deleteGallery();
@@ -565,7 +574,7 @@
     }
 
     /** Update the encryption password if it is enabled **/
-    private void updateEncryptionPassword(String password) {
+    private void updateEncryptionPassword(int type, String password) {
         DevicePolicyManager dpm = getDevicePolicyManager();
         if (dpm.getStorageEncryptionStatus(getCurrentOrCallingUserId())
                 != DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE) {
@@ -580,7 +589,7 @@
 
         IMountService mountService = IMountService.Stub.asInterface(service);
         try {
-            mountService.changeEncryptionPassword(password);
+            mountService.changeEncryptionPassword(type, password);
         } catch (RemoteException e) {
             Log.e(TAG, "Error changing encryption password", e);
         }
@@ -623,12 +632,15 @@
             getLockSettings().setLockPassword(password, userHandle);
             DevicePolicyManager dpm = getDevicePolicyManager();
             if (password != null) {
+                int computedQuality = computePasswordQuality(password);
+
                 if (userHandle == UserHandle.USER_OWNER) {
                     // Update the encryption password.
-                    updateEncryptionPassword(password);
+                    int type = computedQuality == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
+                        ? StorageManager.CRYPT_TYPE_PIN : StorageManager.CRYPT_TYPE_PASSWORD;
+                    updateEncryptionPassword(type, password);
                 }
 
-                int computedQuality = computePasswordQuality(password);
                 if (!isFallback) {
                     deleteGallery();
                     setLong(PASSWORD_TYPE_KEY, Math.max(quality, computedQuality), userHandle);
@@ -675,8 +687,7 @@
                             0, 0, 0, 0, 0, 0, 0, userHandle);
                 }
                 // Add the password to the password history. We assume all
-                // password
-                // hashes have the same length for simplicity of implementation.
+                // password hashes have the same length for simplicity of implementation.
                 String passwordHistory = getString(PASSWORD_HISTORY_KEY, userHandle);
                 if (passwordHistory == null) {
                     passwordHistory = new String();
@@ -695,6 +706,11 @@
                 }
                 setString(PASSWORD_HISTORY_KEY, passwordHistory, userHandle);
             } else {
+                if (userHandle == UserHandle.USER_OWNER) {
+                    // Update the encryption password.
+                    updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, password);
+                }
+
                 dpm.setActivePasswordState(
                         DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0, 0,
                         userHandle);
diff --git a/core/java/com/android/server/SystemService.java b/core/java/com/android/server/SystemService.java
index 0c89f94..194a084 100644
--- a/core/java/com/android/server/SystemService.java
+++ b/core/java/com/android/server/SystemService.java
@@ -85,14 +85,6 @@
     }
 
     /**
-     * Services are not yet available. This is a good place to do setup work that does
-     * not require other services.
-     *
-     * @param context The system context.
-     */
-    public void onCreate(Context context) {}
-
-    /**
      * Called when the dependencies listed in the @Service class-annotation are available
      * and after the chosen start phase.
      * When this method returns, the service should be published.
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 77c5c18..100f71d 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -761,13 +761,6 @@
         mOptions.add(opt);
     }
 
-    /*
-     * We don't have /tmp on the device, but we often have an SD card.  Apps
-     * shouldn't use this, but some test suites might want to exercise it.
-     */
-    opt.optionString = "-Djava.io.tmpdir=/sdcard";
-    mOptions.add(opt);
-
     initArgs.version = JNI_VERSION_1_4;
     initArgs.options = mOptions.editArray();
     initArgs.nOptions = mOptions.size();
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 24160ab..d97a945 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -466,7 +466,6 @@
     } else {

         bitmap->setAlphaType(kUnpremul_SkAlphaType);

     }

-    bitmap->setIsOpaque(!hasAlpha);

 }

 

 static jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, jlong bitmapHandle) {

diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp
index db84d000..26405b5 100644
--- a/core/jni/android_os_SELinux.cpp
+++ b/core/jni/android_os_SELinux.cpp
@@ -415,7 +415,7 @@
         return false;
     }
 
-    int ret = selinux_android_restorecon(pathname.c_str());
+    int ret = selinux_android_restorecon(pathname.c_str(), 0);
     ALOGV("restorecon(%s) => %d", pathname.c_str(), ret);
     return (ret == 0);
 }
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index f96aef8..7162a1c 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -35,7 +35,16 @@
 #include <androidfw/AssetManager.h>
 #include <androidfw/ResourceTypes.h>
 
+#include <private/android_filesystem_config.h> // for AID_SYSTEM
+
 #include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <linux/capability.h>
+extern "C" int capget(cap_user_header_t hdrp, cap_user_data_t datap);
+extern "C" int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
+
 
 namespace android {
 
@@ -100,6 +109,63 @@
     return block;
 }
 
+// This is called by zygote (running as user root) as part of preloadResources.
+static void verifySystemIdmaps()
+{
+    pid_t pid;
+    char system_id[10];
+
+    snprintf(system_id, sizeof(system_id), "%d", AID_SYSTEM);
+
+    switch (pid = fork()) {
+        case -1:
+            ALOGE("failed to fork for idmap: %s", strerror(errno));
+            break;
+        case 0: // child
+            {
+                struct __user_cap_header_struct capheader;
+                struct __user_cap_data_struct capdata;
+
+                memset(&capheader, 0, sizeof(capheader));
+                memset(&capdata, 0, sizeof(capdata));
+
+                capheader.version = _LINUX_CAPABILITY_VERSION;
+                capheader.pid = 0;
+
+                if (capget(&capheader, &capdata) != 0) {
+                    ALOGE("capget: %s\n", strerror(errno));
+                    exit(1);
+                }
+
+                capdata.effective = capdata.permitted;
+                if (capset(&capheader, &capdata) != 0) {
+                    ALOGE("capset: %s\n", strerror(errno));
+                    exit(1);
+                }
+
+                if (setgid(AID_SYSTEM) != 0) {
+                    ALOGE("setgid: %s\n", strerror(errno));
+                    exit(1);
+                }
+
+                if (setuid(AID_SYSTEM) != 0) {
+                    ALOGE("setuid: %s\n", strerror(errno));
+                    exit(1);
+                }
+
+                execl(AssetManager::IDMAP_BIN, AssetManager::IDMAP_BIN, "--scan",
+                        AssetManager::OVERLAY_DIR, AssetManager::TARGET_PACKAGE_NAME,
+                        AssetManager::TARGET_APK_PATH, AssetManager::IDMAP_DIR, (char*)NULL);
+                ALOGE("failed to execl for idmap: %s", strerror(errno));
+                exit(1); // should never get here
+            }
+            break;
+        default: // parent
+            waitpid(pid, NULL, 0);
+            break;
+    }
+}
+
 // ----------------------------------------------------------------------------
 
 // this guy is exported to other jni routines
@@ -444,6 +510,25 @@
     return (res) ? static_cast<jint>(cookie) : 0;
 }
 
+static jint android_content_AssetManager_addOverlayPath(JNIEnv* env, jobject clazz,
+                                                     jstring idmapPath)
+{
+    ScopedUtfChars idmapPath8(env, idmapPath);
+    if (idmapPath8.c_str() == NULL) {
+        return 0;
+    }
+
+    AssetManager* am = assetManagerForJavaObject(env, clazz);
+    if (am == NULL) {
+        return 0;
+    }
+
+    int32_t cookie;
+    bool res = am->addOverlayPath(String8(idmapPath8.c_str()), &cookie);
+
+    return (res) ? (jint)cookie : 0;
+}
+
 static jboolean android_content_AssetManager_isUpToDate(JNIEnv* env, jobject clazz)
 {
     AssetManager* am = assetManagerForJavaObject(env, clazz);
@@ -1579,8 +1664,11 @@
     return array;
 }
 
-static void android_content_AssetManager_init(JNIEnv* env, jobject clazz)
+static void android_content_AssetManager_init(JNIEnv* env, jobject clazz, jboolean isSystem)
 {
+    if (isSystem) {
+        verifySystemIdmaps();
+    }
     AssetManager* am = new AssetManager();
     if (am == NULL) {
         jniThrowException(env, "java/lang/OutOfMemoryError", "");
@@ -1658,6 +1746,8 @@
         (void*) android_content_AssetManager_getAssetRemainingLength },
     { "addAssetPathNative", "(Ljava/lang/String;)I",
         (void*) android_content_AssetManager_addAssetPath },
+    { "addOverlayPath",   "(Ljava/lang/String;)I",
+        (void*) android_content_AssetManager_addOverlayPath },
     { "isUpToDate",     "()Z",
         (void*) android_content_AssetManager_isUpToDate },
 
@@ -1724,7 +1814,7 @@
         (void*) android_content_AssetManager_getArrayIntResource },
 
     // Bookkeeping.
-    { "init",           "()V",
+    { "init",           "(Z)V",
         (void*) android_content_AssetManager_init },
     { "destroy",        "()V",
         (void*) android_content_AssetManager_destroy },
diff --git a/core/jni/android_view_SurfaceSession.cpp b/core/jni/android_view_SurfaceSession.cpp
index 87e339c..609c565 100644
--- a/core/jni/android_view_SurfaceSession.cpp
+++ b/core/jni/android_view_SurfaceSession.cpp
@@ -35,22 +35,22 @@
 sp<SurfaceComposerClient> android_view_SurfaceSession_getClient(
         JNIEnv* env, jobject surfaceSessionObj) {
     return reinterpret_cast<SurfaceComposerClient*>(
-            env->GetIntField(surfaceSessionObj, gSurfaceSessionClassInfo.mNativeClient));
+            env->GetLongField(surfaceSessionObj, gSurfaceSessionClassInfo.mNativeClient));
 }
 
 
-static jint nativeCreate(JNIEnv* env, jclass clazz) {
+static jlong nativeCreate(JNIEnv* env, jclass clazz) {
     SurfaceComposerClient* client = new SurfaceComposerClient();
     client->incStrong((void*)nativeCreate);
-    return reinterpret_cast<jint>(client);
+    return reinterpret_cast<jlong>(client);
 }
 
-static void nativeDestroy(JNIEnv* env, jclass clazz, jint ptr) {
+static void nativeDestroy(JNIEnv* env, jclass clazz, jlong ptr) {
     SurfaceComposerClient* client = reinterpret_cast<SurfaceComposerClient*>(ptr);
     client->decStrong((void*)nativeCreate);
 }
 
-static void nativeKill(JNIEnv* env, jclass clazz, jint ptr) {
+static void nativeKill(JNIEnv* env, jclass clazz, jlong ptr) {
     SurfaceComposerClient* client = reinterpret_cast<SurfaceComposerClient*>(ptr);
     client->dispose();
 }
@@ -58,11 +58,11 @@
 
 static JNINativeMethod gMethods[] = {
     /* name, signature, funcPtr */
-    { "nativeCreate", "()I",
+    { "nativeCreate", "()J",
             (void*)nativeCreate },
-    { "nativeDestroy", "(I)V",
+    { "nativeDestroy", "(J)V",
             (void*)nativeDestroy },
-    { "nativeKill", "(I)V",
+    { "nativeKill", "(J)V",
             (void*)nativeKill }
 };
 
@@ -72,7 +72,7 @@
     LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
 
     jclass clazz = env->FindClass("android/view/SurfaceSession");
-    gSurfaceSessionClassInfo.mNativeClient = env->GetFieldID(clazz, "mNativeClient", "I");
+    gSurfaceSessionClassInfo.mNativeClient = env->GetFieldID(clazz, "mNativeClient", "J");
     return 0;
 }
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7ea08af..30e6161 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1103,6 +1103,14 @@
         android:label="@string/permlab_readPhoneState"
         android:description="@string/permdesc_readPhoneState" />
 
+    <!-- Allows read only access to precise phone state.
+         @hide Pending API council approval -->
+    <permission android:name="android.permission.READ_PRECISE_PHONE_STATE"
+        android:permissionGroup="android.permission-group.PHONE_CALLS"
+        android:protectionLevel="dangerous"
+        android:label="@string/permlab_readPrecisePhoneState"
+        android:description="@string/permdesc_readPrecisePhoneState" />
+
     <!-- Allows read access to privileged phone state.
          @hide Used internally. -->
     <permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
@@ -1206,7 +1214,7 @@
         android:permissionGroup="android.permission-group.STORAGE"
         android:label="@string/permlab_manageDocs"
         android:description="@string/permdesc_manageDocs"
-        android:protectionLevel="signature|system" />
+        android:protectionLevel="signature" />
 
     <!-- ================================== -->
     <!-- Permissions for screenlock         -->
@@ -1541,7 +1549,7 @@
         @hide -->
     <permission android:name="android.permission.FORCE_STOP_PACKAGES"
         android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
-        android:protectionLevel="signature"
+        android:protectionLevel="signature|system"
         android:label="@string/permlab_forceStopPackages"
         android:description="@string/permdesc_forceStopPackages" />
 
diff --git a/core/res/res/values-ja/bools.xml b/core/res/res/color/primary_text_disable_only_quantum_dark.xml
similarity index 66%
copy from core/res/res/values-ja/bools.xml
copy to core/res/res/color/primary_text_disable_only_quantum_dark.xml
index 59cf744..2a6c33c 100644
--- a/core/res/res/values-ja/bools.xml
+++ b/core/res/res/color/primary_text_disable_only_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2010 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<resources>
-    <bool name="flip_controller_fallback_keys">true</bool>
-</resources>
-
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false" android:color="@android:color/bright_foreground_dark_disabled"/>
+    <item android:color="@android:color/bright_foreground_dark"/>
+</selector>
diff --git a/core/res/res/values-ja/bools.xml b/core/res/res/color/primary_text_disable_only_quantum_light.xml
similarity index 65%
copy from core/res/res/values-ja/bools.xml
copy to core/res/res/color/primary_text_disable_only_quantum_light.xml
index 59cf744..ff83f6a 100644
--- a/core/res/res/values-ja/bools.xml
+++ b/core/res/res/color/primary_text_disable_only_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2010 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<resources>
-    <bool name="flip_controller_fallback_keys">true</bool>
-</resources>
-
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false" android:color="@android:color/bright_foreground_light_disabled"/>
+    <item android:color="@android:color/bright_foreground_light"/>
+</selector>
diff --git a/core/res/res/color/primary_text_nodisable_quantum_dark.xml b/core/res/res/color/primary_text_nodisable_quantum_dark.xml
new file mode 100644
index 0000000..1044428
--- /dev/null
+++ b/core/res/res/color/primary_text_nodisable_quantum_dark.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:color="@android:color/bright_foreground_dark_inverse"/>
+    <item android:state_activated="true" android:color="@android:color/bright_foreground_dark_inverse"/>
+    <item android:color="@android:color/bright_foreground_dark"/>
+</selector>
diff --git a/core/res/res/values-ja/bools.xml b/core/res/res/color/primary_text_nodisable_quantum_light.xml
similarity index 60%
copy from core/res/res/values-ja/bools.xml
copy to core/res/res/color/primary_text_nodisable_quantum_light.xml
index 59cf744..fde143f 100644
--- a/core/res/res/values-ja/bools.xml
+++ b/core/res/res/color/primary_text_nodisable_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2010 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<resources>
-    <bool name="flip_controller_fallback_keys">true</bool>
-</resources>
-
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:color="@android:color/bright_foreground_light"/>
+    <item android:state_activated="true" android:color="@android:color/bright_foreground_light"/>
+    <item android:color="@android:color/bright_foreground_light"/>
+</selector>
diff --git a/core/res/res/color/primary_text_quantum_dark.xml b/core/res/res/color/primary_text_quantum_dark.xml
new file mode 100644
index 0000000..65f49ae
--- /dev/null
+++ b/core/res/res/color/primary_text_quantum_dark.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false" android:color="@android:color/bright_foreground_disabled_holo_dark"/>
+    <item android:state_window_focused="false" android:color="@android:color/bright_foreground_holo_dark"/>
+    <item android:state_pressed="true" android:color="@android:color/bright_foreground_holo_dark"/>
+    <item android:state_selected="true" android:color="@android:color/bright_foreground_holo_dark"/>
+    <item android:state_activated="true" android:color="@android:color/bright_foreground_holo_dark"/>
+    <item android:color="@android:color/bright_foreground_holo_dark"/>
+</selector>
diff --git a/core/res/res/color/primary_text_quantum_light.xml b/core/res/res/color/primary_text_quantum_light.xml
new file mode 100644
index 0000000..372745d
--- /dev/null
+++ b/core/res/res/color/primary_text_quantum_light.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false" android:color="@android:color/bright_foreground_disabled_holo_light"/>
+    <item android:state_window_focused="false" android:color="@android:color/bright_foreground_holo_light"/>
+    <item android:state_pressed="true" android:color="@android:color/bright_foreground_holo_light"/>
+    <item android:state_selected="true" android:color="@android:color/bright_foreground_holo_light"/>
+    <item android:state_activated="true" android:color="@android:color/bright_foreground_holo_light"/>
+    <item android:color="@android:color/bright_foreground_holo_light"/>
+</selector>
diff --git a/core/res/res/values-ja/bools.xml b/core/res/res/color/search_url_text_quantum_dark.xml
similarity index 60%
copy from core/res/res/values-ja/bools.xml
copy to core/res/res/color/search_url_text_quantum_dark.xml
index 59cf744..62337bd 100644
--- a/core/res/res/values-ja/bools.xml
+++ b/core/res/res/color/search_url_text_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2010 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<resources>
-    <bool name="flip_controller_fallback_keys">true</bool>
-</resources>
-
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:color="@android:color/search_url_text_pressed"/>
+    <item android:state_selected="true" android:color="@android:color/search_url_text_selected"/>
+    <item android:color="@android:color/search_url_text_normal"/>
+</selector>
diff --git a/core/res/res/values-ja/bools.xml b/core/res/res/color/search_url_text_quantum_light.xml
similarity index 60%
copy from core/res/res/values-ja/bools.xml
copy to core/res/res/color/search_url_text_quantum_light.xml
index 59cf744..62337bd 100644
--- a/core/res/res/values-ja/bools.xml
+++ b/core/res/res/color/search_url_text_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2010 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<resources>
-    <bool name="flip_controller_fallback_keys">true</bool>
-</resources>
-
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:color="@android:color/search_url_text_pressed"/>
+    <item android:state_selected="true" android:color="@android:color/search_url_text_selected"/>
+    <item android:color="@android:color/search_url_text_normal"/>
+</selector>
diff --git a/core/res/res/color/secondary_text_nodisable_quantum_dark.xml b/core/res/res/color/secondary_text_nodisable_quantum_dark.xml
new file mode 100644
index 0000000..3ab25a0
--- /dev/null
+++ b/core/res/res/color/secondary_text_nodisable_quantum_dark.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:color="@android:color/dim_foreground_dark_inverse"/>
+    <item android:state_activated="true" android:color="@android:color/bright_foreground_dark_inverse"/>
+    <item android:color="@android:color/dim_foreground_dark"/>
+</selector>
diff --git a/core/res/res/color/secondary_text_nodisable_quantum_light.xml b/core/res/res/color/secondary_text_nodisable_quantum_light.xml
new file mode 100644
index 0000000..3ab25a0
--- /dev/null
+++ b/core/res/res/color/secondary_text_nodisable_quantum_light.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:color="@android:color/dim_foreground_dark_inverse"/>
+    <item android:state_activated="true" android:color="@android:color/bright_foreground_dark_inverse"/>
+    <item android:color="@android:color/dim_foreground_dark"/>
+</selector>
diff --git a/core/res/res/color/secondary_text_quantum_dark.xml b/core/res/res/color/secondary_text_quantum_dark.xml
new file mode 100644
index 0000000..fb7a07a
--- /dev/null
+++ b/core/res/res/color/secondary_text_quantum_dark.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_window_focused="false" android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_dark"/>
+    <item android:state_window_focused="false" android:color="@android:color/dim_foreground_holo_dark"/>
+    <item android:state_selected="true" android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_dark"/>
+    <item android:state_pressed="true" android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_dark"/>
+    <item android:state_selected="true" android:color="@android:color/dim_foreground_holo_dark"/>
+    <item android:state_activated="true" android:color="@android:color/bright_foreground_holo_dark"/>
+    <item android:state_pressed="true" android:color="@android:color/dim_foreground_holo_dark"/>
+    <item android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_dark"/>
+    <item android:color="@android:color/dim_foreground_holo_dark"/>
+</selector>
diff --git a/core/res/res/color/secondary_text_quantum_light.xml b/core/res/res/color/secondary_text_quantum_light.xml
new file mode 100644
index 0000000..744ace5
--- /dev/null
+++ b/core/res/res/color/secondary_text_quantum_light.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_window_focused="false" android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_light"/>
+    <item android:state_window_focused="false" android:color="@android:color/dim_foreground_holo_light"/>
+    <!-- Since there is only one selector (for both light and dark), the light's selected state shouldn't be inversed like the dark's. -->
+    <item android:state_pressed="true" android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_light"/>
+    <item android:state_selected="true" android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_light"/>
+    <item android:state_pressed="true" android:color="@android:color/dim_foreground_holo_light"/>
+    <item android:state_selected="true" android:color="@android:color/dim_foreground_holo_light"/>
+    <item android:state_activated="true" android:color="@android:color/bright_foreground_holo_light"/>
+    <item android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_light"/>
+    <item android:color="@android:color/dim_foreground_holo_light"/>
+</selector>
diff --git a/core/res/res/color/tertiary_text_quantum_dark.xml b/core/res/res/color/tertiary_text_quantum_dark.xml
new file mode 100644
index 0000000..cb39565
--- /dev/null
+++ b/core/res/res/color/tertiary_text_quantum_dark.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false" android:color="#808080"/>
+    <item android:state_window_focused="false" android:color="#808080"/>
+    <item android:state_pressed="true" android:color="#808080"/>
+    <item android:state_selected="true" android:color="@android:color/dim_foreground_holo_light"/>
+    <item android:color="#808080"/>
+</selector>
diff --git a/core/res/res/color/tertiary_text_quantum_light.xml b/core/res/res/color/tertiary_text_quantum_light.xml
new file mode 100644
index 0000000..b23162a
--- /dev/null
+++ b/core/res/res/color/tertiary_text_quantum_light.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false" android:color="#808080"/>
+    <item android:state_window_focused="false" android:color="#808080"/>
+    <item android:state_pressed="true" android:color="#808080"/>
+    <item android:state_selected="true" android:color="#808080"/>
+    <item android:color="#808080"/>
+</selector>
diff --git a/core/res/res/values-ja/bools.xml b/core/res/res/drawable/background_cache_hint_selector_quantum_dark.xml
similarity index 67%
copy from core/res/res/values-ja/bools.xml
copy to core/res/res/drawable/background_cache_hint_selector_quantum_dark.xml
index 59cf744..7d64abc 100644
--- a/core/res/res/values-ja/bools.xml
+++ b/core/res/res/drawable/background_cache_hint_selector_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2010 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<resources>
-    <bool name="flip_controller_fallback_keys">true</bool>
-</resources>
-
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_accelerated="false" android:color="@android:color/background_quantum_dark" />
+    <item android:color="@android:color/transparent" />
+</selector>
diff --git a/core/res/res/values-ja/bools.xml b/core/res/res/drawable/background_cache_hint_selector_quantum_light.xml
similarity index 66%
copy from core/res/res/values-ja/bools.xml
copy to core/res/res/drawable/background_cache_hint_selector_quantum_light.xml
index 59cf744..3fc3483 100644
--- a/core/res/res/values-ja/bools.xml
+++ b/core/res/res/drawable/background_cache_hint_selector_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2010 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<resources>
-    <bool name="flip_controller_fallback_keys">true</bool>
-</resources>
-
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_accelerated="false" android:color="@android:color/background_quantum_light" />
+    <item android:color="@android:color/transparent" />
+</selector>
diff --git a/core/res/res/drawable/btn_default_quantum.xml b/core/res/res/drawable/btn_default_quantum_dark.xml
similarity index 86%
copy from core/res/res/drawable/btn_default_quantum.xml
copy to core/res/res/drawable/btn_default_quantum_dark.xml
index 1affe3a..84b1090 100644
--- a/core/res/res/drawable/btn_default_quantum.xml
+++ b/core/res/res/drawable/btn_default_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2014 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.
@@ -18,17 +18,18 @@
     <item>
         <selector>
             <item android:state_window_focused="false" android:state_enabled="true"
-                android:drawable="@drawable/btn_default_normal_holo_light" />
+                android:drawable="@drawable/btn_default_normal_holo_dark" />
             <item android:state_window_focused="false" android:state_enabled="false"
-                android:drawable="@drawable/btn_default_disabled_holo_light" />
+                android:drawable="@drawable/btn_default_disabled_holo_dark" />
             <item android:state_focused="true" android:state_enabled="true"
-                android:drawable="@drawable/btn_default_focused_holo_light" />
+                android:drawable="@drawable/btn_default_focused_holo_dark" />
             <item android:state_enabled="true"
-                android:drawable="@drawable/btn_default_normal_holo_light" />
+                android:drawable="@drawable/btn_default_normal_holo_dark" />
             <item android:state_focused="true"
-                android:drawable="@drawable/btn_default_disabled_focused_holo_light" />
+                android:drawable="@drawable/btn_default_disabled_focused_holo_dark" />
             <item
-                android:drawable="@drawable/btn_default_disabled_holo_light" />
+                android:drawable="@drawable/btn_default_disabled_holo_dark" />
         </selector>
     </item>
+    <item android:drawable="@drawable/btn_default_pressed_holo_dark" />
 </reveal>
diff --git a/core/res/res/drawable/btn_default_quantum.xml b/core/res/res/drawable/btn_default_quantum_light.xml
similarity index 95%
rename from core/res/res/drawable/btn_default_quantum.xml
rename to core/res/res/drawable/btn_default_quantum_light.xml
index 1affe3a..b559198 100644
--- a/core/res/res/drawable/btn_default_quantum.xml
+++ b/core/res/res/drawable/btn_default_quantum_light.xml
@@ -31,4 +31,5 @@
                 android:drawable="@drawable/btn_default_disabled_holo_light" />
         </selector>
     </item>
+    <item android:drawable="@drawable/btn_default_pressed_holo_light" />
 </reveal>
diff --git a/core/res/res/drawable/item_background_quantum.xml b/core/res/res/drawable/item_background_quantum.xml
deleted file mode 100644
index 5c44c87..0000000
--- a/core/res/res/drawable/item_background_quantum.xml
+++ /dev/null
@@ -1,29 +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.
--->
-
-<reveal xmlns:android="http://schemas.android.com/apk/res/android">
-    <item>
-        <selector>
-            <item android:state_focused="true" android:state_enabled="false"
-                android:drawable="@drawable/list_selector_disabled_holo_light" />
-            <item android:state_focused="true"
-                android:drawable="@drawable/list_focused_holo" />
-            <item
-                android:drawable="@color/transparent" />
-        </selector>
-    </item>
-    <item android:drawable="@drawable/list_selector_background_transition_holo_light" />
-</reveal>
diff --git a/core/res/res/values-ja/bools.xml b/core/res/res/drawable/item_background_quantum_dark.xml
similarity index 71%
copy from core/res/res/values-ja/bools.xml
copy to core/res/res/drawable/item_background_quantum_dark.xml
index 59cf744..5ccaa8e 100644
--- a/core/res/res/values-ja/bools.xml
+++ b/core/res/res/drawable/item_background_quantum_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2014 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.
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<resources>
-    <bool name="flip_controller_fallback_keys">true</bool>
-</resources>
-
+<reveal xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@color/transparent" />
+    <item android:drawable="@color/lighter_gray" />
+</reveal>
diff --git a/core/res/res/values-ja/bools.xml b/core/res/res/drawable/item_background_quantum_light.xml
similarity index 71%
rename from core/res/res/values-ja/bools.xml
rename to core/res/res/drawable/item_background_quantum_light.xml
index 59cf744..f1453c5 100644
--- a/core/res/res/values-ja/bools.xml
+++ b/core/res/res/drawable/item_background_quantum_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2014 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.
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<resources>
-    <bool name="flip_controller_fallback_keys">true</bool>
-</resources>
-
+<reveal xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@color/transparent" />
+    <item android:drawable="@color/darker_gray" />
+</reveal>
diff --git a/core/res/res/drawable/list_selector_quantum.xml b/core/res/res/drawable/list_selector_quantum.xml
deleted file mode 100644
index d41247c..0000000
--- a/core/res/res/drawable/list_selector_quantum.xml
+++ /dev/null
@@ -1,29 +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.
--->
-
-<reveal xmlns:android="http://schemas.android.com/apk/res/android">
-    <item>
-        <selector>
-            <item android:state_window_focused="false"
-                android:drawable="@color/transparent" />
-            <item android:state_focused="true" android:state_enabled="false"
-                android:drawable="@drawable/list_selector_disabled_holo_light" />
-            <item android:state_focused="true"
-                android:drawable="@drawable/list_focused_holo" />
-        </selector>
-    </item>
-    <item android:drawable="@drawable/list_selector_background_transition_holo_light" />
-</reveal>
diff --git a/core/res/res/drawable/list_selector_quantum_dark.xml b/core/res/res/drawable/list_selector_quantum_dark.xml
new file mode 100644
index 0000000..fea55a8
--- /dev/null
+++ b/core/res/res/drawable/list_selector_quantum_dark.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<reveal xmlns:android="http://schemas.android.com/apk/res/android">
+    <selector>
+        <item android:state_window_focused="false" android:drawable="@color/transparent" />
+        <item android:state_focused="true" android:state_enabled="false"
+            android:drawable="@drawable/list_selector_disabled_holo_dark" />
+        <item android:state_focused="true" android:drawable="@drawable/list_focused_holo" />
+    </selector>
+    <selector>
+        <item android:state_window_focused="false" android:drawable="@color/transparent" />
+        <item android:state_focused="true" android:state_enabled="false"
+            android:state_pressed="true" android:drawable="@drawable/list_selector_disabled_holo_dark" />
+        <item android:state_focused="true" android:state_pressed="true"
+            android:drawable="@drawable/list_selector_background_transition_holo_dark" />
+        <item android:state_focused="false" android:state_pressed="true"
+            android:drawable="@drawable/list_selector_background_transition_holo_dark" />
+    </selector>
+</reveal>
diff --git a/core/res/res/drawable/list_selector_quantum_light.xml b/core/res/res/drawable/list_selector_quantum_light.xml
new file mode 100644
index 0000000..1e32eac
--- /dev/null
+++ b/core/res/res/drawable/list_selector_quantum_light.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<reveal xmlns:android="http://schemas.android.com/apk/res/android">
+    <selector>
+        <item android:state_window_focused="false" android:drawable="@color/transparent" />
+        <item android:state_focused="true" android:state_enabled="false"
+            android:drawable="@drawable/list_selector_disabled_holo_light" />
+        <item android:state_focused="true" android:drawable="@drawable/list_focused_holo" />
+    </selector>
+    <selector>
+        <item android:state_window_focused="false" android:drawable="@color/transparent" />
+        <item android:state_focused="true" android:state_enabled="false"
+            android:state_pressed="true" android:drawable="@drawable/list_selector_disabled_holo_light" />
+        <item android:state_focused="true" android:state_pressed="true"
+            android:drawable="@drawable/list_selector_background_transition_holo_light" />
+        <item android:state_focused="false" android:state_pressed="true"
+            android:drawable="@drawable/list_selector_background_transition_holo_light" />
+    </selector>
+</reveal>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index d74c404..246bda1 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Laat die program toe om enige geïnstalleer mediadekodeerder te gebruik om te kan dekodeer vir terugspeel."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"bestuur vertroude eiebewyse"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Laat die program CA-sertifikate as vertroude eiebewyse installeer en deïnstalleer."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"bind aan ledige dienste"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Hierdie toestemming laat die Android-stelsel toe om aan \'n program se ledige dienste te bind."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"laat program gedurende ledige tyd loop"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Met hierdie toestemming kan die Android-stelsel die program in die agtergrond laat loop terwyl die toestel nie gebruik word nie."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lees/skryf na bronne wat diag besit"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Laat die program toe om na enige hulpbron wat deur die diag-groep besit word, te skryf, byvoorbeeld lêers in /dev. Dit kan potensieel stelselstabiliteit en sekuriteit affekteer. Dit moet NET gebruik word vir hardewarespesifieke diagnose deur die vervaardiger of operateur."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktiveer of deaktiveer programkomponente"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Laat die program toe om die foonkenmerke van die toestel te beheer. \'n Program met hierdie toestemming kan tussen netwerke wissel, die foonradio aan en af skakel, en dies meer, sonder om jou ooit te laat weet."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"lees foonstatus en identiteit"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Laat die program toe om toegang tot die foonfunksies van die toestel te verkry. Hierdie toestemming laat die program toe om te bepaal wat die foonnommer en toestel-IDs is, of die oproep aan die gang is, en die afgeleë nommer wat deur \'n oproep verbind word."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"lees presiese foonstate"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Gee die program toegang tot presiese foonstate. Hierdie toestemming laat die program toe om die werklike oproepstatus te bepaal, of \'n oproep aktief is en of dit in die agtergrond is. Dit kan ook mislukte oproepe, presiese dataverbindingstatus en mislukte dataverbindings bepaal."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"verhoed dat tablet slaap"</string>
     <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>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 56bdd24..4f38a82 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"ለመልሰህ አጫውት ፍታን በማንኛውም የተጫኑ በማህደረ መረጃ ዲኮደር ለመጠቀም  ለመተግበሪያ ይፈቅዳል።"</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"የታመኑ ምስክርነቶችን ያስተዳድሩ"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"መተግበሪያው CA የምስክር ወረቀቶችን እንደሚታመኑ ምስክርነቶች አንዲጭን እና እንዲያራግፍ ይፍቀዱ።"</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"ከስራ ፈት አገልግሎቶች ጋር ይሰሩ"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"ይህ ፍቃድ የAndroid ስርዓቱ የአንድ መተግበሪያ ስራ-ፈት አገልግሎቶችን እንዲያስር ያስችለዋል።"</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"ስራ በተፈታበት ጊዜ ላይ መተግበሪያውን አሂድ"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"ይህ ፍቃድ መሣሪያው ስራ ላይ ባልሆነ ጊዜ የAndroid ስርዓቱ መተግበሪያውን በጀርባ ውስጥ እንዲያሂደው ያስችለዋል።"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"በdiag ባለቤትነት ያሉ ንብረቶችን አንብብ/ፃፍ"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"በዲያግ ቡድን ባለቤትነት ወደ አለ ማንኛውም ንብረት ለምሳሌ በ/dev ያሉ ፋይሎች ለማንበብ እና ለመፃፍ ለመተግበሪያው ይፈቅዳሉ። ይህ በመሰረቱ የስርዓት መረጋጋትን እና ደህንነትን ሊጎዳ ይችላል። ይህ ውስን የሀርድዌር-ተኮር ዲያግኖስቲክስ በአምራቹ ወይም ከዋኙ ብቻ መሆን አለበት።"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"የመተግበሪያ ምንዝሮችን አንቃ ወይም አቦዝን"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"የመገልገያ መሳሪያውን የስልክ ባህሪያት ለመቆጣጠር ለመተግበሪያው ይፈቅዳል፡፡ ከዚህ ፍቃድ ጋር መተግበሪያ አውታረ መረቦችን ሊለውጥ ይችላል፤አንተን ምንም ሳያሳውቅ የስልኩን ሬድዮ አብራ እና አጥፋ እና የመሳሰሉትን ሊያበራ ይችላል፡፡"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"የስልክ ሁኔታና ማንነት አንብብ"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"መተግበሪያው የመሳሪያውን የስልክ ባህሪያት ላይ እንዲደርስ ይፈቅድለታል። ይህ ፈቃድ መተግበሪያው የስልክ ቁጥሩን እና የመሳሪያውን መታወቂያዎች፣ ጥሪ የነቃ እንደሆነ፣ እና በጥሪ የተገናኘውን የሩቅ ቁጥር እንዲወስን ይፈቅድለታል።"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"ትክክለኛዎቹን የስልክ ሁኔታዎች ያነብባል"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"መተግበሪያው ትክክለኛዎቹ የስልክ ሁኔታዎችን እንዲደርስባቸው ያስችለዋል። ይህ ፍቃድ መተግበሪያው የእውነተኛ ጥሪው ሁኔታ፣ አንድ ጥሪ ገባሪ ወይም ጀርባ ላይ ይሁን፣ ያልተሳኩ ጥሪዎች፣ ትክክለኛው የውሂብ ግንኙነት ሁኔታ እና የውሂብ ግንኙነት አለመሳካቶችን እንዲያውቅ ያስችለዋል።"</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ጡባዊ ከማንቀላፋት ተከላከል"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ስልክ ከማንቀላፋት ተከላከል"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ጡባዊውን ከመተኛት መከልከል ለመተግበሪያው ይፈቅዳሉ።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 56addd1..2c3549d 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"السماح للتطبيق باستخدام أي برنامج فك تشفير وسائط مثبت لفك التشفير من أجل التشغيل."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"إدارة بيانات الاعتماد الموثوقة"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"‏السماح للتطبيق بتثبيت شهادات CA وإلغاء تثبيتها باعتبارها بيانات اعتماد محل ثقة."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"الالتزام بالخدمات الخاملة"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"‏يتيح هذا الإذن لنظام Android الارتباط بخدمات وضع الخمول لأحد التطبيقات."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"تشغيل التطبيق أثناء وقت الخمول"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"‏يتيح هذا الإذن لنظام Android تشغيل التطبيق في الخلفية في حين أن الجهاز ليس قيد الاستخدام."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"قراءة/كتابة إلى الموارد المملوكة بواسطة التشخيص"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"‏للسماح للتطبيق بالقراءة والكتابة إلى أي مورد مملوك بواسطة مجموعة التشخيصات؛ على سبيل المثال، الملفات في /dev. من المحتمل أن يؤثر ذلك في استقرار النظام وأمانه. يجب ألا يستخدم ذلك سوى للتشخيصات الخاصة بالنظام من قِبل المصنِّع أو المشغِّل."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"تمكين مكونات التطبيق أو تعطيلها"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"للسماح للتطبيق بالتحكم في ميزات الهاتف بالجهاز. يمكن لأحد التطبيقات بهذا الإذن تبديل الشبكات وتشغيل لاسلكي الهاتف وإيقاف تشغيله وما إلى ذلك بدون إعلامك على الإطلاق."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"قراءة حالة الهاتف والهوية"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"للسماح للتطبيق بالدخول إلى ميزات الهاتف في الجهاز. ويتيح هذا الإذن للتطبيق تحديد رقم الهاتف ومعرّفات الجهاز، وما إذا كانت هناك مكالمة نشطة والرقم البعيد الذي تم الاتصال به في المكالمة."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"قراءة حالات الهاتف الدقيقة"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"للسماح للتطبيق بالوصول إلى حالات الهاتف الدقيقة. يتيح هذا الإذن للتطبيق تحديد حالة المكالمة الفعلية، سواء أكانت مكالمة نشطة أم في الخلفية، وإخفاق الاتصال، وحالة اتصال البيانات الدقيقة، وإخفاق اتصال البيانات."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"منع الجهاز اللوحي من الدخول في وضع السكون"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"منع الهاتف من الدخول في وضع السكون"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"للسماح للتطبيق بمنع الجهاز اللوحي من الانتقال إلى وضع السكون."</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 218d54a..af7f9e8 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Разрешава на приложението да използва всеки инсталиран медиен декодер с цел декодиране за възпроизвеждане."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"управление на надеждните идентификационни данни"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Разрешава на приложението да инсталира и деинсталира сертификати от сертифициращи органи като надеждни идентификационни данни."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"обвързване с услуги при неактивност"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Това разрешение позволява на системата Android да се свързва с неактивните услуги на приложението."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"изпълняване на приложението по време на неактивност"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Това разрешение позволява на системата Android да изпълнява приложението на заден план, докато устройството не се използва."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"четене/запис в ресурси, притежавани от diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Разрешава на приложението да чете и записва във всеки ресурс, притежаван от групата diag, например файловете в /dev. Това потенциално може да засегне стабилността и сигурността на системата. То трябва да се използва САМО за диагностика, конкретно за хардуера, от страна на производителя или оператора."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"активиране или деактивиране на компоненти на приложенията"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Разрешава на приложението да контролира телефонните функции на устройството. Приложение с такова разрешение може да превключва между мрежи, да включва и изключва радиомодула на телефона и други подобни, без изобщо да ви известява."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"четене на състоянието и идентификационните данни на телефона"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Разрешава на приложението достъп до телефонните функции на устройството. Това разрешение позволява на приложението да определя телефонния номер и идентификационния номер на устройството, дали се води разговор и отдалечения номер, до който е установена връзка с обаждането."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"четене на точните състояния на телефона"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Позволява на приложението да осъществява достъп до точните състояния на телефона. С това разрешение то може да определи действителното състояние на обаждането – дали е активно, или е на заден план, дали е неуспешно, точното състояние на връзката за пренос на данни и неуспешната връзка за пренос."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"предотвратяване на спящия режим на таблета"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"предотвратява спящ режим на телефона"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Разрешава на приложението да предотвратява преминаването на таблета в спящ режим."</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 415e248..50c7187 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permet que l\'aplicació utilitzi qualsevol descodificador de mitjans instal·lat per descodificar per a la reproducció."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gestiona les credencials de confiança"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permet que l\'aplicació instal·li i desinstal·li certificats de CA com a credencials de confiança."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"vincula als serveis inactius"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Amb aquest permís, el sistema Android podrà vincular-se amb els serveis inactius d\'una aplicació."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"executar l\'aplicació durant el temps d\'inactivitat"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Aquest permís permet que el sistema Android executi l\'aplicació en segon pla mentre el dispositiu no està en ús."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"llegir/escriure recursos propietat de diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permet que l\'aplicació llegeixi i escrigui a qualsevol recurs propietat del grup diag; per exemple, els fitxers de /dev. Això podria afectar l\'estabilitat i la seguretat del sistema. NOMÉS l\'hauria d\'utilitzar el fabricant o l\'operador per a diagnòstics específics de maquinari."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activa o desactiva els components de l\'aplicació"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permet que l\'aplicació controli les funcions de telèfon del dispositiu. Una aplicació amb aquest permís pot canviar de xarxa, activar i desactivar el senyal mòbil i dur a terme accions semblants sense notificar-t\'ho."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"veure l\'estat i la identitat del telèfon"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permet que l\'aplicació accedeixi a les funcions de telèfon del dispositiu. Aquest permís permet que l\'aplicació determini el número de telèfon i els identificadors del dispositiu, si hi ha una trucada activa i el número remot connectat amb una trucada."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"llegeix els estats exactes del telèfon"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permet que l\'aplicació accedeixi als estats exactes del telèfon. Amb aquest permís, l\'aplicació pot determinar l\'estat real de la trucada, si la trucada està activa o en segon pla, si s\'ha produït algun error, l\'estat exacte de la connexió de dades i els errors de la connexió de dades."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"evita que la tauleta entri en mode d\'inactivitat"</string>
     <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>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index c338661..69ca648 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Umožňuje aplikaci používat libovolný nainstalovaný dekodér médií k dekódování při přehrávání."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"správa důvěryhodných identifikačních údajů"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Umožňuje aplikaci instalovat a odinstalovat certifikáty CA jako důvěryhodné identifikační údaje."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"napojit se na nečinné služby"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Toto oprávnění umožní systému Android vázat se na nečinné služby aplikace."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"spustit aplikaci během nečinnosti"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Toto oprávnění umožňuje systému Android spustit aplikaci na pozadí, když zařízení není používáno."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"čtení nebo zápis do prostředků funkce diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Umožňuje aplikaci číst libovolné prostředky ve skupině diag, např. soubory ve složce /dev, a zapisovat do nich. Může dojít k ovlivnění stability a bezpečnosti systému. Toto nastavení by měl používat POUZE výrobce či operátor pro diagnostiku hardwaru."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivace či deaktivace komponent aplikací"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Umožňuje aplikaci ovládat telefonní funkce zařízení. Aplikace s tímto oprávněním smí bez upozornění přepínat sítě, zapínat a vypínat bezdrátový modul telefonu a podobně."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"čtení stavu a identity telefonu"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Umožňuje aplikaci získat přístup k telefonním funkcím zařízení. Toto oprávnění umožňuje aplikaci zjistit telefonní číslo telefonu, identifikační čísla zařízení, zda zrovna probíhá hovor, a vzdálené číslo, ke kterému je hovor připojen."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"čtení přesných stavů telefonů"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Umožňuje aplikaci používat přesné stavy telefonů. Toto oprávnění aplikaci umožňuje zjistit skutečný stav volání, zda je volání aktivní nebo na pozadí, zda volání selhalo, přesný stav datového připojení a zda datové připojení selhalo."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"bránění přechodu tabletu do režimu spánku"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"bránění přechodu telefonu do režimu spánku"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Umožňuje aplikaci zabránit přechodu tabletu do režimu spánku."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index bd4a3ec..07474b7 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Tillader, at appen bruger enhver installeret medieafkoder til at afkode til afspilning."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"administrer pålidelige logonoplysninger"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Tillader, at appen installerer og afinstallerer CA-certifikater som pålidelige loginoplysninger."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"knyt til tjenester i dvale"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Med denne tilladelse kan Android-systemet bindes til en applikations dvaletjenester."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"kør applikation, mens enheden er i dvale"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Med denne tilladelse kan Android-systemet køre applikationen i baggrunden, mens enheden ikke er i brug."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"læs/skriv til ressourcer ejet af diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Tillader, at appen kan læse og skrive til alle ressourcer, der ejes af diag-gruppen,  f.eks. filer i /dev. Dette kan muligvis påvirke systemets stabilitet og sikkerhed. Dette bør KUN bruges til hardwarespecifik diagnosticering, som foretages af producenten eller udbyderen."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivere eller deaktivere appkomponenter"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Tillader, at appen kan styre enhedens telefonfunktioner. En app med denne tilladelse kan skifte netværk, slå telefonsenderen til og fra og lignende uden at underrette dig."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"læse telefonens status og identitet"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Tillader, at appen kan få adgang til telefonfunktionerne på enheden. Med denne tilladelse kan appen fastslå telefonnummeret og enheds-id\'erne, hvorvidt et opkald er aktivt samt det eksterne nummer, der oprettes forbindelse til via et opkald."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"læse nøjagtig status for telefonen"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Tillader, at appen får adgang til den nøjagtige status for telefonen. Denne tilladelse giver appen mulighed for at fastlægge den rigtige opkaldsstatus – om et opkald er aktivt eller kører i baggrunden, om opkaldet mislykkes, hvad den nøjagtige status for dataforbindelsen er, og om dataforbindelsen mislykkes."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"afholde tabletcomputeren fra at gå i dvale"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"afholde telefonen fra at gå i dvale"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Tillader, at appen kan forhindre tabletten i at gå i dvale."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 4da2043..5d2515f 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Ermöglicht der App, alle installierten Mediendecodierer zur Wiedergabe zu verwenden."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"Vertrauenswürdige Anmeldedaten verwalten"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Ermöglicht der App, CA-Zertifikate als vertrauenswürdige Anmeldedaten zu installieren und zu deinstallieren."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"An inaktive Dienste binden"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Mit dieser Berechtigung kann sich das Android-System an die inaktiven Dienste einer App binden."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"App bei Inaktivität ausführen"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Diese Berechtigung ermöglicht es dem Android-System, die App im Hintergrund auszuführen, wenn das Gerät nicht verwendet wird."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"Lese-/Schreibberechtigung für zu Diagnosegruppe gehörige Elemente"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Ermöglicht der App, alle Elemente in der Diagnosegruppe zu lesen und zu bearbeiten, etwa Dateien in \"/dev\". Dies könnte eine potenzielle Gefährdung für die Stabilität und Sicherheit des Systems darstellen und sollte NUR für hardwarespezifische Diagnosen des Herstellers oder Mobilfunkanbieters verwendet werden."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"App-Komponenten aktivieren oder deaktivieren"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Ermöglicht der App, die Telefonfunktionen des Geräts zu steuern. Eine App mit dieser Berechtigung kann das Netzwerk wechseln oder das Radio des Telefons ein- und ausschalten, ohne Sie darüber zu informieren."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"Telefonstatus und Identität abrufen"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Ermöglicht der App, auf die Telefonfunktionen des Geräts zuzugreifen. Die Berechtigung erlaubt der App, die Telefonnummer und Geräte-IDs zu erfassen, festzustellen, ob gerade ein Gespräch geführt wird, und die Rufnummer verbundener Anrufer zu lesen."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"Genaue Telefonstatusangaben abrufen"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Ermöglicht der App, auf die genauen Telefonstatusangaben zuzugreifen. Diese Erlaubnis ermöglicht der App, den tatsächlichen Rufstatus zu ermitteln, das bedeutet, ob ein Anruf aktiv ist oder im Hintergrund abläuft, ob bei einem Anruf ein Fehler aufgetreten ist, wie der genaue Datenverbindungsstatus lautet oder ob bei der Datenverbindung ein Fehler aufgetreten ist."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"Ruhezustand des Tablets deaktivieren"</string>
     <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>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 9e06e2a..8f297e1 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Επιτρέπει στην εφαρμογή τη χρήση οποιουδήποτε εγκατεστημένου αποκωδικοποιητή μέσων για αναπαραγωγή."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"διαχείριση αξιόπιστων διαπιστευτηρίων"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Επιτρέπει στην εφαρμογή την εγκατάσταση και την απεγκατάσταση πιστοποιητικών CA ως αξιόπιστων διαπιστευτηρίων."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"σύνδεση σε υπηρεσίες αδράνειας"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Αυτή η άδεια επιτρέπει στο σύστημα Android να συνδέεται στις υπηρεσίες αδράνειας μιας εφαρμογής."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"εκτέλεση εφαρμογής κατά τη λειτουργία αδράνειας"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Αυτή η άδεια επιτρέπει στο σύστημα Android να εκτελεί την εφαρμογή στο παρασκήνιο όταν δεν χρησιμοποιείται η συσκευή."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"ανάγνωση/εγγραφή σε πόρους που ανήκουν στο διαγνωστικό"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Επιτρέπει στην εφαρμογή την ανάγνωση και την εγγραφή σε οποιονδήποτε πόρο που ανήκει στην ομάδα διαγνωστικού (π.χ. αρχεία στον κατάλογο /dev). Αυτό ενδέχεται να επηρεάσει την σταθερότητα και την ασφάλεια του συστήματος. Θα πρέπει να χρησιμοποιείται ΜΟΝΟ για διαγνωστικά υλικού από τον κατασκευαστή ή τον χειριστή."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ενεργοποίηση ή απενεργοποίηση στοιχείων εφαρμογής"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Επιτρέπει στην εφαρμογή να ελέγχει τις λειτουργίες τηλεφώνου της συσκευής. Μια εφαρμογή η οποία διαθέτει αυτήν την άδεια μπορεί να κάνει εναλλαγή μεταξύ δικτύων, να ενεργοποιεί και να απενεργοποιεί το ραδιόφωνο του τηλεφώνου και άλλα, χωρίς να ειδοποιείστε."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"ανάγνωση κατάστασης και ταυτότητας τηλεφώνου"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Επιτρέπει στην εφαρμογή την πρόσβαση στις λειτουργίες τηλεφώνου της συσκευής. Αυτή η άδεια δίνει τη δυνατότητα στην εφαρμογή να καθορίζει τον αριθμό τηλεφώνου και τα αναγνωριστικά συσκευών, εάν μια κλήση είναι ενεργή, καθώς και τον απομακρυσμένο αριθμό που συνδέεται από μια κλήση."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"ανάγνωση ακριβούς κατάστασης τηλεφώνου"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Επιτρέπει στην εφαρμογή να αποκτήσει πρόσβαση στην ακριβή κατάσταση του τηλεφώνου. Αυτή η άδεια επιτρέπει στην εφαρμογή να καθορίσει την πραγματική κατάσταση της κλήσης, εάν η κλήση είναι ενεργή ή πραγματοποιείται στο παρασκήνιο, αποτυχίες κλήσεων, ακριβή δεδομένα κατάστασης σύνδεσης και αποτυχίες σύνδεσης δεδομένων."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"παρεμπόδιση μετάβασης του tablet σε κατάσταση αδράνειας"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"παρεμπόδιση μετάβασης του τηλεφώνου σε κατάσταση αδράνειας"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Επιτρέπει στην εφαρμογή την παρεμπόδιση της μετάβασης του tablet σε κατάσταση αδράνειας."</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index a4b2f93..c5158498 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Allows the app to use any installed media decoder to decode for playback."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"manage trusted credentials"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Allows the app to install and uninstall CA certificates as trusted credentials."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"bind to idle services"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"This permission allows the Android system to bind to an application\'s idle services."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"run application during idle time"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"This permission allows the Android system to run the application in the background while the device is not in use."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"read/write to resources owned by diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Allows the app to read and write to any resource owned by the diag group; for example, files in /dev. This could potentially affect system stability and security. This should ONLY be used for hardware-specific diagnostics by the manufacturer or operator."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"enable or disable app components"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Allows the app to control the phone features of the device. An app with this permission can switch networks, turn the phone radio on and off and the like without ever notifying you."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"read phone status and identity"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Allows the app to access the phone features of the device. This permission allows the app to determine the phone number and device IDs, whether a call is active and the remote number connected by a call."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"read precise phone states"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Allows the app to access the precise phone states. This permission allows the app to determine the real call status, whether a call is active or in the background, call fails, precise data connection status and data connection fails."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"prevent tablet from sleeping"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"prevent phone from sleeping"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Allows the app to prevent the tablet from going to sleep."</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index a4b2f93..c5158498 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Allows the app to use any installed media decoder to decode for playback."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"manage trusted credentials"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Allows the app to install and uninstall CA certificates as trusted credentials."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"bind to idle services"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"This permission allows the Android system to bind to an application\'s idle services."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"run application during idle time"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"This permission allows the Android system to run the application in the background while the device is not in use."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"read/write to resources owned by diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Allows the app to read and write to any resource owned by the diag group; for example, files in /dev. This could potentially affect system stability and security. This should ONLY be used for hardware-specific diagnostics by the manufacturer or operator."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"enable or disable app components"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Allows the app to control the phone features of the device. An app with this permission can switch networks, turn the phone radio on and off and the like without ever notifying you."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"read phone status and identity"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Allows the app to access the phone features of the device. This permission allows the app to determine the phone number and device IDs, whether a call is active and the remote number connected by a call."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"read precise phone states"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Allows the app to access the precise phone states. This permission allows the app to determine the real call status, whether a call is active or in the background, call fails, precise data connection status and data connection fails."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"prevent tablet from sleeping"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"prevent phone from sleeping"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Allows the app to prevent the tablet from going to sleep."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index f8e789c..4a0c78a 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -423,8 +423,10 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permite que la aplicación use cualquier decodificador de archivos multimedia instalado para la reproducción."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"administrar credenciales de confianza"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permite que la aplicación instale y desinstale certificados de CA como credenciales de confianza."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"vincular con servicios inactivos"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Este permiso autoriza al sistema Android a vincularse con los servicios inactivos de una aplicación."</string>
+    <!-- no translation found for permlab_bindIdleService (816311765497613780) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (1767538493214100612) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"leer y escribir a recursos dentro del grupo de diagnóstico"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite que la aplicación lea y escriba en cualquier recurso propiedad del grupo de diagnóstico como, por ejemplo, archivos in/dev. Este permiso podría afectar la seguridad y estabilidad del sistema. SOLO se debe utilizar para diagnósticos específicos de hardware realizados por el fabricante o el operador."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activar o desactivar componentes de la aplicación"</string>
@@ -563,6 +565,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permite que la aplicación controle las funciones de teléfono del dispositivo. Una aplicación con este permiso puede cambiar redes, encender y apagar la radio del teléfono y tareas similares sin siquiera notificártelo."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"leer la identidad y el estado del dispositivo"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite que la aplicación acceda a las funciones de teléfono del dispositivo. La aplicación puede utilizar este permiso para descubrir identificadores de dispositivos y números de teléfono, para saber si una llamada está activa y para conocer el número remoto con el que se ha establecido conexión mediante una llamada."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"Leer estados precisos del teléfono"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permite que la aplicación acceda a los estados precisos del teléfono y determine el estado real de la llamada, si hay una llamada activa o en segundo plano, si se produjeron fallos en la llamada, el estado preciso de la conexión de datos y si hubo fallos relacionados con la conexión de datos."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"evitar que el tablet entre en estado de inactividad"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"evitar que el dispositivo entre en estado de inactividad"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permite que la aplicación evite que la tablet entre en estado de inactividad."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 5010841..515caca 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permite que la aplicación use cualquier decodificador de archivos multimedia instalado para la reproducción."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"administrar credenciales de confianza"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permite que la aplicación instale y desinstale certificados de CA como credenciales de confianza."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"ocultar para servicios inactivos"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Esto permite que el sistema Android enlace con servicios inactivos de una aplicación."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"ejecutar la aplicación durante el tiempo de inactividad"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Esto permite que el sistema Android ejecute la aplicación en segundo plano mientras el dispositivo no se utiliza."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"leer/escribir en los recursos propiedad del grupo de diagnóstico"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite que la aplicación consulte y escriba en cualquier recurso del grupo de diagnóstico como, por ejemplo, archivos en /dev. Este permiso podría afectar a la seguridad y estabilidad del sistema. SOLO se debe usar para diagnósticos específicos de hardware realizados por el fabricante o el operador."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"habilitar o inhabilitar componentes de la aplicación"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permite que la aplicación controle las funciones de teléfono del dispositivo. Las aplicaciones que tengan este permiso pueden cambiar de red, desactivar la señal móvil, etc., sin necesidad de informar al usuario."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"consultar la identidad y el estado del teléfono"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite que la aplicación acceda a las funciones de teléfono del dispositivo. La aplicación puede utilizar este permiso para descubrir identificadores de dispositivos y números de teléfono, para saber si una llamada está activa y para conocer el número remoto con el que se ha establecido conexión mediante una llamada."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"leer estados precisos del teléfono"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permite que la aplicación acceda a estados precisos del teléfono y que pueda determinar el estado real de la llamada, si una llamada está activa o en segundo plano, si se ha producido un error en la llamada, el estado de conexión de datos preciso y si se ha producido un error en la conexión de datos."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"impedir que el tablet entre en modo de suspensión"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"impedir que el teléfono entre en modo de suspensión"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permite que la aplicación impida que el tablet entre en modo de suspensión."</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 29feb3e..988ab47 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Võimaldab rakendusel taasesituseks kasutada mis tahes installitud meediumidekooderit."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"usaldusväärsete mandaatide haldamine"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Lubab rakendusel installida ja desinstallida usaldusväärsete mandaatidena CA-sertifikaate."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"sidumine tegevusetute teenustega"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"See luba võimaldab Androidi süsteemil siduda end rakenduse tegevusetute teenustega."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"rakenduse käitamine tegevusetul ajal"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"See luba võimaldab Android-süsteemil käitada rakendust taustal siis, kui seadet ei kasutata."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"loe/kirjuta valija allikaid"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Võimaldab rakendusel lugeda valimisrühma mis tahes ressurssi ja sellesse kirjutada (näiteks kaustas /dev olevad failid). See võib mõjutada süsteemi stabiilsust ja turvet. Seda tohiks kasutada tootja või operaator AINULT riistvaraspetsiifiliseks diagnostikaks."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"Rakenduse komponentide lubamine või keelamine"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Võimaldab rakendusel juhtida seadme telefonifunktsioone. Selle loaga rakendus saab vahetada võrke, lülitada telefoniraadiot sisse ja välja ning teha muudki ilma teid teavitamata."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"lugege telefoni olekut ja identiteeti"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Annab rakendusele juurdepääsu seadme telefonifunktsioonidele. See luba võimaldab rakendusel määrata telefoninumbri ja seadme ID-d ning kontrollida, kas kõne on aktiivne ja kaugnumber on kõne kaudu telefoniga ühendatud."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"telefoni täpsete olekute lugemine"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Lubab rakendusel hankida juurdepääsu telefoni täpsetele olekutele. Selle loa korral saab rakendus tuvastada kõne tõelise oleku, kas kõne on aktiivne või taustal, kõnede ebaõnnestumised, täpse andmesideühenduse oleku ja andmesideühenduse ebaõnnestumised."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"tahvelarvuti uinumise vältimine"</string>
     <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>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 34ee392..8ce67fd 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -423,8 +423,10 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"‏اجازه می‎دهد برنامه از هر رمزگشای رسانه نصب شده‌ای استفاده کند تا برای پخش رمزگشایی شود."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"مدیریت اطلاعات کاربری مورد اعتماد"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"‏به برنامه امکان می‌دهد گواهینامه‌های CA را به عنوان اطلاعات کاربری مورد اعتماد نصب یا حذف نصب کند."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"اتصال با سرویس‌های غیرفعال"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"‏این مجوز به سیستم Android امکان می‌دهد به سرویس‌های غیرفعال یک برنامه متصل شود."</string>
+    <!-- no translation found for permlab_bindIdleService (816311765497613780) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (1767538493214100612) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"خواندن/نوشتن منابع متعلق به تشخیص"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"‏به برنامه اجازه می‌دهد هر منبعی را که متعلق به گروه تشخیص است بخواند و در آن بنویسد؛ به‌عنوان مثال، فایل‌های /dev. این امر به‌صورت بالقوه می‌تواند بر پایدار بودن و امنیت سیستم تأثیر بگذارد. این تنها باید برای تشخیص‎‌های مختص سخت‌افزار توسط تولیدکننده یا اپراتور استفاده شود."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"فعال یا غیر فعال کردن اجزای برنامه"</string>
@@ -563,6 +565,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"‏به برنامه اجازه می‎دهد ویژگی‌های دستگاه را کنترل کند. برنامه‎ای که این مجوز را دارد می‎تواند بدون اطلاع شما تعویض شبکه داشته باشد، رادیوی تلفن را روشن یا خاموش کند و کارهایی از این قبیل را انجام دهد."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"خواندن وضعیت تلفن و شناسه"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"به برنامه اجازه می‌دهد به ویژگی‌های تلفن دستگاه شما دسترسی پیدا کند. این مجوز به برنامه اجازه می‌دهد شماره تلفن و شناسه‌های دستگاه، فعال بودن یک تماس و شماره راه دوری که با یک تماس متصل شده است را مشخص کند."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"خواندن وضعیت‌های دقیق تلفن"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"به برنامه امکان می‌دهد به وضعیت‌های دقیق تلفن دسترسی داشته باشد. این مجوز به برنامه امکان می‌دهد وضعیت واقعی تماس اینکه آیا تماس فعال است یا در پس‌زمینه قرار دارد، تماس‌های ناموفق، وضعیت دقیق اتصال داده و اتصال‌های ناموفق داده را تعیین کند."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ممانعت از به خواب رفتن رایانهٔ لوحی"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ممانعت از به خواب رفتن تلفن"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"‏به برنامه اجازه می‎دهد تا از غیرفعال شدن رایانهٔ لوحی جلوگیری کند."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 01f37d5..602b513 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -423,8 +423,10 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Sallii sovelluksen käyttää mitä tahansa asennettua tietovälineen koodin purkajaa toistoa varten."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"hallinnoi luotettavia varmenteita"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Antaa sovellukselle luvan asentaa ja poistaa luotettavia CA-varmenteita."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"sido käyttämättömiin palveluihin"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Tämä käyttöoikeus antaa Android-järjestelmän sitoa sovelluksen käyttämättömiä palveluita."</string>
+    <!-- no translation found for permlab_bindIdleService (816311765497613780) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (1767538493214100612) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lue diag:in omistamia resursseja / kirjoita resursseihin"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Antaa sovelluksen lukea ja kirjoittaa diag-ryhmän omistamiin resursseihin, esimerkiksi /dev-hakemistossa oleviin tiedostoihin. Tämä voi vaikuttaa järjestelmän vakauteen ja turvallisuuteen. Tämä lupa tulee myöntää VAIN valmistajan tai operaattorin laitteistotesteille."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"sovelluskomponenttien ottaminen käyttöön tai pois käytöstä"</string>
@@ -563,6 +565,10 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Antaa sovelluksen hallita laitteen puhelinominaisuuksia. Jos sovelluksella on tämä oikeus, se voi esimerkiksi vaihtaa verkkoa tai ottaa puhelinradion käyttöön tai poistaa sen käytöstä ilmoittamatta käyttäjälle."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"lue puhelimen tila ja identiteetti"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Antaa sovelluksen käyttää laitteen puhelinominaisuuksia. Sovellus voi määrittää puhelinnumeron ja laitteen tunnuksen, puhelun tilan sekä soitetun numeron."</string>
+    <!-- no translation found for permlab_readPrecisePhoneState (5476483020282007597) -->
+    <skip />
+    <!-- no translation found for permdesc_readPrecisePhoneState (6648009074263855418) -->
+    <skip />
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"estä tablet-laitetta menemästä virransäästötilaan"</string>
     <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>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index fe29fb8..679eed1 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -423,8 +423,10 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permet à une application d\'utiliser n\'importe quel décodeur installé pour lire les fichiers multimédias."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gérer les certificats de confiance"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permet à l\'application d\'installer et de désinstaller les certificats CA en tant que certificats de confiance."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"lier aux services inactifs"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Cette autorisation permet à la plateforme Android de se lier aux services inactifs d\'une application."</string>
+    <!-- no translation found for permlab_bindIdleService (816311765497613780) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (1767538493214100612) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lire ou modifier les ressources appartenant au groupe de diagnostics"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permet à l\'application d\'obtenir des droits en lecture et en écriture pour toute ressource appartenant au groupe de diagnostics (par exemple, les fichiers du répertoire /dev). Cela peut affecter la stabilité et la sécurité du système. Cette fonctionnalité est UNIQUEMENT réservée aux diagnostics matériels effectués par le fabricant ou le fournisseur de services."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activer ou désactiver les composants d\'une application"</string>
@@ -563,6 +565,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permet à l\'application de contrôler les fonctionnalités de téléphonie de l\'appareil. Une application disposant de cette autorisation peut, par exemple, basculer d\'un réseau à l\'autre et activer ou désactiver le signal radio du téléphone à votre insu."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"voir l\'état et l\'identité du téléphone"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permet à l\'application d\'accéder aux fonctionnalités téléphoniques de l\'appareil. Cette autorisation permet à l\'application de déterminer le numéro de téléphone et les identifiants de l\'appareil, si un appel est actif et le numéro distant connecté par un appel."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"accéder aux états précis du téléphone"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permet à l\'application d\'accéder aux états précis du téléphone. Cette autorisation lui permet de déterminer le statut d\'appel réel, si un appel est actif ou en arrière-plan, si des appels ont échoué, l\'état précis de la connexion et si cette dernière a échoué."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"empêcher la tablette de passer en mode veille"</string>
     <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>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index dae681d..51f0f76 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permet à une application d\'utiliser n\'importe quel décodeur installé pour lire les fichiers multimédias."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gérer les certificats de confiance"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permet à l\'application d\'installer et de désinstaller les certificats CA en tant que certificats de confiance."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"associer aux services d\'inactivité"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Cette autorisation permet à la plate-forme Android de se lier aux services inactifs d\'une application."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"exécuter l\'application lorsque l\'appareil est inactif"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Cette autorisation permet au système Android d\'exécuter l\'application en arrière-plan lorsque l\'appareil est inactif."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"Lecture/écriture dans les ressources appartenant aux diagnostics"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permet à l\'application d\'obtenir des droits en lecture/écriture concernant toute ressource appartenant au groupe de diagnostics (par exemple, les fichiers du répertoire /dev). Ceci peut affecter la stabilité et la sécurité du système. Cette fonctionnalité est UNIQUEMENT réservée aux diagnostics matériels effectués par le fabricant ou l\'opérateur."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activer ou désactiver les composants de l\'application"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permet à l\'application de contrôler les fonctionnalités de téléphonie de l\'appareil. Une application disposant de cette autorisation peut, par exemple, basculer d\'un réseau à l\'autre et activer ou désactiver le signal radio du téléphone à votre insu."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"voir l\'état et l\'identité du téléphone"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permet à l\'application d\'accéder aux fonctionnalités téléphoniques de l\'appareil. Cette autorisation permet à l\'application de déterminer le numéro de téléphone et les identifiants de l\'appareil, si un appel est actif et le numéro distant connecté par un appel."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"Accéder aux états précis du téléphone"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permet à l\'application d\'accéder aux états précis du téléphone. Cette autorisation lui permet de déterminer le statut d\'appel réel, si un appel est actif ou en arrière-plan, si des appels ont échoué, l\'état précis de la connexion et si cette dernière a échoué."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"empêcher la tablette de passer en mode veille"</string>
     <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>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index f0c005d..b35c14f 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"ऐप्स  को प्लेबैक डीकोड करने के लिए किसी भी इंस्टॉल किए गए डीकोडर का उपयोग करने देता है."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"विश्वसनीय क्रेडेंशियल प्रबंधित करें"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"ऐप्स  को CA प्रमाणपत्रों को विश्वसनीय क्रेडेंशियल के रूप में इंस्टॉल और अनइंस्टॉल करने दें"</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"निष्क्रिय सेवाओं से आबद्ध करें"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"यह अनुमति Android सिस्टम को किसी एप्लिकेशन की निष्क्रिय सेवाओं से आबद्ध होने देती है."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"निष्क्रिय समय के दौरान एप्लिकेशन चलाएं"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"यह अनुमति Android सिस्टम को उपकरण के उपयोग में नहीं रहने पर एप्लिकेशन को पृष्ठभूमि में चलाने देती है."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"निदान के स्‍वामित्‍व वाले संसाधनों को पढ़ें/लिखें"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"ऐप्स को diag समूह के स्‍वामित्‍व वाले किसी संसाधन को पढ़ने और उसमें लिखने देता है; उदाहरण के लिए, /dev की फ़ाइलें. यह सिस्‍टम की स्‍थिरता और सुरक्षा को संभावित रूप से प्रभावित कर सकता है. इसका उपयोग निर्माता या ऑपरेटर द्वारा केवल हार्डवेयर-विशिष्ट निदान के लिए किया जाना चाहिए."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ऐप्स घटकों को सक्षम या अक्षम करें"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"ऐप्स को उपकरण की फ़ोन सुविधाएं नियंत्रित करने देता है. इस अनुमति वाला कोई ऐप्स आपको सूचित किए बिना नेटवर्क स्‍विच कर सकता है, फ़ोन का रेडियो चालू और बंद कर सकता है और ऐसे ही अन्य कार्य कर सकता है."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"फ़ोन की स्‍थिति और पहचान पढ़ें"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ऐप्स  को उपकरण की फ़ोन सुविधाओं तक पहुंचने देता है. यह अनुमति ऐप्स  को फ़ोन नंबर और उपकरण आईडी, कॉल सक्रिय है या नहीं, और कॉल द्वारा कनेक्ट किया गया दूरस्‍थ नंबर निर्धारित करने देती है."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"सटीक फ़ोन स्थितियों को पढ़ना"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"ऐप्स को सटीक फ़ोन स्थितियों की एक्सेस देती है. यह अनुमति ऐप्स को कॉल की वास्तविक स्थिति, चाहे वह कॉल सक्रिय हो या पृष्ठभूमि में हो, कॉल विफलताओं, सटीक डेटा कनेक्शन की स्थिति और डेटा कनेक्शन विफलताओं का पता लगाने देती है."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"टेबलेट को निष्‍क्रिय होने से रोकें"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"फ़ोन को निष्‍क्रिय होने से रोकें"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ऐप्स  को टेबलेट को प्रयोग में नहीं हो जाने से रोकता है."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 5b7a098..4504bad 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Aplikaciji omogućuje korištenje bilo kojim instaliranim dekoderom medija za dekodiranje radi reprodukcije."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"upravljanje pouzdanim vjerodajnicama"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Omogućuje aplikaciji instaliranje i deinstaliranje CA certifikata kao pouzdanih vjerodajnica."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"veži uz usluge u mirovanju"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"To dopuštenje omogućuje sustavu Android da se veže uz aplikacijine usluge u mirovanju."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"izvodi aplikaciju tijekom mirovanja"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"To dopuštenje omogućuje sustavu Android da izvodi aplikaciju u pozadini dok se uređaj ne upotrebljava."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"pisanje/čitanje u resursima čije je vlasnik dijagnostika"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Aplikaciji omogućuje čitanje i pisanje na bilo koji resurs u vlasništvu dijag. grupe; na primjer, datoteke u sustavu /dev. To bi moglo utjecati na stabilnost sustava i sigurnost. Dozvolu bi trebao upotrebljavati proizvođač ili operater SAMO za dijagnostiku koja se odnosi na hardver."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"omogućavanje ili onemogućavanje komponenti aplikacije"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Omogućuje aplikaciji upravljanje telefonskim značajkama uređaja. Aplikacija s tom dozvolom može izmjenjivati mreže, uključiti i isključiti radiouređaj telefona i tome slično, a da vas o tome uopće ne obavijesti."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"čitanje statusa i identiteta telefona"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Aplikaciji omogućuje pristup telefonskim značajkama uređaja. Ta dozvola aplikaciji omogućuje utvrđivanje telefonskog broja i ID-ova uređaja, je li poziv aktivan te udaljeni broj koji je povezan pozivom."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"čitaj precizna stanja telefona"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Omogućuje aplikaciji pristup preciznim stanjima telefona. To dopuštenje omogućuje aplikaciji da odredi stvarni status poziva, je li poziv aktivan ili u pozadini, neuspjele pozive, precizne podatke o statusu veze te neuspjela uspostavljanja podatkovnih veza."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"spriječi mirovanje tabletnog uređaja"</string>
     <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>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index c48ca2a..92ab180 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Lehetővé teszi egy alkalmazás számára bármely telepített médiadekóder használatát a lejátszás dekódolásához."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"megbízható tanúsítványok kezelése"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Lehetővé teszi az alkalmazás számára a CA tanúsítványok telepítését és eltávolítását."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"csatolás tétlen szolgáltatásokhoz"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Ez az engedély lehetővé teszi az Android számára, hogy összekapcsolódjon egy alkalmazás tétlen szolgáltatásaival."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"alkalmazás futtatása tétlen időszakban"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Ezzel az engedéllyel az Android a háttérben futtathatja az alkalmazást, amikor az eszközt nem használják."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"a diag tulajdonában lévő erőforrások olvasása és írása"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Lehetővé teszi egy alkalmazás számára, hogy olvassa és írja a diagnosztikai csoport minden erőforrását, például a /dev könyvtárban lévő fájlokat. Ez potenciálisan befolyásolhatja a rendszer stabilitását és biztonságát, ezért CSAK a gyártó vagy a szolgáltató használhatja hardverspecifikus diagnosztizálásra."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"alkalmazáskomponensek be- és kikapcsolása"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Lehetővé teszi az alkalmazás számára, hogy az eszköz telefonálási funkcióit vezérelje. Egy ilyen engedéllyel rendelkező alkalmazás váltani tud a hálózatok között, be- és kikapcsolhatja a telefon rádióját, és hasonlókat tehet anélkül, hogy valaha értesítené Önt."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"telefonállapot és azonosító olvasása"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Lehetővé teszi az alkalmazás számára, hogy hozzáférjen az eszköz telefonálási funkcióihoz. Az engedéllyel rendelkező alkalmazás meghatározhatja a telefonszámot és eszközazonosítókat, hogy egy hívás aktív-e, valamint híváskor a másik fél telefonszámát."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"pontos telefonállapot megállapítása"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Engedélyezi, hogy az alkalmazás hozzáférjen a pontos telefonállapothoz. Az ilyen engedéllyel rendelkező alkalmazás képes meghatározni a valós hívási állapotot: hogy egy hívás aktív-e vagy a háttérben van, a hívás meghiúsult-e, illetve a pontos adatkapcsoltot és az adatkapcsolati műveletek meghiúsulását."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"táblagép alvás üzemmódjának megakadályozása"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"telefon alvó üzemmódjának megakadályozása"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Lehetővé teszi az alkalmazás számára, hogy megakadályozza, hogy a táblagép alvó üzemmódra váltson."</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index c544ddb..77b8070 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Թույլ է տալիս հավելվածին օգտագործել ցանկացած տեղադրված մեդիա վերծանիչ` նվագարկումը ապակոդավորելու համար:"</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"կառավարել վստահելի հավաստագրերը"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Թույլատրում է հավելվածին տեղադրել և ապատեղադրել CA վկայագրերը՝ որպես վստահելի հավաստագրեր:"</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"կապակցել ոչ ակտիվ ծառայությունների հետ"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Այս թույլտվությունը հնարավորություն է տալիս Android համակարգին կապ հաստատել ծրագրի չաշխատող ծառայությունների հետ:"</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"գործադրել ծրագրեր պարապուրդի ժամանակ"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Այս թույլտվությունը հնարավորություն է տալիս, որ Android համակարգը ծրագրեր գործադրի ֆոնային ռեժիմում, երբ սարքը չի օգտագործվում:"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"կարդալ կամ գրել ախտորոշիչին պատկանող ռեսուրսները"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Թույլ է տալիս հավելվածին կարդալ և գրել ախտորոշիչ խմբին պատկանող ցանկացած ռեսուրսում, ինչպես օրինակ ֆայլերը /dev-ում: Դա կարող է ազդել համակարգի կայունության և անվտանգության վրա: Սա պետք է օգտագործել միայն արտադրողի կամ օպերատորի կողմից սարքին հատուկ ախտորոշման համար:"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"միացնել կամ անջատել հավելվածի բաղադրիչները"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Թույլ է տալիս հավելվածին կառավարել սարքի հեռախոսային գործիքները: Այս թույլտվությամբ հավելվածը կարող է փոխարկել ցանցերը, միացնելև անջատել հեռախոսի ռադիոն և նման այլ բաներ` առանց ձեզ երբևէ տեղեկացնելու:"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"կարդալ հեռախոսի կարգավիճակը և ինքնությունը"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Թույլ է տալիս հավելվածին օգտագործել սարքի հեռախոսային գործիքները: Այս թույլտվությունը հավելվածին հնարավորություն է տալիս որոշել հեռախոսահամարը և սարքի ID-ները, արդյոք զանգը ակտիվ է և միացված զանգի հեռակա հեռախոսահամարը:"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"դիտել հեռախոսի ճշգրիտ կարգավիճակները"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Թույլ է տալիս ծրագրին մուտք ունենալ հեռախոսի ճշգրիտ կարգավիճակներին: Այս թույլատվության շնորհիվ ծրագիրը կարող է որոշել զանգի իրական կարգավիճակը, արդյոք զանգը ակտիվ է, թե հետին պլանում է, զանգերի ժամանակ տեղի ունեցած սխալները, տվյալների միացման ճշգրիտ կարգավիճակը և տվյալների միացման ժամանակ տեղի ունեցած սխալները:"</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"զերծ պահել գրասալիկը քնելուց"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"կանխել հեռախոսի քնի ռեժիմին անցնելը"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Թույլ է տալիս հավելվածին կանխել գրասալիկի` քնի ռեժիմին անցնելը:"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index c144c60..de49cba 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Mengizinkan apl menggunakan pengawasandi media apa pun yang terpasang guna mengawasandikan media untuk diputar."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"kelola kredensial tepercaya"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Izinkan aplikasi memasang dan mencopot pemasangan sertifikat CA sebagai kredensial tepercaya."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"mengikat ke layanan yang sedang menganggur"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Izin ini memungkinkan sistem Android mengikat layanan waktu menganggur aplikasi."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"menjalankan aplikasi selama waktu nganggur"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Izin ini memungkinkan sistem Android menjalankan aplikasi di latar belakang saat perangkat tidak digunakan."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"baca/tulis ke sumber daya yang dimiliki oleh diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Mengizinkan apl membaca dan menulis ke sumber daya apa pun yang dimiliki oleh grup diag; misalnya, file dalam /dev. Izin ini berpotensi memengaruhi kestabilan dan keamanan sistem. Sebaiknya ini HANYA digunakan untuk diagnosis khusus perangkat keras oleh pabrikan atau operator."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"mengaktifkan atau menonaktifkan komponen apl"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Mengizinkan apl mengontrol fitur telepon perangkat. Apl dengan izin ini dapat mengalihkan jaringan, menyalakan dan mematikan radio ponsel, dan melakukan hal serupa lainnya tanpa pernah memberi tahu Anda."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"baca identitas dan status ponsel"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Memungkinkan aplikasi mengakses fitur telepon perangkat. Izin ini memungkinkan aplikasi menentukan nomor telepon dan ID perangkat, apakah suatu panggilan aktif atau tidak, dan nomor jarak jauh yang tersambung oleh sebuah panggilan."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"membaca keadaan ponsel dengan akurat"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Memungkinkan aplikasi mengakses keadaan ponsel dengan akurat. Izin ini memungkinkan aplikasi menentukan status panggilan yang sebenarnya, apakah panggilan sedang aktif atau di latar belakang, kegagalan panggilan, status sambungan data yang akurat, dan kegagalan sambungan data."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"cegah tablet dari tidur"</string>
     <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>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index a16e5d0..808a3be 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Consente all\'applicazione di utilizzare qualsiasi decoder multimediale installato per la decodifica ai fini della riproduzione."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gestione di credenziali attendibili"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Consente all\'app di installare e disinstallare certificati CA come credenziali attendibili."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"associazione a servizi non disponibili"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Questa autorizzazione consente al sistema Android di associarsi ai servizi inattivi di un\'applicazione."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"esegui l\'applicazione nel tempo di inattività del sistema"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Questa autorizzazione consente al sistema Android di eseguire l\'applicazione in background mentre il dispositivo non è in uso."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lettura/scrittura risorse di proprietà di diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Consente all\'applicazione di leggere le risorse del gruppo diag e scrivere in esse, ad esempio i file in /dev. Ciò potrebbe influire su stabilità e sicurezza del sistema. Dovrebbe essere utilizzata SOLTANTO per diagnostiche specifiche dell\'hardware effettuate dal produttore o dall\'operatore."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"attivazione/disattivazione componenti applicazioni"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Consente all\'applicazione di controllare le funzioni telefoniche del dispositivo. Un\'applicazione con questa autorizzazione può cambiare rete, attivare/disattivare il segnale radio del telefono e così via a tua insaputa."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"lettura stato e identità telefono"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Consente all\'applicazione di accedere alle funzioni telefoniche del dispositivo. Questa autorizzazione consente all\'applicazione di determinare il numero di telefono e gli ID dei dispositivi, se una chiamata è attiva e il numero remoto connesso da una chiamata."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"rileva gli stati esatti del telefono"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Consente all\'app di accedere allo stato esatto del telefono. Questa autorizzazione consente all\'app di determinare il reale stato della chiamata: se una chiamata è attiva, in sottofondo o non riuscita. Inoltre, rileva l\'esatto stato della connessione dati nonché le connessioni dati non riuscite."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"disattivazione stand-by del tablet"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"disattivazione stand-by del telefono"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Consente all\'applicazione di impedire lo stand-by del tablet."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 20218f2..096c4ed 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"הרשאה זו מאפשרת לאפליקציה להשתמש בכל מפענח מדיה מותקן כדי לבצע פענוח להשמעה."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"ניהול פרטי כניסה מהימנים"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"‏מאפשרת לאפליקציה להתקין ולהסיר אישורי CA כפרטי כניסה מהימנים."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"אגד עם שירותים במצב לא פעיל"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"‏ההרשאה הזו מאפשרת למערכת Android לאגד אל שירותי אפליקציה במצב לא פעיל."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"הרצת אפליקציה בזמן מצב לא פעיל"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"‏ההרשאה הזו מאפשרת למערכת Android להריץ את האפליקציה ברקע כשהמכשיר אינו בשימוש."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"‏קרא/כתוב במשאבים בבעלות diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"‏מאפשר לאפליקציה לקרוא ולכתוב בכל משאב שבבעלות קבוצת ה-diag; לדוגמה, קבצים ב-‎/dev. פעולה זו עשויה להשפיע על היציבות והאבטחה של המערכת. אפשרות זו צריכה לשמש רק את היצרן או המפעיל, לצורך אבחונים ספציפיים לחומרה."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"הפעלה או השבתה של רכיבי אפליקציות"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"מאפשר לאפליקציה לשלוט בתכונות הטלפון של המכשיר. אפליקציה בעלת הרשאה זו יכולה לעבור בין רשתות, להפעיל ולכבות את הרדיו בטלפון ולבצע פעולות נוספות דומות מבלי ליידע אותך."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"קריאת הסטטוס והזהות של הטלפון"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"מאפשר לאפליקציה לגשת לתכונות הטלפון של המכשיר. אישור זה מתיר לאפליקציה לגלות את מספר הטלפון ואת זיהויי המכשיר, האם שיחה פעילה ואת המספר המרוחק המחובר באמצעות שיחה."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"קריאת מצבי טלפון מדויקים"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"מאפשר לאפליקציה לגשת למצבי הטלפון המדויקים. ההרשאה הזו מאפשרית לאפליקציה לדעת מה סטטוס השיחה בפועל, האם שיחה פעילה או ברקע, כשלי שיחות, סטטוס מדויק על חיבור נתונים וכשלים בחיבור נתונים."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"מנע מהטאבלט לעבור למצב שינה"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"מניעת מעבר הטלפון למצב שינה"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"מאפשר לאפליקציה למנוע מהטאבלט לעבור למצב שינה."</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 58495e8..8f5d7fe 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"インストール済みのメディアデコーダーを使用して再生用にデコードすることをアプリに許可します。"</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"信頼できる認証情報の管理"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"CA証明書を信頼できる認証情報としてインストールしたりアンインストールしたりすることをアプリに許可します。"</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"アイドルサービスへのバインディング"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"この許可により、Androidシステムはアプリのアイドルサービスにバインディングできるようになります。"</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"アイドル状態でのアプリの実行"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"この権限により、端末が使用中でない場合でもAndroidシステムがバックグラウンドでアプリを実行できるようになります。"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"diagが所有するリソースの読み書き"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"diagグループが所有するリソース(/dev内のファイルなど)の読み書きをアプリに許可します。許可すると、システムの安定性とセキュリティに影響が生じる可能性があります。メーカー/通信事業者によるハードウェア固有の診断以外には使用しないでください。"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"アプリのコンポーネントの有効/無効化"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"端末の電話機能の制御をアプリに許可します。許可すると、アプリではユーザーに通知なくネットワークの切り替え、無線通信のON/OFFなどを行えるようになります。"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"端末のステータスとIDの読み取り"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"端末の電話機能へのアクセスをアプリに許可します。これにより、電話番号、端末ID、通話中かどうか、通話相手の電話番号をアプリから特定できるようになります。"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"正確な電話ステータスの読み取り"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"正確な電話ステータスにアクセスすることをアプリに許可します。これにより、実際の発信ステータス(発信がアクティブか、バックグラウンドか)、発信エラー、正確なデータ接続ステータス、データ接続エラーをアプリから特定できるようになります。"</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"タブレットのスリープを無効化"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"端末のスリープを無効にする"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"タブレットのスリープを無効にすることをアプリに許可します。"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index c82b606..8bb038c 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"აპს დასაკრავად შეეძლება გამოიყენოს ნებისმიერი დაყენებული მედია დეკოდერი."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"სანდო მტკიცებულებების მართვა"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"აპისთვის ნების დართვა, მოახდინოს CA სერტიფიკატების სანდო მტკიცებულებებად ინსტალაცია და დეინსტალაცია."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"უქმე სერვისებზე მიბმა"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"ეს უფლება საშუალებას აძლევს Android-ის სისტემას, განახორციელოს აპლიკაციის უქმე სერვისების მიბმა."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"უქმე მდგომარეობისას აპლიკაციის გაშვება"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"ეს უფლება Android-ის სისტემას უფლებას ანიჭებს ფონურად გაუშვას აპლიკაცია, როდესაც მოწყობილობა არ გამოიყენება."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"სისტემის დიაგნოსტიკის რესურსებში წაკითხვა/ჩაწერის უფლება"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"აპს შეეძლება, წაიკითხოს ან ჩაწეროს ნებისმიერ რესურსში, რომელიც დიაგნოსტიკის ჯგუფს ეკუთვნის, მაგალითად, ფაილები /dev-ში. ამან შესაძლოა იმოქმედოს სისტემის სტაბილურობასა და უსაფრთხოებაზე. მისი გამოყენება მხოლოდ მწარმოებლის ან ოპერატორის მიერ ტექნიკის სპეციფიკური დიაგნოსტიკისთვის უნდა მოხდეს."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"აპის კომპონენტების ჩართვა ან გამორთვა"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"აპს შეეძლება აკონტროლოს მოწყობილობაზე ტელეფონის ფუნქციები. ამ უფლების მქონე აპს შეუძლია ქსელების გადართვა, ტელეფონის რადიოს ჩართვა და გამორთვა, მომხმარებლისათვის შეტყობინების გარეშე."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"ტელეფონის სტატუსისა და იდენტობის წაკითხვა"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"აპს შეეძლება ჰქონდეს წვდომა მოწყობილობის სატელეფონო ფუნქციებზე. აპმა მსგავსი უფლებით შეძლებს დაადგინოს ტელეფონის ნომერი, მისი სერიული გამოცემა, აქტიური ზარი, დაკავშირებული ნომერი და მსგავსი."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"ტელეფონის ზუსტი მდგომარეობების დადგენა"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"ანიჭებს აპს ტელეფონის ზუსტ მდგომარეობაზე წვდომას. ეს უფლება საშუალებას აძლევს აპს შეიტყოს ინფორმაცია ზარის რეალურ სტატუსზე, აქტიურია ზარი თუ უკანა ფონზეა, ვერ განხორციელებული ზარები, მონაცემთა გადაცემის ზუსტი სტატუსი და ვერ განხორციელებული მონაცემთა კავშირები."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"დაიცავით ტაბლეტი დაძინებისგან"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ტელეფონის ძილის რეჟიმში გადასვლის აღკვეთა"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"აპს შეეძლება ხელი შეუშალოს ტაბლეტის დაძინებას."</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index f0026be..1d93e2e 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"ឲ្យ​កម្មវិធី​ប្រើ​កម្មវិធី​ឌិកូដ​មេឌៀ​ដែល​បាន​ដំឡើង ដើម្បី​ឌិកូដ​សម្រាប់​ការ​ចាក់​ឡើងវិញ។"</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"គ្រប់គ្រង​ព័ត៌មាន​សម្ងាត់​ដែល​ទុកចិត្ត"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​ដំឡើង និង​លុប​វិញ្ញាបនបត្រ CA នៅ​ពេល​មាន​ព័ត៌មាន​សម្ងាត់​ដែល​ទុកចិត្ត។"</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"ភ្ជាប់​​ទៅ​​សេវាកម្ម​ទំនេរ"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​ប្រព័ន្ធ Android ចង​​សេវាកម្ម​ទំនេរ​របស់​កម្មវិធី។"</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"ដំណើរការ​កម្មវិធី​អំឡុង​ពេល​ទំនេរ"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​ប្រព័ន្ធ Android ដំណើរការ​កម្មវិធី​ក្នុង​ផ្ទៃ​ខាង​ក្រោយ ខណៈ​ដែល​ឧបករណ៍​មិន​កំពុង​ប្រើ។"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"អាន/សរសេរ​ធនធាន​គ្រប់គ្រង​ប្រអប់"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"ឲ្យ​កម្មវិធី​អាន និង​សរសេរ​ប្រភព​ណាមួយ​ដែល​គ្រប់គ្រង​ដោយ​ក្រុម​អ្នក​វិនិច្ឆ័យ ឧទាហរណ៍ ឯកសារ​នៅ​ក្នុង /dev ។ វា​អាច​ប៉ះពាល់​យ៉ាង​ខ្លាំង​ដល់​ស្ថេរ​ភាព​ និង​សុវត្ថិភាព​ប្រព័ន្ធ។ វា​គួរ​ត្រូវ​បាន​ប្រើ​សម្រាប់​វិនិច្ឆ័យ​ផ្នែក​រឹង​ជាក់​លាក់​ដោយ​ក្រុមហ៊ុន​ផលិត ឬ​ប្រតិបត្តិ​ករ។"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"បិទ ឬ​បើក​សមាសធាតុ​កម្មវិធី"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"ឲ្យ​កម្មវិធី​ពិនិត្យ​លក្ខណៈ​ទូរស័ព្ទ​នៃ​ឧបករណ៍។ កម្មវិធី​ដែល​មាន​សិទ្ធិ​នេះ​អាច​ប្ដូរ​បណ្ដាញ បិទ និង​បើកវិទ្យុ​ក្នុង​ទូរស័ព្ទ​ដោយ​មិន​ជូន​ដំណឹង​អ្នក។"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"អាន​ស្ថានភាព និង​អត្តសញ្ញាណ​ទូរស័ព្ទ"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ឲ្យ​កម្មវិធី​ចូល​ដំណើរការ​លក្ខណៈ​ទូរស័ព្ទ​នៃ​ឧបករណ៍។ សិទ្ធិ​នេះ​​ឲ្យ​កម្មវិធី​កំណត់​លេខ​ទូរស័ព្ទ និង​លេខ​សម្គាល់​ឧបករណ៍ ថា​តើ​ការ​ហៅ​សកម្ម និង​លេខ​ពី​ចម្ងាយ​បាន​ភ្ជាប់​ដោយ​ការ​ហៅ។"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"អាន​ស្ថានភាព​ទូរស័ព្ទ​ត្រឹមត្រូវ"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"ឲ្យ​កម្មវិធី​ចូល​ដំណើរ​ការ​ស្ថានភាព​ទូរស័ព្ទ​​​ត្រឹមត្រូវ។ សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​កម្មវិធី​កំណត់​ស្ថានភាព​ហៅ​ជាក់ស្ដែង ថា​តើ​ការ​ហៅ​សកម្ម ឬ​ស្ថិត​ក្នុង​ផ្ទៃ​ខាងក្រោយ ការ​ហៅ​បរាជ័យ ស្ថានភាព​ភ្ជាប់​ទិន្នន័យ​ត្រឹមត្រូវ និង​ការ​ភ្ជាប់​ទិន្នន័យ​បរាជ័យ។"</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ការពារ​​កុំព្យូទ័រ​បន្ទះ​មិន​ឲ្យ​ដេក"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ការ​ពារ​ទូរស័ព្ទ​មិន​ឲ្យ​ដេក"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ឲ្យ​​កម្មវិធី​ការពារ​កុំព្យូទ័រ​បន្ទះ​មិន​ឲ្យ​ដេក។"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 5a7f9b8..03542c5 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"애플리케이션에서 설치된 모든 미디어 디코더를 사용하여 재생하는 데 디코딩할 수 있도록 허용합니다."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"신뢰할 수 있는 자격증명 관리"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"앱에서 CA 인증서를 신뢰할 수 있는 자격증명으로 설치 및 제거하도록 허용합니다."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"유휴 서비스에 연결"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"이 권한을 부여하면 Android 시스템이 애플리케이션의 유휴 서비스에 연결할 수 있습니다."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"유휴 시간 동안 애플리케이션 실행"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"이 권한을 부여하면 기기를 사용하지 않는 동안 Android 시스템이 백그라운드에서 애플리케이션을 실행할 수 있게 됩니다."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"진단 그룹 소유의 리소스 읽기/쓰기"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"앱이 진단 그룹 소유의 리소스(예: /dev에 있는 파일)를 읽고 쓸 수 있도록 허용합니다. 이 기능은 시스템 안정성 및 보안에 영향을 미칠 수 있으므로 제조업체 또는 사업자가 하드웨어 관련 진단을 수행하는 경우에만 사용해야 합니다."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"앱 구성요소 사용 또는 사용 안함"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"앱이 기기의 휴대전화 기능을 관리할 수 있도록 허용합니다. 이 권한을 갖는 앱은 사용자에게 알리지 않고 네트워크를 전환하거나 무선 기능을 켜고 끄는 등의 작업을 수행할 수 있습니다."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"휴대전화 상태 및 ID 읽기"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"앱이 기기의 휴대전화 기능에 액세스할 수 있도록 허용합니다. 이 권한을 사용하면 앱이 전화번호 및 기기의 ID, 활성 통화인지 여부, 통화가 연결된 원격 번호 등을 확인할 수 있습니다."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"정확한 전화 상태 읽기"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"앱이 정확한 전화 상태에 액세스할 수 있도록 허용합니다. 이 권한을 부여하면 앱이 실제 통화 상태, 활성 통화 또는 백그라운드 상태인지 여부, 통화 실패, 정확한 데이터 연결 상태 및 데이터 연결 실패 등을 판단합니다."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"태블릿이 절전 모드로 전환되지 않도록 설정"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"휴대전화가 절전 모드로 전환되지 않도록 설정"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"앱이 태블릿의 절전 모드 전환을 막도록 허용합니다."</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index abca9cd..fabdf87 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -423,8 +423,10 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"ອະນຸຍາດໃຫ້ແອັບຯໃຊ້ທຸກຕົວຖອດລະຫັດສື່ທີ່ຕິດຕັ້ງໄວ້ແລ້ວ ເພື່ອການຖອດລະຫັດການຫຼິ້ນໄຟລ໌ຕ່າງໆ."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"ຈັດການໜັງສືຮັບຮອງທີ່ເຊື່ອຖືໄດ້."</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"ອະ​ນຸ​ຍາດ​ໃຫ້ແອັບຯ ຕິດຕັ້ງ ແລະ ຖອນການຕິດຕັ້ງໃບຢັ້ງຢືນ CA ທີ່ເປັນໃບຮັບຮອງທີ່ເຊື່ອຖືໄດ້."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"ເຊື່ອມຫາບໍລິການທີ່ບໍ່ໄດ້ນໍາໃຊ້"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"ສິດນີ້ຈະອະນຸຍາດໃຫ້ລະບົບ Android ສາມາດຜູກກັບການບໍລິການຂອງແອັບພລິເຄຊັນທີ່ບໍ່ໄດ້ເຮັດວຽກຢູ່ໄດ້."</string>
+    <!-- no translation found for permlab_bindIdleService (816311765497613780) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (1767538493214100612) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"ອ່ານ/ຂຽນ ໃສ່ຊັບພະຍາກອນທີ່ເປັນຂອງກຸ່ມວິໄຈ"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນອ່ານ ແລະຂຽນ ໃສ່ທຸກຊັບພະຍາກອນທີ່ເປັນຂອງກຸ່ມວິນິໄສ; ຕົວຢ່າງ: ໄຟລ໌ໃນ /dev. ສິ່ງນີ້ອາດສົ່ງຜົນກະທົບຕໍ່ຄວາມສະຖຽນ ແລະຄວາມປອດໄພຂອງລະບົບ. ສິ່ງນີ້ຄວນໃຊ້ສຳຫຼັບການວິເຄາະບັນຫາຈຳເພາະ ຂອງບາງຮາດແວໂດຍຜູ່ຜະລິດ ຫຼືຜູ່ປະຕິບັດການເທົ່ານັ້ນ."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ເປີດ ຫຼືປິດນຳໃຊ້ອົງປະກອບຂອງແອັບຯ"</string>
@@ -563,6 +565,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມຄວາມສາມາດຂອງໂທລະສັບໃນອຸປະກອນ. ແອັບຯທີ່ມີການອະນຸຍາດນີ້ຈະສາມາດສະລັບເຄືອຂ່າຍ, ເປີດ ຫຼືປິດສັນຍານວິທະຍຸ ແລະຄວາມສາມາດອື່ນທີ່ຄ້າຍກັນ ໂດຍບໍ່ມີການແຈ້ງເຕືອນທ່ານ."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"ອ່ານສະຖານະ ແລະຂໍ້ມູນລະບຸໂຕຕົນຂອງໂທລະສັບ"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ອະນຸຍາດໃຫ້ແອັບຯ ເຂົ້າເຖິງຄວາມສາມາດການໂທລະສັບຂອງອຸປະກອນ. ການກຳນົດສິດນີ້ເຮັດໃຫ້ແອັບຯສາມາດກວດສອບເບີໂທລະສັບ ແລະ ID ຂອງອຸປະກອນ, ບໍ່ວ່າການໂທຈະຍັງດຳເນີນຢູ່ ແລະເບີປາຍທາງເຊື່ອມຕໍ່ຢູ່ຫຼືບໍ່ກໍຕາມ."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"ອ່ານ​ຄ່າ​ສະ​ຖາ​ນະ​ລະ​ອຽດ​ຂອງ​ໂທ​ລະ​ສັບ"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບຯ​ເຂົ້າ​ເຖິງ​ສະ​ຖາ​ນະ​ໂດຍ​ລະ​ອຽດ​ຂອງ​ໂທ​ລະ​ສັບ. ການ​ອະ​ນຸ​ຍາດ​ນີ້​ຈະ​ຍິນຍອມ​ໃຫ້​ແອັບຯ​ກວດ​ສອບ​ສະ​ຖານ​ະ​ການ​ໂທ​ແທ້ໆ ວ່າ​ກຳ​ລັງ​ດຳ​ເນີນ​ຢູ່ ຫຼື​ຢູ່​ໃນ​ແບັກ​ກ​ຣາວ, ຄວາມລົ້ມ​ເຫລວ​ຂອງ​ການ​ໂທ, ສະ​ຖາ​ນະ​ການ​ເຊື່ອມ​ຕໍ່​ຂໍ້​ມູນ​ແບບ​ລະ​ອຽດ ແລະ​ຄວາມ​ລົ້ມ​ເຫລວ​ຂອງ​ການ​ເຊື່ອມ​ຕໍ່​ຂໍ້​ມູນ."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ຂັດຂວາງບໍ່ໃຫ້ປິດໜ້າຈໍແທັບເລັດ"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ຂັດຂວາງບໍ່ໃຫ້ໂທລະສັບປິດໜ້າຈໍ"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ອະນຸຍາດໃຫ້ແອັບຯ ປ້ອງກັນບໍ່ໃຫ້ປິດໜ້າຈໍແທັບເລັດ."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index c4e7d11..e08dd93 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Leidžiama programai naudoti bet kurį įdiegtą medijos dekoderį norint iššifruoti atkūrimą."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"tvarkyti patikimus prisijungimo duomenis"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Programoje galima įdiegti ir iš jos pašalinti CA sertifikatus kaip patikimus prisijungimo duomenis."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"susaistyti su neaktyviomis paslaugomis"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Šiuo leidimu „Android“ sistemai leidžiama susaistyti su programos neaktyviomis paslaugomis."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"paleisti programą, kai įrenginys yra neaktyvus"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Šiuo leidimu sistemai „Android“ leidžiama fone paleisti programą, kai įrenginys yra nenaudojamas."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"skaityti / rašyti ištekliuose, priklausančiuose diagnostikai"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Leidžiama programai skaityti ir rašyti visuose diagnostikos grupei priklausančiuose ištekliuose, pvz., failuose, esančiuose /dev. Tai gali paveikti sistemos stabilumą ir saugą. Tai turėtų būti naudojama TIK gamintojui ar operatoriui atliekant aparatinės įrangos diagnostiką."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"įgalinti programos komponentus arba jų neleisti"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Leidžiama programai valdyti įrenginio telefono funkcijas. Šį leidimą turinti programa gali perjungti tinklus, įjungti ir išjungti telefono radiją ir atlikti panašius veiksmus jūsų neįspėdama."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"skaityti telefono būseną ir tapatybę"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Leidžiama programai pasiekti telefono funkcijas įrenginyje. Šis leidimas suteikia teisę programai nustatyti telefono numerį ir įrenginio ID, tai, ar skambutis aktyvus, ir skambučiu prijungtą nuotolinį numerį."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"skaityti tikslias telefono būsenas"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Programai leidžiama pasiekti tikslias telefono būsenas. Šiuo leidimu programai leidžiama nustatyti tikrą skambučio būseną, ar skambutis yra aktyvus, ar vyksta fone, ar paskambinti nepavyksta, tikslią duomenų ryšio būseną ir ar nepavyksta užmegzto duomenų ryšio."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"neleisti planšetiniam kompiuteriui užmigti"</string>
     <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>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 4ba1f96..33dd64f 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Ļauj lietotnei izmantot jebkuru instalētu multivides failu dekodētāju, lai dekodētu failus atskaņošanai."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"Uzticamo akreditācijas datu pārvaldība"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Ļauj lietotnei instalēt un atinstalēt CA sertifikātus kā uzticamus akreditācijas datus."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"saistīšana ar neaktīviem pakalpojumiem"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Pamatojoties uz šo atļauju, Android sistēma var izveidot saiti ar lietojumprogrammas neaktīvajiem pakalpojumiem."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"Lietojumprogrammas darbība dīkstāves laikā"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Ar šo atļauju Android sistēmā lietojumprogramma darbojas fonā, kad ierīce netiek lietota."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lasīt grupas “diag” resursus un rakstīt tajos"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Ļauj lietotnei lasīt un rakstīt jebkurā resursā, kas pieder diagnostikas grupai, piemēram, failiem mapē /dev. Tas var ietekmēt sistēmas stabilitāti un drošību. Var izmantot ražotājs vai operators TIKAI konkrētas aparatūras diagnostikai."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"iespējot vai atspējot lietotnes komponentus"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Ļauj lietotnei kontrolēt ierīces tālruņa funkcijas. Lietotne, kurai ir šī atļauja, var pārslēgt tīklus, ieslēgt un izslēgt tālruņa radio un veikt tamlīdzīgas darbības, nebrīdinot jūs."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"lasīt tālruņa statusu un identitāti"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Ļauj lietotnei piekļūt ierīces tālruņa funkcijām. Ar šo atļauju lietotne var noteikt tālruņa numuru un ierīču ID, zvana statusu un attālo numuru, ar ko ir izveidots savienojums, veicot zvanu."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"precīzu tālruņa statusa datu lasīšana"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Ļauj lietotnei piekļūt precīziem datiem par tālruņa statusu. Izmantojot šo atļauju, lietotne var noteikt zvana faktisko statusu, vai zvans ir aktīvs vai notiek fonā, vai zvans nav izdevies, kā arī precīzu datu savienojuma statusu un neizdevušos datu savienojumus."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"novērst planšetdatora pāriešanu miega režīmā"</string>
     <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>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 0d2da73..1590063 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Апп нь тоглуулах үедээ код тайлахдаа суулгагдсан ямарч медиа код тайлагчийг ашиглах боломжтой."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"итгэмжлэгдсэн жуухуудыг удирдах"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Апп-д CA сертификатуудыг итгэмжлэгдсэн жуух байдлаар суулгах болон устгахыг зөвшөөрнө."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"идэвхгүй үйлчилгээнүүдтэй холбогдох"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Энэ зөвшөөрөл Андройд системд аппликешний идэвхгүй үйлчилгээтэй холбогдох боломж олгоно."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"Сул зогсолтын хугацаанд аппликешнийг ажиллуулна"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Энэ зөвшөөрөл нь Андройд системд төхөөрөмжийг ашиглахгүй байгаа үед аппликешныг далд ажиллуулах боломж олгоно."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"оношлох грүпийн эзэмшдэг нөөцрүү унших/бичих"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Апп нь оношлох грүпийн эзэмшдэг, жишээ нь /dev доторх файлууд, дурын  нөөцийг унших бичих боломжтой.Энэ нь системийн тогвортой байдал болон аюулгүй байдалд бодитоор нөлөөлнө. Энэ нь үйлдвэрлэгч болон операторын хардверт-зориулсан оношлогоонд ашиглагдана."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"апп компонентыг идэвхжүүлэх эсвэл идэвхгүй болгох"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Апп-н төхөөрөмжийн утасны функцийг удирдах боломжтой. Энэ зөвшөөрөлтэй апп  нь танд анхааруулахгүйгээр сүлжээг сэлгэх, утасны радиог асаах, унтраах боломжтой."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"утасны статус ба таниулбарыг унших"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Апп нь төхөөрөмжийн утасны функцд хандах боломжтой. Энэ зөвшөөрөл нь апп-д утасны дугаар болон төхөөрөмжийн ID-г, дуудлага идэвхтэй эсэх, холын дугаар дуудлагаар холбогдсон байгаа эсэхийг тогтоох боломжийг олгоно,"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"утасны байдлыг нарийн унших"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Апп-д утасны тодорхой байдалд хандах боломжийг олгодог. Энэ зөвшөөрөл апп-д дуудлагын бодит статус, дуудлага идэвхтэй эсхүл ар талд тавигдсан эсэх, амжилтгүй дуудлага болон дата холболтын нарийн статус болон дата холболтын алдааг тодорхойлох боломж олгоно."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"таблетыг унтуулахгүй байлгах"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"утсыг унтуулахгүй байлгах"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Апп нь таблетыг унтахаас сэргийлэх боломжтой"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 6ebdfe1..f2fed04 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -423,8 +423,10 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Membenarkan apl untuk menggunakan sebarang penyahkod media yang dipasangkan untuk menyahkod main semula."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"urus bukti kelayakan yang dipercayai"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Membenarkan apl memasang dan menyahpasang sijil CA sebagai bukti kelayakan yang dipercayai."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"diikat ke perkhidmatan melahu"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Kebenaran ini membolehkan sistem Android mengikat kepada perkhidmatan melahu aplikasi."</string>
+    <!-- no translation found for permlab_bindIdleService (816311765497613780) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (1767538493214100612) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"baca/tulis ke sumber yang dimiliki oleh diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Membenarkan apl membaca dan menulis ke sebarang sumber yang dimiliki oleh kumpulan diag; contohnya, fail dalam /dev. Hal ini berpotensi menjejaskan kestabilan dan keselamatan sistem. Perkara ini seharusnya HANYA digunakan untuk diagnosis khusus perkakasan oleh pengilang atau pengendali."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"dayakan atau lumpuhkan komponen apl"</string>
@@ -563,6 +565,10 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Membenarkan apl untuk mengawal ciri-ciri telefon peranti. Apl dengan kebenaran ini boleh menukar rangkaian, menghidupkan dan mematikan radio telefon dan sebagainya tanpa memberitahu anda."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"baca status dan identiti telefon"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Membenarkan apl mengakses ciri telefon pada peranti. Kebenaran ini membolehkan apl menentukan nombor telefon dan ID peranti, sama ada panggilan aktif dan nombor jauh yang dihubungkan dengan panggilan."</string>
+    <!-- no translation found for permlab_readPrecisePhoneState (5476483020282007597) -->
+    <skip />
+    <!-- no translation found for permdesc_readPrecisePhoneState (6648009074263855418) -->
+    <skip />
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"menghalang tablet daripada tidur"</string>
     <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>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 26b27fb..2e584e5 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Lar appen bruke en hvilken som helst installert mediedekoder for å dekode for avspilling."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"administrer pålitelig legitimasjon"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Lar appen installere og avinstallere CA-sertifikater som pålitelig legitimasjon."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"knytt til inaktive tjenester"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Denne tillatelsen gjør at Android-systemet kan binde seg til appers inaktive tjenester."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"kjør appen når den ikke er i bruk"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Denne tillatelsen gjør at Android-systemet kan kjøre appen i bakgrunnen mens enheten ikke er i bruk."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lese/skrive ressurser eid av diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Lar appen lese og skrive til alle ressurser som eies av gruppen «diag», som for eksempel filer i /dev. Dette kan potensielt påvirke systemets sikkerhet og stabilitet. Dette bør BARE brukes av produsenten eller operatøren til maskinvarespesifikk diagnostikk."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivere eller deaktivere appkomponenter"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Lar appen kontrollere telefonfunksjonene til enheten. En app som har denne tillatelsen kan bytte nettverk, slå telefonens radio på og av og lignende, uten å varsle deg i det hele tatt."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"lese telefonstatus og -identitet"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Lar appen bruke enhetens telefonfunksjoner. Med denne tillatelsen kan appen finne telefonnummer og enhets-ID-er, registrere om en samtale pågår, og se det eksterne nummeret det opprettes en forbindelse med via oppringing."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"lese nøyaktige telefontilstander"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Gir appen tillatelse til å bruke nøyaktige telefontilstander. Denne tillatelsen gjør at appen kan fastslå den faktiske anropstatusen, om et anrop er aktivt eller i bakgrunnen, anropsfeil, nøyaktig status for datatilkobling og datatilkoblingsfeil."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"hindre nettbrettet fra å gå over til sovemodus"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"forhindre telefonen fra å sove"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Lar appen hindre nettbrettet fra å gå over i sovemodus."</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index b8a7122..09497dc 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Hiermee kan de app alle geïnstalleerde mediadecoders gebruiken om te decoderen voor het afspelen."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"vertrouwde inloggegevens beheren"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Hiermee kan de app CA-certificaten installeren en verwijderen als vertrouwde inloggegevens."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"koppelen aan inactieve services"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Met deze toestemming kan het Android-systeem koppelen aan de inactieve services van een app."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"app uitvoeren tijdens inactiviteit"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Met dit recht kan het Android-systeem de app op de achtergrond uitvoeren terwijl het apparaat niet wordt gebruikt."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lezen/schrijven naar bronnen van diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Hiermee kan de app lezen en schrijven naar elke bron die hoort bij de diagnostische groep, zoals bestanden in /dev. Hierdoor kan de systeemstabiliteit en -veiligheid worden beïnvloed. Dit mag ALLEEN worden gebruikt voor hardwarespecifieke diagnostiek door de fabrikant of provider."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"componenten van apps in- of uitschakelen"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Hiermee kan de app de telefoonfuncties van het apparaat beheren. Een app met deze toestemming kan schakelen tussen netwerken, kan de radio van de telefoon in- en uitschakelen en dergelijke acties uitvoeren zonder dat u hiervan op de hoogte wordt gesteld."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"telefoonstatus en -identiteit lezen"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Hiermee kan de app toegang krijgen tot de telefoonfuncties van het apparaat, Met deze toestemming kan de app het telefoonnummer en de apparaat-ID\'s bepalen, of een oproep actief is, en het andere telefoonnummer waarmee wordt gebeld."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"exacte telefoonstatus lezen"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Toestaan dat de app toegang krijgt tot de exacte telefoonstatus. Hiermee kan de app bepalen wat de echte oproepstatus is, of een oproep actief is of zich op de achtergrond bevindt, of er mislukte oproepen zijn, wat de exacte status van de gegevensverbinding is en of er mislukte gegevensverbindingen zijn."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"voorkomen dat tablet overschakelt naar slaapmodus"</string>
     <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>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 8aa847f..37dd42d 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Pozwala aplikacji na użycie dowolnego zainstalowanego dekodera multimediów do odtwarzania."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"zarządzanie zaufanymi danymi uwierzytelniającymi"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Zezwala aplikacji na instalowanie i odinstalowywanie certyfikatów CA jako zaufanych danych uwierzytelniających."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"powiązanie z nieaktywnymi usługami"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"To uprawnienie umożliwia powiązanie systemu Android z nieaktywnymi usługami aplikacji."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"uruchom aplikację w czasie bezczynności"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"To uprawnienie pozwala systemowi Android uruchomić aplikację w tle, gdy urządzenie nie jest używane."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"czytanie/zapisywanie w zasobach należących do diagnostyki"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Pozwala aplikacji na czytanie i zapisywanie wszystkich zasobów należących do grupy diagnostyki, na przykład plików w katalogu /dev. Może to potencjalnie wpłynąć na stabilność i bezpieczeństwo systemu. Powinno być wykorzystywane WYŁĄCZNIE do diagnozowania sprzętu przez producenta lub operatora."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"włączanie lub wyłączanie składników aplikacji"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Pozwala aplikacji na kontrolowanie funkcji telefonu w urządzeniu. Aplikacja z tymi uprawnieniami może zmieniać, włączać i wyłączać sieci bezprzewodowe itp. bez informowania użytkownika."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"odczytywanie stanu i informacji o telefonie"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Pozwala aplikacji na dostęp do funkcji telefonicznych urządzenia. Aplikacja z tym uprawnieniem może odczytać numer telefonu i identyfikator urządzenia, sprawdzić, czy połączenie jest aktywne, oraz poznać numer, z którym jest nawiązane połączenie."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"dokładne rozpoznawanie stanów telefonu"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Pozwala aplikacji dokładnie rozpoznawać stany telefonu. Aplikacja z tym uprawnieniem może określić rzeczywisty stan połączenia, ustalić, czy jest ono aktywne czy znajduje się w tle, odczytać informacje o nieudanych połączeniach, precyzyjnie określić stan połączenia transmisji danych oraz odczytać informacje o błędach transmisji danych."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"zapobieganie przechodzeniu tabletu do trybu uśpienia"</string>
     <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>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index b87a4b0..6eb6cb2 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permite que a aplicação utilize qualquer descodificador de multimédia instalado para descodificar a reprodução."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gerir credenciais fidedignas"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permite que a aplicação instale e desinstale certificados da AC (Autoridade de certificação) como credenciais fidedignas."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"associar a serviços inativos"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Esta autorização permite que o sistema Android seja vinculado aos serviços inativos de uma aplicação."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"executar aplicação durante o tempo de inatividade"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Esta autorização permite ao sistema Android executar a aplicação em segundo plano enquanto o dispositivo não estiver a ser utilizado."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"ler/escrever em recursos propriedade de diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite à aplicação ler e escrever em qualquer recurso que seja propriedade do grupo diag; por exemplo, ficheiros em /dev. Isto pode potencialmente afetar a estabilidade e a segurança do sistema e deve ser utilizado APENAS para diagnósticos específicos do hardware pelo fabricante ou pelo operador."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ativar ou desativar componentes da aplicação"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permite que a aplicação controle as funcionalidades de telefone do aparelho. Uma aplicação com esta permissão pode alternar entre redes, ligar/desligar o rádio do telefone e outras coisas semelhantes sem sequer o notificar."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"ler o estado e a identidade do telemóvel"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite que a aplicação aceda às funcionalidades de telefone do dispositivo. Esta autorização permite que a aplicação determine o número de telefone e IDs do dispositivo, se alguma chamada está ativa e qual o número remoto ligado por uma chamada."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"ler os estados precisos do telemóvel"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permite que a aplicação aceda ao estados precisos do telemóvel. Esta autorização permite que a aplicação determine o estado real da chamada, se uma chamada está ativa ou em segundo plano, falhas em chamadas, o estado preciso da ligação de dados e falhas de ligação de dados."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"impedir que o tablet entre em inactividade"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"impedir modo de inactividade do telefone"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permite que a aplicação impeça o tablet de entrar no modo de suspensão."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 2cfad8f..3a5b131 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permite que o aplicativo use qualquer decodificador de mídia instalado para reprodução."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gerenciar credenciais confiáveis"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permite que o aplicativo instale e desinstale certificados CA como credenciais confiáveis."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"associar a serviços inativos"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Permite que o sistema Android seja associado aos serviços inativos de um aplicativo."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"executar o aplicativo durante o tempo ocioso"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Permite que o sistema Android execute o aplicativo em segundo plano enquanto o dispositivo não está em uso."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"ler/gravar em recursos pertencentes ao diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite que um aplicativo leia e grave em qualquer recurso que pertença ao grupo de diagnósticos, por exemplo, arquivos in/dev. Isso pode afetar a estabilidade e a segurança do sistema. Esse recurso deve ser usado APENAS para diagnósticos específicos do hardware realizados pelo fabricante ou pela operadora."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ativar ou desativar os componentes do aplicativo"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permite que o aplicativo controle os recursos de telefone do dispositivo. Um aplicativo com essa permissão pode alternar entre redes, ligar e desligar o rádio do telefone e assim por diante, sem nunca notificá-lo."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"ler status e identidade do telefone"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite que o aplicativo acesse os recursos de telefonia do dispositivo. Esta permissão autoriza o aplicativo a determinar o número de telefone e IDs de dispositivo, quando uma chamada está ativa, e o número remoto conectado a uma chamada."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"ler estados precisos do telefone"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permite que o aplicativo acesse estados precisos do telefone. Permite que o aplicativo determine o status real da chamada, se uma chamada está ativa em segundo plano, falhas em chamadas, o status preciso da conexão de dados e falhas na conexão de dados."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"impedir modo de inatividade do tablet"</string>
     <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>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 407f6ed..f252f50 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -678,9 +678,9 @@
     <skip />
     <!-- no translation found for permdesc_manageCaCertificates (4015644047196937014) -->
     <skip />
-    <!-- no translation found for permlab_bindIdleService (7521398788076342815) -->
+    <!-- no translation found for permlab_bindIdleService (816311765497613780) -->
     <skip />
-    <!-- no translation found for permdesc_bindIdleService (7747505810143356528) -->
+    <!-- no translation found for permdesc_bindIdleService (1767538493214100612) -->
     <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"leger/scriver en resursas che appartegnan a diagnostics"</string>
     <!-- no translation found for permdesc_diagnostic (6608295692002452283) -->
@@ -935,6 +935,10 @@
     <skip />
     <!-- no translation found for permdesc_readPhoneState (1639212771826125528) -->
     <skip />
+    <!-- no translation found for permlab_readPrecisePhoneState (5476483020282007597) -->
+    <skip />
+    <!-- no translation found for permdesc_readPrecisePhoneState (6648009074263855418) -->
+    <skip />
     <!-- no translation found for permlab_wakeLock (1531731435011495015) -->
     <skip />
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"evitar ch\'il telefon midia en il modus stand-by"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 21c8a11..046d3ae 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -423,8 +423,10 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permite aplicaţiei să utilizeze orice decodor media instalat pentru a decodifica redarea."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gestionarea acreditărilor de încredere"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permite aplicației să instaleze și să dezinstaleze certificate CA ca acreditări de încredere."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"asociați cu serviciile inactive"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Această autorizare permite sistemului Android să se conecteze la serviciile inactive ale unei aplicații."</string>
+    <!-- no translation found for permlab_bindIdleService (816311765497613780) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (1767538493214100612) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"citire/scriere în resursele deţinute de diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite aplicaţiei să citească şi să scrie în orice resursă deţinută de grupul diag, de ex., fişierele din /dev. Această permisiune ar putea să afecteze stabilitatea şi securitatea sistemului. Permisiunea trebuie utilizată NUMAI de producător sau de operator pentru diagnostice specifice pentru hardware."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activare sau dezactivare a componentelor aplicaţiei"</string>
@@ -563,6 +565,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permite aplicaţiei să controleze funcţiile de telefon ale dispozitivului. O aplicaţie cu această permisiune poate să schimbe reţeaua, să închidă şi să deschidă radioul şi să efectueze alte acţiuni similare, fără să vă înştiinţeze."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"citeşte starea şi identitatea telefonului"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite aplicaţiei să acceseze funcţiile de telefon ale dispozitivului. Cu această permisiune aplicaţia stabileşte numărul de telefon şi ID-urile de dispozitiv, dacă un apel este activ, precum şi numărul de la distanţă conectat printr-un apel."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"accesați stările exacte ale telefonului"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permite aplicației să acceseze stările exacte ale telefonului. Cu această permisiune, aplicația poate să determine starea reală a apelului, dacă apelul este activ sau în fundal, dacă apelul nu reușește, starea exactă și întreruperile conexiunii de date."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"împiedicarea computerului tablet PC să intre în repaus"</string>
     <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>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 9bc6bcd..6d8aca7 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Приложение сможет использовать любой установленный дешифратор."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"Управление учетными данными"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Приложение сможет устанавливать сертификаты ЦС в качестве надежных учетных данных, а также удалять их."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"привязка неактивных сервисов"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Android сможет подключаться к неактивным сервисам."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"запуск приложений в свящем режиме"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Система Android сможет запускать приложение в фоновом режиме, когда устройство не будет использоваться."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"Чтение/запись данных в системы диагностики"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Приложение сможет считывать и записывать данные системы диагностики (например, файлы в каталоге /dev). Это может повлиять на стабильность и безопасность системы. Это разрешение должно использоваться ТОЛЬКО производителем или оператором для диагностики аппаратного обеспечения."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"Включение/отключение компонентов приложения"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Приложение сможет управлять на устройстве функциями телефона: переключать сети, включать и выключать приемопередатчик, а также выполнять другие подобные действия без уведомления."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"Получение данных о статусе телефона"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Приложение получит доступ к функциям телефона на устройстве. Кроме того, оно сможет определять номера телефонов и серийные номера моделей, состояние активности вызова, а также удаленные номера, с которыми установлено соединение."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"Доступ к точным статусам телефона"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Приложение сможет определять точный статус вызовов (активный, в фоновом режиме или сбой), а также статус интернет-соединения (в том числе, если подключиться не удалось)."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"Отключение спящего режима"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"Отключение спящего режима"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Приложение сможет запрещать перевод планшетного ПК в спящий режим."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 7f4e0ed..a056ff1 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -423,8 +423,10 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Umožňuje aplikácii používať na reprodukciu ľubovoľný nainštalovaný dekódovač na dekódovanie."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"spravovať dôveryhodné poverenia"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Umožňuje aplikácii inštalovať a odinštalovať certifikáty CA ako dôveryhodné poverenia."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"previazať s nečinnými službami"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Toto povolenie umožní systému Android viazať sa na nečinné služby aplikácie."</string>
+    <!-- no translation found for permlab_bindIdleService (816311765497613780) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (1767538493214100612) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"čítanie alebo zápis do prostriedkov funkcie diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Umožňuje aplikácii čítať ľubovoľné prostriedky v skupine diag, napr. súbory v priečinku /dev, a zapisovať do nich. Môže dôjsť k ovplyvneniu stability a bezpečnosti systému. Toto nastavenie by mal používať IBA výrobca či operátor na diagnostiku hardvéru."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"povoliť alebo zakázať súčasti aplikácie"</string>
@@ -563,6 +565,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Umožňuje aplikácii ovládať telefónne funkcie zariadenia. Aplikácia s týmto povolením môže prepínať siete alebo zapnúť a vypnúť rádio bez toho, aby vás na to upozornila."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"čítať stav a identitu telefónu"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Umožňuje aplikácii pristupovať k telefónnym funkciám zariadenia. Aplikácia s týmto povolením môže určiť telefónne číslo a ID zariadenia, či práve prebieha hovor, a vzdialené číslo, s ktorým je prostredníctvom hovoru nadviazané spojenie."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"čítanie presných stavov telefónu"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Umožňuje aplikácii pristupovať k presným stavom telefónu. Toto povolenie umožňuje aplikácii zistiť skutočný stav hovoru, či je hovor aktívny alebo na pozadí, zlyhania hovorov, presný stav dátového pripojenia a zlyhania dátového pripojenia."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"zabránenie prechodu tabletu do režimu spánku"</string>
     <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>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 1f1ab78..5e8c45b 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Programu omogoča, da uporabi kateri koli dekodirnik večpredstavnosti za predvajanje."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"upravljanje preverjenih poverilnic"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Aplikaciji dovoli nameščanje in odstranjevanje potrdil overitelja potrdil kot preverjenih poverilnic."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"vezanje na nedejavne storitve"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"To dovoljenje dovoli sistemu Android vezanje nedejavnih storitev aplikacije."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"izvajanje aplikacije ob nedejavnosti"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"To dovoljenje sistemu Android omogoča, da izvaja aplikacijo v ozadju, ko se naprava ne uporablja."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"branje/pisanje v sredstva, ki so v lasti skupine za diagnostiko"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Programu omogoča branje in pisanje na poljuben vir, ki je v lasti skupine za diagnostiko; na primer datoteke v mapi /dev. To lahko vpliva na stabilnost in varnost sistema. To naj uporablja SAMO izdelovalec ali operater za diagnostiko, specifično za strojno opremo."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"omogočanje ali onemogočanje komponent programa"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Programu omogoča nadziranje telefonskih funkcij naprave. Program lahko s tem dovoljenjem preklaplja omrežja, vklopi ali izklopi radio v telefonu, ne da bi vas obvestil."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"branje stanja in identitete telefona"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Aplikaciji omogoča dostop do funkcij telefona v napravi. S tem dovoljenjem lahko aplikacija določi telefonsko številko in ID-je naprave, določi lahko tudi, ali je klic aktiven, in oddaljeno številko, s katero je klic povezan."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"branje natančnih stanj telefona"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Aplikaciji dovoli dostop do natančnih stanj telefona. To dovoljenje aplikaciji omogoča ugotoviti pravo stanje klica; ali je klic aktiven ali v ozadju; neuspele klice; natančno stanje podatkovne povezave in neuspele podatkovne povezave."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"preprečitev prehoda tabličnega računalnika v stanje pripravljenosti"</string>
     <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>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 4a29310..fb12e96 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Омогућава апликацији да користи било који инсталирани декодер медија за декодирање за репродукцију."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"управљање поузданим акредитивима"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Дозвољава апликацији да инсталира и деинсталира CA сертификате као поуздане акредитиве."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"повезивање са неактивним услугама"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Ова дозвола дозвољава систему Android да се веже за неактивне услуге апликације."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"покреће апликације током неактивности"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Ова дозвола омогућава систему Android да покреће апликације у позадини док се уређај не користи."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"читање ресурса у власништву дијагностике и уписивање података у њих"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Дозвољава апликацији да чита и уписује податке у било који ресурс у власништву групе за дијагностиковање, на пример, датотеке у директоријуму /dev. То може да угрози стабилност и безбедност система и треба да је користе САМО произвођач или оператер у сврхе дијагностиковањa хардвера."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"омогућавање или онемогућавање компоненти апликације"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Дозвољава апликацији да управља функцијама телефона на уређају. Апликација са овом дозволом може да прелази са једне мреже на другу и да без обавештења укључује и искључује радио телефона и сличне функције."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"читање статуса и идентитета телефона"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Дозвољава апликацији да приступа функцијама телефона на уређају. Ова дозвола омогућава апликацији да утврди број телефона и ИД-ове уређаја, затим да ли је позив активан, као и број даљинског уређаја са којим је успостављен позив."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"читај прецизне статусе телефона"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Омогућава апликацији да приступа прецизним статусима телефона. Ова дозвола омогућава апликацији да утврди стварни статус позива, да ли је позив активан или у позадини, неуспеле позиве, прецизан статус везе за пренос података и неуспела успостављања везе за пренос података."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"спречавање преласка таблета у стање спавања"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"спречавање преласка телефона у стање спавања"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Дозвољава апликацији да спречи таблет да пређе у стање спавања."</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 09763b1..882fd76 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -423,8 +423,10 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Tillåter att appen använder installerade medieavkodare för att avkoda media för uppspelning."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"hantera betrodda uppgifter"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Tillåter att appen installerar och avinstallerar CA-certifikat som betrodda uppgifter."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"knyt till inaktiva tjänster"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Med den här behörigheten kan Android-systemet bindas till en apps inaktiva tjänster."</string>
+    <!-- no translation found for permlab_bindIdleService (816311765497613780) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (1767538493214100612) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"läsa/skriva till resurser som ägs av diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Tillåter att appen läser och skriver till en resurs som ägs av diag-gruppen, till exempel filer i /dev. Detta kan eventuellt påverka systemets stabilitet och säkerhet. Detta bör ENDAST användas av tillverkaren eller operatören för maskinvaruspecifik diagnostik."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivera eller inaktivera appkomponenter"</string>
@@ -563,6 +565,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Tillåter att appen styr enhetens telefonfunktioner. En app med den här behörigheten kan byta nätverk, aktivera/inaktivera mobilens radio och liknande utan att meddela dig."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"läsa telefonens status och identitet"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Tillåter att appen kommer åt enhetens telefonfunktioner. Med den här behörigheten tillåts appen att identifiera mobilens telefonnummer och enhets-ID, om ett samtal pågår och vilket nummer samtalet är kopplat till."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"läsa mobilens exakta status"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Tillåter att appen får tillgång till mobilens exakta status. Appen får behörighet att avgöra mobilens faktiska samtalsstatus, om samtalet är aktivt eller i bakgrunden, om samtal misslyckas, mobilens exakta dataanslutningsstatus och om dataanslutningar misslyckas."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"förhindra att surfplattan går in i viloläge"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"förhindra att telefonen sätts i viloläge"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Tillåter att appen förhindrar att surfplattan går in i viloläge."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index e840e37..7604de7 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -348,7 +348,7 @@
     <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"rekebisha takwimu za oparesheni ya programu"</string>
     <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"Inaruhusu programu kurekebisha takwimu za matumizi ya programu zilizokusanywa. Si ya kutumiwa na programu za kawaida."</string>
     <string name="permlab_backup" msgid="470013022865453920">"Dhibiti kuhifadhi nakala na kurejesha kwa mfumo"</string>
-    <string name="permdesc_backup" msgid="6912230525140589891">"Inaruhusu programu kudhibiti utaratibu wa kucheleza na kurejesha wa mfumo. Si kwa matumizi na programu za kawaida."</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"Huruhusu programu kudhibiti utaratibu wa kuhifadhi nakala rudufu na kurejesha mfumo. Haifai kutumiwa na programu za kawaida."</string>
     <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"thibitisha chelezo kamilifu au rejesha upya uendeshaji"</string>
     <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Huruhusu programu kuzindua kiolesura cha kuthibitisha kuhifadhiwa kwa nakala rudufu kamili. Haitumiwi na programu yoyote."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"onyesha madirisha yasiyoidhinishwa"</string>
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Huruhusu programu kutumia vyombo vyovyote vya habari vilivyosakinishwa ili kusimbua kwa ajili ya kucheza tena."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"dhibiti vitambulisho vinavyoaminika"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Huruhusu programu kusakinisha na kusanidua vyeti vya CA kama vitambulisho vinavyoaminika."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"funga kwenye huduma zisizofanya kitu"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Ruhusa hii huruhusu mfumo wa Android kuunga kwenye huduma za programu amabazo hazitumiki."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"endesha programu wakati haifanyi kitu"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Ruhusa hii huwezesha mfumo wa Android kuendesha programu chini chini wakati kifaa hakitumiki."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"soma/andika kwa vyanzo vinavyomilikiwa na diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Inaruhusu programu kusoma na kuandika kwa chanzo chochote kinachomilikiwa na kikundi cha diag; kwa mfano, faili katika /dev. Hii inaweza kuathiri udhabiti na usalama wa mfumo. Hii inapaswa kutumiwa TU kwa utambuzi mahsusi wa maunzi na mtengenezaji au opareta."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"wezesha au lemeza vijenzi vya programu"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Inaruhusu programu kudhibiti vipengee vya kifaa. Programu iliyo na ruhusa hii inaweza badilisha mtandao, kuzima na kuwasha redio ya simu bila hata kukujulisha."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"kusoma hali na kitambulisho cha simu"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Inaruhusu programu kufikia vipengele vya simu vya kifaa. Idhini hii inaruhusu programu kutambua nambari ya simu na kifaa, kama simu ni amilifu, na nambari ya mbali iliyounganishwa kwa simu."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"Soma hali sahihi ya simu"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Huruhusu programu kufikia hali sahihi ya simu. Ruhusa hii huwezesha programu kufahamu hali sahihi ya simu, iwapo simu inatumika au katika hali ya chini chini, simu inaposhindikana, hali sahihi ya muunganisho wa data na muunganisho wa data unaposhindikana."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"zuia kompyuta ndogo dhidi ya kulala"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"kuzuia simu isilale"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Inaruhusu programu kuzuia kompyuta kibao  kwenda kulala."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index c1f1c9b..4a9ef4d 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"อนุญาตให้แอปพลิเคชันใช้ตัวถอดรหัสสื่อใดก็ได้ที่ติดตั้งไว้เพื่อถอดรหัสสำหรับการเล่น"</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"จัดการข้อมูลรับรองที่เชื่อถือได้"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"อนุญาตให้แอปติดตั้งและถอนการติดตั้งใบรับรอง CA ในฐานะข้อมูลรับรองที่เชื่อถือได้"</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"เชื่อมโยงกับบริการที่ไม่ได้ใช้งาน"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"สิทธิ์นี้จะทำให้ระบบแอนดรอยด์สามารถเชื่อมโยงกับบริการรายงานเวลาที่ไม่มีการใช้งานของแอปพลิเคชัน"</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"เรียกใช้แอปพลิเคชันในระหว่างที่ไม่ได้ใช้งาน"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"สิทธิ์นี้ช่วยให้ระบบแอนดรอยด์สามารถเรียกใช้แอปพลิเคชันในพื้นหลังขณะไม่ได้ใช้งานอุปกรณ์อยู่"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"อ่าน/เขียนไปยังรีซอร์สที่เป็นเจ้าของโดยกลุ่มวินิจฉัย"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"อนุญาตให้แอปพลิเคชันอ่านและเขียนไปยังทรัพยากรที่เป็นของกลุ่มวินิจฉัย เช่น ไฟล์ใน /dev การทำเช่นนี้อาจส่งผลต่อความเสถียรและความปลอดภัยของระบบ และควรใช้สำหรับการวินิจฉัยเกี่ยวกับฮาร์ดแวร์โดยเฉพาะที่ทำโดยผู้ผลิตหรือผู้ให้บริการเท่านั้น"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"เปิดหรือปิดใช้งานคอมโพเนนต์ของแอปพลิเคชัน"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"อนุญาตให้แอปพลิชันควบคุมคุณลักษณะโทรศัพท์ของอุปกรณ์ แอปพลิเคชันที่ได้รับอนุญาตจะสามารถสลับเครือข่าย เปิดและปิดวิทยุในโทรศัพท์ และคุณลักษณะอื่นที่คล้ายกันนี้ได้โดยไม่ต้องแจ้งให้คุณทราบ"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"อ่านสถานะและข้อมูลระบุตัวตนของโทรศัพท์"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"อนุญาตให้แอปพลิเคชันเข้าถึงคุณลักษณะโทรศัพท์ของอุปกรณ์ การอนุญาตนี้ทำให้แอปพลิเคชันสามารถตรวจสอบหมายเลขโทรศัพท์และรหัสอุปกรณ์ ตรวจสอบว่ามีการโทรที่ทำงานอยู่หรือไม่ และตรวจสอบหมายเลขระยะไกลที่เชื่อมต่อด้วยการโทร"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"อ่านสถานะที่แม่นยำของโทรศัพท์"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"ช่วยให้แอปสามารถเข้าถึงสถานะที่แม่นยำของโทรศัพท์ สิทธิ์นี้ช่วยให้แอปสามารถทราบถึงสถานะการโทรที่แท้จริงว่ากำลังมีการโทรอยู่หรือการโทรอยู่ในพื้นหลัง การโทรล้มเหลว สถานะการเชื่อมต่อข้อมูลที่แม่นยำและการเชื่อมต่อข้อมูลล้มเหลว"</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ป้องกันไม่ให้แท็บเล็ตเข้าสู่โหมดสลีป"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ป้องกันไม่ให้โทรศัพท์เข้าโหมดสลีป"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"อนุญาตให้แอปพลิเคชันป้องกันไม่ให้แท็บเล็ตเข้าสู่โหมดสลีป"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 4196a82..0f5f53c 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Pinapayagan ang app na gumamit ng anumang naka-install na media decoder upang mag-decode para sa pag-playback."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"mga pinamamahalaang pinagkakatiwalaang kredensyal"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Pinapayagan ang app na mag-install at mag-uninstall ng mga CA certificate bilang mga pinagkakatiwalaang kredensyal."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"sumailalim sa mga idle na serbisyo"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Nagbibigay-daan ang pahintulot na ito sa Android system na sumailalim sa mga idle na serbisyo ng isang application."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"paganahin ang application habang idle"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Nagbibigay-daan ang pahintulot na ito sa Android system na paganahin ang application sa background habang hindi ginagamit ang device."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"magbasa/magsulat sa mga mapagkukunang pag-aari ng diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Pinapayagan ang app na magbasa at magsulat sa anumang mapagkukunang pag-aari ng pangkat ng diag; halimbawa, mga file sa /dev. Maaaring potensyal na maapektuhan nito ang katatagan at seguridad ng system. Dapat LAMANG itong gamitin para sa diagnostics na tukoy sa hardware ng tagagawa o operator."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"paganahin o huwag paganahin ang mga bahagi ng app"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Pinapayagan ang app na kontrolin ang mga tampok ng telepono ng device. Maaaring lumipat ng mga network ang isang app na mayroong ganitong pahintulot, i-on o i-off ang radyo ng telepono at mga kaparehong bagay nang hindi ka nano-notify."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"basahin ang katayuan at pagkakakilanlan ng telepono"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Pinapayagan ang app na i-access ang mga tampok ng telepono ng device. Pinapayagan ng pahintulot na ito ang app na tukuyin ang numero ng telepono at  mga ID ng device, kung aktibo man ang isang tawag, at ang malayuang numerong ikinonekta ng isang tawag."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"basahin ang tiyak na katayuan ng telepono"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Binibigyang-daan ang app na ma-access ang tumpak na katayuan ng telepono. Nagbibigay-daan ang pahintulot na ito sa app na matukoy ang tunay na status ng tawag, kung aktibo ang isang tawag o nasa background, mga hindi natuloy na tawag, tumpak na status ng koneksyon sa data at hindi natuloy na pagkonekta sa data."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"pigilan ang tablet mula sa pag-sleep"</string>
     <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>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 132d9f0..0834e48 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -423,8 +423,10 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Uygulamaya, oynatma kodunu çözmek için herhangi bir yüklü medya kod çözücüyü kullanma izni verir."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"güvenilen kimlik bilgilerini yönetme"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Uygulamaya, güvenilir kimlik bilgileri olarak CA sertifikaları yükleme veya sertifikaların yüklemelerini kaldırma izni verir."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"boşta kalma hizmetlerine bağlan"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Bu izin, Android sistemin, bir uygulamanın boşta kalma hizmetlerine bağlanmasına olanak sağlar."</string>
+    <!-- no translation found for permlab_bindIdleService (816311765497613780) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (1767538493214100612) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"sahibi tanılama olan kaynakları oku/bunlara yaz"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Uygulamaya, tanılama grubunun sahip olduğu tüm kaynaklara (örneğin /dev içindeki dosyalar) okuma ve yazma izni verir. Bu işlevin sistem kararlılığını ve güvenliğini olumsuz etkileme olasılığı vardır. Üretici veya operatör tarafından YALNIZCA donanıma özgü tanılama için kullanılmalıdır."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"uygulama bileşenlerini etkinleştir veya devre dışı bırak"</string>
@@ -563,6 +565,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Uygulamaya, cihazın telefon özelliklerini kontrol etme izni verir. Bu izne sahip bir uygulama sizi hiç uyarmadan ağlar arasında geçiş, telefonun radyosunu açıp kapatma ve benzeri işlemler yapabilir."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"telefonun durumunu ve kimliğini okuma"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Uygulamaya cihazdaki telefon özelliklerine erişme izni verir. Bu izin, uygulamanın telefon numarasını ve cihaz kimliğini, etkin bir çağrı olup olmadığını ve çağrıda bağlanılan karşı tarafın numarasını öğrenmesine olanak sağlar."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"telefon durum bilgilerini hassas bir şekilde oku"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Uygulamanın, telefonun durum bilgilerine hassas bir şekilde erişmesine izin verir. Bu izin sayesinde uygulama, gerçek çağrı durumunu, çağrının aktif mi yoksa arka planda mı olduğunu, çağrının başarısız olup olmadığını, veri bağlantısı durumuyla ilgili hassas bilgileri ve veri bağlantısının başarısız olup olmadığını belirleyebilir."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"tabletin uykuya geçmesini önle"</string>
     <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>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 3922b0c..34b4e89 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Дозволяє програмі використовувати будь-який установлений медіа-декодер для декодування з метою відтворення."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"керувати захищеними обліковими даними"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Дозволяє програмі встановлювати та видаляти сертифікати центру сертифікації (CA) як захищені облікові дані."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"взаємодіяти з неактивними службами"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Такий дозвіл дає змогу системі Android прив’язуватися до неактивних служб програми."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"запускати програму, коли пристрій неактивний"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Маючи цей дозвіл, система Android може запускати програму у фоновому режимі, коли пристрій не використовується."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"чит./зап. на ресури., якими вол. діаг."</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Дозволяє програмі читати та писати на будь-який ресурс, яким володіє діагностична група; наприклад, у файли в папці /dev. Це потенційно може вплинути на стабільність і безпеку системи. Потрібно використовувати ЛИШЕ для певної діагностики обладнання, яку виконує виробник чи оператор."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"вмикати чи вимикати компоненти програми"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Дозволяє програмі контролювати телефонні функції пристрою. Програма з цим дозволом може переключати мережі, вмикати та вимикати радіо в телефоні тощо без вашого відома."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"читати статус та ідентифікаційну інформацію телефону"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Дозволяє програмі отримувати доступ до телефонних функцій пристрою. Такий дозвіл дає програмі змогу визначати номер телефону й ідентифікатори пристрою, активність виклику, а також віддалений номер, на який здійснюється виклик."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"читати точні статуси телефону"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Дозволяє додатку отримувати доступ до статусів телефону. Цей дозвіл дає додатку змогу визначати статус виклику (активний чи у фоновому режимі), помилки викликів, точний статус передавання даних і помилки передавання даних."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"не доп.перехід пристр.в реж.сну"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"недоп. перехід тел. в реж. сну"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Дозволяє програмі не допускати перехід планшетного ПК у режим сну."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index e774e8e..d5ea7e2 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Cho phép ứng dụng sử dụng bất kỳ trình giải mã phương tiện nào đã cài đặt nhằm giải mã để phát lại."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"quản lý thông tin xác thực đáng tin cậy"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Cho phép ứng dụng cài đặt và gỡ cài đặt chứng chỉ CA dưới dạng thông tin xác thực đáng tin cậy."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"liên kết với dịch vụ không dùng đến"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Quyền này cho phép hệ thống Android liên kết với các dịch vụ ở trạng thái rảnh của ứng dụng."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"chạy ứng dụng trong thời gian rảnh"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Sự cho phép này cho phép hệ thống Android chạy ứng dụng trong nền khi thiết bị không được sử dụng."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"đọc/ghi vào tài nguyên do chẩn đoán sở hữu"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Cho phép ứng dụng đọc và ghi vào bất kỳ tài nguyên nào do nhóm chẩn đoán sở hữu; ví dụ: các tệp trong /dev. Quyền này có thể ảnh hưởng đến sự ổn định và tính bảo mật của hệ thống. CHỈ nên sử dụng quyền này cho các chẩn đoán phần cứng cụ thể của nhà sản xuất hoặc nhà cung cấp."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"bật hoặc tắt cấu phần ứng dụng"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Cho phép ứng dụng kiểm soát các tính năng điện thoại của thiết bị. Ứng dụng có quyền này có thể chuyển đổi mạng, bật và tắt radio điện thoại cũng như thực hiện các tác vụ tương tự mà không cần thông báo cho bạn."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"đọc trạng thái và nhận dạng của điện thoại"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Cho phép ứng dụng truy cập vào các tính năng điện thoại của thiết bị. Quyền này cho phép ứng dụng xác định số điện thoại và ID thiết bị, cho dù cuộc gọi có hiện hoạt hay không và số từ xa có được kết nối bằng một cuộc gọi hay không."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"đọc trạng thái điện thoại chính xác"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Cho phép ứng dụng truy cập trạng thái điện thoại chính xác. Quyền này cho phép ứng dụng xác định trạng thái cuộc gọi thực, cuộc gọi đang hoạt động hay trong nền, cuộc gọi không thành công, trạng thái kết nối dữ liệu chính xác và kết nối dữ liệu không thành công."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ngăn máy tính bảng chuyển sang chế độ ngủ"</string>
     <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>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 035c5b6..e3886ad 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -423,8 +423,10 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"允许该应用使用任何已安装的媒体解码器进行解码,以便播放媒体。"</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"管理受信任的凭据"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"允许应用安装和卸载 CA 证书(作为受信任的凭据)。"</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"绑定到闲置服务"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"此权限允许Android系统绑定至应用的闲置服务。"</string>
+    <!-- no translation found for permlab_bindIdleService (816311765497613780) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (1767538493214100612) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"读取/写入诊断所拥有的资源"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"允许应用读取/写入诊断组拥有的所有资源(例如 /dev 中的文件)。这可能会影响系统的稳定性和安全性。此权限仅供制造商或运营商诊断硬件方面的问题时使用。"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"启用或停用应用组件"</string>
@@ -563,6 +565,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"允许应用控制设备的电话功能。拥有此权限的应用可在不通知您的情况下执行切换网络、开关手机无线装置等此类操作。"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"读取手机状态和身份"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"允许该应用访问设备的电话功能。此权限可让该应用确定本机号码和设备 ID、是否正处于通话状态以及拨打的号码。"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"读取确切的手机状态"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"允许应用获取确切的手机状态。此权限可让应用确定实际通话状态、通话是在界面上进行还是在后台进行、通话未接通次数、确切的数据网络连接状态,以及数据网络连接失败次数。"</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"阻止平板电脑进入休眠状态"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"防止手机休眠"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"允许应用阻止平板电脑进入休眠状态。"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 42aaf93..303affa 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"允許應用程式使用任何已安裝的媒體解碼器為播放解碼。"</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"管理信任的憑證"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"允許應用程式安裝 CA 憑證為信任的憑證及解除安裝 CA 憑證。"</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"繫結至閒置服務"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"此權限允許 Android 系統繫結至應用程式的閒置服務。"</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"當裝置閒置時執行應用程式"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"當您不使用裝置時,此權限允許 Android 系統在背景執行應用程式。"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"讀取/寫入由診斷應用程式擁有的資源"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"允許應用程式讀取及寫入診斷群組所擁有的任何資源 (例如:位於 /dev 中的檔案)。這可能會影響系統的穩定性及安全性,只應對製造商或網絡供應商所使用的硬件專用診斷程式開放這項權限。"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"啟用或停用應用程式元件"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"允許應用程式控制裝置上的電話功能。具備此權限的應用程式可在未通知您的情況下,進行切換網絡以及開關手機無線電之類的操作。"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"讀取手機狀態和識別碼"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"允許應用程式使用裝置的電話功能。這項權限允許應用程式確定手機號碼和裝置編號、是否正在通話中,以及所撥打的對方號碼。"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"讀取精確的手機狀態"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"允許應用程式存取精確的手機狀態。此權限可讓應用程式判斷實際的通話狀態、是否正在通話或在背景中運作、無法通話次數、精確的數據連線狀態和數據連線失敗次數。"</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"防止平板電腦進入休眠狀態"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"防止手機進入休眠狀態"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"允許應用程式防止平板電腦進入休眠狀態。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 6c3f1c4..d079ac5 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"允許應用程式使用任何已安裝的媒體解碼器進行解碼以播放影片。"</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"管理信任的憑證"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"允許應用程式安裝 CA 憑證 (做為信任的憑證) 及解除安裝 CA 憑證。"</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"繫結至閒置服務"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"此權限允許 Android 系統繫結至應用程式的閒置服務。"</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"當裝置閒置時執行應用程式"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"當裝置處於未使用狀態時,此權限允許 Android 系統在背景執行應用程式。"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"讀寫 diag 擁有的資源"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"允許應用程式讀取或寫入診斷群組擁有的任何資源,例如 /dev 底下的檔案。這可能會影響系統的穩定性和安全性,因此應由製造商或電信業者操作,且只用在特定硬體診斷。"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"啟用或停用應用程式元件"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"允許應用程式控制裝置的電話功能。擁有這項權限的應用程式可在未通知您的情況下,任意切換網路、開啟或關閉手機無線電等。"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"讀取手機狀態和識別碼"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"允許應用程式使用裝置的電話功能。這項權限可讓應用程式判讀手機號碼和裝置 ID、是否正在通話中,以及所撥打的對方號碼。"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"讀取精確手機狀態"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"允許應用程式存取精確的手機狀態。這項權限可讓應用程式判別實際通話狀態、通話程序正在進行中或是在背景運作、通話失敗次數、精確數據連線狀態和數據連線失敗次數。"</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"防止平板電腦進入休眠狀態"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"防止手機進入待命狀態"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"允許應用程式防止平板電腦進入休眠狀態。"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index c897bdc..802fc0f 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -423,8 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Ivumela uhlelo lokusebenza ukusebenzisa noma isiphi isiqophi semidiya esifakiwe ukuqopha ukudlala."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"phatha ukuqinisekisa okuthenjiwe"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Ivumela uhlelo lokusebenza ukuthi lifake liphinde likhiphe izitifiketi ze-CA njengokuqinisekiswa okuthenjiwe."</string>
-    <string name="permlab_bindIdleService" msgid="7521398788076342815">"bophezela kumasevisi angenzi lutho"</string>
-    <string name="permdesc_bindIdleService" msgid="7747505810143356528">"Le mvume ivumela isistimu ye-Android ukuthi ibophezeleke kumasevisi angenzi lutho wohlelo lokusebenza."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"qalisa uhlelo lokusebenza ngesikhathi sokungenzi lutho"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Le mvume ivumela isistimu ye-Android ukuthi iqalise uhlelo lokusebenza ngemuva ngenkathi idivayisi ingasebenzi."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"funda/bhalela emithombweni ephethwe idayegi"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Ivumela uhlelo lokusebenza ukufunda nokubhala kunoma yimuphi umthombo weqembu ledayegi; ngokwesibonelo, amafayela akwi/dev. Lokhu kungase kuthinte kakhulu ukuba nokuphepha kohlelo. Lokhu kumele kusebenziselwe KUPHELA ukuhlola ihadiwe okucacile ngumkhiqizi noma u-opheretha."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"vumela noma vimbela izingxenye zensiza"</string>
@@ -563,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Ivumela ukuthi uhlelo lokusebenza ilawule okuqukethwe ocingweni edivayisini. Insiza enalemvume ingaguquguqula amanethwekhi, ivule umsakazo wocingo iphinde iwucishe kanye nokunye okufana nalokho ngaphandle kokukwazisa."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"funda isimo sefoni kanye nesazisi"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Ivumela uhlelo lokusebenza ukufinyelela izici zefoni zedivayisi. Le mvume ivumela uhlelo lokusebenza ukucacisa inombolo yefoni nobunikazi bedivayisi, ukuthi noma ikholi iyasebenza, futhi nenombolo yesilawuli kude zixhunywe ngekholi."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"funda izimo zefoni ezinembile"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Ivumelanisa uhlelo lokusebenza ukuthi lufinyelele kuzimo ezinembile zefoni. Le mvume ivumela uhlelo lokusebenza ukuthi linqume isimo sekholi sangempela, noma ikholi isebenza noma ingemuva, ikholi ihluleka, isimo esinembile sokuxhumeka kwedatha nokuhluleka kokuxhumeka kwedatha."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"gwema ithebhulethi ukuba ingalali"</string>
     <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>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 95792ba..d1fa082 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -77,7 +77,8 @@
        <item>@drawable/btn_default_disabled_focused_holo_dark</item>
        <item>@drawable/btn_default_holo_dark</item>
        <item>@drawable/btn_default_holo_light</item>
-       <item>@drawable/btn_default_quantum</item>
+       <item>@drawable/btn_default_quantum_dark</item>
+       <item>@drawable/btn_default_quantum_light</item>
        <item>@drawable/btn_star_off_normal_holo_light</item>
        <item>@drawable/btn_star_on_normal_holo_light</item>
        <item>@drawable/btn_star_on_disabled_holo_light</item>
@@ -135,7 +136,8 @@
        <item>@drawable/expander_group_holo_light</item>
        <item>@drawable/list_selector_holo_dark</item>
        <item>@drawable/list_selector_holo_light</item>
-       <item>@drawable/list_selector_quantum</item>
+       <item>@drawable/list_selector_quantum_light</item>
+       <item>@drawable/list_selector_quantum_dark</item>
        <item>@drawable/list_section_divider_holo_light</item>
        <item>@drawable/list_section_divider_holo_dark</item>
        <item>@drawable/menu_hardkey_panel_holo_dark</item>
@@ -228,9 +230,11 @@
        <item>@drawable/ic_clear</item>
        <item>@drawable/ic_clear_disabled</item>
        <item>@drawable/ic_clear_normal</item>
-       <item>@drawable/ic_search</item>
+       <item>@drawable/ic_search_api_holo_dark</item>
+       <item>@drawable/ic_search_api_holo_light</item>
        <item>@drawable/ic_go</item>
-       <item>@drawable/ic_voice_search</item>
+       <item>@drawable/ic_voice_search_api_holo_dark</item>
+       <item>@drawable/ic_voice_search_api_holo_light</item>
        <item>@drawable/dialog_bottom_holo_dark</item>
        <item>@drawable/dialog_bottom_holo_light</item>
        <item>@drawable/dialog_full_holo_dark</item>
@@ -259,7 +263,8 @@
        <item>@drawable/ab_solid_shadow_holo</item>
        <item>@drawable/item_background_holo_dark</item>
        <item>@drawable/item_background_holo_light</item>
-       <item>@drawable/item_background_quantum</item>
+       <item>@drawable/item_background_quantum_light</item>
+       <item>@drawable/item_background_quantum_dark</item>
        <item>@drawable/fastscroll_thumb_holo</item>
        <item>@drawable/fastscroll_thumb_pressed_holo</item>
        <item>@drawable/fastscroll_thumb_default_holo</item>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index b20f5ba..4647413 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1777,6 +1777,16 @@
         <attr name="publicKey" />
     </declare-styleable>
 
+    <!-- Attributes relating to resource overlay packages. -->
+    <declare-styleable name="AndroidManifestResourceOverlay" parent="AndroidManifest">
+        <!-- Package name of base package whose resources will be overlaid. -->
+        <attr name="targetPackage" />
+
+        <!-- Load order of overlay package. -->
+        <attr name="priority" />
+
+    </declare-styleable>
+
     <!-- Declaration of an {@link android.content.Intent} object in XML.  May
          also include zero or more {@link #IntentCategory <category> and
          {@link #Extra <extra>} tags. -->
diff --git a/core/res/res/values/bools.xml b/core/res/res/values/bools.xml
index 10a5d85..18e4f2f 100644
--- a/core/res/res/values/bools.xml
+++ b/core/res/res/values/bools.xml
@@ -26,5 +26,4 @@
     <bool name="show_ongoing_ime_switcher">true</bool>
     <bool name="action_bar_expanded_action_views_exclusive">true</bool>
     <bool name="target_honeycomb_needs_options_menu">true</bool>
-    <bool name="flip_controller_fallback_keys">false</bool>
 </resources>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 55babfa..1947c50 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -123,8 +123,8 @@
     <color name="facelock_spotlight_mask">#CC000000</color>
 
     <!-- For holo theme -->
-      <drawable name="screen_background_holo_light">#fff3f3f3</drawable>
-      <drawable name="screen_background_holo_dark">#ff000000</drawable>
+    <drawable name="screen_background_holo_light">#fff3f3f3</drawable>
+    <drawable name="screen_background_holo_dark">#ff000000</drawable>
     <color name="background_holo_dark">#ff000000</color>
     <color name="background_holo_light">#fff3f3f3</color>
     <color name="bright_foreground_holo_dark">@android:color/background_holo_light</color>
diff --git a/core/res/res/values/colors_quantum.xml b/core/res/res/values/colors_quantum.xml
new file mode 100644
index 0000000..b623263
--- /dev/null
+++ b/core/res/res/values/colors_quantum.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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>
+    <color name="background_quantum_dark">#ff000000</color>
+    <color name="background_quantum_light">#fff3f3f3</color>
+
+    <color name="bright_foreground_quantum_dark">@color/background_quantum_light</color>
+    <color name="bright_foreground_quantum_light">@color/background_quantum_dark</color>
+    <color name="bright_foreground_disabled_quantum_dark">#ff4c4c4c</color>
+    <color name="bright_foreground_disabled_quantum_light">#ffb2b2b2</color>
+    <color name="bright_foreground_inverse_quantum_dark">@color/bright_foreground_quantum_light</color>
+    <color name="bright_foreground_inverse_quantum_light">@color/bright_foreground_quantum_dark</color>
+
+    <color name="dim_foreground_quantum_dark">#bebebe</color>
+    <color name="dim_foreground_quantum_light">#323232</color>
+    <color name="dim_foreground_disabled_quantum_dark">#80bebebe</color>
+    <color name="dim_foreground_disabled_quantum_light">#80323232</color>
+
+    <color name="hint_foreground_quantum_dark">#808080</color>
+    <color name="hint_foreground_quantum_light">#808080</color>
+    <color name="highlighted_text_quantum_dark">#6633b5e5</color>
+    <color name="highlighted_text_quantum_light">#6633b5e5</color>
+
+    <color name="timepicker_default_background_quantum_dark">#ff303030</color>
+    <color name="timepicker_default_background_quantum_light">@color/white</color>
+    <color name="timepicker_default_text_color_quantum_dark">@color/white</color>
+    <color name="timepicker_default_text_color_quantum_light">#8c8c8c</color>
+    <color name="timepicker_default_disabled_color_quantum_dark">#7f08c8c8</color>
+    <color name="timepicker_default_disabled_color_quantum_light">#7f000000</color>
+    <color name="timepicker_default_ampm_selected_background_color_quantum_dark">@color/holo_blue_light</color>
+    <color name="timepicker_default_ampm_selected_background_color_quantum_light">@color/holo_blue_light</color>
+    <color name="timepicker_default_ampm_unselected_background_color_quantum_dark">@color/transparent</color>
+    <color name="timepicker_default_ampm_unselected_background_color_quantum_light">@color/white</color>
+</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d70ce0a..91bef50 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1175,10 +1175,14 @@
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE]-->
     <string name="permdesc_manageCaCertificates">Allows the app to install and uninstall CA certificates as trusted credentials.</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_bindIdleService">bind to idle services</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_bindIdleService">This permission allows the Android system to bind to an application\'s idle services.</string>
+    <!-- Title of a permission that is never presented to the user.  This is not a
+         permission that an application must be granted by the user.  Instead, it
+         is part of a mechanism that applications use to indicate to the system
+         that they want to do occasional work while the device is idle.  -->
+    <string name="permlab_bindIdleService">run application during idle time</string>
+    <!-- Description of an application permission, so that the user can understand
+         what is being done if they are curious. -->
+    <string name="permdesc_bindIdleService">This permission allows the Android system to run the application in the background while the device is not in use.</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_diagnostic">read/write to resources owned by diag</string>
@@ -1654,6 +1658,14 @@
       connected by a call.</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_readPrecisePhoneState">read precise phone states</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_readPrecisePhoneState">Allows the app to access the precise
+      phone states.  This permission allows the app to determine the real
+      call status, whether a call is active or in the background, call fails,
+      precise data connection status and data connection fails.</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_wakeLock" product="tablet">prevent tablet from sleeping</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_wakeLock" product="default">prevent phone from sleeping</string>
diff --git a/core/res/res/values/styles_quantum.xml b/core/res/res/values/styles_quantum.xml
index cbf11cf..df850a7 100644
--- a/core/res/res/values/styles_quantum.xml
+++ b/core/res/res/values/styles_quantum.xml
@@ -33,57 +33,57 @@
     <eat-comment />
 
     <style name="Preference.Quantum">
-        <item name="android:layout">@android:layout/preference_holo</item>
+        <item name="layout">@layout/preference_holo</item>
     </style>
 
     <style name="PreferenceFragment.Quantum">
-        <item name="android:paddingStart">@dimen/preference_fragment_padding_side</item>
-        <item name="android:paddingEnd">@dimen/preference_fragment_padding_side</item>
+        <item name="paddingStart">@dimen/preference_fragment_padding_side</item>
+        <item name="paddingEnd">@dimen/preference_fragment_padding_side</item>
     </style>
 
     <style name="Preference.Quantum.Information">
-        <item name="android:layout">@android:layout/preference_information_holo</item>
-        <item name="android:enabled">false</item>
-        <item name="android:shouldDisableView">false</item>
+        <item name="layout">@layout/preference_information_holo</item>
+        <item name="enabled">false</item>
+        <item name="shouldDisableView">false</item>
     </style>
 
     <style name="Preference.Quantum.Category">
-        <item name="android:layout">@android:layout/preference_category_holo</item>
+        <item name="layout">@layout/preference_category_holo</item>
         <!-- The title should not dim if the category is disabled, instead only the preference children should dim. -->
-        <item name="android:shouldDisableView">false</item>
-        <item name="android:selectable">false</item>
+        <item name="shouldDisableView">false</item>
+        <item name="selectable">false</item>
     </style>
 
     <style name="Preference.Quantum.CheckBoxPreference">
-        <item name="android:widgetLayout">@android:layout/preference_widget_checkbox</item>
+        <item name="widgetLayout">@layout/preference_widget_checkbox</item>
     </style>
 
     <style name="Preference.Quantum.SwitchPreference">
-        <item name="android:widgetLayout">@android:layout/preference_widget_switch</item>
-        <item name="android:switchTextOn">@android:string/capital_on</item>
-        <item name="android:switchTextOff">@android:string/capital_off</item>
+        <item name="widgetLayout">@layout/preference_widget_switch</item>
+        <item name="switchTextOn">@string/capital_on</item>
+        <item name="switchTextOff">@string/capital_off</item>
     </style>
 
     <style name="Preference.Quantum.PreferenceScreen"/>
 
     <style name="Preference.Quantum.DialogPreference">
-        <item name="android:positiveButtonText">@android:string/ok</item>
-        <item name="android:negativeButtonText">@android:string/cancel</item>
+        <item name="positiveButtonText">@string/ok</item>
+        <item name="negativeButtonText">@string/cancel</item>
     </style>
 
     <style name="Preference.Quantum.DialogPreference.YesNoPreference">
-        <item name="android:positiveButtonText">@android:string/yes</item>
-        <item name="android:negativeButtonText">@android:string/no</item>
+        <item name="positiveButtonText">@string/yes</item>
+        <item name="negativeButtonText">@string/no</item>
     </style>
 
     <style name="Preference.Quantum.DialogPreference.EditTextPreference">
-        <item name="android:dialogLayout">@android:layout/preference_dialog_edittext</item>
+        <item name="dialogLayout">@layout/preference_dialog_edittext</item>
     </style>
 
     <style name="Preference.Quantum.RingtonePreference">
-        <item name="android:ringtoneType">ringtone</item>
-        <item name="android:showSilent">true</item>
-        <item name="android:showDefault">true</item>
+        <item name="ringtoneType">ringtone</item>
+        <item name="showSilent">true</item>
+        <item name="showDefault">true</item>
     </style>
 
     <!-- Begin Quantum theme styles -->
@@ -92,10 +92,10 @@
     <style name="TextAppearance.Quantum" parent="TextAppearance"/>
 
     <style name="TextAppearance.Quantum.Inverse" parent="TextAppearance.Inverse">
-        <item name="android:textColor">?textColorPrimaryInverse</item>
-        <item name="android:textColorHint">?textColorHintInverse</item>
-        <item name="android:textColorHighlight">?textColorHighlightInverse</item>
-        <item name="android:textColorLink">?textColorLinkInverse</item>
+        <item name="textColor">?textColorPrimaryInverse</item>
+        <item name="textColorHint">?textColorHintInverse</item>
+        <item name="textColorHighlight">?textColorHighlightInverse</item>
+        <item name="textColorLink">?textColorLinkInverse</item>
     </style>
 
     <style name="TextAppearance.Quantum.Large" parent="TextAppearance.Large"/>
@@ -105,183 +105,183 @@
     <style name="TextAppearance.Quantum.Small" parent="TextAppearance.Small"/>
 
     <style name="TextAppearance.Quantum.Large.Inverse">
-        <item name="android:textColor">?textColorPrimaryInverse</item>
-        <item name="android:textColorHint">?textColorHintInverse</item>
-        <item name="android:textColorHighlight">?textColorHighlightInverse</item>
-        <item name="android:textColorLink">?textColorLinkInverse</item>
+        <item name="textColor">?textColorPrimaryInverse</item>
+        <item name="textColorHint">?textColorHintInverse</item>
+        <item name="textColorHighlight">?textColorHighlightInverse</item>
+        <item name="textColorLink">?textColorLinkInverse</item>
     </style>
 
     <style name="TextAppearance.Quantum.Medium.Inverse">
-        <item name="android:textColor">?textColorPrimaryInverse</item>
-        <item name="android:textColorHint">?textColorHintInverse</item>
-        <item name="android:textColorHighlight">?textColorHighlightInverse</item>
-        <item name="android:textColorLink">?textColorLinkInverse</item>
+        <item name="textColor">?textColorPrimaryInverse</item>
+        <item name="textColorHint">?textColorHintInverse</item>
+        <item name="textColorHighlight">?textColorHighlightInverse</item>
+        <item name="textColorLink">?textColorLinkInverse</item>
     </style>
 
     <style name="TextAppearance.Quantum.Small.Inverse">
-        <item name="android:textColor">?textColorSecondaryInverse</item>
-        <item name="android:textColorHint">?textColorHintInverse</item>
-        <item name="android:textColorHighlight">?textColorHighlightInverse</item>
-        <item name="android:textColorLink">?textColorLinkInverse</item>
+        <item name="textColor">?textColorSecondaryInverse</item>
+        <item name="textColorHint">?textColorHintInverse</item>
+        <item name="textColorHighlight">?textColorHighlightInverse</item>
+        <item name="textColorLink">?textColorLinkInverse</item>
     </style>
 
     <style name="TextAppearance.Quantum.SearchResult">
-        <item name="android:textStyle">normal</item>
-        <item name="android:textColor">?textColorPrimary</item>
-        <item name="android:textColorHint">?textColorHint</item>
+        <item name="textStyle">normal</item>
+        <item name="textColor">?textColorPrimary</item>
+        <item name="textColorHint">?textColorHint</item>
     </style>
 
     <style name="TextAppearance.Quantum.SearchResult.Title">
-         <item name="android:textSize">18sp</item>
+         <item name="textSize">18sp</item>
     </style>
 
     <style name="TextAppearance.Quantum.SearchResult.Subtitle">
-        <item name="android:textSize">14sp</item>
-        <item name="android:textColor">?textColorSecondary</item>
+        <item name="textSize">14sp</item>
+        <item name="textColor">?textColorSecondary</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget" parent="TextAppearance.Widget"/>
 
     <style name="TextAppearance.Quantum.Widget.Button" parent="TextAppearance.Quantum.Small.Inverse">
-        <item name="android:textColor">@android:color/primary_text_light_nodisable</item>
+        <item name="textColor">@color/primary_text_light_nodisable</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.IconMenu.Item" parent="TextAppearance.Quantum.Small">
-        <item name="android:textColor">?textColorPrimary</item>
+        <item name="textColor">?textColorPrimary</item>
     </style>
 
     <!-- This style is for smaller screens; values-xlarge defines a version
          for larger screens. -->
     <style name="TextAppearance.Quantum.Widget.TabWidget">
-        <item name="android:textSize">14sp</item>
-        <item name="android:textStyle">normal</item>
-        <item name="android:textColor">@android:color/tab_indicator_text</item>
+        <item name="textSize">14sp</item>
+        <item name="textStyle">normal</item>
+        <item name="textColor">@color/tab_indicator_text</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.TextView">
-        <item name="android:textColor">?textColorPrimaryDisableOnly</item>
-        <item name="android:textColorHint">?textColorHint</item>
+        <item name="textColor">?textColorPrimaryDisableOnly</item>
+        <item name="textColorHint">?textColorHint</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.TextView.PopupMenu">
-        <item name="android:textSize">18sp</item>
-        <item name="android:textColor">?textColorPrimaryDisableOnly</item>
-        <item name="android:textColorHint">?textColorHint</item>
+        <item name="textSize">18sp</item>
+        <item name="textColor">?textColorPrimaryDisableOnly</item>
+        <item name="textColorHint">?textColorHint</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.DropDownHint">
-        <item name="android:textColor">?textColorPrimary</item>
-        <item name="android:textSize">14sp</item>
+        <item name="textColor">?textColorPrimary</item>
+        <item name="textSize">14sp</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.DropDownItem">
-        <item name="android:textColor">?textColorPrimaryDisableOnly</item>
+        <item name="textColor">?textColorPrimaryDisableOnly</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.TextView.SpinnerItem">
-        <item name="android:textColor">?textColorPrimaryDisableOnly</item>
+        <item name="textColor">?textColorPrimaryDisableOnly</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.EditText">
-        <item name="android:textColor">@android:color/bright_foreground_light</item>
-        <item name="android:textColorHint">@android:color/hint_foreground_holo_light</item>
+        <item name="textColor">@color/bright_foreground_light</item>
+        <item name="textColorHint">@color/hint_foreground_quantum_light</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.PopupMenu" parent="TextAppearance.Widget.PopupMenu">
-        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="textColor">?attr/textColorPrimary</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.PopupMenu.Large">
-        <item name="android:textSize">18sp</item>
+        <item name="textSize">18sp</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.PopupMenu.Small">
-        <item name="android:textSize">14sp</item>
+        <item name="textSize">14sp</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.ActionBar.Title"
            parent="TextAppearance.Quantum.Medium">
-        <item name="android:textSize">@android:dimen/action_bar_title_text_size</item>
+        <item name="textSize">@dimen/action_bar_title_text_size</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.ActionBar.Subtitle"
            parent="TextAppearance.Quantum.Small">
-        <item name="android:textSize">@android:dimen/action_bar_subtitle_text_size</item>
+        <item name="textSize">@dimen/action_bar_subtitle_text_size</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.ActionBar.Title.Inverse"
            parent="TextAppearance.Quantum.Medium.Inverse">
-        <item name="android:textSize">@android:dimen/action_bar_title_text_size</item>
+        <item name="textSize">@dimen/action_bar_title_text_size</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.ActionBar.Subtitle.Inverse"
            parent="TextAppearance.Quantum.Small.Inverse">
-        <item name="android:textSize">@android:dimen/action_bar_subtitle_text_size</item>
+        <item name="textSize">@dimen/action_bar_subtitle_text_size</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.ActionBar.Menu"
            parent="TextAppearance.Quantum.Small">
-        <item name="android:textSize">12sp</item>
-        <item name="android:textStyle">bold</item>
-        <item name="android:textColor">?android:attr/actionMenuTextColor</item>
-        <item name="android:textAllCaps">@android:bool/config_actionMenuItemAllCaps</item>
+        <item name="textSize">12sp</item>
+        <item name="textStyle">bold</item>
+        <item name="textColor">?attr/actionMenuTextColor</item>
+        <item name="textAllCaps">@bool/config_actionMenuItemAllCaps</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.ActionMode"/>
 
     <style name="TextAppearance.Quantum.Widget.ActionMode.Title"
            parent="TextAppearance.Quantum.Medium">
-        <item name="android:textSize">@android:dimen/action_bar_title_text_size</item>
+        <item name="textSize">@dimen/action_bar_title_text_size</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.ActionMode.Subtitle"
            parent="TextAppearance.Quantum.Small">
-        <item name="android:textSize">@android:dimen/action_bar_subtitle_text_size</item>
+        <item name="textSize">@dimen/action_bar_subtitle_text_size</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.ActionMode.Title.Inverse"
            parent="TextAppearance.Quantum.Medium.Inverse">
-        <item name="android:textSize">@android:dimen/action_bar_title_text_size</item>
+        <item name="textSize">@dimen/action_bar_title_text_size</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.ActionMode.Subtitle.Inverse"
            parent="TextAppearance.Quantum.Small.Inverse">
-        <item name="android:textSize">@android:dimen/action_bar_subtitle_text_size</item>
+        <item name="textSize">@dimen/action_bar_subtitle_text_size</item>
     </style>
 
     <style name="TextAppearance.Quantum.Widget.Switch" parent="TextAppearance.Quantum.Small">
         <!-- Switch thumb asset presents a dark background. -->
-        <item name="android:textColor">@android:color/secondary_text_holo_dark</item>
+        <item name="textColor">@color/secondary_text_quantum_dark</item>
     </style>
 
     <style name="TextAppearance.Quantum.Light.Widget.Switch" parent="TextAppearance.Quantum.Small">
         <!-- Switch thumb asset presents a dark background. -->
-        <item name="android:textColor">@android:color/primary_text_holo_dark</item>
+        <item name="textColor">@color/primary_text_quantum_dark</item>
     </style>
 
     <style name="TextAppearance.Quantum.WindowTitle">
-        <item name="android:textColor">#fff</item>
-        <item name="android:textSize">14sp</item>
-        <item name="android:textStyle">bold</item>
+        <item name="textColor">#fff</item>
+        <item name="textSize">14sp</item>
+        <item name="textStyle">bold</item>
     </style>
 
     <style name="TextAppearance.Quantum.DialogWindowTitle">
-        <item name="android:textSize">22sp</item>
-        <item name="android:textColor">@android:color/holo_blue_light</item>
+        <item name="textSize">22sp</item>
+        <item name="textColor">@color/holo_blue_light</item>
     </style>
 
     <style name="TextAppearance.Quantum.CalendarViewWeekDayView" parent="TextAppearance.Small.CalendarViewWeekDayView">
-        <item name="android:textColor">#505050</item>
+        <item name="textColor">#505050</item>
     </style>
 
     <!-- Light text styles -->
     <style name="TextAppearance.Quantum.Light" parent="TextAppearance.Quantum"/>
 
     <style name="TextAppearance.Quantum.Light.Inverse">
-        <item name="android:textColor">?textColorPrimaryInverse</item>
-        <item name="android:textColorHint">?textColorHintInverse</item>
-        <item name="android:textColorHighlight">?textColorHighlightInverse</item>
-        <item name="android:textColorLink">?textColorLinkInverse</item>
+        <item name="textColor">?textColorPrimaryInverse</item>
+        <item name="textColorHint">?textColorHintInverse</item>
+        <item name="textColorHighlight">?textColorHighlightInverse</item>
+        <item name="textColorLink">?textColorLinkInverse</item>
     </style>
 
     <style name="TextAppearance.Quantum.Light.Large" parent="TextAppearance.Quantum.Large"/>
@@ -291,38 +291,38 @@
     <style name="TextAppearance.Quantum.Light.Small" parent="TextAppearance.Quantum.Small"/>
 
     <style name="TextAppearance.Quantum.Light.Large.Inverse">
-        <item name="android:textColor">?textColorPrimaryInverse</item>
-        <item name="android:textColorHint">?textColorHintInverse</item>
-        <item name="android:textColorHighlight">?textColorHighlightInverse</item>
-        <item name="android:textColorLink">?textColorLinkInverse</item>
+        <item name="textColor">?textColorPrimaryInverse</item>
+        <item name="textColorHint">?textColorHintInverse</item>
+        <item name="textColorHighlight">?textColorHighlightInverse</item>
+        <item name="textColorLink">?textColorLinkInverse</item>
     </style>
 
     <style name="TextAppearance.Quantum.Light.Medium.Inverse">
-        <item name="android:textColor">?textColorPrimaryInverse</item>
-        <item name="android:textColorHint">?textColorHintInverse</item>
-        <item name="android:textColorHighlight">?textColorHighlightInverse</item>
-        <item name="android:textColorLink">?textColorLinkInverse</item>
+        <item name="textColor">?textColorPrimaryInverse</item>
+        <item name="textColorHint">?textColorHintInverse</item>
+        <item name="textColorHighlight">?textColorHighlightInverse</item>
+        <item name="textColorLink">?textColorLinkInverse</item>
     </style>
 
     <style name="TextAppearance.Quantum.Light.Small.Inverse">
-        <item name="android:textColor">?textColorPrimaryInverse</item>
-        <item name="android:textColorHint">?textColorHintInverse</item>
-        <item name="android:textColorHighlight">?textColorHighlightInverse</item>
-        <item name="android:textColorLink">?textColorLinkInverse</item>
+        <item name="textColor">?textColorPrimaryInverse</item>
+        <item name="textColorHint">?textColorHintInverse</item>
+        <item name="textColorHighlight">?textColorHighlightInverse</item>
+        <item name="textColorLink">?textColorLinkInverse</item>
     </style>
 
     <style name="TextAppearance.Quantum.Light.SearchResult" parent="TextAppearance.Quantum.SearchResult">
-        <item name="android:textColor">?textColorPrimary</item>
-        <item name="android:textColorHint">?textColorHint</item>
+        <item name="textColor">?textColorPrimary</item>
+        <item name="textColorHint">?textColorHint</item>
     </style>
 
     <style name="TextAppearance.Quantum.Light.SearchResult.Title">
-        <item name="android:textSize">18sp</item>
+        <item name="textSize">18sp</item>
     </style>
 
     <style name="TextAppearance.Quantum.Light.SearchResult.Subtitle">
-        <item name="android:textSize">14sp</item>
-        <item name="android:textColor">?textColorSecondary</item>
+        <item name="textSize">14sp</item>
+        <item name="textColor">?textColorSecondary</item>
     </style>
 
     <style name="TextAppearance.Quantum.Light.Widget" parent="TextAppearance.Widget"/>
@@ -330,8 +330,8 @@
     <style name="TextAppearance.Quantum.Light.Widget.Button"/>
 
     <style name="TextAppearance.Quantum.Light.Widget.EditText">
-        <item name="android:textColor">@android:color/bright_foreground_dark</item>
-        <item name="android:textColorHint">@android:color/hint_foreground_holo_dark</item>
+        <item name="textColor">@color/bright_foreground_dark</item>
+        <item name="textColorHint">@color/hint_foreground_quantum_dark</item>
     </style>
 
     <style name="TextAppearance.Quantum.Light.Widget.PopupMenu" parent="TextAppearance.Quantum.Widget.PopupMenu"/>
@@ -347,14 +347,14 @@
     <style name="TextAppearance.Quantum.Light.Widget.ActionMode.Subtitle" parent="TextAppearance.Widget.ActionMode.Subtitle"/>
 
     <style name="TextAppearance.Quantum.Light.WindowTitle">
-        <item name="android:textColor">#fff</item>
-        <item name="android:textSize">14sp</item>
-        <item name="android:textStyle">bold</item>
+        <item name="textColor">#fff</item>
+        <item name="textSize">14sp</item>
+        <item name="textStyle">bold</item>
     </style>
 
     <style name="TextAppearance.Quantum.Light.DialogWindowTitle">
-        <item name="android:textSize">22sp</item>
-        <item name="android:textColor">@android:color/holo_blue_light</item>
+        <item name="textSize">22sp</item>
+        <item name="textColor">@color/holo_blue_light</item>
     </style>
 
     <style name="TextAppearance.Quantum.Light.CalendarViewWeekDayView" parent="TextAppearance.Small.CalendarViewWeekDayView"/>
@@ -367,67 +367,67 @@
     <style name="Quantum.Light" />
 
     <style name="Widget.Quantum.Button" parent="Widget.Button">
-        <item name="android:background">@android:drawable/btn_default_holo_dark</item>
-        <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
-        <item name="android:textColor">@android:color/primary_text_holo_dark</item>
-        <item name="android:minHeight">48dip</item>
-        <item name="android:minWidth">64dip</item>
+        <item name="background">@drawable/btn_default_quantum_dark</item>
+        <item name="textAppearance">?attr/textAppearanceMedium</item>
+        <item name="textColor">@color/primary_text_quantum_dark</item>
+        <item name="minHeight">48dip</item>
+        <item name="minWidth">64dip</item>
     </style>
 
     <style name="Widget.Quantum.StackView">
-        <item name="android:resOutColor">@android:color/holo_blue_light</item>
-        <item name="android:clickColor">@android:color/holo_blue_light</item>
+        <item name="resOutColor">@color/holo_blue_light</item>
+        <item name="clickColor">@color/holo_blue_light</item>
     </style>
 
     <style name="Widget.Quantum.Button.Borderless">
-        <item name="android:background">?android:attr/selectableItemBackground</item>
-        <item name="android:paddingStart">4dip</item>
-        <item name="android:paddingEnd">4dip</item>
+        <item name="background">?attr/selectableItemBackground</item>
+        <item name="paddingStart">4dip</item>
+        <item name="paddingEnd">4dip</item>
     </style>
 
     <style name="Widget.Quantum.Button.Borderless.Small">
-        <item name="android:textSize">14sp</item>
+        <item name="textSize">14sp</item>
     </style>
 
     <style name="Widget.Quantum.Button.Small">
-        <item name="android:background">@android:drawable/btn_default_holo_dark</item>
-        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
-        <item name="android:textColor">@android:color/primary_text_holo_dark</item>
-        <item name="android:minHeight">48dip</item>
-        <item name="android:minWidth">48dip</item>
+        <item name="background">@drawable/btn_default_quantum_dark</item>
+        <item name="textAppearance">?attr/textAppearanceSmall</item>
+        <item name="textColor">@color/primary_text_quantum_dark</item>
+        <item name="minHeight">48dip</item>
+        <item name="minWidth">48dip</item>
     </style>
 
     <style name="Widget.Quantum.Button.Inset">
-        <item name="android:background">@android:drawable/button_inset</item>
+        <item name="background">@drawable/button_inset</item>
     </style>
 
     <style name="Widget.Quantum.Button.Toggle">
-        <item name="android:background">@android:drawable/btn_toggle_holo_dark</item>
-        <item name="android:textOn">@android:string/capital_on</item>
-        <item name="android:textOff">@android:string/capital_off</item>
-        <item name="android:disabledAlpha">?android:attr/disabledAlpha</item>
-        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
-        <item name="android:minHeight">48dip</item>
+        <item name="background">@drawable/btn_toggle_holo_dark</item>
+        <item name="textOn">@string/capital_on</item>
+        <item name="textOff">@string/capital_off</item>
+        <item name="disabledAlpha">?attr/disabledAlpha</item>
+        <item name="textAppearance">?attr/textAppearanceSmall</item>
+        <item name="minHeight">48dip</item>
     </style>
 
     <style name="Quantum.ButtonBar" parent="ButtonBar">
-        <item name="android:paddingTop">0dip</item>
-        <item name="android:paddingStart">0dip</item>
-        <item name="android:paddingEnd">0dip</item>
-        <item name="android:paddingBottom">0dip</item>
-        <item name="divider">?android:attr/dividerVertical</item>
+        <item name="paddingTop">0dip</item>
+        <item name="paddingStart">0dip</item>
+        <item name="paddingEnd">0dip</item>
+        <item name="paddingBottom">0dip</item>
+        <item name="divider">?attr/dividerVertical</item>
         <item name="showDividers">middle</item>
         <item name="dividerPadding">12dip</item>
         <item name="background">@null</item>
     </style>
 
     <style name="Quantum.SegmentedButton" parent="SegmentedButton">
-        <item name="android:background">@android:drawable/btn_group_holo_dark</item>
+        <item name="background">@drawable/btn_group_holo_dark</item>
     </style>
 
     <style name="Quantum.ButtonBar.AlertDialog">
-        <item name="android:background">@null</item>
-        <item name="android:dividerPadding">0dp</item>
+        <item name="background">@null</item>
+        <item name="dividerPadding">0dp</item>
     </style>
 
     <style name="Widget.Quantum.TextView" parent="Widget.TextView"/>
@@ -435,8 +435,8 @@
     <style name="Widget.Quantum.CheckedTextView" parent="Widget.CheckedTextView"/>
 
     <style name="Widget.Quantum.TextView.ListSeparator" parent="Widget.TextView.ListSeparator">
-        <item name="android:background">@android:drawable/list_section_divider_holo_dark</item>
-        <item name="android:textAllCaps">true</item>
+        <item name="background">@drawable/list_section_divider_holo_dark</item>
+        <item name="textAllCaps">true</item>
     </style>
 
     <style name="Widget.Quantum.TextSelectHandle" parent="Widget.TextSelectHandle"/>
@@ -446,8 +446,8 @@
     <style name="Widget.Quantum.AbsListView" parent="Widget.AbsListView"/>
 
     <style name="Widget.Quantum.AutoCompleteTextView" parent="Widget.AutoCompleteTextView">
-        <item name="android:dropDownSelector">@android:drawable/list_selector_holo_dark</item>
-        <item name="android:popupBackground">@android:drawable/menu_dropdown_panel_holo_dark</item>
+        <item name="dropDownSelector">@drawable/list_selector_quantum_dark</item>
+        <item name="popupBackground">@drawable/menu_dropdown_panel_holo_dark</item>
     </style>
 
     <style name="Widget.Quantum.CompoundButton" parent="Widget.CompoundButton"/>
@@ -459,10 +459,10 @@
     <style name="Widget.Quantum.EditText" parent="Widget.EditText"/>
 
     <style name="Widget.Quantum.ExpandableListView" parent="Widget.Quantum.ListView">
-        <item name="android:groupIndicator">@android:drawable/expander_group_holo_dark</item>
-        <item name="android:indicatorLeft">?android:attr/expandableListPreferredItemIndicatorLeft</item>
-        <item name="android:indicatorRight">?android:attr/expandableListPreferredItemIndicatorRight</item>
-        <item name="android:childDivider">?android:attr/listDivider</item>
+        <item name="groupIndicator">@drawable/expander_group_holo_dark</item>
+        <item name="indicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
+        <item name="indicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
+        <item name="childDivider">?attr/listDivider</item>
     </style>
 
     <style name="Widget.Quantum.ExpandableListView.White"/>
@@ -474,52 +474,52 @@
     <style name="Widget.Quantum.GestureOverlayView" parent="Widget.GestureOverlayView"/>
 
     <style name="Widget.Quantum.GridView" parent="Widget.GridView">
-        <item name="android:listSelector">?android:attr/selectableItemBackground</item>
+        <item name="listSelector">?attr/selectableItemBackground</item>
     </style>
 
     <style name="Widget.Quantum.CalendarView" parent="Widget.CalendarView">
-        <item name="android:selectedWeekBackgroundColor">#330099FF</item>
-        <item name="android:focusedMonthDateColor">#FFFFFFFF</item>
-        <item name="android:unfocusedMonthDateColor">#66FFFFFF</item>
-        <item name="android:weekNumberColor">#33FFFFFF</item>
-        <item name="android:weekSeparatorLineColor">#19FFFFFF</item>
-        <item name="android:selectedDateVerticalBar">@android:drawable/day_picker_week_view_dayline_holo</item>
-        <item name="android:weekDayTextAppearance">@android:style/TextAppearance.Quantum.CalendarViewWeekDayView</item>
+        <item name="selectedWeekBackgroundColor">#330099FF</item>
+        <item name="focusedMonthDateColor">#FFFFFFFF</item>
+        <item name="unfocusedMonthDateColor">#66FFFFFF</item>
+        <item name="weekNumberColor">#33FFFFFF</item>
+        <item name="weekSeparatorLineColor">#19FFFFFF</item>
+        <item name="selectedDateVerticalBar">@drawable/day_picker_week_view_dayline_holo</item>
+        <item name="weekDayTextAppearance">@style/TextAppearance.Quantum.CalendarViewWeekDayView</item>
     </style>
 
     <style name="Widget.Quantum.ImageButton" parent="Widget.ImageButton">
-        <item name="android:background">@android:drawable/btn_default_holo_dark</item>
+        <item name="background">@drawable/btn_default_quantum_dark</item>
     </style>
 
     <style name="Widget.Quantum.NumberPicker" parent="Widget.NumberPicker">
-        <item name="android:internalLayout">@android:layout/number_picker_with_selector_wheel</item>
-        <item name="android:solidColor">@android:color/transparent</item>
-        <item name="android:selectionDivider">@android:drawable/numberpicker_selection_divider</item>
-        <item name="android:selectionDividerHeight">2dip</item>
-        <item name="android:selectionDividersDistance">48dip</item>
-        <item name="android:internalMinWidth">64dip</item>
-        <item name="android:internalMaxHeight">180dip</item>
-        <item name="virtualButtonPressedDrawable">?android:attr/selectableItemBackground</item>
+        <item name="internalLayout">@layout/number_picker_with_selector_wheel</item>
+        <item name="solidColor">@color/transparent</item>
+        <item name="selectionDivider">@drawable/numberpicker_selection_divider</item>
+        <item name="selectionDividerHeight">2dip</item>
+        <item name="selectionDividersDistance">48dip</item>
+        <item name="internalMinWidth">64dip</item>
+        <item name="internalMaxHeight">180dip</item>
+        <item name="virtualButtonPressedDrawable">?attr/selectableItemBackground</item>
     </style>
 
     <style name="Widget.Quantum.TimePicker" parent="Widget.TimePicker">
-        <item name="android:legacyLayout">@android:layout/time_picker_legacy_holo</item>
-        <item name="android:internalLayout">@android:layout/time_picker_holo</item>
-        <item name="android:disabledColor">@android:color/timepicker_default_disabled_color_holo_dark</item>
-        <item name="android:headerSelectedTextColor">@android:color/holo_blue_light</item>
-        <item name="android:headerUnselectedTextColor">@android:color/timepicker_default_text_color_holo_dark</item>
-        <item name="android:headerBackgroundColor">@android:color/timepicker_default_background_holo_dark</item>
-        <item name="android:numbersTextColor">@android:color/timepicker_default_text_color_holo_dark</item>
-        <item name="android:numbersBackgroundColor">@android:color/timepicker_default_background_holo_dark</item>
-        <item name="android:amPmTextColor">@android:color/timepicker_default_text_color_holo_dark</item>
-        <item name="android:amPmUnselectedBackgroundColor">@android:color/timepicker_default_background_holo_dark</item>
-        <item name="android:amPmSelectedBackgroundColor">@android:color/holo_blue_light</item>
-        <item name="android:numbersSelectorColor">@android:color/holo_blue_light</item>
+        <item name="legacyLayout">@layout/time_picker_legacy_holo</item>
+        <item name="internalLayout">@layout/time_picker_holo</item>
+        <item name="disabledColor">@color/timepicker_default_disabled_color_quantum_dark</item>
+        <item name="headerSelectedTextColor">@color/holo_blue_light</item>
+        <item name="headerUnselectedTextColor">@color/timepicker_default_text_color_quantum_dark</item>
+        <item name="headerBackgroundColor">@color/timepicker_default_background_quantum_dark</item>
+        <item name="numbersTextColor">@color/timepicker_default_text_color_quantum_dark</item>
+        <item name="numbersBackgroundColor">@color/timepicker_default_background_quantum_dark</item>
+        <item name="amPmTextColor">@color/timepicker_default_text_color_quantum_dark</item>
+        <item name="amPmUnselectedBackgroundColor">@color/timepicker_default_background_quantum_dark</item>
+        <item name="amPmSelectedBackgroundColor">@color/holo_blue_light</item>
+        <item name="numbersSelectorColor">@color/holo_blue_light</item>
     </style>
 
     <style name="Widget.Quantum.DatePicker" parent="Widget.DatePicker">
-        <item name="android:internalLayout">@android:layout/date_picker_holo</item>
-        <item name="android:calendarViewShown">true</item>
+        <item name="internalLayout">@layout/date_picker_holo</item>
+        <item name="calendarViewShown">true</item>
     </style>
 
     <style name="Widget.Quantum.ActivityChooserView" parent="Widget.ActivityChooserView"/>
@@ -527,8 +527,8 @@
     <style name="Widget.Quantum.ImageWell" parent="Widget.ImageWell"/>
 
     <style name="Widget.Quantum.ListView" parent="Widget.ListView">
-        <item name="android:divider">?android:attr/listDivider</item>
-        <item name="android:listSelector">?android:attr/listChoiceBackgroundIndicator</item>
+        <item name="divider">?attr/listDivider</item>
+        <item name="listSelector">?attr/listChoiceBackgroundIndicator</item>
     </style>
 
     <style name="Widget.Quantum.ListView.White"/>
@@ -536,29 +536,29 @@
     <style name="Widget.Quantum.PopupWindow" parent="Widget.PopupWindow"/>
 
     <style name="Widget.Quantum.PopupWindow.ActionMode">
-        <item name="android:popupBackground">@android:color/black</item>
-        <item name="android:popupAnimationStyle">@android:style/Animation.PopupWindow.ActionMode</item>
+        <item name="popupBackground">@color/black</item>
+        <item name="popupAnimationStyle">@style/Animation.PopupWindow.ActionMode</item>
     </style>
 
     <style name="Widget.Quantum.ProgressBar" parent="Widget.ProgressBar">
-        <item name="android:indeterminateDrawable">@android:drawable/progress_medium_holo</item>
+        <item name="indeterminateDrawable">@drawable/progress_medium_holo</item>
     </style>
 
     <style name="Widget.Quantum.ProgressBar.Horizontal" parent="Widget.ProgressBar.Horizontal">
-        <item name="android:progressDrawable">@android:drawable/progress_horizontal_holo_dark</item>
-        <item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal_holo</item>
-        <item name="android:minHeight">16dip</item>
-        <item name="android:maxHeight">16dip</item>
+        <item name="progressDrawable">@drawable/progress_horizontal_holo_dark</item>
+        <item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal_holo</item>
+        <item name="minHeight">16dip</item>
+        <item name="maxHeight">16dip</item>
     </style>
 
     <style name="Widget.Quantum.ProgressBar.Small" parent="Widget.ProgressBar.Small">
-        <item name="android:indeterminateDrawable">@android:drawable/progress_small_holo</item>
+        <item name="indeterminateDrawable">@drawable/progress_small_holo</item>
     </style>
 
     <style name="Widget.Quantum.ProgressBar.Small.Title"/>
 
     <style name="Widget.Quantum.ProgressBar.Large" parent="Widget.ProgressBar.Large">
-        <item name="android:indeterminateDrawable">@android:drawable/progress_large_holo</item>
+        <item name="indeterminateDrawable">@drawable/progress_large_holo</item>
     </style>
 
     <style name="Widget.Quantum.ProgressBar.Inverse"/>
@@ -568,36 +568,36 @@
     <style name="Widget.Quantum.ProgressBar.Large.Inverse"/>
 
     <style name="Widget.Quantum.SeekBar">
-        <item name="android:indeterminateOnly">false</item>
-        <item name="android:progressDrawable">@android:drawable/scrubber_progress_horizontal_holo_dark</item>
-        <item name="android:indeterminateDrawable">@android:drawable/scrubber_progress_horizontal_holo_dark</item>
-        <item name="android:minHeight">13dip</item>
-        <item name="android:maxHeight">13dip</item>
-        <item name="android:thumb">@android:drawable/scrubber_control_selector_holo</item>
-        <item name="android:thumbOffset">16dip</item>
-        <item name="android:focusable">true</item>
-        <item name="android:paddingStart">16dip</item>
-        <item name="android:paddingEnd">16dip</item>
-        <item name="android:mirrorForRtl">true</item>
+        <item name="indeterminateOnly">false</item>
+        <item name="progressDrawable">@drawable/scrubber_progress_horizontal_holo_dark</item>
+        <item name="indeterminateDrawable">@drawable/scrubber_progress_horizontal_holo_dark</item>
+        <item name="minHeight">13dip</item>
+        <item name="maxHeight">13dip</item>
+        <item name="thumb">@drawable/scrubber_control_selector_holo</item>
+        <item name="thumbOffset">16dip</item>
+        <item name="focusable">true</item>
+        <item name="paddingStart">16dip</item>
+        <item name="paddingEnd">16dip</item>
+        <item name="mirrorForRtl">true</item>
     </style>
 
     <style name="Widget.Quantum.RatingBar" parent="Widget.RatingBar">
-        <item name="android:progressDrawable">@android:drawable/ratingbar_full_holo_dark</item>
-        <item name="android:indeterminateDrawable">@android:drawable/ratingbar_full_holo_dark</item>
+        <item name="progressDrawable">@drawable/ratingbar_full_holo_dark</item>
+        <item name="indeterminateDrawable">@drawable/ratingbar_full_holo_dark</item>
     </style>
 
     <style name="Widget.Quantum.RatingBar.Indicator" parent="Widget.RatingBar.Indicator">
-        <item name="android:progressDrawable">@android:drawable/ratingbar_holo_dark</item>
-        <item name="android:indeterminateDrawable">@android:drawable/ratingbar_holo_dark</item>
-        <item name="android:minHeight">35dip</item>
-        <item name="android:maxHeight">35dip</item>
+        <item name="progressDrawable">@drawable/ratingbar_holo_dark</item>
+        <item name="indeterminateDrawable">@drawable/ratingbar_holo_dark</item>
+        <item name="minHeight">35dip</item>
+        <item name="maxHeight">35dip</item>
     </style>
 
     <style name="Widget.Quantum.RatingBar.Small" parent="Widget.RatingBar.Small">
-        <item name="android:progressDrawable">@android:drawable/ratingbar_small_holo_dark</item>
-        <item name="android:indeterminateDrawable">@android:drawable/ratingbar_small_holo_dark</item>
-        <item name="android:minHeight">16dip</item>
-        <item name="android:maxHeight">16dip</item>
+        <item name="progressDrawable">@drawable/ratingbar_small_holo_dark</item>
+        <item name="indeterminateDrawable">@drawable/ratingbar_small_holo_dark</item>
+        <item name="minHeight">16dip</item>
+        <item name="maxHeight">16dip</item>
     </style>
 
     <style name="Widget.Quantum.CompoundButton.RadioButton" parent="Widget.CompoundButton.RadioButton"/>
@@ -607,47 +607,47 @@
     <style name="Widget.Quantum.HorizontalScrollView" parent="Widget.HorizontalScrollView"/>
 
     <style name="Widget.Quantum.Spinner" parent="Widget.Spinner.DropDown">
-        <item name="android:background">@android:drawable/spinner_background_holo_dark</item>
-        <item name="android:dropDownSelector">@android:drawable/list_selector_holo_dark</item>
-        <item name="android:popupBackground">@android:drawable/menu_dropdown_panel_holo_dark</item>
-        <item name="android:dropDownVerticalOffset">0dip</item>
-        <item name="android:dropDownHorizontalOffset">0dip</item>
-        <item name="android:dropDownWidth">wrap_content</item>
-        <item name="android:popupPromptView">@android:layout/simple_dropdown_hint</item>
-        <item name="android:gravity">start|center_vertical</item>
-        <item name="android:disableChildrenWhenDisabled">true</item>
+        <item name="background">@drawable/spinner_background_holo_dark</item>
+        <item name="dropDownSelector">@drawable/list_selector_quantum_dark</item>
+        <item name="popupBackground">@drawable/menu_dropdown_panel_holo_dark</item>
+        <item name="dropDownVerticalOffset">0dip</item>
+        <item name="dropDownHorizontalOffset">0dip</item>
+        <item name="dropDownWidth">wrap_content</item>
+        <item name="popupPromptView">@layout/simple_dropdown_hint</item>
+        <item name="gravity">start|center_vertical</item>
+        <item name="disableChildrenWhenDisabled">true</item>
     </style>
 
     <style name="Widget.Quantum.Spinner.DropDown"/>
 
     <style name="Widget.Quantum.Spinner.DropDown.ActionBar">
-        <item name="android:background">@android:drawable/spinner_ab_holo_dark</item>
+        <item name="background">@drawable/spinner_ab_holo_dark</item>
     </style>
 
     <style name="Widget.Quantum.CompoundButton.Star" parent="Widget.CompoundButton.Star">
-        <item name="android:button">@android:drawable/btn_star_holo_dark</item>
+        <item name="button">@drawable/btn_star_holo_dark</item>
     </style>
 
     <style name="Widget.Quantum.TabWidget" parent="Widget.TabWidget">
-        <item name="android:tabStripLeft">@null</item>
-        <item name="android:tabStripRight">@null</item>
-        <item name="android:tabStripEnabled">false</item>
-        <item name="android:divider">?android:attr/dividerVertical</item>
-        <item name="android:showDividers">middle</item>
-        <item name="android:dividerPadding">8dip</item>
-        <item name="android:measureWithLargestChild">true</item>
-        <item name="android:tabLayout">@android:layout/tab_indicator_holo</item>
+        <item name="tabStripLeft">@null</item>
+        <item name="tabStripRight">@null</item>
+        <item name="tabStripEnabled">false</item>
+        <item name="divider">?attr/dividerVertical</item>
+        <item name="showDividers">middle</item>
+        <item name="dividerPadding">8dip</item>
+        <item name="measureWithLargestChild">true</item>
+        <item name="tabLayout">@layout/tab_indicator_holo</item>
     </style>
 
     <style name="Widget.Quantum.Tab" parent="Widget.Quantum.ActionBar.TabView">
-        <item name="android:background">@android:drawable/tab_indicator_holo</item>
-        <item name="android:layout_width">0dip</item>
-        <item name="android:layout_weight">1</item>
-        <item name="android:minWidth">80dip</item>
+        <item name="background">@drawable/tab_indicator_holo</item>
+        <item name="layout_width">0dip</item>
+        <item name="layout_weight">1</item>
+        <item name="minWidth">80dip</item>
     </style>
 
     <style name="Widget.Quantum.TabText" parent="Widget.Quantum.ActionBar.TabText">
-        <item name="android:maxWidth">180dip</item>
+        <item name="maxWidth">180dip</item>
     </style>
 
     <style name="Widget.Quantum.WebTextView" parent="Widget.WebTextView"/>
@@ -655,17 +655,17 @@
     <style name="Widget.Quantum.WebView" parent="Widget.WebView"/>
 
     <style name="Widget.Quantum.DropDownItem" parent="Widget.DropDownItem">
-        <item name="android:textAppearance">@style/TextAppearance.Quantum.Widget.DropDownItem</item>
-        <item name="android:paddingStart">8dp</item>
-        <item name="android:paddingEnd">8dp</item>
+        <item name="textAppearance">@style/TextAppearance.Quantum.Widget.DropDownItem</item>
+        <item name="paddingStart">8dp</item>
+        <item name="paddingEnd">8dp</item>
     </style>
 
     <style name="Widget.Quantum.DropDownItem.Spinner"/>
 
     <style name="Widget.Quantum.TextView.SpinnerItem" parent="Widget.TextView.SpinnerItem">
-        <item name="android:textAppearance">@style/TextAppearance.Quantum.Widget.TextView.SpinnerItem</item>
-        <item name="android:paddingStart">8dp</item>
-        <item name="android:paddingEnd">8dp</item>
+        <item name="textAppearance">@style/TextAppearance.Quantum.Widget.TextView.SpinnerItem</item>
+        <item name="paddingStart">8dp</item>
+        <item name="paddingEnd">8dp</item>
     </style>
 
     <style name="Widget.Quantum.KeyboardView" parent="Widget.KeyboardView"/>
@@ -683,104 +683,104 @@
     <style name="Widget.Quantum.QuickContactBadgeSmall.WindowLarge" parent="Widget.QuickContactBadgeSmall.WindowLarge"/>
 
     <style name="Widget.Quantum.ListPopupWindow" parent="Widget.ListPopupWindow">
-        <item name="android:dropDownSelector">@android:drawable/list_selector_holo_dark</item>
-        <item name="android:popupBackground">@android:drawable/menu_panel_holo_dark</item>
-        <item name="android:dropDownVerticalOffset">0dip</item>
-        <item name="android:dropDownHorizontalOffset">0dip</item>
-        <item name="android:dropDownWidth">wrap_content</item>
+        <item name="dropDownSelector">@drawable/list_selector_quantum_dark</item>
+        <item name="popupBackground">@drawable/menu_panel_holo_dark</item>
+        <item name="dropDownVerticalOffset">0dip</item>
+        <item name="dropDownHorizontalOffset">0dip</item>
+        <item name="dropDownWidth">wrap_content</item>
     </style>
 
     <style name="Widget.Quantum.PopupMenu" parent="Widget.Quantum.ListPopupWindow"/>
 
     <style name="Widget.Quantum.ButtonBar">
-        <item name="android:divider">?android:attr/dividerVertical</item>
+        <item name="divider">?attr/dividerVertical</item>
     </style>
 
     <style name="Widget.Quantum.ButtonBar.Button"/>
 
     <style name="Widget.Quantum.ActionButton" parent="Widget.ActionButton">
-        <item name="android:minWidth">@android:dimen/action_button_min_width</item>
-        <item name="android:gravity">center</item>
-        <item name="android:paddingStart">12dip</item>
-        <item name="android:paddingEnd">12dip</item>
-        <item name="android:scaleType">center</item>
-        <item name="android:maxLines">2</item>
+        <item name="minWidth">@dimen/action_button_min_width</item>
+        <item name="gravity">center</item>
+        <item name="paddingStart">12dip</item>
+        <item name="paddingEnd">12dip</item>
+        <item name="scaleType">center</item>
+        <item name="maxLines">2</item>
     </style>
 
     <style name="Widget.Quantum.ActionButton.Overflow">
-        <item name="android:src">@android:drawable/ic_menu_moreoverflow_holo_dark</item>
-        <item name="android:background">?android:attr/actionBarItemBackground</item>
-        <item name="android:contentDescription">@string/action_menu_overflow_description</item>
+        <item name="src">@drawable/ic_menu_moreoverflow_holo_dark</item>
+        <item name="background">?attr/actionBarItemBackground</item>
+        <item name="contentDescription">@string/action_menu_overflow_description</item>
     </style>
 
     <style name="Widget.Quantum.ActionButton.TextButton" parent="Widget.Quantum.ButtonBar.Button"/>
 
     <style name="Widget.Quantum.ActionBar.TabView" parent="Widget.ActionBar.TabView">
-        <item name="android:background">@drawable/tab_indicator_ab_holo</item>
-        <item name="android:paddingStart">16dip</item>
-        <item name="android:paddingEnd">16dip</item>
+        <item name="background">@drawable/tab_indicator_ab_holo</item>
+        <item name="paddingStart">16dip</item>
+        <item name="paddingEnd">16dip</item>
     </style>
 
     <style name="Widget.Quantum.ActionBar.TabBar" parent="Widget.ActionBar.TabBar">
-        <item name="android:divider">?android:attr/actionBarDivider</item>
-        <item name="android:showDividers">middle</item>
-        <item name="android:dividerPadding">12dip</item>
+        <item name="divider">?attr/actionBarDivider</item>
+        <item name="showDividers">middle</item>
+        <item name="dividerPadding">12dip</item>
     </style>
 
     <style name="Widget.Quantum.ActionBar.TabText" parent="Widget.ActionBar.TabText">
-        <item name="android:textAppearance">@style/TextAppearance.Quantum.Medium</item>
-        <item name="android:textColor">?android:attr/textColorPrimary</item>
-        <item name="android:textSize">12sp</item>
-        <item name="android:textStyle">bold</item>
-        <item name="android:textAllCaps">true</item>
-        <item name="android:ellipsize">marquee</item>
-        <item name="android:maxLines">2</item>
+        <item name="textAppearance">@style/TextAppearance.Quantum.Medium</item>
+        <item name="textColor">?attr/textColorPrimary</item>
+        <item name="textSize">12sp</item>
+        <item name="textStyle">bold</item>
+        <item name="textAllCaps">true</item>
+        <item name="ellipsize">marquee</item>
+        <item name="maxLines">2</item>
     </style>
 
     <style name="Widget.Quantum.ActionMode" parent="Widget.ActionMode">
-        <item name="android:titleTextStyle">@android:style/TextAppearance.Quantum.Widget.ActionMode.Title</item>
-        <item name="android:subtitleTextStyle">@android:style/TextAppearance.Quantum.Widget.ActionMode.Subtitle</item>
+        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Title</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Subtitle</item>
     </style>
 
     <style name="Widget.Quantum.ActionButton.CloseMode">
-        <item name="android:background">@drawable/btn_cab_done_holo_dark</item>
+        <item name="background">@drawable/btn_cab_done_holo_dark</item>
     </style>
 
     <style name="Widget.Quantum.ActionBar" parent="Widget.ActionBar">
-        <item name="android:titleTextStyle">@android:style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
-        <item name="android:subtitleTextStyle">@android:style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
-        <item name="android:background">@android:drawable/ab_transparent_dark_holo</item>
-        <item name="android:backgroundStacked">@android:drawable/ab_stacked_transparent_dark_holo</item>
-        <item name="android:backgroundSplit">@android:drawable/ab_bottom_transparent_dark_holo</item>
-        <item name="android:divider">?android:attr/dividerVertical</item>
-        <item name="android:progressBarStyle">@android:style/Widget.Quantum.ProgressBar.Horizontal</item>
-        <item name="android:indeterminateProgressStyle">@android:style/Widget.Quantum.ProgressBar</item>
-        <item name="android:progressBarPadding">32dip</item>
-        <item name="android:itemPadding">8dip</item>
+        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
+        <item name="background">@drawable/ab_transparent_dark_holo</item>
+        <item name="backgroundStacked">@drawable/ab_stacked_transparent_dark_holo</item>
+        <item name="backgroundSplit">@drawable/ab_bottom_transparent_dark_holo</item>
+        <item name="divider">?attr/dividerVertical</item>
+        <item name="progressBarStyle">@style/Widget.Quantum.ProgressBar.Horizontal</item>
+        <item name="indeterminateProgressStyle">@style/Widget.Quantum.ProgressBar</item>
+        <item name="progressBarPadding">32dip</item>
+        <item name="itemPadding">8dip</item>
     </style>
 
     <style name="Widget.Quantum.ActionBar.Solid">
-        <item name="android:titleTextStyle">@android:style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
-        <item name="android:subtitleTextStyle">@android:style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
-        <item name="android:background">@android:drawable/ab_solid_dark_holo</item>
-        <item name="android:backgroundStacked">@android:drawable/ab_stacked_solid_dark_holo</item>
-        <item name="android:backgroundSplit">@android:drawable/ab_bottom_solid_dark_holo</item>
-        <item name="android:divider">?android:attr/dividerVertical</item>
-        <item name="android:progressBarStyle">@android:style/Widget.Quantum.ProgressBar.Horizontal</item>
-        <item name="android:indeterminateProgressStyle">@android:style/Widget.Quantum.ProgressBar</item>
-        <item name="android:progressBarPadding">32dip</item>
-        <item name="android:itemPadding">8dip</item>
+        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
+        <item name="background">@drawable/ab_solid_dark_holo</item>
+        <item name="backgroundStacked">@drawable/ab_stacked_solid_dark_holo</item>
+        <item name="backgroundSplit">@drawable/ab_bottom_solid_dark_holo</item>
+        <item name="divider">?attr/dividerVertical</item>
+        <item name="progressBarStyle">@style/Widget.Quantum.ProgressBar.Horizontal</item>
+        <item name="indeterminateProgressStyle">@style/Widget.Quantum.ProgressBar</item>
+        <item name="progressBarPadding">32dip</item>
+        <item name="itemPadding">8dip</item>
     </style>
 
     <style name="Widget.Quantum.CompoundButton.Switch">
-        <item name="android:track">@android:drawable/switch_track_holo_dark</item>
-        <item name="android:thumb">@android:drawable/switch_inner_holo_dark</item>
-        <item name="android:switchTextAppearance">@android:style/TextAppearance.Quantum.Widget.Switch</item>
-        <item name="android:textOn">@android:string/capital_on</item>
-        <item name="android:textOff">@android:string/capital_off</item>
-        <item name="android:thumbTextPadding">12dip</item>
-        <item name="android:switchMinWidth">96dip</item>
-        <item name="android:switchPadding">16dip</item>
+        <item name="track">@drawable/switch_track_holo_dark</item>
+        <item name="thumb">@drawable/switch_inner_holo_dark</item>
+        <item name="switchTextAppearance">@style/TextAppearance.Quantum.Widget.Switch</item>
+        <item name="textOn">@string/capital_on</item>
+        <item name="textOff">@string/capital_off</item>
+        <item name="thumbTextPadding">12dip</item>
+        <item name="switchMinWidth">96dip</item>
+        <item name="switchPadding">16dip</item>
     </style>
 
     <!-- Light widget styles -->
@@ -788,51 +788,51 @@
     <style name="Widget.Quantum.Light"/>
 
     <style name="Widget.Quantum.Light.Button" parent="Widget.Button">
-        <item name="android:background">@android:drawable/btn_default_holo_light</item>
-        <item name="android:textAppearance">?android:attr/textAppearanceMediumInverse</item>
-        <item name="android:textColor">@android:color/primary_text_holo_light</item>
-        <item name="android:minHeight">48dip</item>
-        <item name="android:minWidth">64dip</item>
+        <item name="background">@drawable/btn_default_quantum_light</item>
+        <item name="textAppearance">?attr/textAppearanceMediumInverse</item>
+        <item name="textColor">@color/primary_text_quantum_light</item>
+        <item name="minHeight">48dip</item>
+        <item name="minWidth">64dip</item>
     </style>
 
     <style name="Widget.Quantum.Light.Button.Borderless">
-        <item name="android:background">?android:attr/selectableItemBackground</item>
-        <item name="android:paddingStart">4dip</item>
-        <item name="android:paddingEnd">4dip</item>
+        <item name="background">?attr/selectableItemBackground</item>
+        <item name="paddingStart">4dip</item>
+        <item name="paddingEnd">4dip</item>
     </style>
 
     <style name="Widget.Quantum.Light.Button.Borderless.Small">
-        <item name="android:textSize">14sp</item>
+        <item name="textSize">14sp</item>
     </style>
 
     <style name="Widget.Quantum.Light.Button.Small">
-        <item name="android:background">@android:drawable/btn_default_holo_light</item>
-        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
-        <item name="android:textColor">@android:color/primary_text_holo_light</item>
-        <item name="android:minHeight">48dip</item>
-        <item name="android:minWidth">48dip</item>
+        <item name="background">@drawable/btn_default_quantum_light</item>
+        <item name="textAppearance">?attr/textAppearanceSmall</item>
+        <item name="textColor">@color/primary_text_quantum_light</item>
+        <item name="minHeight">48dip</item>
+        <item name="minWidth">48dip</item>
     </style>
 
     <style name="Widget.Quantum.Light.Button.Inset"/>
 
     <style name="Widget.Quantum.Light.Button.Toggle">
-        <item name="android:background">@android:drawable/btn_toggle_holo_light</item>
-        <item name="android:textOn">@android:string/capital_on</item>
-        <item name="android:textOff">@android:string/capital_off</item>
-        <item name="android:disabledAlpha">?android:attr/disabledAlpha</item>
-        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
-        <item name="android:minHeight">48dip</item>
+        <item name="background">@drawable/btn_toggle_holo_light</item>
+        <item name="textOn">@string/capital_on</item>
+        <item name="textOff">@string/capital_off</item>
+        <item name="disabledAlpha">?attr/disabledAlpha</item>
+        <item name="textAppearance">?attr/textAppearanceSmall</item>
+        <item name="minHeight">48dip</item>
     </style>
 
     <style name="Quantum.Light.ButtonBar" parent="Quantum.ButtonBar"/>
 
     <style name="Quantum.Light.ButtonBar.AlertDialog">
-        <item name="android:background">@null</item>
-        <item name="android:dividerPadding">0dp</item>
+        <item name="background">@null</item>
+        <item name="dividerPadding">0dp</item>
     </style>
 
     <style name="Quantum.Light.SegmentedButton" parent="SegmentedButton">
-        <item name="android:background">@android:drawable/btn_group_holo_light</item>
+        <item name="background">@drawable/btn_group_holo_light</item>
     </style>
 
     <style name="Widget.Quantum.Light.TextView" parent="Widget.TextView"/>
@@ -840,8 +840,8 @@
     <style name="Widget.Quantum.Light.CheckedTextView" parent="Widget.CheckedTextView"/>
 
     <style name="Widget.Quantum.Light.TextView.ListSeparator" parent="Widget.TextView.ListSeparator">
-        <item name="android:background">@android:drawable/list_section_divider_holo_light</item>
-        <item name="android:textAllCaps">true</item>
+        <item name="background">@drawable/list_section_divider_holo_light</item>
+        <item name="textAllCaps">true</item>
     </style>
 
     <style name="Widget.Quantum.Light.TextSelectHandle" parent="Widget.TextSelectHandle"/>
@@ -851,8 +851,8 @@
     <style name="Widget.Quantum.Light.AbsListView" parent="Widget.AbsListView"/>
 
     <style name="Widget.Quantum.Light.AutoCompleteTextView" parent="Widget.AutoCompleteTextView">
-        <item name="android:dropDownSelector">@android:drawable/list_selector_holo_light</item>
-        <item name="android:popupBackground">@android:drawable/menu_dropdown_panel_holo_light</item>
+        <item name="dropDownSelector">@drawable/list_selector_quantum_light</item>
+        <item name="popupBackground">@drawable/menu_dropdown_panel_holo_light</item>
     </style>
 
     <style name="Widget.Quantum.Light.CompoundButton.CheckBox" parent="Widget.CompoundButton.CheckBox"/>
@@ -862,10 +862,10 @@
     <style name="Widget.Quantum.Light.EditText" parent="Widget.Quantum.EditText"/>
 
     <style name="Widget.Quantum.Light.ExpandableListView" parent="Widget.Quantum.Light.ListView">
-        <item name="android:groupIndicator">@android:drawable/expander_group_holo_light</item>
-        <item name="android:indicatorLeft">?android:attr/expandableListPreferredItemIndicatorLeft</item>
-        <item name="android:indicatorRight">?android:attr/expandableListPreferredItemIndicatorRight</item>
-        <item name="android:childDivider">?android:attr/listDivider</item>
+        <item name="groupIndicator">@drawable/expander_group_holo_light</item>
+        <item name="indicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
+        <item name="indicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
+        <item name="childDivider">?attr/listDivider</item>
     </style>
 
     <style name="Widget.Quantum.Light.ExpandableListView.White"/>
@@ -879,39 +879,39 @@
     <style name="Widget.Quantum.Light.GridView" parent="Widget.Quantum.GridView"/>
 
     <style name="Widget.Quantum.Light.ImageButton" parent="Widget.Quantum.ImageButton">
-        <item name="android:background">@android:drawable/btn_default_holo_light</item>
+        <item name="background">@drawable/btn_default_quantum_light</item>
     </style>
 
     <style name="Widget.Quantum.Light.CalendarView" parent="Widget.CalendarView">
-        <item name="android:selectedWeekBackgroundColor">#330066ff</item>
-        <item name="android:focusedMonthDateColor">#FF000000</item>
-        <item name="android:unfocusedMonthDateColor">#7F08002B</item>
-        <item name="android:weekNumberColor">#7F080021</item>
-        <item name="android:weekSeparatorLineColor">#7F08002A</item>
-        <item name="android:weekDayTextAppearance">@android:style/TextAppearance.Quantum.Light.CalendarViewWeekDayView</item>
+        <item name="selectedWeekBackgroundColor">#330066ff</item>
+        <item name="focusedMonthDateColor">#FF000000</item>
+        <item name="unfocusedMonthDateColor">#7F08002B</item>
+        <item name="weekNumberColor">#7F080021</item>
+        <item name="weekSeparatorLineColor">#7F08002A</item>
+        <item name="weekDayTextAppearance">@style/TextAppearance.Quantum.Light.CalendarViewWeekDayView</item>
     </style>
 
     <style name="Widget.Quantum.Light.NumberPicker" parent="Widget.Quantum.NumberPicker"/>
 
     <style name="Widget.Quantum.Light.TimePicker" parent="Widget.TimePicker">
-        <item name="android:legacyLayout">@android:layout/time_picker_legacy_holo</item>
-        <item name="android:internalLayout">@android:layout/time_picker_holo</item>
-        <item name="android:disabledColor">@android:color/timepicker_default_disabled_color_holo_light</item>
-        <item name="android:headerSelectedTextColor">@android:color/holo_blue_light</item>
-        <item name="android:headerUnselectedTextColor">@android:color/timepicker_default_text_color_holo_light</item>
-        <item name="android:headerBackgroundColor">@android:color/timepicker_default_background_holo_light</item>
-        <item name="android:numbersTextColor">@android:color/timepicker_default_text_color_holo_light</item>
-        <item name="android:numbersBackgroundColor">@android:color/timepicker_default_background_holo_light</item>
-        <item name="android:amPmTextColor">@android:color/timepicker_default_text_color_holo_light</item>
-        <item name="android:amPmUnselectedBackgroundColor">@android:color/timepicker_default_background_holo_light</item>
-        <item name="android:amPmSelectedBackgroundColor">@android:color/holo_blue_light</item>
-        <item name="android:numbersSelectorColor">@android:color/holo_blue_light</item>
+        <item name="legacyLayout">@layout/time_picker_legacy_holo</item>
+        <item name="internalLayout">@layout/time_picker_holo</item>
+        <item name="disabledColor">@color/timepicker_default_disabled_color_quantum_light</item>
+        <item name="headerSelectedTextColor">@color/holo_blue_light</item>
+        <item name="headerUnselectedTextColor">@color/timepicker_default_text_color_quantum_light</item>
+        <item name="headerBackgroundColor">@color/timepicker_default_background_quantum_light</item>
+        <item name="numbersTextColor">@color/timepicker_default_text_color_quantum_light</item>
+        <item name="numbersBackgroundColor">@color/timepicker_default_background_quantum_light</item>
+        <item name="amPmTextColor">@color/timepicker_default_text_color_quantum_light</item>
+        <item name="amPmUnselectedBackgroundColor">@color/timepicker_default_background_quantum_light</item>
+        <item name="amPmSelectedBackgroundColor">@color/holo_blue_light</item>
+        <item name="numbersSelectorColor">@color/holo_blue_light</item>
     </style>
 
     <style name="Widget.Quantum.Light.DatePicker" parent="Widget.Quantum.DatePicker"/>
 
     <style name="Widget.Quantum.Light.ActivityChooserView" parent="Widget.Quantum.ActivityChooserView">
-        <item name="android:background">@android:drawable/ab_share_pack_holo_light</item>
+        <item name="background">@drawable/ab_share_pack_holo_light</item>
     </style>
 
     <style name="Widget.Quantum.Light.ImageWell" parent="Widget.ImageWell"/>
@@ -923,14 +923,14 @@
     <style name="Widget.Quantum.Light.PopupWindow" parent="Widget.PopupWindow"/>
 
     <style name="Widget.Quantum.Light.PopupWindow.ActionMode">
-        <item name="android:popupBackground">@android:color/white</item>
-        <item name="android:popupAnimationStyle">@android:style/Animation.PopupWindow.ActionMode</item>
+        <item name="popupBackground">@color/white</item>
+        <item name="popupAnimationStyle">@style/Animation.PopupWindow.ActionMode</item>
     </style>
 
     <style name="Widget.Quantum.Light.ProgressBar" parent="Widget.Quantum.ProgressBar"/>
 
     <style name="Widget.Quantum.Light.ProgressBar.Horizontal" parent="Widget.Quantum.ProgressBar.Horizontal">
-        <item name="android:progressDrawable">@android:drawable/progress_horizontal_holo_light</item>
+        <item name="progressDrawable">@drawable/progress_horizontal_holo_light</item>
     </style>
 
     <style name="Widget.Quantum.Light.ProgressBar.Small" parent="Widget.Quantum.ProgressBar.Small"/>
@@ -946,27 +946,27 @@
     <style name="Widget.Quantum.Light.ProgressBar.Large.Inverse" parent="Widget.Quantum.ProgressBar.Large.Inverse"/>
 
     <style name="Widget.Quantum.Light.SeekBar" parent="Widget.Quantum.SeekBar">
-        <item name="android:progressDrawable">@android:drawable/scrubber_progress_horizontal_holo_light</item>
-        <item name="android:indeterminateDrawable">@android:drawable/scrubber_progress_horizontal_holo_light</item>
+        <item name="progressDrawable">@drawable/scrubber_progress_horizontal_holo_light</item>
+        <item name="indeterminateDrawable">@drawable/scrubber_progress_horizontal_holo_light</item>
     </style>
 
     <style name="Widget.Quantum.Light.RatingBar" parent="Widget.RatingBar">
-        <item name="android:progressDrawable">@android:drawable/ratingbar_full_holo_light</item>
-        <item name="android:indeterminateDrawable">@android:drawable/ratingbar_full_holo_light</item>
+        <item name="progressDrawable">@drawable/ratingbar_full_holo_light</item>
+        <item name="indeterminateDrawable">@drawable/ratingbar_full_holo_light</item>
     </style>
 
     <style name="Widget.Quantum.Light.RatingBar.Indicator" parent="Widget.RatingBar.Indicator">
-        <item name="android:progressDrawable">@android:drawable/ratingbar_holo_light</item>
-        <item name="android:indeterminateDrawable">@android:drawable/ratingbar_holo_light</item>
-        <item name="android:minHeight">35dip</item>
-        <item name="android:maxHeight">35dip</item>
+        <item name="progressDrawable">@drawable/ratingbar_holo_light</item>
+        <item name="indeterminateDrawable">@drawable/ratingbar_holo_light</item>
+        <item name="minHeight">35dip</item>
+        <item name="maxHeight">35dip</item>
     </style>
 
     <style name="Widget.Quantum.Light.RatingBar.Small" parent="Widget.RatingBar.Small">
-        <item name="android:progressDrawable">@android:drawable/ratingbar_small_holo_light</item>
-        <item name="android:indeterminateDrawable">@android:drawable/ratingbar_small_holo_light</item>
-        <item name="android:minHeight">16dip</item>
-        <item name="android:maxHeight">16dip</item>
+        <item name="progressDrawable">@drawable/ratingbar_small_holo_light</item>
+        <item name="indeterminateDrawable">@drawable/ratingbar_small_holo_light</item>
+        <item name="minHeight">16dip</item>
+        <item name="maxHeight">16dip</item>
     </style>
 
     <style name="Widget.Quantum.Light.CompoundButton.RadioButton" parent="Widget.CompoundButton.RadioButton"/>
@@ -976,23 +976,23 @@
     <style name="Widget.Quantum.Light.HorizontalScrollView" parent="Widget.HorizontalScrollView"/>
 
     <style name="Widget.Quantum.Light.Spinner" parent="Widget.Quantum.Spinner">
-        <item name="android:background">@android:drawable/spinner_background_holo_light</item>
-        <item name="android:dropDownSelector">@android:drawable/list_selector_holo_light</item>
-        <item name="android:popupBackground">@android:drawable/menu_dropdown_panel_holo_light</item>
-        <item name="android:dropDownVerticalOffset">0dip</item>
-        <item name="android:dropDownHorizontalOffset">0dip</item>
-        <item name="android:dropDownWidth">wrap_content</item>
-        <item name="android:popupPromptView">@android:layout/simple_dropdown_hint</item>
+        <item name="background">@drawable/spinner_background_holo_light</item>
+        <item name="dropDownSelector">@drawable/list_selector_quantum_light</item>
+        <item name="popupBackground">@drawable/menu_dropdown_panel_holo_light</item>
+        <item name="dropDownVerticalOffset">0dip</item>
+        <item name="dropDownHorizontalOffset">0dip</item>
+        <item name="dropDownWidth">wrap_content</item>
+        <item name="popupPromptView">@layout/simple_dropdown_hint</item>
     </style>
 
     <style name="Widget.Quantum.Light.Spinner.DropDown"/>
 
     <style name="Widget.Quantum.Light.Spinner.DropDown.ActionBar">
-        <item name="android:background">@android:drawable/spinner_ab_holo_light</item>
+        <item name="background">@drawable/spinner_ab_holo_light</item>
     </style>
 
     <style name="Widget.Quantum.Light.CompoundButton.Star" parent="Widget.CompoundButton.Star">
-        <item name="android:button">@android:drawable/btn_star_holo_light</item>
+        <item name="button">@drawable/btn_star_holo_light</item>
     </style>
 
     <style name="Widget.Quantum.Light.TabWidget" parent="Widget.Quantum.TabWidget"/>
@@ -1022,11 +1022,11 @@
     <style name="Widget.Quantum.Light.QuickContactBadgeSmall.WindowLarge" parent="Widget.QuickContactBadgeSmall.WindowLarge"/>
 
     <style name="Widget.Quantum.Light.ListPopupWindow" parent="Widget.ListPopupWindow">
-        <item name="android:dropDownSelector">@android:drawable/list_selector_holo_light</item>
-        <item name="android:popupBackground">@android:drawable/menu_panel_holo_light</item>
-        <item name="android:dropDownVerticalOffset">0dip</item>
-        <item name="android:dropDownHorizontalOffset">0dip</item>
-        <item name="android:dropDownWidth">wrap_content</item>
+        <item name="dropDownSelector">@drawable/list_selector_quantum_light</item>
+        <item name="popupBackground">@drawable/menu_panel_holo_light</item>
+        <item name="dropDownVerticalOffset">0dip</item>
+        <item name="dropDownHorizontalOffset">0dip</item>
+        <item name="dropDownWidth">wrap_content</item>
     </style>
 
     <style name="Widget.Quantum.Light.PopupMenu" parent="Widget.Quantum.Light.ListPopupWindow"/>
@@ -1034,17 +1034,17 @@
     <style name="Widget.Quantum.Light.ActionButton" parent="Widget.Quantum.ActionButton"/>
 
     <style name="Widget.Quantum.Light.ActionButton.Overflow">
-        <item name="android:src">@android:drawable/ic_menu_moreoverflow_holo_light</item>
-        <item name="android:contentDescription">@string/action_menu_overflow_description</item>
+        <item name="src">@drawable/ic_menu_moreoverflow_holo_light</item>
+        <item name="contentDescription">@string/action_menu_overflow_description</item>
     </style>
 
     <style name="Widget.Quantum.Light.ActionBar.TabView" parent="Widget.Quantum.ActionBar.TabView"/>
 
     <style name="Widget.Quantum.Light.Tab" parent="Widget.Quantum.Light.ActionBar.TabView">
-        <item name="android:background">@android:drawable/tab_indicator_holo</item>
-        <item name="android:layout_width">0dip</item>
-        <item name="android:layout_weight">1</item>
-        <item name="android:minWidth">80dip</item>
+        <item name="background">@drawable/tab_indicator_holo</item>
+        <item name="layout_width">0dip</item>
+        <item name="layout_weight">1</item>
+        <item name="minWidth">80dip</item>
     </style>
 
     <style name="Widget.Quantum.Light.ActionBar.TabBar" parent="Widget.Quantum.ActionBar.TabBar"/>
@@ -1056,69 +1056,69 @@
     <style name="Widget.Quantum.Light.ActionBar.TabBar.Inverse"/>
 
     <style name="Widget.Quantum.Light.ActionBar.TabText.Inverse">
-        <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
+        <item name="textColor">?attr/textColorPrimaryInverse</item>
     </style>
 
     <style name="Widget.Quantum.Light.ActionMode" parent="Widget.Quantum.ActionMode">
-        <item name="android:titleTextStyle">@android:style/TextAppearance.Quantum.Widget.ActionMode.Title</item>
-        <item name="android:subtitleTextStyle">@android:style/TextAppearance.Quantum.Widget.ActionMode.Subtitle</item>
+        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Title</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Subtitle</item>
     </style>
 
     <style name="Widget.Quantum.Light.ActionMode.Inverse" parent="Widget.ActionMode">
-        <item name="android:titleTextStyle">@android:style/TextAppearance.Quantum.Widget.ActionMode.Title.Inverse</item>
-        <item name="android:subtitleTextStyle">@android:style/TextAppearance.Quantum.Widget.ActionMode.Subtitle.Inverse</item>
+        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Title.Inverse</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Subtitle.Inverse</item>
     </style>
 
     <style name="Widget.Quantum.Light.ActionButton.CloseMode">
-        <item name="android:background">@drawable/btn_cab_done_holo_light</item>
+        <item name="background">@drawable/btn_cab_done_holo_light</item>
     </style>
 
     <style name="Widget.Quantum.Light.ActionBar" parent="Widget.Quantum.ActionBar">
-        <item name="android:titleTextStyle">@android:style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
-        <item name="android:subtitleTextStyle">@android:style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
-        <item name="android:background">@android:drawable/ab_transparent_light_holo</item>
-        <item name="android:backgroundStacked">@android:drawable/ab_stacked_transparent_light_holo</item>
-        <item name="android:backgroundSplit">@android:drawable/ab_bottom_transparent_light_holo</item>
-        <item name="android:homeAsUpIndicator">@android:drawable/ic_ab_back_holo_light</item>
-        <item name="android:progressBarStyle">@android:style/Widget.Quantum.Light.ProgressBar.Horizontal</item>
-        <item name="android:indeterminateProgressStyle">@android:style/Widget.Quantum.Light.ProgressBar</item>
+        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
+        <item name="background">@drawable/ab_transparent_light_holo</item>
+        <item name="backgroundStacked">@drawable/ab_stacked_transparent_light_holo</item>
+        <item name="backgroundSplit">@drawable/ab_bottom_transparent_light_holo</item>
+        <item name="homeAsUpIndicator">@drawable/ic_ab_back_holo_light</item>
+        <item name="progressBarStyle">@style/Widget.Quantum.Light.ProgressBar.Horizontal</item>
+        <item name="indeterminateProgressStyle">@style/Widget.Quantum.Light.ProgressBar</item>
     </style>
 
     <style name="Widget.Quantum.Light.ActionBar.Solid">
-        <item name="android:titleTextStyle">@android:style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
-        <item name="android:subtitleTextStyle">@android:style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
-        <item name="android:background">@android:drawable/ab_solid_light_holo</item>
-        <item name="android:backgroundStacked">@android:drawable/ab_stacked_solid_light_holo</item>
-        <item name="android:backgroundSplit">@android:drawable/ab_bottom_solid_light_holo</item>
-        <item name="android:divider">?android:attr/dividerVertical</item>
-        <item name="android:progressBarStyle">@android:style/Widget.Quantum.Light.ProgressBar.Horizontal</item>
-        <item name="android:indeterminateProgressStyle">@android:style/Widget.Quantum.Light.ProgressBar</item>
-        <item name="android:progressBarPadding">32dip</item>
-        <item name="android:itemPadding">8dip</item>
+        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
+        <item name="background">@drawable/ab_solid_light_holo</item>
+        <item name="backgroundStacked">@drawable/ab_stacked_solid_light_holo</item>
+        <item name="backgroundSplit">@drawable/ab_bottom_solid_light_holo</item>
+        <item name="divider">?attr/dividerVertical</item>
+        <item name="progressBarStyle">@style/Widget.Quantum.Light.ProgressBar.Horizontal</item>
+        <item name="indeterminateProgressStyle">@style/Widget.Quantum.Light.ProgressBar</item>
+        <item name="progressBarPadding">32dip</item>
+        <item name="itemPadding">8dip</item>
     </style>
 
     <style name="Widget.Quantum.Light.ActionBar.Solid.Inverse">
-        <item name="android:titleTextStyle">@android:style/TextAppearance.Quantum.Widget.ActionBar.Title.Inverse</item>
-        <item name="android:subtitleTextStyle">@android:style/TextAppearance.Quantum.Widget.ActionBar.Subtitle.Inverse</item>
-        <item name="android:background">@android:drawable/ab_solid_dark_holo</item>
-        <item name="android:backgroundStacked">@android:drawable/ab_stacked_solid_dark_holo</item>
-        <item name="android:backgroundSplit">@android:drawable/ab_bottom_solid_inverse_holo</item>
-        <item name="android:divider">@android:drawable/list_divider_holo_dark</item>
-        <item name="android:progressBarStyle">@android:style/Widget.Quantum.ProgressBar.Horizontal</item>
-        <item name="android:indeterminateProgressStyle">@android:style/Widget.Quantum.ProgressBar</item>
-        <item name="android:progressBarPadding">32dip</item>
-        <item name="android:itemPadding">8dip</item>
+        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title.Inverse</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle.Inverse</item>
+        <item name="background">@drawable/ab_solid_dark_holo</item>
+        <item name="backgroundStacked">@drawable/ab_stacked_solid_dark_holo</item>
+        <item name="backgroundSplit">@drawable/ab_bottom_solid_inverse_holo</item>
+        <item name="divider">@drawable/list_divider_holo_dark</item>
+        <item name="progressBarStyle">@style/Widget.Quantum.ProgressBar.Horizontal</item>
+        <item name="indeterminateProgressStyle">@style/Widget.Quantum.ProgressBar</item>
+        <item name="progressBarPadding">32dip</item>
+        <item name="itemPadding">8dip</item>
     </style>
 
     <style name="Widget.Quantum.Light.CompoundButton.Switch" parent="Widget.CompoundButton.Switch">
-        <item name="android:track">@android:drawable/switch_track_holo_light</item>
-        <item name="android:thumb">@android:drawable/switch_inner_holo_light</item>
-        <item name="android:switchTextAppearance">@android:style/TextAppearance.Quantum.Light.Widget.Switch</item>
-        <item name="android:textOn">@android:string/capital_on</item>
-        <item name="android:textOff">@android:string/capital_off</item>
-        <item name="android:thumbTextPadding">12dip</item>
-        <item name="android:switchMinWidth">96dip</item>
-        <item name="android:switchPadding">16dip</item>
+        <item name="track">@drawable/switch_track_holo_light</item>
+        <item name="thumb">@drawable/switch_inner_holo_light</item>
+        <item name="switchTextAppearance">@style/TextAppearance.Quantum.Light.Widget.Switch</item>
+        <item name="textOn">@string/capital_on</item>
+        <item name="textOff">@string/capital_off</item>
+        <item name="thumbTextPadding">12dip</item>
+        <item name="switchMinWidth">96dip</item>
+        <item name="switchPadding">16dip</item>
     </style>
 
     <!-- Animation Styles -->
@@ -1132,109 +1132,109 @@
     <!-- Dialog styles -->
 
     <style name="AlertDialog.Quantum" parent="AlertDialog">
-        <item name="fullDark">@android:drawable/dialog_full_holo_dark</item>
-        <item name="topDark">@android:drawable/dialog_top_holo_dark</item>
-        <item name="centerDark">@android:drawable/dialog_middle_holo_dark</item>
-        <item name="bottomDark">@android:drawable/dialog_bottom_holo_dark</item>
-        <item name="fullBright">@android:drawable/dialog_full_holo_dark</item>
-        <item name="topBright">@android:drawable/dialog_top_holo_dark</item>
-        <item name="centerBright">@android:drawable/dialog_middle_holo_dark</item>
-        <item name="bottomBright">@android:drawable/dialog_bottom_holo_dark</item>
-        <item name="bottomMedium">@android:drawable/dialog_bottom_holo_dark</item>
-        <item name="centerMedium">@android:drawable/dialog_middle_holo_dark</item>
-        <item name="layout">@android:layout/alert_dialog_holo</item>
-        <item name="listLayout">@android:layout/select_dialog_holo</item>
-        <item name="progressLayout">@android:layout/progress_dialog_holo</item>
-        <item name="horizontalProgressLayout">@android:layout/alert_dialog_progress_holo</item>
-        <item name="listItemLayout">@android:layout/select_dialog_item_holo</item>
-        <item name="multiChoiceItemLayout">@android:layout/select_dialog_multichoice_holo</item>
-        <item name="singleChoiceItemLayout">@android:layout/select_dialog_singlechoice_holo</item>
+        <item name="fullDark">@drawable/dialog_full_holo_dark</item>
+        <item name="topDark">@drawable/dialog_top_holo_dark</item>
+        <item name="centerDark">@drawable/dialog_middle_holo_dark</item>
+        <item name="bottomDark">@drawable/dialog_bottom_holo_dark</item>
+        <item name="fullBright">@drawable/dialog_full_holo_dark</item>
+        <item name="topBright">@drawable/dialog_top_holo_dark</item>
+        <item name="centerBright">@drawable/dialog_middle_holo_dark</item>
+        <item name="bottomBright">@drawable/dialog_bottom_holo_dark</item>
+        <item name="bottomMedium">@drawable/dialog_bottom_holo_dark</item>
+        <item name="centerMedium">@drawable/dialog_middle_holo_dark</item>
+        <item name="layout">@layout/alert_dialog_holo</item>
+        <item name="listLayout">@layout/select_dialog_holo</item>
+        <item name="progressLayout">@layout/progress_dialog_holo</item>
+        <item name="horizontalProgressLayout">@layout/alert_dialog_progress_holo</item>
+        <item name="listItemLayout">@layout/select_dialog_item_holo</item>
+        <item name="multiChoiceItemLayout">@layout/select_dialog_multichoice_holo</item>
+        <item name="singleChoiceItemLayout">@layout/select_dialog_singlechoice_holo</item>
     </style>
 
     <style name="AlertDialog.Quantum.Light">
-        <item name="fullDark">@android:drawable/dialog_full_holo_light</item>
-        <item name="topDark">@android:drawable/dialog_top_holo_light</item>
-        <item name="centerDark">@android:drawable/dialog_middle_holo_light</item>
-        <item name="bottomDark">@android:drawable/dialog_bottom_holo_light</item>
-        <item name="fullBright">@android:drawable/dialog_full_holo_light</item>
-        <item name="topBright">@android:drawable/dialog_top_holo_light</item>
-        <item name="centerBright">@android:drawable/dialog_middle_holo_light</item>
-        <item name="bottomBright">@android:drawable/dialog_bottom_holo_light</item>
-        <item name="bottomMedium">@android:drawable/dialog_bottom_holo_light</item>
-        <item name="centerMedium">@android:drawable/dialog_middle_holo_light</item>
+        <item name="fullDark">@drawable/dialog_full_holo_light</item>
+        <item name="topDark">@drawable/dialog_top_holo_light</item>
+        <item name="centerDark">@drawable/dialog_middle_holo_light</item>
+        <item name="bottomDark">@drawable/dialog_bottom_holo_light</item>
+        <item name="fullBright">@drawable/dialog_full_holo_light</item>
+        <item name="topBright">@drawable/dialog_top_holo_light</item>
+        <item name="centerBright">@drawable/dialog_middle_holo_light</item>
+        <item name="bottomBright">@drawable/dialog_bottom_holo_light</item>
+        <item name="bottomMedium">@drawable/dialog_bottom_holo_light</item>
+        <item name="centerMedium">@drawable/dialog_middle_holo_light</item>
     </style>
 
     <!-- Window title -->
     <style name="WindowTitleBackground.Quantum">
-        <item name="android:background">@null</item>
+        <item name="background">@null</item>
     </style>
 
     <style name="WindowTitle.Quantum">
-        <item name="android:singleLine">true</item>
-        <item name="android:textAppearance">@style/TextAppearance.Quantum.WindowTitle</item>
-        <item name="android:shadowColor">#BB000000</item>
-        <item name="android:shadowRadius">2.75</item>
+        <item name="singleLine">true</item>
+        <item name="textAppearance">@style/TextAppearance.Quantum.WindowTitle</item>
+        <item name="shadowColor">#BB000000</item>
+        <item name="shadowRadius">2.75</item>
     </style>
 
     <style name="DialogWindowTitle.Quantum">
-        <item name="android:maxLines">1</item>
-        <item name="android:scrollHorizontally">true</item>
-        <item name="android:textAppearance">@style/TextAppearance.Quantum.DialogWindowTitle</item>
+        <item name="maxLines">1</item>
+        <item name="scrollHorizontally">true</item>
+        <item name="textAppearance">@style/TextAppearance.Quantum.DialogWindowTitle</item>
     </style>
 
     <style name="DialogWindowTitle.Quantum.Light">
-        <item name="android:maxLines">1</item>
-        <item name="android:scrollHorizontally">true</item>
-        <item name="android:textAppearance">@style/TextAppearance.Quantum.Light.DialogWindowTitle</item>
+        <item name="maxLines">1</item>
+        <item name="scrollHorizontally">true</item>
+        <item name="textAppearance">@style/TextAppearance.Quantum.Light.DialogWindowTitle</item>
     </style>
 
     <style name="Widget.Quantum.PreferenceFrameLayout">
-        <item name="android:borderTop">0dip</item>
-        <item name="android:borderBottom">@dimen/preference_fragment_padding_bottom</item>
-        <item name="android:borderLeft">?attr/preferenceFragmentPaddingSide</item>
-        <item name="android:borderRight">?attr/preferenceFragmentPaddingSide</item>
+        <item name="borderTop">0dip</item>
+        <item name="borderBottom">@dimen/preference_fragment_padding_bottom</item>
+        <item name="borderLeft">?attr/preferenceFragmentPaddingSide</item>
+        <item name="borderRight">?attr/preferenceFragmentPaddingSide</item>
     </style>
 
     <style name="Widget.Quantum.MediaRouteButton">
-        <item name="android:background">?android:attr/selectableItemBackground</item>
-        <item name="android:externalRouteEnabledDrawable">@drawable/ic_media_route_holo_dark</item>
-        <item name="android:minWidth">56dp</item>
-        <item name="android:minHeight">48dp</item>
-        <item name="android:focusable">true</item>
-        <item name="android:contentDescription">@android:string/media_route_button_content_description</item>
+        <item name="background">?attr/selectableItemBackground</item>
+        <item name="externalRouteEnabledDrawable">@drawable/ic_media_route_holo_dark</item>
+        <item name="minWidth">56dp</item>
+        <item name="minHeight">48dp</item>
+        <item name="focusable">true</item>
+        <item name="contentDescription">@string/media_route_button_content_description</item>
     </style>
 
     <style name="Widget.Quantum.Light.MediaRouteButton" parent="Widget.Quantum.MediaRouteButton">
-        <item name="android:externalRouteEnabledDrawable">@drawable/ic_media_route_holo_light</item>
+        <item name="externalRouteEnabledDrawable">@drawable/ic_media_route_holo_light</item>
     </style>
 
     <style name="TextAppearance.Quantum.TimePicker.TimeLabel" parent="TextAppearance.Quantum">
-        <item name="android:textSize">@dimen/timepicker_time_label_size</item>
-        <item name="android:textColor">@android:color/timepicker_default_text_color_holo_dark</item>
+        <item name="textSize">@dimen/timepicker_time_label_size</item>
+        <item name="textColor">@color/timepicker_default_text_color_quantum_dark</item>
     </style>
 
     <style name="TextAppearance.Quantum.TimePicker.AmPmLabel" parent="TextAppearance.Quantum">
-        <item name="android:textSize">@dimen/timepicker_ampm_label_size</item>
-        <item name="android:textAllCaps">true</item>
-        <item name="android:textColor">@android:color/timepicker_default_text_color_holo_dark</item>
-        <item name="android:textStyle">bold</item>
+        <item name="textSize">@dimen/timepicker_ampm_label_size</item>
+        <item name="textAllCaps">true</item>
+        <item name="textColor">@color/timepicker_default_text_color_quantum_dark</item>
+        <item name="textStyle">bold</item>
     </style>
 
     <style name="TextAppearance.Quantum.Light.TimePicker.TimeLabel" parent="TextAppearance.Quantum.Light">
-        <item name="android:textSize">@dimen/timepicker_time_label_size</item>
-        <item name="android:textColor">@color/timepicker_default_text_color_holo_light</item>
+        <item name="textSize">@dimen/timepicker_time_label_size</item>
+        <item name="textColor">@color/timepicker_default_text_color_quantum_light</item>
     </style>
 
     <style name="TextAppearance.Quantum.Light.TimePicker.AmPmLabel" parent="TextAppearance.Quantum.Light">
-        <item name="android:textSize">@dimen/timepicker_ampm_label_size</item>
-        <item name="android:textAllCaps">true</item>
-        <item name="android:textColor">@color/timepicker_default_text_color_holo_light</item>
-        <item name="android:textStyle">bold</item>
+        <item name="textSize">@dimen/timepicker_ampm_label_size</item>
+        <item name="textAllCaps">true</item>
+        <item name="textColor">@color/timepicker_default_text_color_quantum_light</item>
+        <item name="textStyle">bold</item>
     </style>
 
     <style name="Widget.Quantum.FastScroll" parent="Widget.FastScroll">
-        <item name="android:thumbMinWidth">0dp</item>
-        <item name="android:thumbMinHeight">0dp</item>
+        <item name="thumbMinWidth">0dp</item>
+        <item name="thumbMinHeight">0dp</item>
     </style>
 
     <style name="Widget.Quantum.Light.FastScroll" parent="Widget.Quantum.FastScroll"/>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3ac762f..e574e8d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -289,7 +289,6 @@
   <java-symbol type="bool" name="config_useFixedVolume" />
   <java-symbol type="bool" name="config_forceDefaultOrientation" />
   <java-symbol type="bool" name="config_wifi_batched_scan_supported" />
-  <java-symbol type="bool" name="flip_controller_fallback_keys" />
 
   <java-symbol type="integer" name="config_cursorWindowSize" />
   <java-symbol type="integer" name="config_extraFreeKbytesAdjust" />
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 7a654e6..4a0158e 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -365,7 +365,7 @@
         <item name="searchViewCloseIcon">@android:drawable/ic_clear</item>
         <item name="searchViewSearchIcon">@android:drawable/ic_search_api_holo_dark</item>
         <item name="searchViewGoIcon">@android:drawable/ic_go</item>
-        <item name="searchViewVoiceIcon">@android:drawable/ic_voice_search</item>
+        <item name="searchViewVoiceIcon">@android:drawable/ic_voice_search_api_holo_dark</item>
         <item name="searchViewEditQuery">@android:drawable/ic_commit_search_api_holo_dark</item>
         <item name="searchViewEditQueryBackground">?attr/selectableItemBackground</item>
 
diff --git a/core/res/res/values/themes_quantum.xml b/core/res/res/values/themes_quantum.xml
index 0a197b9..f0db46c 100644
--- a/core/res/res/values/themes_quantum.xml
+++ b/core/res/res/values/themes_quantum.xml
@@ -33,7 +33,7 @@
     <!-- Quantum Paper theme (dark version).
          <p>If you want to ensure that your
          app consistently uses the Quantum theme at all times, you must explicitly declare it in your
-         manifest. For example, {@code &lt;application android:theme="@android:style/Theme.Quantum"&gt;}.
+         manifest. For example, {@code &lt;application android:theme="@style/Theme.Quantum"&gt;}.
 
          <p>Styles used by the Quantum theme are named using the convention Type.Quantum.Etc
          (for example, {@code Widget.Quantum.Button} and {@code
@@ -42,10 +42,10 @@
          with trailing _dark or _light specifiers if they are not shared between both light and
          dark versions of the theme. -->
     <style name="Theme.Quantum">
-        <item name="colorForeground">@android:color/bright_foreground_holo_dark</item>
-        <item name="colorForegroundInverse">@android:color/bright_foreground_inverse_holo_dark</item>
-        <item name="colorBackground">@android:color/background_holo_dark</item>
-        <item name="colorBackgroundCacheHint">@android:drawable/background_cache_hint_selector_holo_dark</item>
+        <item name="colorForeground">@color/bright_foreground_quantum_dark</item>
+        <item name="colorForegroundInverse">@color/bright_foreground_quantum_light</item>
+        <item name="colorBackground">@color/background_quantum_dark</item>
+        <item name="colorBackgroundCacheHint">@drawable/background_cache_hint_selector_quantum_dark</item>
         <item name="disabledAlpha">0.5</item>
         <item name="backgroundDimAmount">0.6</item>
 
@@ -56,72 +56,72 @@
         <item name="colorActivatedHighlight">@color/holo_blue_dark</item>
 
         <!-- Text styles -->
-        <item name="textAppearance">@android:style/TextAppearance.Quantum</item>
-        <item name="textAppearanceInverse">@android:style/TextAppearance.Quantum.Inverse</item>
+        <item name="textAppearance">@style/TextAppearance.Quantum</item>
+        <item name="textAppearanceInverse">@style/TextAppearance.Quantum.Inverse</item>
 
-        <item name="textColorPrimary">@android:color/primary_text_holo_dark</item>
-        <item name="textColorSecondary">@android:color/secondary_text_holo_dark</item>
-        <item name="textColorTertiary">@android:color/tertiary_text_holo_dark</item>
-        <item name="textColorPrimaryInverse">@android:color/primary_text_holo_light</item>
-        <item name="textColorSecondaryInverse">@android:color/secondary_text_holo_light</item>
-        <item name="textColorTertiaryInverse">@android:color/tertiary_text_holo_light</item>
-        <item name="textColorPrimaryDisableOnly">@android:color/primary_text_disable_only_holo_dark</item>
-        <item name="textColorPrimaryInverseDisableOnly">@android:color/primary_text_disable_only_holo_light</item>
-        <item name="textColorPrimaryNoDisable">@android:color/primary_text_nodisable_holo_dark</item>
-        <item name="textColorSecondaryNoDisable">@android:color/secondary_text_nodisable_holo_dark</item>
-        <item name="textColorPrimaryInverseNoDisable">@android:color/primary_text_nodisable_holo_light</item>
-        <item name="textColorSecondaryInverseNoDisable">@android:color/secondary_text_nodisable_holo_light</item>
-        <item name="textColorHint">@android:color/hint_foreground_holo_dark</item>
-        <item name="textColorHintInverse">@android:color/hint_foreground_holo_light</item>
-        <item name="textColorSearchUrl">@android:color/search_url_text_holo</item>
-        <item name="textColorHighlight">@android:color/highlighted_text_holo_dark</item>
-        <item name="textColorHighlightInverse">@android:color/highlighted_text_holo_light</item>
-        <item name="textColorLink">@android:color/holo_blue_light</item>
-        <item name="textColorLinkInverse">@android:color/holo_blue_light</item>
-        <item name="textColorAlertDialogListItem">@android:color/primary_text_holo_dark</item>
+        <item name="textColorPrimary">@color/primary_text_quantum_dark</item>
+        <item name="textColorSecondary">@color/secondary_text_quantum_dark</item>
+        <item name="textColorTertiary">@color/tertiary_text_quantum_dark</item>
+        <item name="textColorPrimaryInverse">@color/primary_text_quantum_light</item>
+        <item name="textColorSecondaryInverse">@color/secondary_text_quantum_light</item>
+        <item name="textColorTertiaryInverse">@color/tertiary_text_quantum_light</item>
+        <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_quantum_dark</item>
+        <item name="textColorPrimaryInverseDisableOnly">@color/primary_text_disable_only_quantum_light</item>
+        <item name="textColorPrimaryNoDisable">@color/primary_text_nodisable_quantum_dark</item>
+        <item name="textColorSecondaryNoDisable">@color/secondary_text_nodisable_quantum_dark</item>
+        <item name="textColorPrimaryInverseNoDisable">@color/primary_text_nodisable_quantum_light</item>
+        <item name="textColorSecondaryInverseNoDisable">@color/secondary_text_nodisable_quantum_light</item>
+        <item name="textColorHint">@color/hint_foreground_quantum_dark</item>
+        <item name="textColorHintInverse">@color/hint_foreground_quantum_light</item>
+        <item name="textColorSearchUrl">@color/search_url_text_quantum_dark</item>
+        <item name="textColorHighlight">@color/highlighted_text_quantum_dark</item>
+        <item name="textColorHighlightInverse">@color/highlighted_text_quantum_light</item>
+        <item name="textColorLink">@color/holo_blue_light</item>
+        <item name="textColorLinkInverse">@color/holo_blue_light</item>
+        <item name="textColorAlertDialogListItem">@color/primary_text_quantum_dark</item>
 
-        <item name="textAppearanceLarge">@android:style/TextAppearance.Quantum.Large</item>
-        <item name="textAppearanceMedium">@android:style/TextAppearance.Quantum.Medium</item>
-        <item name="textAppearanceSmall">@android:style/TextAppearance.Quantum.Small</item>
-        <item name="textAppearanceLargeInverse">@android:style/TextAppearance.Quantum.Large.Inverse</item>
-        <item name="textAppearanceMediumInverse">@android:style/TextAppearance.Quantum.Medium.Inverse</item>
-        <item name="textAppearanceSmallInverse">@android:style/TextAppearance.Quantum.Small.Inverse</item>
-        <item name="textAppearanceSearchResultTitle">@android:style/TextAppearance.Quantum.SearchResult.Title</item>
-        <item name="textAppearanceSearchResultSubtitle">@android:style/TextAppearance.Quantum.SearchResult.Subtitle</item>
+        <item name="textAppearanceLarge">@style/TextAppearance.Quantum.Large</item>
+        <item name="textAppearanceMedium">@style/TextAppearance.Quantum.Medium</item>
+        <item name="textAppearanceSmall">@style/TextAppearance.Quantum.Small</item>
+        <item name="textAppearanceLargeInverse">@style/TextAppearance.Quantum.Large.Inverse</item>
+        <item name="textAppearanceMediumInverse">@style/TextAppearance.Quantum.Medium.Inverse</item>
+        <item name="textAppearanceSmallInverse">@style/TextAppearance.Quantum.Small.Inverse</item>
+        <item name="textAppearanceSearchResultTitle">@style/TextAppearance.Quantum.SearchResult.Title</item>
+        <item name="textAppearanceSearchResultSubtitle">@style/TextAppearance.Quantum.SearchResult.Subtitle</item>
 
-        <item name="textAppearanceButton">@android:style/TextAppearance.Quantum.Widget.Button</item>
+        <item name="textAppearanceButton">@style/TextAppearance.Quantum.Widget.Button</item>
 
-        <item name="editTextColor">?android:attr/textColorPrimary</item>
-        <item name="editTextBackground">@android:drawable/edit_text_holo_dark</item>
+        <item name="editTextColor">?attr/textColorPrimary</item>
+        <item name="editTextBackground">@drawable/edit_text_holo_dark</item>
 
-        <item name="candidatesTextStyleSpans">@android:string/candidates_style</item>
+        <item name="candidatesTextStyleSpans">@string/candidates_style</item>
 
-        <item name="textCheckMark">@android:drawable/indicator_check_mark_dark</item>
-        <item name="textCheckMarkInverse">@android:drawable/indicator_check_mark_light</item>
+        <item name="textCheckMark">@drawable/indicator_check_mark_dark</item>
+        <item name="textCheckMarkInverse">@drawable/indicator_check_mark_light</item>
 
-        <item name="textAppearanceLargePopupMenu">@android:style/TextAppearance.Quantum.Widget.PopupMenu.Large</item>
-        <item name="textAppearanceSmallPopupMenu">@android:style/TextAppearance.Quantum.Widget.PopupMenu.Small</item>
+        <item name="textAppearanceLargePopupMenu">@style/TextAppearance.Quantum.Widget.PopupMenu.Large</item>
+        <item name="textAppearanceSmallPopupMenu">@style/TextAppearance.Quantum.Widget.PopupMenu.Small</item>
 
         <!-- Button styles -->
-        <item name="buttonStyle">@android:style/Widget.Quantum.Button</item>
+        <item name="buttonStyle">@style/Widget.Quantum.Button</item>
 
-        <item name="buttonStyleSmall">@android:style/Widget.Quantum.Button.Small</item>
-        <item name="buttonStyleInset">@android:style/Widget.Quantum.Button.Inset</item>
+        <item name="buttonStyleSmall">@style/Widget.Quantum.Button.Small</item>
+        <item name="buttonStyleInset">@style/Widget.Quantum.Button.Inset</item>
 
-        <item name="buttonStyleToggle">@android:style/Widget.Quantum.Button.Toggle</item>
-        <item name="switchStyle">@android:style/Widget.Quantum.CompoundButton.Switch</item>
-        <item name="mediaRouteButtonStyle">@android:style/Widget.Quantum.MediaRouteButton</item>
+        <item name="buttonStyleToggle">@style/Widget.Quantum.Button.Toggle</item>
+        <item name="switchStyle">@style/Widget.Quantum.CompoundButton.Switch</item>
+        <item name="mediaRouteButtonStyle">@style/Widget.Quantum.MediaRouteButton</item>
 
-        <item name="selectableItemBackground">@android:drawable/item_background_holo_dark</item>
-        <item name="borderlessButtonStyle">@android:style/Widget.Quantum.Button.Borderless</item>
-        <item name="homeAsUpIndicator">@android:drawable/ic_ab_back_holo_dark</item>
+        <item name="selectableItemBackground">@drawable/item_background_quantum_dark</item>
+        <item name="borderlessButtonStyle">@style/Widget.Quantum.Button.Borderless</item>
+        <item name="homeAsUpIndicator">@drawable/ic_ab_back_holo_dark</item>
 
         <!-- List attributes -->
         <item name="listPreferredItemHeight">64dip</item>
         <item name="listPreferredItemHeightSmall">48dip</item>
         <item name="listPreferredItemHeightLarge">80dip</item>
-        <item name="dropdownListPreferredItemHeight">?android:attr/listPreferredItemHeightSmall</item>
-        <item name="textAppearanceListItemSmall">?android:attr/textAppearanceMedium</item>
+        <item name="dropdownListPreferredItemHeight">?attr/listPreferredItemHeightSmall</item>
+        <item name="textAppearanceListItemSmall">?attr/textAppearanceMedium</item>
         <item name="listPreferredItemPaddingLeft">8dip</item>
         <item name="listPreferredItemPaddingRight">8dip</item>
         <item name="listPreferredItemPaddingStart">8dip</item>
@@ -130,31 +130,32 @@
         <!-- @hide -->
         <item name="searchResultListItemHeight">58dip</item>
         <item name="listDivider">@drawable/list_divider_holo_dark</item>
-        <item name="listSeparatorTextViewStyle">@android:style/Widget.Quantum.TextView.ListSeparator</item>
+        <item name="listSeparatorTextViewStyle">@style/Widget.Quantum.TextView.ListSeparator</item>
 
-        <item name="listChoiceIndicatorSingle">@android:drawable/btn_radio_holo_dark</item>
-        <item name="listChoiceIndicatorMultiple">@android:drawable/btn_check_holo_dark</item>
+        <item name="listChoiceIndicatorSingle">@drawable/btn_radio_holo_dark</item>
+        <item name="listChoiceIndicatorMultiple">@drawable/btn_check_holo_dark</item>
 
-        <item name="listChoiceBackgroundIndicator">@android:drawable/list_selector_holo_dark</item>
+        <item name="listChoiceBackgroundIndicator">@drawable/list_selector_quantum_dark</item>
 
-        <item name="activatedBackgroundIndicator">@android:drawable/activated_background_holo_dark</item>
+        <item name="activatedBackgroundIndicator">@drawable/activated_background_holo_dark</item>
 
-        <item name="listDividerAlertDialog">@android:drawable/list_divider_holo_dark</item>
+        <item name="listDividerAlertDialog">@drawable/list_divider_holo_dark</item>
 
         <item name="expandableListPreferredItemPaddingLeft">40dip</item>
-        <item name="expandableListPreferredChildPaddingLeft">?android:attr/expandableListPreferredItemPaddingLeft</item>
+        <item name="expandableListPreferredChildPaddingLeft">?attr/expandableListPreferredItemPaddingLeft</item>
 
         <item name="expandableListPreferredItemIndicatorLeft">3dip</item>
         <item name="expandableListPreferredItemIndicatorRight">0dip</item>
-        <item name="expandableListPreferredChildIndicatorLeft">?android:attr/expandableListPreferredItemIndicatorLeft</item>
-        <item name="expandableListPreferredChildIndicatorRight">?android:attr/expandableListPreferredItemIndicatorRight</item>
-        <item name="findOnPageNextDrawable">@android:drawable/ic_find_next_holo_dark</item>
-        <item name="findOnPagePreviousDrawable">@android:drawable/ic_find_previous_holo_dark</item>
+        <item name="expandableListPreferredChildIndicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
+        <item name="expandableListPreferredChildIndicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
+        <item name="findOnPageNextDrawable">@drawable/ic_find_next_holo_dark</item>
+        <item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_holo_dark</item>
 
         <!-- Gallery attributes -->
-        <item name="galleryItemBackground">@android:drawable/gallery_item_background</item>
+        <item name="galleryItemBackground">@drawable/gallery_item_background</item>
 
         <!-- Window attributes -->
+        <item name="windowBackground">@color/background_quantum_dark</item>
         <item name="windowFrame">@null</item>
         <item name="windowNoTitle">false</item>
         <item name="windowFullscreen">false</item>
@@ -162,177 +163,177 @@
         <item name="windowIsFloating">false</item>
         <item name="windowContentOverlay">@null</item>
         <item name="windowShowWallpaper">false</item>
-        <item name="windowTitleStyle">@android:style/WindowTitle.Quantum</item>
+        <item name="windowTitleStyle">@style/WindowTitle.Quantum</item>
         <item name="windowTitleSize">25dip</item>
-        <item name="windowTitleBackgroundStyle">@android:style/WindowTitleBackground.Quantum</item>
+        <item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Quantum</item>
         <item name="windowContentTransitions">true</item>
-        <item name="windowAnimationStyle">@android:style/Animation.Quantum.Activity</item>
+        <item name="windowAnimationStyle">@style/Animation.Quantum.Activity</item>
         <item name="windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
         <item name="windowActionBar">true</item>
         <item name="windowActionModeOverlay">false</item>
 
         <!-- Dialog attributes -->
-        <item name="dialogTheme">@android:style/Theme.Quantum.Dialog</item>
+        <item name="dialogTheme">@style/Theme.Quantum.Dialog</item>
         <item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_holo</item>
         <item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_holo</item>
         <item name="dialogTitleDecorLayout">@layout/dialog_title_holo</item>
 
         <!-- AlertDialog attributes -->
-        <item name="alertDialogTheme">@android:style/Theme.Quantum.Dialog.Alert</item>
-        <item name="alertDialogStyle">@android:style/AlertDialog.Quantum</item>
+        <item name="alertDialogTheme">@style/Theme.Quantum.Dialog.Alert</item>
+        <item name="alertDialogStyle">@style/AlertDialog.Quantum</item>
         <item name="alertDialogCenterButtons">false</item>
-        <item name="alertDialogIcon">@android:drawable/ic_dialog_alert_holo_dark</item>
+        <item name="alertDialogIcon">@drawable/ic_dialog_alert_holo_dark</item>
 
         <!-- Presentation attributes -->
-        <item name="presentationTheme">@android:style/Theme.Quantum.Dialog.Presentation</item>
+        <item name="presentationTheme">@style/Theme.Quantum.Dialog.Presentation</item>
 
         <!-- Toast attributes -->
-        <item name="toastFrameBackground">@android:drawable/toast_frame</item>
+        <item name="toastFrameBackground">@drawable/toast_frame</item>
 
         <!-- Panel attributes -->
-        <item name="panelBackground">@android:drawable/menu_hardkey_panel_holo_dark</item>
-        <item name="panelFullBackground">@android:drawable/menu_background_fill_parent_width</item>
+        <item name="panelBackground">@drawable/menu_hardkey_panel_holo_dark</item>
+        <item name="panelFullBackground">@drawable/menu_background_fill_parent_width</item>
         <!-- These three attributes do not seems to be used by the framework. Declared public though -->
         <item name="panelColorBackground">#000</item>
-        <item name="panelColorForeground">?android:attr/textColorPrimary</item>
-        <item name="panelTextAppearance">?android:attr/textAppearance</item>
+        <item name="panelColorForeground">?attr/textColorPrimary</item>
+        <item name="panelTextAppearance">?attr/textAppearance</item>
 
         <item name="panelMenuIsCompact">true</item>
         <item name="panelMenuListWidth">250dip</item>
-        <item name="panelMenuListTheme">@android:style/Theme.Quantum.CompactMenu</item>
+        <item name="panelMenuListTheme">@style/Theme.Quantum.CompactMenu</item>
 
         <!-- Scrollbar attributes -->
         <item name="scrollbarFadeDuration">250</item>
         <item name="scrollbarDefaultDelayBeforeFade">300</item>
         <item name="scrollbarSize">10dip</item>
-        <item name="scrollbarThumbHorizontal">@android:drawable/scrollbar_handle_holo_dark</item>
-        <item name="scrollbarThumbVertical">@android:drawable/scrollbar_handle_holo_dark</item>
+        <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_holo_dark</item>
+        <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_holo_dark</item>
         <item name="scrollbarTrackHorizontal">@null</item>
         <item name="scrollbarTrackVertical">@null</item>
 
         <!-- Text selection handle attributes -->
-        <item name="textSelectHandleLeft">@android:drawable/text_select_handle_left</item>
-        <item name="textSelectHandleRight">@android:drawable/text_select_handle_right</item>
-        <item name="textSelectHandle">@android:drawable/text_select_handle_middle</item>
-        <item name="textSelectHandleWindowStyle">@android:style/Widget.Quantum.TextSelectHandle</item>
-        <item name="textSuggestionsWindowStyle">@android:style/Widget.Quantum.TextSuggestionsPopupWindow</item>
-        <item name="textCursorDrawable">@android:drawable/text_cursor_holo_dark</item>
+        <item name="textSelectHandleLeft">@drawable/text_select_handle_left</item>
+        <item name="textSelectHandleRight">@drawable/text_select_handle_right</item>
+        <item name="textSelectHandle">@drawable/text_select_handle_middle</item>
+        <item name="textSelectHandleWindowStyle">@style/Widget.Quantum.TextSelectHandle</item>
+        <item name="textSuggestionsWindowStyle">@style/Widget.Quantum.TextSuggestionsPopupWindow</item>
+        <item name="textCursorDrawable">@drawable/text_cursor_holo_dark</item>
 
         <!-- Widget styles -->
-        <item name="absListViewStyle">@android:style/Widget.Quantum.AbsListView</item>
-        <item name="autoCompleteTextViewStyle">@android:style/Widget.Quantum.AutoCompleteTextView</item>
-        <item name="checkboxStyle">@android:style/Widget.Quantum.CompoundButton.CheckBox</item>
-        <item name="checkedTextViewStyle">@android:style/Widget.Quantum.CheckedTextView</item>
-        <item name="dropDownListViewStyle">@android:style/Widget.Quantum.ListView.DropDown</item>
-        <item name="editTextStyle">@android:style/Widget.Quantum.EditText</item>
-        <item name="expandableListViewStyle">@android:style/Widget.Quantum.ExpandableListView</item>
-        <item name="expandableListViewWhiteStyle">@android:style/Widget.Quantum.ExpandableListView.White</item>
-        <item name="fastScrollStyle">@android:style/Widget.Quantum.FastScroll</item>
-        <item name="galleryStyle">@android:style/Widget.Quantum.Gallery</item>
-        <item name="gestureOverlayViewStyle">@android:style/Widget.Quantum.GestureOverlayView</item>
-        <item name="gridViewStyle">@android:style/Widget.Quantum.GridView</item>
-        <item name="imageButtonStyle">@android:style/Widget.Quantum.ImageButton</item>
-        <item name="imageWellStyle">@android:style/Widget.Quantum.ImageWell</item>
-        <item name="listViewStyle">@android:style/Widget.Quantum.ListView</item>
-        <item name="listViewWhiteStyle">@android:style/Widget.Quantum.ListView.White</item>
-        <item name="popupWindowStyle">@android:style/Widget.Quantum.PopupWindow</item>
-        <item name="progressBarStyle">@android:style/Widget.Quantum.ProgressBar</item>
-        <item name="progressBarStyleHorizontal">@android:style/Widget.Quantum.ProgressBar.Horizontal</item>
-        <item name="progressBarStyleSmall">@android:style/Widget.Quantum.ProgressBar.Small</item>
-        <item name="progressBarStyleSmallTitle">@android:style/Widget.Quantum.ProgressBar.Small.Title</item>
-        <item name="progressBarStyleLarge">@android:style/Widget.Quantum.ProgressBar.Large</item>
-        <item name="progressBarStyleInverse">@android:style/Widget.Quantum.ProgressBar.Inverse</item>
-        <item name="progressBarStyleSmallInverse">@android:style/Widget.Quantum.ProgressBar.Small.Inverse</item>
-        <item name="progressBarStyleLargeInverse">@android:style/Widget.Quantum.ProgressBar.Large.Inverse</item>
-        <item name="seekBarStyle">@android:style/Widget.Quantum.SeekBar</item>
-        <item name="ratingBarStyle">@android:style/Widget.Quantum.RatingBar</item>
-        <item name="ratingBarStyleIndicator">@android:style/Widget.Quantum.RatingBar.Indicator</item>
-        <item name="ratingBarStyleSmall">@android:style/Widget.Quantum.RatingBar.Small</item>
-        <item name="radioButtonStyle">@android:style/Widget.Quantum.CompoundButton.RadioButton</item>
-        <item name="scrollViewStyle">@android:style/Widget.Quantum.ScrollView</item>
-        <item name="horizontalScrollViewStyle">@android:style/Widget.Quantum.HorizontalScrollView</item>
-        <item name="spinnerStyle">?android:attr/dropDownSpinnerStyle</item>
-        <item name="dropDownSpinnerStyle">@android:style/Widget.Quantum.Spinner.DropDown</item>
-        <item name="starStyle">@android:style/Widget.Quantum.CompoundButton.Star</item>
-        <item name="tabWidgetStyle">@android:style/Widget.Quantum.TabWidget</item>
-        <item name="textViewStyle">@android:style/Widget.Quantum.TextView</item>
-        <item name="errorMessageBackground">@android:drawable/popup_inline_error_holo_dark</item>
-        <item name="errorMessageAboveBackground">@android:drawable/popup_inline_error_above_holo_dark</item>
-        <item name="webTextViewStyle">@android:style/Widget.Quantum.WebTextView</item>
-        <item name="webViewStyle">@android:style/Widget.Quantum.WebView</item>
-        <item name="dropDownItemStyle">@android:style/Widget.Quantum.DropDownItem</item>
-        <item name="spinnerDropDownItemStyle">@android:style/Widget.Quantum.DropDownItem.Spinner</item>
-        <item name="spinnerItemStyle">@android:style/Widget.Quantum.TextView.SpinnerItem</item>
-        <item name="dropDownHintAppearance">@android:style/TextAppearance.Quantum.Widget.DropDownHint</item>
-        <item name="keyboardViewStyle">@android:style/Widget.Quantum.KeyboardView</item>
-        <item name="quickContactBadgeStyleWindowSmall">@android:style/Widget.Quantum.QuickContactBadge.WindowSmall</item>
-        <item name="quickContactBadgeStyleWindowMedium">@android:style/Widget.Quantum.QuickContactBadge.WindowMedium</item>
-        <item name="quickContactBadgeStyleWindowLarge">@android:style/Widget.Quantum.QuickContactBadge.WindowLarge</item>
-        <item name="quickContactBadgeStyleSmallWindowSmall">@android:style/Widget.Quantum.QuickContactBadgeSmall.WindowSmall</item>
-        <item name="quickContactBadgeStyleSmallWindowMedium">@android:style/Widget.Quantum.QuickContactBadgeSmall.WindowMedium</item>
-        <item name="quickContactBadgeStyleSmallWindowLarge">@android:style/Widget.Quantum.QuickContactBadgeSmall.WindowLarge</item>
-        <item name="listPopupWindowStyle">@android:style/Widget.Quantum.ListPopupWindow</item>
-        <item name="popupMenuStyle">@android:style/Widget.Quantum.PopupMenu</item>
-        <item name="stackViewStyle">@android:style/Widget.Quantum.StackView</item>
-        <item name="activityChooserViewStyle">@android:style/Widget.Quantum.ActivityChooserView</item>
-        <item name="fragmentBreadCrumbsStyle">@android:style/Widget.Quantum.FragmentBreadCrumbs</item>
+        <item name="absListViewStyle">@style/Widget.Quantum.AbsListView</item>
+        <item name="autoCompleteTextViewStyle">@style/Widget.Quantum.AutoCompleteTextView</item>
+        <item name="checkboxStyle">@style/Widget.Quantum.CompoundButton.CheckBox</item>
+        <item name="checkedTextViewStyle">@style/Widget.Quantum.CheckedTextView</item>
+        <item name="dropDownListViewStyle">@style/Widget.Quantum.ListView.DropDown</item>
+        <item name="editTextStyle">@style/Widget.Quantum.EditText</item>
+        <item name="expandableListViewStyle">@style/Widget.Quantum.ExpandableListView</item>
+        <item name="expandableListViewWhiteStyle">@style/Widget.Quantum.ExpandableListView.White</item>
+        <item name="fastScrollStyle">@style/Widget.Quantum.FastScroll</item>
+        <item name="galleryStyle">@style/Widget.Quantum.Gallery</item>
+        <item name="gestureOverlayViewStyle">@style/Widget.Quantum.GestureOverlayView</item>
+        <item name="gridViewStyle">@style/Widget.Quantum.GridView</item>
+        <item name="imageButtonStyle">@style/Widget.Quantum.ImageButton</item>
+        <item name="imageWellStyle">@style/Widget.Quantum.ImageWell</item>
+        <item name="listViewStyle">@style/Widget.Quantum.ListView</item>
+        <item name="listViewWhiteStyle">@style/Widget.Quantum.ListView.White</item>
+        <item name="popupWindowStyle">@style/Widget.Quantum.PopupWindow</item>
+        <item name="progressBarStyle">@style/Widget.Quantum.ProgressBar</item>
+        <item name="progressBarStyleHorizontal">@style/Widget.Quantum.ProgressBar.Horizontal</item>
+        <item name="progressBarStyleSmall">@style/Widget.Quantum.ProgressBar.Small</item>
+        <item name="progressBarStyleSmallTitle">@style/Widget.Quantum.ProgressBar.Small.Title</item>
+        <item name="progressBarStyleLarge">@style/Widget.Quantum.ProgressBar.Large</item>
+        <item name="progressBarStyleInverse">@style/Widget.Quantum.ProgressBar.Inverse</item>
+        <item name="progressBarStyleSmallInverse">@style/Widget.Quantum.ProgressBar.Small.Inverse</item>
+        <item name="progressBarStyleLargeInverse">@style/Widget.Quantum.ProgressBar.Large.Inverse</item>
+        <item name="seekBarStyle">@style/Widget.Quantum.SeekBar</item>
+        <item name="ratingBarStyle">@style/Widget.Quantum.RatingBar</item>
+        <item name="ratingBarStyleIndicator">@style/Widget.Quantum.RatingBar.Indicator</item>
+        <item name="ratingBarStyleSmall">@style/Widget.Quantum.RatingBar.Small</item>
+        <item name="radioButtonStyle">@style/Widget.Quantum.CompoundButton.RadioButton</item>
+        <item name="scrollViewStyle">@style/Widget.Quantum.ScrollView</item>
+        <item name="horizontalScrollViewStyle">@style/Widget.Quantum.HorizontalScrollView</item>
+        <item name="spinnerStyle">?attr/dropDownSpinnerStyle</item>
+        <item name="dropDownSpinnerStyle">@style/Widget.Quantum.Spinner.DropDown</item>
+        <item name="starStyle">@style/Widget.Quantum.CompoundButton.Star</item>
+        <item name="tabWidgetStyle">@style/Widget.Quantum.TabWidget</item>
+        <item name="textViewStyle">@style/Widget.Quantum.TextView</item>
+        <item name="errorMessageBackground">@drawable/popup_inline_error_holo_dark</item>
+        <item name="errorMessageAboveBackground">@drawable/popup_inline_error_above_holo_dark</item>
+        <item name="webTextViewStyle">@style/Widget.Quantum.WebTextView</item>
+        <item name="webViewStyle">@style/Widget.Quantum.WebView</item>
+        <item name="dropDownItemStyle">@style/Widget.Quantum.DropDownItem</item>
+        <item name="spinnerDropDownItemStyle">@style/Widget.Quantum.DropDownItem.Spinner</item>
+        <item name="spinnerItemStyle">@style/Widget.Quantum.TextView.SpinnerItem</item>
+        <item name="dropDownHintAppearance">@style/TextAppearance.Quantum.Widget.DropDownHint</item>
+        <item name="keyboardViewStyle">@style/Widget.Quantum.KeyboardView</item>
+        <item name="quickContactBadgeStyleWindowSmall">@style/Widget.Quantum.QuickContactBadge.WindowSmall</item>
+        <item name="quickContactBadgeStyleWindowMedium">@style/Widget.Quantum.QuickContactBadge.WindowMedium</item>
+        <item name="quickContactBadgeStyleWindowLarge">@style/Widget.Quantum.QuickContactBadge.WindowLarge</item>
+        <item name="quickContactBadgeStyleSmallWindowSmall">@style/Widget.Quantum.QuickContactBadgeSmall.WindowSmall</item>
+        <item name="quickContactBadgeStyleSmallWindowMedium">@style/Widget.Quantum.QuickContactBadgeSmall.WindowMedium</item>
+        <item name="quickContactBadgeStyleSmallWindowLarge">@style/Widget.Quantum.QuickContactBadgeSmall.WindowLarge</item>
+        <item name="listPopupWindowStyle">@style/Widget.Quantum.ListPopupWindow</item>
+        <item name="popupMenuStyle">@style/Widget.Quantum.PopupMenu</item>
+        <item name="stackViewStyle">@style/Widget.Quantum.StackView</item>
+        <item name="activityChooserViewStyle">@style/Widget.Quantum.ActivityChooserView</item>
+        <item name="fragmentBreadCrumbsStyle">@style/Widget.Quantum.FragmentBreadCrumbs</item>
 
         <!-- Preference styles -->
-        <item name="preferenceScreenStyle">@android:style/Preference.Quantum.PreferenceScreen</item>
+        <item name="preferenceScreenStyle">@style/Preference.Quantum.PreferenceScreen</item>
         <item name="preferenceFragmentStyle">@style/PreferenceFragment.Quantum</item>
-        <item name="preferenceCategoryStyle">@android:style/Preference.Quantum.Category</item>
-        <item name="preferenceStyle">@android:style/Preference.Quantum</item>
-        <item name="preferenceInformationStyle">@android:style/Preference.Quantum.Information</item>
-        <item name="checkBoxPreferenceStyle">@android:style/Preference.Quantum.CheckBoxPreference</item>
-        <item name="switchPreferenceStyle">@android:style/Preference.Quantum.SwitchPreference</item>
-        <item name="yesNoPreferenceStyle">@android:style/Preference.Quantum.DialogPreference.YesNoPreference</item>
-        <item name="dialogPreferenceStyle">@android:style/Preference.Quantum.DialogPreference</item>
-        <item name="editTextPreferenceStyle">@android:style/Preference.Quantum.DialogPreference.EditTextPreference</item>
-        <item name="ringtonePreferenceStyle">@android:style/Preference.Quantum.RingtonePreference</item>
-        <item name="preferenceLayoutChild">@android:layout/preference_child_holo</item>
-        <item name="detailsElementBackground">@android:drawable/panel_bg_holo_dark</item>
+        <item name="preferenceCategoryStyle">@style/Preference.Quantum.Category</item>
+        <item name="preferenceStyle">@style/Preference.Quantum</item>
+        <item name="preferenceInformationStyle">@style/Preference.Quantum.Information</item>
+        <item name="checkBoxPreferenceStyle">@style/Preference.Quantum.CheckBoxPreference</item>
+        <item name="switchPreferenceStyle">@style/Preference.Quantum.SwitchPreference</item>
+        <item name="yesNoPreferenceStyle">@style/Preference.Quantum.DialogPreference.YesNoPreference</item>
+        <item name="dialogPreferenceStyle">@style/Preference.Quantum.DialogPreference</item>
+        <item name="editTextPreferenceStyle">@style/Preference.Quantum.DialogPreference.EditTextPreference</item>
+        <item name="ringtonePreferenceStyle">@style/Preference.Quantum.RingtonePreference</item>
+        <item name="preferenceLayoutChild">@layout/preference_child_holo</item>
+        <item name="detailsElementBackground">@drawable/panel_bg_holo_dark</item>
 
         <!-- Search widget styles -->
-        <item name="searchWidgetCorpusItemBackground">@android:color/search_widget_corpus_item_background</item>
+        <item name="searchWidgetCorpusItemBackground">@color/search_widget_corpus_item_background</item>
 
         <!-- Action bar styles -->
-        <item name="actionDropDownStyle">@android:style/Widget.Quantum.Spinner.DropDown.ActionBar</item>
-        <item name="actionButtonStyle">@android:style/Widget.Quantum.ActionButton</item>
-        <item name="actionOverflowButtonStyle">@android:style/Widget.Quantum.ActionButton.Overflow</item>
-        <item name="actionModeBackground">@android:drawable/cab_background_top_holo_dark</item>
-        <item name="actionModeSplitBackground">@android:drawable/cab_background_bottom_holo_dark</item>
-        <item name="actionModeCloseDrawable">@android:drawable/ic_cab_done_holo_dark</item>
+        <item name="actionDropDownStyle">@style/Widget.Quantum.Spinner.DropDown.ActionBar</item>
+        <item name="actionButtonStyle">@style/Widget.Quantum.ActionButton</item>
+        <item name="actionOverflowButtonStyle">@style/Widget.Quantum.ActionButton.Overflow</item>
+        <item name="actionModeBackground">@drawable/cab_background_top_holo_dark</item>
+        <item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_dark</item>
+        <item name="actionModeCloseDrawable">@drawable/ic_cab_done_holo_dark</item>
         <item name="actionBarTabStyle">@style/Widget.Quantum.ActionBar.TabView</item>
         <item name="actionBarTabBarStyle">@style/Widget.Quantum.ActionBar.TabBar</item>
         <item name="actionBarTabTextStyle">@style/Widget.Quantum.ActionBar.TabText</item>
         <item name="actionModeStyle">@style/Widget.Quantum.ActionMode</item>
         <item name="actionModeCloseButtonStyle">@style/Widget.Quantum.ActionButton.CloseMode</item>
-        <item name="actionBarStyle">@android:style/Widget.Quantum.ActionBar</item>
+        <item name="actionBarStyle">@style/Widget.Quantum.ActionBar</item>
         <item name="actionBarSize">@dimen/action_bar_default_height</item>
-        <item name="actionModePopupWindowStyle">@android:style/Widget.Quantum.PopupWindow.ActionMode</item>
+        <item name="actionModePopupWindowStyle">@style/Widget.Quantum.PopupWindow.ActionMode</item>
         <item name="actionBarWidgetTheme">@null</item>
 
-        <item name="actionModeCutDrawable">@android:drawable/ic_menu_cut_holo_dark</item>
-        <item name="actionModeCopyDrawable">@android:drawable/ic_menu_copy_holo_dark</item>
-        <item name="actionModePasteDrawable">@android:drawable/ic_menu_paste_holo_dark</item>
-        <item name="actionModeSelectAllDrawable">@android:drawable/ic_menu_selectall_holo_dark</item>
-        <item name="actionModeShareDrawable">@android:drawable/ic_menu_share_holo_dark</item>
-        <item name="actionModeFindDrawable">@android:drawable/ic_menu_find_holo_dark</item>
-        <item name="actionModeWebSearchDrawable">@android:drawable/ic_menu_search_holo_dark</item>
+        <item name="actionModeCutDrawable">@drawable/ic_menu_cut_holo_dark</item>
+        <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_holo_dark</item>
+        <item name="actionModePasteDrawable">@drawable/ic_menu_paste_holo_dark</item>
+        <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_holo_dark</item>
+        <item name="actionModeShareDrawable">@drawable/ic_menu_share_holo_dark</item>
+        <item name="actionModeFindDrawable">@drawable/ic_menu_find_holo_dark</item>
+        <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_holo_dark</item>
 
-        <item name="dividerVertical">?android:attr/listDivider</item>
-        <item name="dividerHorizontal">?android:attr/listDivider</item>
-        <item name="buttonBarStyle">@android:style/Quantum.ButtonBar</item>
-        <item name="buttonBarButtonStyle">?android:attr/borderlessButtonStyle</item>
-        <item name="segmentedButtonStyle">@android:style/Quantum.SegmentedButton</item>
+        <item name="dividerVertical">?attr/listDivider</item>
+        <item name="dividerHorizontal">?attr/listDivider</item>
+        <item name="buttonBarStyle">@style/Quantum.ButtonBar</item>
+        <item name="buttonBarButtonStyle">?attr/borderlessButtonStyle</item>
+        <item name="segmentedButtonStyle">@style/Quantum.SegmentedButton</item>
 
         <!-- SearchView attributes -->
-        <item name="searchDropdownBackground">@android:drawable/search_dropdown_dark</item>
+        <item name="searchDropdownBackground">@drawable/search_dropdown_dark</item>
 
         <item name="searchDialogTheme">@style/Theme.Quantum.SearchBar</item>
 
         <!-- PreferenceFrameLayout attributes -->
-        <item name="preferenceFrameLayoutStyle">@android:style/Widget.Quantum.PreferenceFrameLayout</item>
+        <item name="preferenceFrameLayoutStyle">@style/Widget.Quantum.PreferenceFrameLayout</item>
 
         <!-- NumberPicker style-->
         <item name="numberPickerStyle">@style/Widget.Quantum.NumberPicker</item>
@@ -344,7 +345,7 @@
         <item name="timePickerStyle">@style/Widget.Quantum.TimePicker</item>
 
         <!-- TimePicker background color -->
-        <item name="timePickerHeaderBackgroundColor">@android:color/timepicker_default_background_holo_dark</item>
+        <item name="timePickerHeaderBackgroundColor">@color/timepicker_default_background_quantum_dark</item>
 
         <!-- TimePicker Header time label text appearance -->
         <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.Quantum.TimePicker.TimeLabel</item>
@@ -353,25 +354,25 @@
         <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.Quantum.TimePicker.AmPmLabel</item>
 
         <!-- TimePicker dialog theme -->
-        <item name="timePickerDialogTheme">@android:style/Theme.Quantum.Dialog.TimePicker</item>
+        <item name="timePickerDialogTheme">@style/Theme.Quantum.Dialog.TimePicker</item>
 
         <!-- DatePicker style -->
         <item name="datePickerStyle">@style/Widget.Quantum.DatePicker</item>
 
-        <item name="fastScrollThumbDrawable">@android:drawable/fastscroll_thumb_holo</item>
-        <item name="fastScrollPreviewBackgroundLeft">@android:drawable/fastscroll_label_left_holo_dark</item>
-        <item name="fastScrollPreviewBackgroundRight">@android:drawable/fastscroll_label_right_holo_dark</item>
-        <item name="fastScrollTrackDrawable">@android:drawable/fastscroll_track_holo_dark</item>
+        <item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_holo</item>
+        <item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_dark</item>
+        <item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_dark</item>
+        <item name="fastScrollTrackDrawable">@drawable/fastscroll_track_holo_dark</item>
         <item name="fastScrollOverlayPosition">atThumb</item>
 
     </style>
 
     <!-- Quantum Paper theme (light version). -->
     <style name="Theme.Quantum.Light" parent="Theme.Light">
-        <item name="colorForeground">@android:color/bright_foreground_holo_light</item>
-        <item name="colorForegroundInverse">@android:color/bright_foreground_inverse_holo_light</item>
-        <item name="colorBackground">@android:color/background_holo_light</item>
-        <item name="colorBackgroundCacheHint">@android:drawable/background_cache_hint_selector_holo_light</item>
+        <item name="colorForeground">@color/bright_foreground_quantum_light</item>
+        <item name="colorForegroundInverse">@color/bright_foreground_quantum_dark</item>
+        <item name="colorBackground">@color/background_quantum_light</item>
+        <item name="colorBackgroundCacheHint">@drawable/background_cache_hint_selector_quantum_light</item>
         <item name="disabledAlpha">0.5</item>
         <item name="backgroundDimAmount">0.6</item>
 
@@ -382,72 +383,72 @@
         <item name="colorActivatedHighlight">@color/holo_blue_dark</item>
 
         <!-- Text styles -->
-        <item name="textAppearance">@android:style/TextAppearance.Quantum.Light</item>
-        <item name="textAppearanceInverse">@android:style/TextAppearance.Quantum.Light.Inverse</item>
+        <item name="textAppearance">@style/TextAppearance.Quantum.Light</item>
+        <item name="textAppearanceInverse">@style/TextAppearance.Quantum.Light.Inverse</item>
 
-        <item name="textColorPrimary">@android:color/primary_text_holo_light</item>
-        <item name="textColorSecondary">@android:color/secondary_text_holo_light</item>
-        <item name="textColorTertiary">@android:color/tertiary_text_holo_light</item>
-        <item name="textColorPrimaryInverse">@android:color/primary_text_holo_dark</item>
-        <item name="textColorSecondaryInverse">@android:color/secondary_text_holo_dark</item>
-        <item name="textColorTertiaryInverse">@android:color/tertiary_text_holo_dark</item>
-        <item name="textColorPrimaryDisableOnly">@android:color/primary_text_disable_only_holo_light</item>
-        <item name="textColorPrimaryInverseDisableOnly">@android:color/primary_text_disable_only_holo_dark</item>
-        <item name="textColorPrimaryNoDisable">@android:color/primary_text_nodisable_holo_light</item>
-        <item name="textColorSecondaryNoDisable">@android:color/secondary_text_nodisable_holo_light</item>
-        <item name="textColorPrimaryInverseNoDisable">@android:color/primary_text_nodisable_holo_dark</item>
-        <item name="textColorSecondaryInverseNoDisable">@android:color/secondary_text_nodisable_holo_dark</item>
-        <item name="textColorHint">@android:color/hint_foreground_holo_light</item>
-        <item name="textColorHintInverse">@android:color/hint_foreground_holo_dark</item>
-        <item name="textColorSearchUrl">@android:color/search_url_text_holo</item>
-        <item name="textColorHighlight">@android:color/highlighted_text_holo_light</item>
-        <item name="textColorHighlightInverse">@android:color/highlighted_text_holo_dark</item>
-        <item name="textColorLink">@android:color/holo_blue_light</item>
-        <item name="textColorLinkInverse">@android:color/holo_blue_light</item>
-        <item name="textColorAlertDialogListItem">@android:color/primary_text_holo_light</item>
+        <item name="textColorPrimary">@color/primary_text_quantum_light</item>
+        <item name="textColorSecondary">@color/secondary_text_quantum_light</item>
+        <item name="textColorTertiary">@color/tertiary_text_quantum_light</item>
+        <item name="textColorPrimaryInverse">@color/primary_text_quantum_dark</item>
+        <item name="textColorSecondaryInverse">@color/secondary_text_quantum_dark</item>
+        <item name="textColorTertiaryInverse">@color/tertiary_text_quantum_dark</item>
+        <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_quantum_light</item>
+        <item name="textColorPrimaryInverseDisableOnly">@color/primary_text_disable_only_quantum_dark</item>
+        <item name="textColorPrimaryNoDisable">@color/primary_text_nodisable_quantum_light</item>
+        <item name="textColorSecondaryNoDisable">@color/secondary_text_nodisable_quantum_light</item>
+        <item name="textColorPrimaryInverseNoDisable">@color/primary_text_nodisable_quantum_dark</item>
+        <item name="textColorSecondaryInverseNoDisable">@color/secondary_text_nodisable_quantum_dark</item>
+        <item name="textColorHint">@color/hint_foreground_quantum_light</item>
+        <item name="textColorHintInverse">@color/hint_foreground_quantum_dark</item>
+        <item name="textColorSearchUrl">@color/search_url_text_quantum_light</item>
+        <item name="textColorHighlight">@color/highlighted_text_quantum_light</item>
+        <item name="textColorHighlightInverse">@color/highlighted_text_quantum_dark</item>
+        <item name="textColorLink">@color/holo_blue_light</item>
+        <item name="textColorLinkInverse">@color/holo_blue_light</item>
+        <item name="textColorAlertDialogListItem">@color/primary_text_quantum_light</item>
 
-        <item name="textAppearanceLarge">@android:style/TextAppearance.Quantum.Light.Large</item>
-        <item name="textAppearanceMedium">@android:style/TextAppearance.Quantum.Light.Medium</item>
-        <item name="textAppearanceSmall">@android:style/TextAppearance.Quantum.Light.Small</item>
-        <item name="textAppearanceLargeInverse">@android:style/TextAppearance.Quantum.Light.Large.Inverse</item>
-        <item name="textAppearanceMediumInverse">@android:style/TextAppearance.Quantum.Light.Medium.Inverse</item>
-        <item name="textAppearanceSmallInverse">@android:style/TextAppearance.Quantum.Light.Small.Inverse</item>
-        <item name="textAppearanceSearchResultTitle">@android:style/TextAppearance.Quantum.Light.SearchResult.Title</item>
-        <item name="textAppearanceSearchResultSubtitle">@android:style/TextAppearance.Quantum.Light.SearchResult.Subtitle</item>
+        <item name="textAppearanceLarge">@style/TextAppearance.Quantum.Light.Large</item>
+        <item name="textAppearanceMedium">@style/TextAppearance.Quantum.Light.Medium</item>
+        <item name="textAppearanceSmall">@style/TextAppearance.Quantum.Light.Small</item>
+        <item name="textAppearanceLargeInverse">@style/TextAppearance.Quantum.Light.Large.Inverse</item>
+        <item name="textAppearanceMediumInverse">@style/TextAppearance.Quantum.Light.Medium.Inverse</item>
+        <item name="textAppearanceSmallInverse">@style/TextAppearance.Quantum.Light.Small.Inverse</item>
+        <item name="textAppearanceSearchResultTitle">@style/TextAppearance.Quantum.Light.SearchResult.Title</item>
+        <item name="textAppearanceSearchResultSubtitle">@style/TextAppearance.Quantum.Light.SearchResult.Subtitle</item>
 
-        <item name="textAppearanceButton">@android:style/TextAppearance.Quantum.Light.Widget.Button</item>
+        <item name="textAppearanceButton">@style/TextAppearance.Quantum.Light.Widget.Button</item>
 
-        <item name="editTextColor">?android:attr/textColorPrimary</item>
-        <item name="editTextBackground">@android:drawable/edit_text_holo_light</item>
+        <item name="editTextColor">?attr/textColorPrimary</item>
+        <item name="editTextBackground">@drawable/edit_text_holo_light</item>
 
-        <item name="candidatesTextStyleSpans">@android:string/candidates_style</item>
+        <item name="candidatesTextStyleSpans">@string/candidates_style</item>
 
-        <item name="textCheckMark">@android:drawable/indicator_check_mark_light</item>
-        <item name="textCheckMarkInverse">@android:drawable/indicator_check_mark_dark</item>
+        <item name="textCheckMark">@drawable/indicator_check_mark_light</item>
+        <item name="textCheckMarkInverse">@drawable/indicator_check_mark_dark</item>
 
-        <item name="textAppearanceLargePopupMenu">@android:style/TextAppearance.Quantum.Light.Widget.PopupMenu.Large</item>
-        <item name="textAppearanceSmallPopupMenu">@android:style/TextAppearance.Quantum.Light.Widget.PopupMenu.Small</item>
+        <item name="textAppearanceLargePopupMenu">@style/TextAppearance.Quantum.Light.Widget.PopupMenu.Large</item>
+        <item name="textAppearanceSmallPopupMenu">@style/TextAppearance.Quantum.Light.Widget.PopupMenu.Small</item>
 
         <!-- Button styles -->
-        <item name="buttonStyle">@android:style/Widget.Quantum.Light.Button</item>
+        <item name="buttonStyle">@style/Widget.Quantum.Light.Button</item>
 
-        <item name="buttonStyleSmall">@android:style/Widget.Quantum.Light.Button.Small</item>
-        <item name="buttonStyleInset">@android:style/Widget.Quantum.Light.Button.Inset</item>
+        <item name="buttonStyleSmall">@style/Widget.Quantum.Light.Button.Small</item>
+        <item name="buttonStyleInset">@style/Widget.Quantum.Light.Button.Inset</item>
 
-        <item name="buttonStyleToggle">@android:style/Widget.Quantum.Light.Button.Toggle</item>
-        <item name="switchStyle">@android:style/Widget.Quantum.Light.CompoundButton.Switch</item>
-        <item name="mediaRouteButtonStyle">@android:style/Widget.Quantum.Light.MediaRouteButton</item>
+        <item name="buttonStyleToggle">@style/Widget.Quantum.Light.Button.Toggle</item>
+        <item name="switchStyle">@style/Widget.Quantum.Light.CompoundButton.Switch</item>
+        <item name="mediaRouteButtonStyle">@style/Widget.Quantum.Light.MediaRouteButton</item>
 
-        <item name="selectableItemBackground">@android:drawable/item_background_holo_light</item>
-        <item name="borderlessButtonStyle">@android:style/Widget.Quantum.Light.Button.Borderless</item>
-        <item name="homeAsUpIndicator">@android:drawable/ic_ab_back_holo_light</item>
+        <item name="selectableItemBackground">@drawable/item_background_quantum_light</item>
+        <item name="borderlessButtonStyle">@style/Widget.Quantum.Light.Button.Borderless</item>
+        <item name="homeAsUpIndicator">@drawable/ic_ab_back_holo_light</item>
 
         <!-- List attributes -->
         <item name="listPreferredItemHeight">64dip</item>
         <item name="listPreferredItemHeightSmall">48dip</item>
         <item name="listPreferredItemHeightLarge">80dip</item>
-        <item name="dropdownListPreferredItemHeight">?android:attr/listPreferredItemHeightSmall</item>
-        <item name="textAppearanceListItemSmall">?android:attr/textAppearanceMedium</item>
+        <item name="dropdownListPreferredItemHeight">?attr/listPreferredItemHeightSmall</item>
+        <item name="textAppearanceListItemSmall">?attr/textAppearanceMedium</item>
         <item name="listPreferredItemPaddingLeft">8dip</item>
         <item name="listPreferredItemPaddingRight">8dip</item>
         <item name="listPreferredItemPaddingStart">8dip</item>
@@ -456,206 +457,207 @@
         <!-- @hide -->
         <item name="searchResultListItemHeight">58dip</item>
         <item name="listDivider">@drawable/list_divider_holo_light</item>
-        <item name="listSeparatorTextViewStyle">@android:style/Widget.Quantum.Light.TextView.ListSeparator</item>
+        <item name="listSeparatorTextViewStyle">@style/Widget.Quantum.Light.TextView.ListSeparator</item>
 
-        <item name="listChoiceIndicatorSingle">@android:drawable/btn_radio_holo_light</item>
-        <item name="listChoiceIndicatorMultiple">@android:drawable/btn_check_holo_light</item>
+        <item name="listChoiceIndicatorSingle">@drawable/btn_radio_holo_light</item>
+        <item name="listChoiceIndicatorMultiple">@drawable/btn_check_holo_light</item>
 
-        <item name="listChoiceBackgroundIndicator">@android:drawable/list_selector_holo_light</item>
+        <item name="listChoiceBackgroundIndicator">@drawable/list_selector_quantum_light</item>
 
-        <item name="activatedBackgroundIndicator">@android:drawable/activated_background_holo_light</item>
+        <item name="activatedBackgroundIndicator">@drawable/activated_background_holo_light</item>
 
         <item name="expandableListPreferredItemPaddingLeft">40dip</item>
-        <item name="expandableListPreferredChildPaddingLeft">?android:attr/expandableListPreferredItemPaddingLeft</item>
+        <item name="expandableListPreferredChildPaddingLeft">?attr/expandableListPreferredItemPaddingLeft</item>
 
         <item name="expandableListPreferredItemIndicatorLeft">3dip</item>
         <item name="expandableListPreferredItemIndicatorRight">0dip</item>
-        <item name="expandableListPreferredChildIndicatorLeft">?android:attr/expandableListPreferredItemIndicatorLeft</item>
-        <item name="expandableListPreferredChildIndicatorRight">?android:attr/expandableListPreferredItemIndicatorRight</item>
+        <item name="expandableListPreferredChildIndicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
+        <item name="expandableListPreferredChildIndicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
 
-        <item name="listDividerAlertDialog">@android:drawable/list_divider_holo_light</item>
-        <item name="findOnPageNextDrawable">@android:drawable/ic_find_next_holo_light</item>
-        <item name="findOnPagePreviousDrawable">@android:drawable/ic_find_previous_holo_light</item>
+        <item name="listDividerAlertDialog">@drawable/list_divider_holo_light</item>
+        <item name="findOnPageNextDrawable">@drawable/ic_find_next_holo_light</item>
+        <item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_holo_light</item>
 
         <!-- Gallery attributes -->
-        <item name="galleryItemBackground">@android:drawable/gallery_item_background</item>
+        <item name="galleryItemBackground">@drawable/gallery_item_background</item>
 
         <!-- Window attributes -->
+        <item name="windowBackground">@color/background_quantum_light</item>
         <item name="windowFrame">@null</item>
         <item name="windowNoTitle">false</item>
         <item name="windowFullscreen">false</item>
         <item name="windowOverscan">false</item>
         <item name="windowIsFloating">false</item>
-        <item name="android:windowContentOverlay">@android:drawable/ab_solid_shadow_holo</item>
+        <item name="windowContentOverlay">@drawable/ab_solid_shadow_holo</item>
         <item name="windowShowWallpaper">false</item>
-        <item name="windowTitleStyle">@android:style/WindowTitle.Quantum</item>
+        <item name="windowTitleStyle">@style/WindowTitle.Quantum</item>
         <item name="windowTitleSize">25dip</item>
-        <item name="windowTitleBackgroundStyle">@android:style/WindowTitleBackground.Quantum</item>
-        <item name="android:windowAnimationStyle">@android:style/Animation.Quantum.Activity</item>
-        <item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
+        <item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Quantum</item>
+        <item name="windowAnimationStyle">@style/Animation.Quantum.Activity</item>
+        <item name="windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
         <item name="windowActionBar">true</item>
         <item name="windowActionModeOverlay">false</item>
 
         <!-- Dialog attributes -->
-        <item name="dialogTheme">@android:style/Theme.Quantum.Light.Dialog</item>
+        <item name="dialogTheme">@style/Theme.Quantum.Light.Dialog</item>
         <item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_holo</item>
         <item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_holo</item>
         <item name="dialogTitleDecorLayout">@layout/dialog_title_holo</item>
 
         <!-- AlertDialog attributes -->
-        <item name="alertDialogTheme">@android:style/Theme.Quantum.Light.Dialog.Alert</item>
-        <item name="alertDialogStyle">@android:style/AlertDialog.Quantum.Light</item>
+        <item name="alertDialogTheme">@style/Theme.Quantum.Light.Dialog.Alert</item>
+        <item name="alertDialogStyle">@style/AlertDialog.Quantum.Light</item>
         <item name="alertDialogCenterButtons">false</item>
-        <item name="alertDialogIcon">@android:drawable/ic_dialog_alert_holo_light</item>
+        <item name="alertDialogIcon">@drawable/ic_dialog_alert_holo_light</item>
 
         <!-- Presentation attributes -->
-        <item name="presentationTheme">@android:style/Theme.Quantum.Light.Dialog.Presentation</item>
+        <item name="presentationTheme">@style/Theme.Quantum.Light.Dialog.Presentation</item>
 
         <!-- Toast attributes -->
-        <item name="toastFrameBackground">@android:drawable/toast_frame</item>
+        <item name="toastFrameBackground">@drawable/toast_frame</item>
 
         <!-- Panel attributes -->
-        <item name="panelBackground">@android:drawable/menu_hardkey_panel_holo_light</item>
-        <item name="panelFullBackground">@android:drawable/menu_background_fill_parent_width</item>
+        <item name="panelBackground">@drawable/menu_hardkey_panel_holo_light</item>
+        <item name="panelFullBackground">@drawable/menu_background_fill_parent_width</item>
         <!-- These three attributes do not seems to be used by the framework. Declared public though -->
         <item name="panelColorBackground">#000</item>
-        <item name="panelColorForeground">?android:attr/textColorPrimary</item>
-        <item name="panelTextAppearance">?android:attr/textAppearance</item>
+        <item name="panelColorForeground">?attr/textColorPrimary</item>
+        <item name="panelTextAppearance">?attr/textAppearance</item>
 
         <item name="panelMenuIsCompact">true</item>
         <item name="panelMenuListWidth">250dip</item>
-        <item name="panelMenuListTheme">@android:style/Theme.Quantum.Light.CompactMenu</item>
+        <item name="panelMenuListTheme">@style/Theme.Quantum.Light.CompactMenu</item>
 
         <!-- Scrollbar attributes -->
         <item name="scrollbarFadeDuration">250</item>
         <item name="scrollbarDefaultDelayBeforeFade">300</item>
         <item name="scrollbarSize">10dip</item>
-        <item name="scrollbarThumbHorizontal">@android:drawable/scrollbar_handle_holo_light</item>
-        <item name="scrollbarThumbVertical">@android:drawable/scrollbar_handle_holo_light</item>
+        <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_holo_light</item>
+        <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_holo_light</item>
         <item name="scrollbarTrackHorizontal">@null</item>
         <item name="scrollbarTrackVertical">@null</item>
 
         <!-- Text selection handle attributes -->
-        <item name="textSelectHandleLeft">@android:drawable/text_select_handle_left</item>
-        <item name="textSelectHandleRight">@android:drawable/text_select_handle_right</item>
-        <item name="textSelectHandle">@android:drawable/text_select_handle_middle</item>
-        <item name="textSelectHandleWindowStyle">@android:style/Widget.Quantum.TextSelectHandle</item>
-        <item name="textSuggestionsWindowStyle">@android:style/Widget.Quantum.Light.TextSuggestionsPopupWindow</item>
-        <item name="textCursorDrawable">@android:drawable/text_cursor_holo_light</item>
+        <item name="textSelectHandleLeft">@drawable/text_select_handle_left</item>
+        <item name="textSelectHandleRight">@drawable/text_select_handle_right</item>
+        <item name="textSelectHandle">@drawable/text_select_handle_middle</item>
+        <item name="textSelectHandleWindowStyle">@style/Widget.Quantum.TextSelectHandle</item>
+        <item name="textSuggestionsWindowStyle">@style/Widget.Quantum.Light.TextSuggestionsPopupWindow</item>
+        <item name="textCursorDrawable">@drawable/text_cursor_holo_light</item>
 
         <!-- Widget styles -->
-        <item name="absListViewStyle">@android:style/Widget.Quantum.Light.AbsListView</item>
-        <item name="autoCompleteTextViewStyle">@android:style/Widget.Quantum.Light.AutoCompleteTextView</item>
-        <item name="checkboxStyle">@android:style/Widget.Quantum.Light.CompoundButton.CheckBox</item>
-        <item name="checkedTextViewStyle">@android:style/Widget.Quantum.Light.CheckedTextView</item>
-        <item name="dropDownListViewStyle">@android:style/Widget.Quantum.ListView.DropDown</item>
-        <item name="editTextStyle">@android:style/Widget.Quantum.Light.EditText</item>
-        <item name="expandableListViewStyle">@android:style/Widget.Quantum.Light.ExpandableListView</item>
-        <item name="expandableListViewWhiteStyle">@android:style/Widget.Quantum.Light.ExpandableListView.White</item>
-        <item name="fastScrollStyle">@android:style/Widget.Quantum.Light.FastScroll</item>
-        <item name="galleryStyle">@android:style/Widget.Quantum.Light.Gallery</item>
-        <item name="gestureOverlayViewStyle">@android:style/Widget.Quantum.Light.GestureOverlayView</item>
-        <item name="gridViewStyle">@android:style/Widget.Quantum.Light.GridView</item>
-        <item name="imageButtonStyle">@android:style/Widget.Quantum.Light.ImageButton</item>
-        <item name="imageWellStyle">@android:style/Widget.Quantum.Light.ImageWell</item>
-        <item name="listViewStyle">@android:style/Widget.Quantum.Light.ListView</item>
-        <item name="listViewWhiteStyle">@android:style/Widget.Quantum.Light.ListView.White</item>
-        <item name="popupWindowStyle">@android:style/Widget.Quantum.Light.PopupWindow</item>
-        <item name="progressBarStyle">@android:style/Widget.Quantum.Light.ProgressBar</item>
-        <item name="progressBarStyleHorizontal">@android:style/Widget.Quantum.Light.ProgressBar.Horizontal</item>
-        <item name="progressBarStyleSmall">@android:style/Widget.Quantum.Light.ProgressBar.Small</item>
-        <item name="progressBarStyleSmallTitle">@android:style/Widget.Quantum.Light.ProgressBar.Small.Title</item>
-        <item name="progressBarStyleLarge">@android:style/Widget.Quantum.Light.ProgressBar.Large</item>
-        <item name="progressBarStyleInverse">@android:style/Widget.Quantum.Light.ProgressBar.Inverse</item>
-        <item name="progressBarStyleSmallInverse">@android:style/Widget.Quantum.Light.ProgressBar.Small.Inverse</item>
-        <item name="progressBarStyleLargeInverse">@android:style/Widget.Quantum.Light.ProgressBar.Large.Inverse</item>
-        <item name="seekBarStyle">@android:style/Widget.Quantum.Light.SeekBar</item>
-        <item name="ratingBarStyle">@android:style/Widget.Quantum.Light.RatingBar</item>
-        <item name="ratingBarStyleIndicator">@android:style/Widget.Quantum.Light.RatingBar.Indicator</item>
-        <item name="ratingBarStyleSmall">@android:style/Widget.Quantum.Light.RatingBar.Small</item>
-        <item name="radioButtonStyle">@android:style/Widget.Quantum.Light.CompoundButton.RadioButton</item>
-        <item name="scrollViewStyle">@android:style/Widget.Quantum.Light.ScrollView</item>
-        <item name="horizontalScrollViewStyle">@android:style/Widget.Quantum.Light.HorizontalScrollView</item>
-        <item name="spinnerStyle">?android:attr/dropDownSpinnerStyle</item>
-        <item name="dropDownSpinnerStyle">@android:style/Widget.Quantum.Light.Spinner.DropDown</item>
-        <item name="starStyle">@android:style/Widget.Quantum.Light.CompoundButton.Star</item>
-        <item name="tabWidgetStyle">@android:style/Widget.Quantum.Light.TabWidget</item>
-        <item name="textViewStyle">@android:style/Widget.Quantum.Light.TextView</item>
-        <item name="errorMessageBackground">@android:drawable/popup_inline_error_holo_light</item>
-        <item name="errorMessageAboveBackground">@android:drawable/popup_inline_error_above_holo_light</item>
-        <item name="webTextViewStyle">@android:style/Widget.Quantum.Light.WebTextView</item>
-        <item name="webViewStyle">@android:style/Widget.Quantum.Light.WebView</item>
-        <item name="dropDownItemStyle">@android:style/Widget.Quantum.Light.DropDownItem</item>
-        <item name="spinnerDropDownItemStyle">@android:style/Widget.Quantum.Light.DropDownItem.Spinner</item>
-        <item name="spinnerItemStyle">@android:style/Widget.Quantum.TextView.SpinnerItem</item>
-        <item name="dropDownHintAppearance">@android:style/TextAppearance.Quantum.Widget.DropDownHint</item>
-        <item name="keyboardViewStyle">@android:style/Widget.Quantum.KeyboardView</item>
-        <item name="quickContactBadgeStyleWindowSmall">@android:style/Widget.Quantum.QuickContactBadge.WindowSmall</item>
-        <item name="quickContactBadgeStyleWindowMedium">@android:style/Widget.Quantum.QuickContactBadge.WindowMedium</item>
-        <item name="quickContactBadgeStyleWindowLarge">@android:style/Widget.Quantum.QuickContactBadge.WindowLarge</item>
-        <item name="quickContactBadgeStyleSmallWindowSmall">@android:style/Widget.Quantum.QuickContactBadgeSmall.WindowSmall</item>
-        <item name="quickContactBadgeStyleSmallWindowMedium">@android:style/Widget.Quantum.QuickContactBadgeSmall.WindowMedium</item>
-        <item name="quickContactBadgeStyleSmallWindowLarge">@android:style/Widget.Quantum.QuickContactBadgeSmall.WindowLarge</item>
-        <item name="listPopupWindowStyle">@android:style/Widget.Quantum.Light.ListPopupWindow</item>
-        <item name="popupMenuStyle">@android:style/Widget.Quantum.Light.PopupMenu</item>
-        <item name="stackViewStyle">@android:style/Widget.Quantum.StackView</item>
-        <item name="activityChooserViewStyle">@android:style/Widget.Quantum.Light.ActivityChooserView</item>
-        <item name="fragmentBreadCrumbsStyle">@android:style/Widget.Quantum.Light.FragmentBreadCrumbs</item>
+        <item name="absListViewStyle">@style/Widget.Quantum.Light.AbsListView</item>
+        <item name="autoCompleteTextViewStyle">@style/Widget.Quantum.Light.AutoCompleteTextView</item>
+        <item name="checkboxStyle">@style/Widget.Quantum.Light.CompoundButton.CheckBox</item>
+        <item name="checkedTextViewStyle">@style/Widget.Quantum.Light.CheckedTextView</item>
+        <item name="dropDownListViewStyle">@style/Widget.Quantum.ListView.DropDown</item>
+        <item name="editTextStyle">@style/Widget.Quantum.Light.EditText</item>
+        <item name="expandableListViewStyle">@style/Widget.Quantum.Light.ExpandableListView</item>
+        <item name="expandableListViewWhiteStyle">@style/Widget.Quantum.Light.ExpandableListView.White</item>
+        <item name="fastScrollStyle">@style/Widget.Quantum.Light.FastScroll</item>
+        <item name="galleryStyle">@style/Widget.Quantum.Light.Gallery</item>
+        <item name="gestureOverlayViewStyle">@style/Widget.Quantum.Light.GestureOverlayView</item>
+        <item name="gridViewStyle">@style/Widget.Quantum.Light.GridView</item>
+        <item name="imageButtonStyle">@style/Widget.Quantum.Light.ImageButton</item>
+        <item name="imageWellStyle">@style/Widget.Quantum.Light.ImageWell</item>
+        <item name="listViewStyle">@style/Widget.Quantum.Light.ListView</item>
+        <item name="listViewWhiteStyle">@style/Widget.Quantum.Light.ListView.White</item>
+        <item name="popupWindowStyle">@style/Widget.Quantum.Light.PopupWindow</item>
+        <item name="progressBarStyle">@style/Widget.Quantum.Light.ProgressBar</item>
+        <item name="progressBarStyleHorizontal">@style/Widget.Quantum.Light.ProgressBar.Horizontal</item>
+        <item name="progressBarStyleSmall">@style/Widget.Quantum.Light.ProgressBar.Small</item>
+        <item name="progressBarStyleSmallTitle">@style/Widget.Quantum.Light.ProgressBar.Small.Title</item>
+        <item name="progressBarStyleLarge">@style/Widget.Quantum.Light.ProgressBar.Large</item>
+        <item name="progressBarStyleInverse">@style/Widget.Quantum.Light.ProgressBar.Inverse</item>
+        <item name="progressBarStyleSmallInverse">@style/Widget.Quantum.Light.ProgressBar.Small.Inverse</item>
+        <item name="progressBarStyleLargeInverse">@style/Widget.Quantum.Light.ProgressBar.Large.Inverse</item>
+        <item name="seekBarStyle">@style/Widget.Quantum.Light.SeekBar</item>
+        <item name="ratingBarStyle">@style/Widget.Quantum.Light.RatingBar</item>
+        <item name="ratingBarStyleIndicator">@style/Widget.Quantum.Light.RatingBar.Indicator</item>
+        <item name="ratingBarStyleSmall">@style/Widget.Quantum.Light.RatingBar.Small</item>
+        <item name="radioButtonStyle">@style/Widget.Quantum.Light.CompoundButton.RadioButton</item>
+        <item name="scrollViewStyle">@style/Widget.Quantum.Light.ScrollView</item>
+        <item name="horizontalScrollViewStyle">@style/Widget.Quantum.Light.HorizontalScrollView</item>
+        <item name="spinnerStyle">?attr/dropDownSpinnerStyle</item>
+        <item name="dropDownSpinnerStyle">@style/Widget.Quantum.Light.Spinner.DropDown</item>
+        <item name="starStyle">@style/Widget.Quantum.Light.CompoundButton.Star</item>
+        <item name="tabWidgetStyle">@style/Widget.Quantum.Light.TabWidget</item>
+        <item name="textViewStyle">@style/Widget.Quantum.Light.TextView</item>
+        <item name="errorMessageBackground">@drawable/popup_inline_error_holo_light</item>
+        <item name="errorMessageAboveBackground">@drawable/popup_inline_error_above_holo_light</item>
+        <item name="webTextViewStyle">@style/Widget.Quantum.Light.WebTextView</item>
+        <item name="webViewStyle">@style/Widget.Quantum.Light.WebView</item>
+        <item name="dropDownItemStyle">@style/Widget.Quantum.Light.DropDownItem</item>
+        <item name="spinnerDropDownItemStyle">@style/Widget.Quantum.Light.DropDownItem.Spinner</item>
+        <item name="spinnerItemStyle">@style/Widget.Quantum.TextView.SpinnerItem</item>
+        <item name="dropDownHintAppearance">@style/TextAppearance.Quantum.Widget.DropDownHint</item>
+        <item name="keyboardViewStyle">@style/Widget.Quantum.KeyboardView</item>
+        <item name="quickContactBadgeStyleWindowSmall">@style/Widget.Quantum.QuickContactBadge.WindowSmall</item>
+        <item name="quickContactBadgeStyleWindowMedium">@style/Widget.Quantum.QuickContactBadge.WindowMedium</item>
+        <item name="quickContactBadgeStyleWindowLarge">@style/Widget.Quantum.QuickContactBadge.WindowLarge</item>
+        <item name="quickContactBadgeStyleSmallWindowSmall">@style/Widget.Quantum.QuickContactBadgeSmall.WindowSmall</item>
+        <item name="quickContactBadgeStyleSmallWindowMedium">@style/Widget.Quantum.QuickContactBadgeSmall.WindowMedium</item>
+        <item name="quickContactBadgeStyleSmallWindowLarge">@style/Widget.Quantum.QuickContactBadgeSmall.WindowLarge</item>
+        <item name="listPopupWindowStyle">@style/Widget.Quantum.Light.ListPopupWindow</item>
+        <item name="popupMenuStyle">@style/Widget.Quantum.Light.PopupMenu</item>
+        <item name="stackViewStyle">@style/Widget.Quantum.StackView</item>
+        <item name="activityChooserViewStyle">@style/Widget.Quantum.Light.ActivityChooserView</item>
+        <item name="fragmentBreadCrumbsStyle">@style/Widget.Quantum.Light.FragmentBreadCrumbs</item>
 
         <!-- Preference styles -->
-        <item name="preferenceScreenStyle">@android:style/Preference.Quantum.PreferenceScreen</item>
+        <item name="preferenceScreenStyle">@style/Preference.Quantum.PreferenceScreen</item>
         <item name="preferenceFragmentStyle">@style/PreferenceFragment.Quantum</item>
-        <item name="preferenceCategoryStyle">@android:style/Preference.Quantum.Category</item>
-        <item name="preferenceStyle">@android:style/Preference.Quantum</item>
-        <item name="preferenceInformationStyle">@android:style/Preference.Quantum.Information</item>
-        <item name="checkBoxPreferenceStyle">@android:style/Preference.Quantum.CheckBoxPreference</item>
-        <item name="switchPreferenceStyle">@android:style/Preference.Quantum.SwitchPreference</item>
-        <item name="yesNoPreferenceStyle">@android:style/Preference.Quantum.DialogPreference.YesNoPreference</item>
-        <item name="dialogPreferenceStyle">@android:style/Preference.Quantum.DialogPreference</item>
-        <item name="editTextPreferenceStyle">@android:style/Preference.Quantum.DialogPreference.EditTextPreference</item>
-        <item name="ringtonePreferenceStyle">@android:style/Preference.Quantum.RingtonePreference</item>
-        <item name="preferenceLayoutChild">@android:layout/preference_child_holo</item>
-        <item name="detailsElementBackground">@android:drawable/panel_bg_holo_light</item>
+        <item name="preferenceCategoryStyle">@style/Preference.Quantum.Category</item>
+        <item name="preferenceStyle">@style/Preference.Quantum</item>
+        <item name="preferenceInformationStyle">@style/Preference.Quantum.Information</item>
+        <item name="checkBoxPreferenceStyle">@style/Preference.Quantum.CheckBoxPreference</item>
+        <item name="switchPreferenceStyle">@style/Preference.Quantum.SwitchPreference</item>
+        <item name="yesNoPreferenceStyle">@style/Preference.Quantum.DialogPreference.YesNoPreference</item>
+        <item name="dialogPreferenceStyle">@style/Preference.Quantum.DialogPreference</item>
+        <item name="editTextPreferenceStyle">@style/Preference.Quantum.DialogPreference.EditTextPreference</item>
+        <item name="ringtonePreferenceStyle">@style/Preference.Quantum.RingtonePreference</item>
+        <item name="preferenceLayoutChild">@layout/preference_child_holo</item>
+        <item name="detailsElementBackground">@drawable/panel_bg_holo_light</item>
 
         <!-- PreferenceFrameLayout attributes -->
-        <item name="preferenceFrameLayoutStyle">@android:style/Widget.Quantum.PreferenceFrameLayout</item>
+        <item name="preferenceFrameLayoutStyle">@style/Widget.Quantum.PreferenceFrameLayout</item>
 
         <!-- Search widget styles -->
-        <item name="searchWidgetCorpusItemBackground">@android:color/search_widget_corpus_item_background</item>
+        <item name="searchWidgetCorpusItemBackground">@color/search_widget_corpus_item_background</item>
 
         <!-- Action bar styles -->
-        <item name="actionDropDownStyle">@android:style/Widget.Quantum.Light.Spinner.DropDown.ActionBar</item>
-        <item name="actionButtonStyle">@android:style/Widget.Quantum.Light.ActionButton</item>
-        <item name="actionOverflowButtonStyle">@android:style/Widget.Quantum.Light.ActionButton.Overflow</item>
-        <item name="actionModeBackground">@android:drawable/cab_background_top_holo_light</item>
-        <item name="actionModeSplitBackground">@android:drawable/cab_background_bottom_holo_light</item>
-        <item name="actionModeCloseDrawable">@android:drawable/ic_cab_done_holo_light</item>
+        <item name="actionDropDownStyle">@style/Widget.Quantum.Light.Spinner.DropDown.ActionBar</item>
+        <item name="actionButtonStyle">@style/Widget.Quantum.Light.ActionButton</item>
+        <item name="actionOverflowButtonStyle">@style/Widget.Quantum.Light.ActionButton.Overflow</item>
+        <item name="actionModeBackground">@drawable/cab_background_top_holo_light</item>
+        <item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_light</item>
+        <item name="actionModeCloseDrawable">@drawable/ic_cab_done_holo_light</item>
         <item name="actionBarTabStyle">@style/Widget.Quantum.Light.ActionBar.TabView</item>
         <item name="actionBarTabBarStyle">@style/Widget.Quantum.Light.ActionBar.TabBar</item>
         <item name="actionBarTabTextStyle">@style/Widget.Quantum.Light.ActionBar.TabText</item>
         <item name="actionModeStyle">@style/Widget.Quantum.Light.ActionMode</item>
         <item name="actionModeCloseButtonStyle">@style/Widget.Quantum.Light.ActionButton.CloseMode</item>
-        <item name="android:actionBarStyle">@android:style/Widget.Quantum.Light.ActionBar.Solid</item>
+        <item name="actionBarStyle">@style/Widget.Quantum.Light.ActionBar.Solid</item>
         <item name="actionBarSize">@dimen/action_bar_default_height</item>
-        <item name="actionModePopupWindowStyle">@android:style/Widget.Quantum.Light.PopupWindow.ActionMode</item>
+        <item name="actionModePopupWindowStyle">@style/Widget.Quantum.Light.PopupWindow.ActionMode</item>
         <item name="actionBarWidgetTheme">@null</item>
 
-        <item name="actionModeCutDrawable">@android:drawable/ic_menu_cut_holo_light</item>
-        <item name="actionModeCopyDrawable">@android:drawable/ic_menu_copy_holo_light</item>
-        <item name="actionModePasteDrawable">@android:drawable/ic_menu_paste_holo_light</item>
-        <item name="actionModeSelectAllDrawable">@android:drawable/ic_menu_selectall_holo_light</item>
-        <item name="actionModeShareDrawable">@android:drawable/ic_menu_share_holo_light</item>
-        <item name="actionModeFindDrawable">@android:drawable/ic_menu_find_holo_light</item>
-        <item name="actionModeWebSearchDrawable">@android:drawable/ic_menu_search_holo_light</item>
+        <item name="actionModeCutDrawable">@drawable/ic_menu_cut_holo_light</item>
+        <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_holo_light</item>
+        <item name="actionModePasteDrawable">@drawable/ic_menu_paste_holo_light</item>
+        <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_holo_light</item>
+        <item name="actionModeShareDrawable">@drawable/ic_menu_share_holo_light</item>
+        <item name="actionModeFindDrawable">@drawable/ic_menu_find_holo_light</item>
+        <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_holo_light</item>
 
-        <item name="dividerVertical">?android:attr/listDivider</item>
-        <item name="dividerHorizontal">?android:attr/listDivider</item>
-        <item name="buttonBarStyle">@android:style/Quantum.Light.ButtonBar</item>
-        <item name="buttonBarButtonStyle">?android:attr/borderlessButtonStyle</item>
-        <item name="segmentedButtonStyle">@android:style/Quantum.Light.SegmentedButton</item>
+        <item name="dividerVertical">?attr/listDivider</item>
+        <item name="dividerHorizontal">?attr/listDivider</item>
+        <item name="buttonBarStyle">@style/Quantum.Light.ButtonBar</item>
+        <item name="buttonBarButtonStyle">?attr/borderlessButtonStyle</item>
+        <item name="segmentedButtonStyle">@style/Quantum.Light.SegmentedButton</item>
 
         <!-- SearchView attributes -->
-        <item name="searchDropdownBackground">@android:drawable/search_dropdown_light</item>
+        <item name="searchDropdownBackground">@drawable/search_dropdown_light</item>
 
         <item name="searchDialogTheme">@style/Theme.Quantum.Light.SearchBar</item>
 
@@ -669,7 +671,7 @@
         <item name="timePickerStyle">@style/Widget.Quantum.Light.TimePicker</item>
 
         <!-- TimePicker Header background color -->
-        <item name="timePickerHeaderBackgroundColor">@android:color/timepicker_default_background_holo_light</item>
+        <item name="timePickerHeaderBackgroundColor">@color/timepicker_default_background_quantum_light</item>
 
         <!-- TimePicker Header time label text appearance -->
         <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.Quantum.Light.TimePicker.TimeLabel</item>
@@ -678,15 +680,15 @@
         <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.Quantum.Light.TimePicker.AmPmLabel</item>
 
         <!-- TimePicker dialog theme -->
-        <item name="timePickerDialogTheme">@android:style/Theme.Quantum.Light.Dialog.TimePicker</item>
+        <item name="timePickerDialogTheme">@style/Theme.Quantum.Light.Dialog.TimePicker</item>
 
         <!-- DatePicker style -->
         <item name="datePickerStyle">@style/Widget.Quantum.Light.DatePicker</item>
 
-        <item name="fastScrollThumbDrawable">@android:drawable/fastscroll_thumb_holo</item>
-        <item name="fastScrollPreviewBackgroundLeft">@android:drawable/fastscroll_label_left_holo_light</item>
-        <item name="fastScrollPreviewBackgroundRight">@android:drawable/fastscroll_label_right_holo_light</item>
-        <item name="fastScrollTrackDrawable">@android:drawable/fastscroll_track_holo_light</item>
+        <item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_holo</item>
+        <item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_light</item>
+        <item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_light</item>
+        <item name="fastScrollTrackDrawable">@drawable/fastscroll_track_holo_light</item>
         <item name="fastScrollOverlayPosition">atThumb</item>
 
     </style>
@@ -695,48 +697,47 @@
          with an inverse color profile. The dark action bar sharply stands out against
          the light content. -->
     <style name="Theme.Quantum.Light.DarkActionBar">
-        <item name="android:windowContentOverlay">@android:drawable/ab_solid_shadow_holo</item>
-        <item name="android:actionBarStyle">@android:style/Widget.Quantum.Light.ActionBar.Solid.Inverse</item>
-        <item name="actionBarWidgetTheme">@android:style/Theme.Quantum</item>
+        <item name="windowContentOverlay">@drawable/ab_solid_shadow_holo</item>
+        <item name="actionBarStyle">@style/Widget.Quantum.Light.ActionBar.Solid.Inverse</item>
+        <item name="actionBarWidgetTheme">@style/Theme.Quantum</item>
 
-        <item name="actionDropDownStyle">@android:style/Widget.Quantum.Spinner.DropDown.ActionBar</item>
-        <item name="actionButtonStyle">@android:style/Widget.Quantum.ActionButton</item>
-        <item name="actionOverflowButtonStyle">@android:style/Widget.Quantum.ActionButton.Overflow</item>
-        <item name="actionModeBackground">@android:drawable/cab_background_top_holo_dark</item>
-        <item name="actionModeSplitBackground">@android:drawable/cab_background_bottom_holo_dark</item>
-        <item name="actionModeCloseDrawable">@android:drawable/ic_cab_done_holo_dark</item>
-        <item name="homeAsUpIndicator">@android:drawable/ic_ab_back_holo_dark</item>
+        <item name="actionDropDownStyle">@style/Widget.Quantum.Spinner.DropDown.ActionBar</item>
+        <item name="actionButtonStyle">@style/Widget.Quantum.ActionButton</item>
+        <item name="actionOverflowButtonStyle">@style/Widget.Quantum.ActionButton.Overflow</item>
+        <item name="actionModeBackground">@drawable/cab_background_top_holo_dark</item>
+        <item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_dark</item>
+        <item name="actionModeCloseDrawable">@drawable/ic_cab_done_holo_dark</item>
+        <item name="homeAsUpIndicator">@drawable/ic_ab_back_holo_dark</item>
         <item name="actionBarTabStyle">@style/Widget.Quantum.Light.ActionBar.TabView.Inverse</item>
         <item name="actionBarTabBarStyle">@style/Widget.Quantum.Light.ActionBar.TabBar.Inverse</item>
         <item name="actionBarTabTextStyle">@style/Widget.Quantum.Light.ActionBar.TabText.Inverse</item>
-        <item name="actionBarDivider">@android:drawable/list_divider_holo_dark</item>
-        <item name="actionBarItemBackground">@android:drawable/item_background_holo_dark</item>
-        <item name="actionMenuTextColor">?android:attr/textColorPrimaryInverse</item>
+        <item name="actionBarDivider">@drawable/list_divider_holo_dark</item>
+        <item name="actionMenuTextColor">?attr/textColorPrimaryInverse</item>
         <item name="actionModeStyle">@style/Widget.Quantum.Light.ActionMode.Inverse</item>
         <item name="actionModeCloseButtonStyle">@style/Widget.Quantum.ActionButton.CloseMode</item>
-        <item name="actionModePopupWindowStyle">@android:style/Widget.Quantum.PopupWindow.ActionMode</item>
+        <item name="actionModePopupWindowStyle">@style/Widget.Quantum.PopupWindow.ActionMode</item>
 
-        <item name="actionModeCutDrawable">@android:drawable/ic_menu_cut_holo_dark</item>
-        <item name="actionModeCopyDrawable">@android:drawable/ic_menu_copy_holo_dark</item>
-        <item name="actionModePasteDrawable">@android:drawable/ic_menu_paste_holo_dark</item>
-        <item name="actionModeSelectAllDrawable">@android:drawable/ic_menu_selectall_holo_dark</item>
-        <item name="actionModeShareDrawable">@android:drawable/ic_menu_share_holo_dark</item>
-        <item name="actionModeFindDrawable">@android:drawable/ic_menu_find_holo_dark</item>
-        <item name="actionModeWebSearchDrawable">@android:drawable/ic_menu_search_holo_dark</item>
+        <item name="actionModeCutDrawable">@drawable/ic_menu_cut_holo_dark</item>
+        <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_holo_dark</item>
+        <item name="actionModePasteDrawable">@drawable/ic_menu_paste_holo_dark</item>
+        <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_holo_dark</item>
+        <item name="actionModeShareDrawable">@drawable/ic_menu_share_holo_dark</item>
+        <item name="actionModeFindDrawable">@drawable/ic_menu_find_holo_dark</item>
+        <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_holo_dark</item>
     </style>
 
     <!-- Variant of the quantum (dark) theme with no action bar. -->
     <style name="Theme.Quantum.NoActionBar">
-        <item name="android:windowActionBar">false</item>
-        <item name="android:windowNoTitle">true</item>
+        <item name="windowActionBar">false</item>
+        <item name="windowNoTitle">true</item>
     </style>
 
     <!-- Variant of the quantum (dark) theme that has no title bar and fills
          the entire screen.  This theme
          sets {@link android.R.attr#windowFullscreen} to true.  -->
     <style name="Theme.Quantum.NoActionBar.Fullscreen">
-        <item name="android:windowFullscreen">true</item>
-        <item name="android:windowContentOverlay">@null</item>
+        <item name="windowFullscreen">true</item>
+        <item name="windowContentOverlay">@null</item>
     </style>
 
     <!-- Variant of the quantum (dark) theme that has no title bar and fills
@@ -744,32 +745,32 @@
          sets {@link android.R.attr#windowFullscreen} and {@link android.R.attr#windowOverscan}
          to true. -->
     <style name="Theme.Quantum.NoActionBar.Overscan">
-        <item name="android:windowFullscreen">true</item>
-        <item name="android:windowOverscan">true</item>
-        <item name="android:windowContentOverlay">@null</item>
+        <item name="windowFullscreen">true</item>
+        <item name="windowOverscan">true</item>
+        <item name="windowContentOverlay">@null</item>
     </style>
 
     <!-- Variant of the quantum (dark) theme that has no title bar and translucent
          system decor.  This theme sets {@link android.R.attr#windowTranslucentStatus} and
          {@link android.R.attr#windowTranslucentNavigation} to true. -->
     <style name="Theme.Quantum.NoActionBar.TranslucentDecor">
-        <item name="android:windowTranslucentStatus">true</item>
-        <item name="android:windowTranslucentNavigation">true</item>
-        <item name="android:windowContentOverlay">@null</item>
+        <item name="windowTranslucentStatus">true</item>
+        <item name="windowTranslucentNavigation">true</item>
+        <item name="windowContentOverlay">@null</item>
     </style>
 
     <!-- Variant of the quantum (light) theme with no action bar. -->
     <style name="Theme.Quantum.Light.NoActionBar">
-        <item name="android:windowActionBar">false</item>
-        <item name="android:windowNoTitle">true</item>
+        <item name="windowActionBar">false</item>
+        <item name="windowNoTitle">true</item>
     </style>
 
     <!-- Variant of the quantum (light) theme that has no title bar and fills
          the entire screen.  This theme
          sets {@link android.R.attr#windowFullscreen} to true.  -->
     <style name="Theme.Quantum.Light.NoActionBar.Fullscreen">
-        <item name="android:windowFullscreen">true</item>
-        <item name="android:windowContentOverlay">@null</item>
+        <item name="windowFullscreen">true</item>
+        <item name="windowContentOverlay">@null</item>
     </style>
 
     <!-- Variant of the quantum (light) theme that has no title bar and fills
@@ -777,18 +778,18 @@
          sets {@link android.R.attr#windowFullscreen} and {@link android.R.attr#windowOverscan}
          to true. -->
     <style name="Theme.Quantum.Light.NoActionBar.Overscan">
-        <item name="android:windowFullscreen">true</item>
-        <item name="android:windowOverscan">true</item>
-        <item name="android:windowContentOverlay">@null</item>
+        <item name="windowFullscreen">true</item>
+        <item name="windowOverscan">true</item>
+        <item name="windowContentOverlay">@null</item>
     </style>
 
     <!-- Variant of the quantum (light) theme that has no title bar and translucent
          system decor.  This theme sets {@link android.R.attr#windowTranslucentStatus} and
          {@link android.R.attr#windowTranslucentNavigation} to true. -->
     <style name="Theme.Quantum.Light.NoActionBar.TranslucentDecor">
-        <item name="android:windowTranslucentStatus">true</item>
-        <item name="android:windowTranslucentNavigation">true</item>
-        <item name="android:windowContentOverlay">@null</item>
+        <item name="windowTranslucentStatus">true</item>
+        <item name="windowTranslucentNavigation">true</item>
+        <item name="windowContentOverlay">@null</item>
     </style>
 
     <!-- Default quantum dark theme for panel windows.  This removes all extraneous
@@ -796,15 +797,15 @@
          to place your content.  It makes the window floating, with a transparent
          background, and turns off dimming behind the window. -->
     <style name="Theme.Quantum.Panel">
-        <item name="android:windowBackground">@android:color/transparent</item>
-        <item name="android:colorBackgroundCacheHint">@null</item>
-        <item name="android:windowFrame">@null</item>
-        <item name="android:windowContentOverlay">@null</item>
-        <item name="android:windowAnimationStyle">@null</item>
-        <item name="android:windowIsFloating">true</item>
-        <item name="android:backgroundDimEnabled">false</item>
-        <item name="android:windowIsTranslucent">true</item>
-        <item name="android:windowNoTitle">true</item>
+        <item name="windowBackground">@color/transparent</item>
+        <item name="colorBackgroundCacheHint">@null</item>
+        <item name="windowFrame">@null</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowAnimationStyle">@null</item>
+        <item name="windowIsFloating">true</item>
+        <item name="backgroundDimEnabled">false</item>
+        <item name="windowIsTranslucent">true</item>
+        <item name="windowNoTitle">true</item>
     </style>
 
     <!-- Default quantum light theme for panel windows.  This removes all extraneous
@@ -812,15 +813,15 @@
          to place your content.  It makes the window floating, with a transparent
          background, and turns off dimming behind the window. -->
     <style name="Theme.Quantum.Light.Panel">
-        <item name="android:windowBackground">@android:color/transparent</item>
-        <item name="android:colorBackgroundCacheHint">@null</item>
-        <item name="android:windowFrame">@null</item>
-        <item name="android:windowContentOverlay">@null</item>
-        <item name="android:windowAnimationStyle">@null</item>
-        <item name="android:windowIsFloating">true</item>
-        <item name="android:backgroundDimEnabled">false</item>
-        <item name="android:windowIsTranslucent">true</item>
-        <item name="android:windowNoTitle">true</item>
+        <item name="windowBackground">@color/transparent</item>
+        <item name="colorBackgroundCacheHint">@null</item>
+        <item name="windowFrame">@null</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowAnimationStyle">@null</item>
+        <item name="windowIsFloating">true</item>
+        <item name="backgroundDimEnabled">false</item>
+        <item name="windowIsTranslucent">true</item>
+        <item name="windowNoTitle">true</item>
     </style>
 
     <!-- Default theme for quantum style input methods, which is used by the
@@ -828,22 +829,22 @@
          this inherits from Theme.Panel, but sets up IME appropriate animations
          and a few custom attributes. -->
     <style name="Theme.Quantum.InputMethod" parent="Theme.Quantum.Light.Panel">
-        <item name="android:windowAnimationStyle">@android:style/Animation.InputMethod</item>
-        <item name="android:imeFullscreenBackground">@android:drawable/screen_background_selector_light</item>
-        <item name="android:imeExtractEnterAnimation">@android:anim/input_method_extract_enter</item>
-        <item name="android:imeExtractExitAnimation">@android:anim/input_method_extract_exit</item>
+        <item name="windowAnimationStyle">@style/Animation.InputMethod</item>
+        <item name="imeFullscreenBackground">@drawable/screen_background_selector_light</item>
+        <item name="imeExtractEnterAnimation">@anim/input_method_extract_enter</item>
+        <item name="imeExtractExitAnimation">@anim/input_method_extract_exit</item>
     </style>
 
     <!-- Theme for the search input bar. -->
 
     <style name="Theme.Quantum.SearchBar" parent="Theme.Quantum.Panel">
-        <item name="actionModeBackground">@android:drawable/cab_background_top_holo_dark</item>
-        <item name="actionModeSplitBackground">@android:drawable/cab_background_bottom_holo_light</item>
+        <item name="actionModeBackground">@drawable/cab_background_top_holo_dark</item>
+        <item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_light</item>
     </style>
 
     <style name="Theme.Quantum.Light.SearchBar" parent="Theme.Quantum.Light.Panel">
-        <item name="actionModeBackground">@android:drawable/cab_background_top_holo_light</item>
-        <item name="actionModeSplitBackground">@android:drawable/cab_background_bottom_holo_light</item>
+        <item name="actionModeBackground">@drawable/cab_background_top_holo_light</item>
+        <item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_light</item>
     </style>
 
     <!-- Menu Themes -->
@@ -851,18 +852,18 @@
 
     <style name="Theme.Quantum.CompactMenu">
         <!-- Menu/item attributes -->
-        <item name="android:itemTextAppearance">?android:attr/textAppearanceMedium</item>
-        <item name="android:listViewStyle">@android:style/Widget.Quantum.ListView</item>
-        <item name="android:windowAnimationStyle">@android:style/Animation.DropDownUp</item>
-        <item name="android:background">@null</item>
+        <item name="itemTextAppearance">?attr/textAppearanceMedium</item>
+        <item name="listViewStyle">@style/Widget.Quantum.ListView</item>
+        <item name="windowAnimationStyle">@style/Animation.DropDownUp</item>
+        <item name="background">@null</item>
     </style>
 
     <style name="Theme.Quantum.Light.CompactMenu">
         <!-- Menu/item attributes -->
-        <item name="android:itemTextAppearance">?android:attr/textAppearanceMedium</item>
-        <item name="android:listViewStyle">@android:style/Widget.Quantum.Light.ListView</item>
-        <item name="android:windowAnimationStyle">@android:style/Animation.DropDownUp</item>
-        <item name="android:background">@null</item>
+        <item name="itemTextAppearance">?attr/textAppearanceMedium</item>
+        <item name="listViewStyle">@style/Widget.Quantum.Light.ListView</item>
+        <item name="windowAnimationStyle">@style/Animation.DropDownUp</item>
+        <item name="background">@null</item>
     </style>
 
     <!-- Dialog themes for Quantum -->
@@ -874,24 +875,24 @@
          contents.  You can set this theme on an activity if you would like to
          make an activity that looks like a Dialog. -->
     <style name="Theme.Quantum.Dialog">
-        <item name="android:windowFrame">@null</item>
-        <item name="android:windowTitleStyle">@android:style/DialogWindowTitle.Quantum</item>
-        <item name="android:windowBackground">@android:drawable/dialog_full_holo_dark</item>
-        <item name="android:windowIsFloating">true</item>
-        <item name="android:windowContentOverlay">@null</item>
-        <item name="android:windowAnimationStyle">@android:style/Animation.Quantum.Dialog</item>
-        <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
-        <item name="android:windowActionBar">false</item>
-        <item name="android:windowActionModeOverlay">true</item>
-        <item name="android:windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
+        <item name="windowFrame">@null</item>
+        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum</item>
+        <item name="windowBackground">@drawable/dialog_full_holo_dark</item>
+        <item name="windowIsFloating">true</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowAnimationStyle">@style/Animation.Quantum.Dialog</item>
+        <item name="windowSoftInputMode">stateUnspecified|adjustPan</item>
+        <item name="windowActionBar">false</item>
+        <item name="windowActionModeOverlay">true</item>
+        <item name="windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
 
-        <item name="android:colorBackgroundCacheHint">@null</item>
+        <item name="colorBackgroundCacheHint">@null</item>
 
-        <item name="android:buttonBarStyle">@android:style/Quantum.ButtonBar.AlertDialog</item>
-        <item name="borderlessButtonStyle">@android:style/Widget.Quantum.Button.Borderless.Small</item>
+        <item name="buttonBarStyle">@style/Quantum.ButtonBar.AlertDialog</item>
+        <item name="borderlessButtonStyle">@style/Widget.Quantum.Button.Borderless.Small</item>
 
-        <item name="textAppearance">@android:style/TextAppearance.Quantum</item>
-        <item name="textAppearanceInverse">@android:style/TextAppearance.Quantum.Inverse</item>
+        <item name="textAppearance">@style/TextAppearance.Quantum</item>
+        <item name="textAppearanceInverse">@style/TextAppearance.Quantum.Inverse</item>
 
         <item name="listPreferredItemPaddingLeft">16dip</item>
         <item name="listPreferredItemPaddingRight">16dip</item>
@@ -904,51 +905,51 @@
     <!-- Variant of Theme.Quantum.Dialog that has a nice minimum width for
          a regular dialog. -->
     <style name="Theme.Quantum.Dialog.MinWidth">
-        <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
-        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
     </style>
 
     <!-- Variant of Theme.Quantum.Dialog that does not include a title bar. -->
     <style name="Theme.Quantum.Dialog.NoActionBar">
-        <item name="android:windowActionBar">false</item>
-        <item name="android:windowNoTitle">true</item>
+        <item name="windowActionBar">false</item>
+        <item name="windowNoTitle">true</item>
     </style>
 
     <!-- Variant of Theme.Quantum.Dialog.NoActionBar that has a nice minimum width for
          a regular dialog. -->
     <style name="Theme.Quantum.Dialog.NoActionBar.MinWidth">
-        <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
-        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
     </style>
 
     <!-- Variant of Theme.Quantum.Dialog that has a fixed size. -->
     <style name="Theme.Quantum.Dialog.FixedSize">
-        <item name="windowFixedWidthMajor">@android:dimen/dialog_fixed_width_major</item>
-        <item name="windowFixedWidthMinor">@android:dimen/dialog_fixed_width_minor</item>
-        <item name="windowFixedHeightMajor">@android:dimen/dialog_fixed_height_major</item>
-        <item name="windowFixedHeightMinor">@android:dimen/dialog_fixed_height_minor</item>
+        <item name="windowFixedWidthMajor">@dimen/dialog_fixed_width_major</item>
+        <item name="windowFixedWidthMinor">@dimen/dialog_fixed_width_minor</item>
+        <item name="windowFixedHeightMajor">@dimen/dialog_fixed_height_major</item>
+        <item name="windowFixedHeightMinor">@dimen/dialog_fixed_height_minor</item>
     </style>
 
     <!-- Variant of Theme.Quantum.Dialog.NoActionBar that has a fixed size. -->
     <style name="Theme.Quantum.Dialog.NoActionBar.FixedSize">
-        <item name="windowFixedWidthMajor">@android:dimen/dialog_fixed_width_major</item>
-        <item name="windowFixedWidthMinor">@android:dimen/dialog_fixed_width_minor</item>
-        <item name="windowFixedHeightMajor">@android:dimen/dialog_fixed_height_major</item>
-        <item name="windowFixedHeightMinor">@android:dimen/dialog_fixed_height_minor</item>
+        <item name="windowFixedWidthMajor">@dimen/dialog_fixed_width_major</item>
+        <item name="windowFixedWidthMinor">@dimen/dialog_fixed_width_minor</item>
+        <item name="windowFixedHeightMajor">@dimen/dialog_fixed_height_major</item>
+        <item name="windowFixedHeightMinor">@dimen/dialog_fixed_height_minor</item>
     </style>
 
     <!-- Variant of Theme.Quantum.Dialog that does not include a frame (or background).
          The view hierarchy of the dialog is responsible for drawing all of
          its pixels. -->
     <style name="Theme.Quantum.Dialog.NoFrame">
-        <item name="windowBackground">@android:color/transparent</item>
-        <item name="android:windowFrame">@null</item>
+        <item name="windowBackground">@color/transparent</item>
+        <item name="windowFrame">@null</item>
         <item name="windowContentOverlay">@null</item>
-        <item name="android:windowAnimationStyle">@null</item>
-        <item name="android:backgroundDimEnabled">false</item>
-        <item name="android:windowIsTranslucent">true</item>
-        <item name="android:windowNoTitle">true</item>
-        <item name="android:windowCloseOnTouchOutside">false</item>
+        <item name="windowAnimationStyle">@null</item>
+        <item name="backgroundDimEnabled">false</item>
+        <item name="windowIsTranslucent">true</item>
+        <item name="windowNoTitle">true</item>
+        <item name="windowCloseOnTouchOutside">false</item>
     </style>
 
     <!-- Quantum theme for alert dialog windows, which is used by the
@@ -957,35 +958,35 @@
          For applications targeting Honeycomb or newer, this is the default
          AlertDialog theme. -->
     <style name="Theme.Quantum.Dialog.Alert">
-        <item name="windowBackground">@android:color/transparent</item>
-        <item name="windowTitleStyle">@android:style/DialogWindowTitle.Quantum</item>
+        <item name="windowBackground">@color/transparent</item>
+        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum</item>
         <item name="windowContentOverlay">@null</item>
-        <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
-        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
     </style>
 
     <!-- Quantum theme for the TimePicker dialog windows, which is used by the
          {@link android.app.TimePickerDialog} class. -->
     <style name="Theme.Quantum.Dialog.TimePicker">
-        <item name="windowBackground">@android:color/transparent</item>
-        <item name="windowTitleStyle">@android:style/DialogWindowTitle.Quantum</item>
+        <item name="windowBackground">@color/transparent</item>
+        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum</item>
         <item name="windowContentOverlay">@null</item>
     </style>
 
     <!-- Theme for a window that will be displayed either full-screen on
          smaller screens (small, normal) or as a dialog on larger screens
          (large, xlarge). -->
-    <style name="Theme.Quantum.DialogWhenLarge" parent="@android:style/Theme.Quantum">
+    <style name="Theme.Quantum.DialogWhenLarge" parent="@style/Theme.Quantum">
     </style>
 
     <!-- Theme for a window without a title bar that will be displayed either
          full-screen on smaller screens (small, normal) or as a dialog on larger screens
          (large, xlarge). -->
-    <style name="Theme.Quantum.DialogWhenLarge.NoActionBar" parent="@android:style/Theme.Quantum.NoActionBar">
+    <style name="Theme.Quantum.DialogWhenLarge.NoActionBar" parent="@style/Theme.Quantum.NoActionBar">
     </style>
 
     <!-- Theme for a presentation window on a secondary display. -->
-    <style name="Theme.Quantum.Dialog.Presentation" parent="@android:style/Theme.Quantum.NoActionBar.Fullscreen">
+    <style name="Theme.Quantum.Dialog.Presentation" parent="@style/Theme.Quantum.NoActionBar.Fullscreen">
     </style>
 
     <!-- Light quantum dialog themes -->
@@ -996,24 +997,24 @@
          contents.  You can set this theme on an activity if you would like to
          make an activity that looks like a Dialog. -->
     <style name="Theme.Quantum.Light.Dialog">
-        <item name="android:windowFrame">@null</item>
-        <item name="android:windowTitleStyle">@android:style/DialogWindowTitle.Quantum.Light</item>
-        <item name="android:windowBackground">@android:drawable/dialog_full_holo_light</item>
-        <item name="android:windowIsFloating">true</item>
-        <item name="android:windowContentOverlay">@null</item>
-        <item name="android:windowAnimationStyle">@android:style/Animation.Quantum.Dialog</item>
-        <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
-        <item name="android:windowActionBar">false</item>
-        <item name="android:windowActionModeOverlay">true</item>
-        <item name="android:windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
+        <item name="windowFrame">@null</item>
+        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum.Light</item>
+        <item name="windowBackground">@drawable/dialog_full_holo_light</item>
+        <item name="windowIsFloating">true</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowAnimationStyle">@style/Animation.Quantum.Dialog</item>
+        <item name="windowSoftInputMode">stateUnspecified|adjustPan</item>
+        <item name="windowActionBar">false</item>
+        <item name="windowActionModeOverlay">true</item>
+        <item name="windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
 
-        <item name="android:colorBackgroundCacheHint">@null</item>
+        <item name="colorBackgroundCacheHint">@null</item>
 
-        <item name="android:buttonBarStyle">@android:style/Quantum.Light.ButtonBar.AlertDialog</item>
-        <item name="borderlessButtonStyle">@android:style/Widget.Quantum.Light.Button.Borderless.Small</item>
+        <item name="buttonBarStyle">@style/Quantum.Light.ButtonBar.AlertDialog</item>
+        <item name="borderlessButtonStyle">@style/Widget.Quantum.Light.Button.Borderless.Small</item>
 
-        <item name="textAppearance">@android:style/TextAppearance.Quantum.Light</item>
-        <item name="textAppearanceInverse">@android:style/TextAppearance.Quantum.Light.Inverse</item>
+        <item name="textAppearance">@style/TextAppearance.Quantum.Light</item>
+        <item name="textAppearanceInverse">@style/TextAppearance.Quantum.Light.Inverse</item>
 
         <item name="listPreferredItemPaddingLeft">16dip</item>
         <item name="listPreferredItemPaddingRight">16dip</item>
@@ -1026,50 +1027,50 @@
     <!-- Variant of Theme.Quantum.Light.Dialog that has a nice minimum width for
          a regular dialog. -->
     <style name="Theme.Quantum.Light.Dialog.MinWidth">
-        <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
-        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
     </style>
 
     <!-- Variant of Theme.Quantum.Light.Dialog that does not include a title bar. -->
     <style name="Theme.Quantum.Light.Dialog.NoActionBar">
-        <item name="android:windowActionBar">false</item>
-        <item name="android:windowNoTitle">true</item>
+        <item name="windowActionBar">false</item>
+        <item name="windowNoTitle">true</item>
     </style>
 
     <!-- Variant of Theme.Quantum.Light.Dialog.NoActionBar that has a nice minimum width for
          a regular dialog. -->
     <style name="Theme.Quantum.Light.Dialog.NoActionBar.MinWidth">
-        <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
-        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
     </style>
 
     <!-- Variant of Theme.Quantum.Light.Dialog that has a fixed size. -->
     <style name="Theme.Quantum.Light.Dialog.FixedSize">
-        <item name="windowFixedWidthMajor">@android:dimen/dialog_fixed_width_major</item>
-        <item name="windowFixedWidthMinor">@android:dimen/dialog_fixed_width_minor</item>
-        <item name="windowFixedHeightMajor">@android:dimen/dialog_fixed_height_major</item>
-        <item name="windowFixedHeightMinor">@android:dimen/dialog_fixed_height_minor</item>
+        <item name="windowFixedWidthMajor">@dimen/dialog_fixed_width_major</item>
+        <item name="windowFixedWidthMinor">@dimen/dialog_fixed_width_minor</item>
+        <item name="windowFixedHeightMajor">@dimen/dialog_fixed_height_major</item>
+        <item name="windowFixedHeightMinor">@dimen/dialog_fixed_height_minor</item>
     </style>
 
     <!-- Variant of Theme.Quantum.Light.Dialog.NoActionBar that has a fixed size. -->
     <style name="Theme.Quantum.Light.Dialog.NoActionBar.FixedSize">
-        <item name="windowFixedWidthMajor">@android:dimen/dialog_fixed_width_major</item>
-        <item name="windowFixedWidthMinor">@android:dimen/dialog_fixed_width_minor</item>
-        <item name="windowFixedHeightMajor">@android:dimen/dialog_fixed_height_major</item>
-        <item name="windowFixedHeightMinor">@android:dimen/dialog_fixed_height_minor</item>
+        <item name="windowFixedWidthMajor">@dimen/dialog_fixed_width_major</item>
+        <item name="windowFixedWidthMinor">@dimen/dialog_fixed_width_minor</item>
+        <item name="windowFixedHeightMajor">@dimen/dialog_fixed_height_major</item>
+        <item name="windowFixedHeightMinor">@dimen/dialog_fixed_height_minor</item>
     </style>
 
     <!-- Theme for a window that will be displayed either full-screen on
          smaller screens (small, normal) or as a dialog on larger screens
          (large, xlarge). -->
-    <style name="Theme.Quantum.Light.DialogWhenLarge" parent="@android:style/Theme.Quantum.Light">
+    <style name="Theme.Quantum.Light.DialogWhenLarge" parent="@style/Theme.Quantum.Light">
     </style>
 
     <!-- Theme for a window without an action bar that will be displayed either full-screen
          on smaller screens (small, normal) or as a dialog on larger screens
          (large, xlarge). -->
     <style name="Theme.Quantum.Light.DialogWhenLarge.NoActionBar"
-            parent="@android:style/Theme.Quantum.Light.NoActionBar">
+            parent="@style/Theme.Quantum.Light.NoActionBar">
     </style>
 
     <!-- Quantum light theme for alert dialog windows, which is used by the
@@ -1078,37 +1079,37 @@
          For applications targeting Honeycomb or newer, this is the default
          AlertDialog theme. -->
     <style name="Theme.Quantum.Light.Dialog.Alert">
-        <item name="windowBackground">@android:color/transparent</item>
-        <item name="windowTitleStyle">@android:style/DialogWindowTitle.Quantum.Light</item>
+        <item name="windowBackground">@color/transparent</item>
+        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum.Light</item>
         <item name="windowContentOverlay">@null</item>
-        <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
-        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
     </style>
 
     <!-- Quantum Light theme for the TimePicker dialog windows, which is used by the
          {@link android.app.TimePickerDialog} class. -->
     <style name="Theme.Quantum.Light.Dialog.TimePicker">
-        <item name="windowBackground">@android:color/transparent</item>
-        <item name="windowTitleStyle">@android:style/DialogWindowTitle.Quantum.Light</item>
+        <item name="windowBackground">@color/transparent</item>
+        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum.Light</item>
         <item name="windowContentOverlay">@null</item>
     </style>
 
     <!-- Theme for a presentation window on a secondary display. -->
-    <style name="Theme.Quantum.Light.Dialog.Presentation" parent="@android:style/Theme.Quantum.Light.NoActionBar.Fullscreen" >
+    <style name="Theme.Quantum.Light.Dialog.Presentation" parent="@style/Theme.Quantum.Light.NoActionBar.Fullscreen" >
     </style>
 
     <!-- Default quantum (dark) for windows that want to have the user's selected
          wallpaper appear behind them.  -->
     <style name="Theme.Quantum.Wallpaper">
-        <item name="android:windowBackground">@android:color/transparent</item>
-        <item name="android:colorBackgroundCacheHint">@null</item>
-        <item name="android:windowShowWallpaper">true</item>
+        <item name="windowBackground">@color/transparent</item>
+        <item name="colorBackgroundCacheHint">@null</item>
+        <item name="windowShowWallpaper">true</item>
     </style>
 
     <!--Default quantum (dark) for windows that want to have the user's selected
          wallpaper appear behind them and without an action bar. -->
     <style name="Theme.Quantum.Wallpaper.NoTitleBar">
-        <item name="android:windowNoTitle">true</item>
+        <item name="windowNoTitle">true</item>
     </style>
 
 </resources>
diff --git a/core/tests/coretests/src/android/util/JsonReaderTest.java b/core/tests/coretests/src/android/util/JsonReaderTest.java
deleted file mode 100644
index 42b7640..0000000
--- a/core/tests/coretests/src/android/util/JsonReaderTest.java
+++ /dev/null
@@ -1,909 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.Arrays;
-import junit.framework.TestCase;
-
-public final class JsonReaderTest extends TestCase {
-
-    private static final int READER_BUFFER_SIZE = 1024;
-
-    public void testReadArray() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("[true, true]"));
-        reader.beginArray();
-        assertEquals(true, reader.nextBoolean());
-        assertEquals(true, reader.nextBoolean());
-        reader.endArray();
-        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
-    }
-
-    public void testReadEmptyArray() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("[]"));
-        reader.beginArray();
-        assertFalse(reader.hasNext());
-        reader.endArray();
-        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
-    }
-
-    public void testReadObject() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader(
-                "{\"a\": \"android\", \"b\": \"banana\"}"));
-        reader.beginObject();
-        assertEquals("a", reader.nextName());
-        assertEquals("android", reader.nextString());
-        assertEquals("b", reader.nextName());
-        assertEquals("banana", reader.nextString());
-        reader.endObject();
-        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
-    }
-
-    public void testReadEmptyObject() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("{}"));
-        reader.beginObject();
-        assertFalse(reader.hasNext());
-        reader.endObject();
-        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
-    }
-
-    public void testSkipObject() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader(
-                "{\"a\": { \"c\": [], \"d\": [true, true, {}] }, \"b\": \"banana\"}"));
-        reader.beginObject();
-        assertEquals("a", reader.nextName());
-        reader.skipValue();
-        assertEquals("b", reader.nextName());
-        reader.skipValue();
-        reader.endObject();
-        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
-    }
-
-    public void testHelloWorld() throws IOException {
-        String json = "{\n" +
-                "   \"hello\": true,\n" +
-                "   \"foo\": [\"world\"]\n" +
-                "}";
-        JsonReader reader = new JsonReader(new StringReader(json));
-        reader.beginObject();
-        assertEquals("hello", reader.nextName());
-        assertEquals(true, reader.nextBoolean());
-        assertEquals("foo", reader.nextName());
-        reader.beginArray();
-        assertEquals("world", reader.nextString());
-        reader.endArray();
-        reader.endObject();
-        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
-    }
-
-    public void testNulls() {
-        try {
-            new JsonReader(null);
-            fail();
-        } catch (NullPointerException expected) {
-        }
-    }
-
-    public void testEmptyString() throws IOException {
-        try {
-            new JsonReader(new StringReader("")).beginArray();
-        } catch (IOException expected) {
-        }
-        try {
-            new JsonReader(new StringReader("")).beginObject();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testNoTopLevelObject() throws IOException {
-        try {
-            new JsonReader(new StringReader("true")).nextBoolean();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testCharacterUnescaping() throws IOException {
-        String json = "[\"a\","
-                + "\"a\\\"\","
-                + "\"\\\"\","
-                + "\":\","
-                + "\",\","
-                + "\"\\b\","
-                + "\"\\f\","
-                + "\"\\n\","
-                + "\"\\r\","
-                + "\"\\t\","
-                + "\" \","
-                + "\"\\\\\","
-                + "\"{\","
-                + "\"}\","
-                + "\"[\","
-                + "\"]\","
-                + "\"\\u0000\","
-                + "\"\\u0019\","
-                + "\"\\u20AC\""
-                + "]";
-        JsonReader reader = new JsonReader(new StringReader(json));
-        reader.beginArray();
-        assertEquals("a", reader.nextString());
-        assertEquals("a\"", reader.nextString());
-        assertEquals("\"", reader.nextString());
-        assertEquals(":", reader.nextString());
-        assertEquals(",", reader.nextString());
-        assertEquals("\b", reader.nextString());
-        assertEquals("\f", reader.nextString());
-        assertEquals("\n", reader.nextString());
-        assertEquals("\r", reader.nextString());
-        assertEquals("\t", reader.nextString());
-        assertEquals(" ", reader.nextString());
-        assertEquals("\\", reader.nextString());
-        assertEquals("{", reader.nextString());
-        assertEquals("}", reader.nextString());
-        assertEquals("[", reader.nextString());
-        assertEquals("]", reader.nextString());
-        assertEquals("\0", reader.nextString());
-        assertEquals("\u0019", reader.nextString());
-        assertEquals("\u20AC", reader.nextString());
-        reader.endArray();
-        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
-    }
-
-    public void testIntegersWithFractionalPartSpecified() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("[1.0,1.0,1.0]"));
-        reader.beginArray();
-        assertEquals(1.0, reader.nextDouble());
-        assertEquals(1, reader.nextInt());
-        assertEquals(1L, reader.nextLong());
-    }
-
-    public void testDoubles() throws IOException {
-        String json = "[-0.0,"
-                + "1.0,"
-                + "1.7976931348623157E308,"
-                + "4.9E-324,"
-                + "0.0,"
-                + "-0.5,"
-                + "2.2250738585072014E-308,"
-                + "3.141592653589793,"
-                + "2.718281828459045,"
-                + "\"1.0\","
-                + "\"011.0\","
-                + "\"NaN\","
-                + "\"Infinity\","
-                + "\"-Infinity\""
-                + "]";
-        JsonReader reader = new JsonReader(new StringReader(json));
-        reader.beginArray();
-        assertEquals(-0.0, reader.nextDouble());
-        assertEquals(1.0, reader.nextDouble());
-        assertEquals(1.7976931348623157E308, reader.nextDouble());
-        assertEquals(4.9E-324, reader.nextDouble());
-        assertEquals(0.0, reader.nextDouble());
-        assertEquals(-0.5, reader.nextDouble());
-        assertEquals(2.2250738585072014E-308, reader.nextDouble());
-        assertEquals(3.141592653589793, reader.nextDouble());
-        assertEquals(2.718281828459045, reader.nextDouble());
-        assertEquals(1,0, reader.nextDouble());
-        assertEquals(11.0, reader.nextDouble());
-        assertTrue(Double.isNaN(reader.nextDouble()));
-        assertEquals(Double.POSITIVE_INFINITY, reader.nextDouble());
-        assertEquals(Double.NEGATIVE_INFINITY, reader.nextDouble());
-        reader.endArray();
-        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
-    }
-
-    public void testLenientDoubles() throws IOException {
-        String json = "["
-                + "011.0,"
-                + "NaN,"
-                + "NAN,"
-                + "Infinity,"
-                + "INFINITY,"
-                + "-Infinity"
-                + "]";
-        JsonReader reader = new JsonReader(new StringReader(json));
-        reader.setLenient(true);
-        reader.beginArray();
-        assertEquals(11.0, reader.nextDouble());
-        assertTrue(Double.isNaN(reader.nextDouble()));
-        try {
-            reader.nextDouble();
-            fail();
-        } catch (NumberFormatException expected) {
-        }
-        assertEquals("NAN", reader.nextString());
-        assertEquals(Double.POSITIVE_INFINITY, reader.nextDouble());
-        try {
-            reader.nextDouble();
-            fail();
-        } catch (NumberFormatException expected) {
-        }
-        assertEquals("INFINITY", reader.nextString());
-        assertEquals(Double.NEGATIVE_INFINITY, reader.nextDouble());
-        reader.endArray();
-        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
-    }
-
-    public void testBufferBoundary() throws IOException {
-        char[] pad = new char[READER_BUFFER_SIZE - 8];
-        Arrays.fill(pad, '5');
-        String json = "[\"" + new String(pad) + "\",33333]";
-        JsonReader reader = new JsonReader(new StringReader(json));
-        reader.beginArray();
-        assertEquals(JsonToken.STRING, reader.peek());
-        assertEquals(new String(pad), reader.nextString());
-        assertEquals(JsonToken.NUMBER, reader.peek());
-        assertEquals(33333, reader.nextInt());
-    }
-
-    public void testTruncatedBufferBoundary() throws IOException {
-        char[] pad = new char[READER_BUFFER_SIZE - 8];
-        Arrays.fill(pad, '5');
-        String json = "[\"" + new String(pad) + "\",33333";
-        JsonReader reader = new JsonReader(new StringReader(json));
-        reader.setLenient(true);
-        reader.beginArray();
-        assertEquals(JsonToken.STRING, reader.peek());
-        assertEquals(new String(pad), reader.nextString());
-        assertEquals(JsonToken.NUMBER, reader.peek());
-        assertEquals(33333, reader.nextInt());
-        try {
-            reader.endArray();
-            fail();
-        } catch (IOException e) {
-        }
-    }
-
-    public void testLongestSupportedNumericLiterals() throws IOException {
-        testLongNumericLiterals(READER_BUFFER_SIZE - 1, JsonToken.NUMBER);
-    }
-
-    public void testLongerNumericLiterals() throws IOException {
-        testLongNumericLiterals(READER_BUFFER_SIZE, JsonToken.STRING);
-    }
-
-    private void testLongNumericLiterals(int length, JsonToken expectedToken) throws IOException {
-        char[] longNumber = new char[length];
-        Arrays.fill(longNumber, '9');
-        longNumber[0] = '1';
-        longNumber[1] = '.';
-
-        String json = "[" + new String(longNumber) + "]";
-        JsonReader reader = new JsonReader(new StringReader(json));
-        reader.setLenient(true);
-        reader.beginArray();
-        assertEquals(expectedToken, reader.peek());
-        assertEquals(2.0d, reader.nextDouble());
-        reader.endArray();
-    }
-
-    public void testLongs() throws IOException {
-        String json = "[0,0,0,"
-                + "1,1,1,"
-                + "-1,-1,-1,"
-                + "-9223372036854775808,"
-                + "9223372036854775807,"
-                + "5.0,"
-                + "1.0e2,"
-                + "\"011\","
-                + "\"5.0\","
-                + "\"1.0e2\""
-                + "]";
-        JsonReader reader = new JsonReader(new StringReader(json));
-        reader.beginArray();
-        assertEquals(0L, reader.nextLong());
-        assertEquals(0, reader.nextInt());
-        assertEquals(0.0, reader.nextDouble());
-        assertEquals(1L, reader.nextLong());
-        assertEquals(1, reader.nextInt());
-        assertEquals(1.0, reader.nextDouble());
-        assertEquals(-1L, reader.nextLong());
-        assertEquals(-1, reader.nextInt());
-        assertEquals(-1.0, reader.nextDouble());
-        try {
-            reader.nextInt();
-            fail();
-        } catch (NumberFormatException expected) {
-        }
-        assertEquals(Long.MIN_VALUE, reader.nextLong());
-        try {
-            reader.nextInt();
-            fail();
-        } catch (NumberFormatException expected) {
-        }
-        assertEquals(Long.MAX_VALUE, reader.nextLong());
-        assertEquals(5, reader.nextLong());
-        assertEquals(100, reader.nextLong());
-        assertEquals(11, reader.nextLong());
-        assertEquals(5, reader.nextLong());
-        assertEquals(100, reader.nextLong());
-        reader.endArray();
-        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
-    }
-
-    /**
-     * This test fails because there's no double for 9223372036854775806, and
-     * our long parsing uses Double.parseDouble() for fractional values.
-     */
-    public void testHighPrecisionLong() throws IOException {
-        String json = "[9223372036854775806.000]";
-        JsonReader reader = new JsonReader(new StringReader(json));
-        reader.beginArray();
-        assertEquals(9223372036854775806L, reader.nextLong());
-        reader.endArray();
-    }
-
-    public void testMatchingValidNumbers() throws IOException {
-        String json = "[-1,99,-0,0,0e1,0e+1,0e-1,0E1,0E+1,0E-1,0.0,1.0,-1.0,1.0e0,1.0e+1,1.0e-1]";
-        JsonReader reader = new JsonReader(new StringReader(json));
-        reader.beginArray();
-        for (int i = 0; i < 16; i++) {
-            assertEquals(JsonToken.NUMBER, reader.peek());
-            reader.nextDouble();
-        }
-        reader.endArray();
-    }
-
-    public void testRecognizingInvalidNumbers() throws IOException {
-        String json = "[-00,00,001,+1,1f,0x,0xf,0x0,0f1,0ee1,1..0,1e0.1,1.-01,1.+1,1.0x,1.0+]";
-        JsonReader reader = new JsonReader(new StringReader(json));
-        reader.setLenient(true);
-        reader.beginArray();
-        for (int i = 0; i < 16; i++) {
-            assertEquals(JsonToken.STRING, reader.peek());
-            reader.nextString();
-        }
-        reader.endArray();
-    }
-
-    public void testNonFiniteDouble() throws IOException {
-        String json = "[NaN]";
-        JsonReader reader = new JsonReader(new StringReader(json));
-        reader.beginArray();
-        try {
-            reader.nextDouble();
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testNumberWithHexPrefix() throws IOException {
-        String json = "[0x11]";
-        JsonReader reader = new JsonReader(new StringReader(json));
-        reader.beginArray();
-        try {
-            reader.nextLong();
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testNumberWithOctalPrefix() throws IOException {
-        String json = "[01]";
-        JsonReader reader = new JsonReader(new StringReader(json));
-        reader.beginArray();
-        try {
-            reader.nextInt();
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testBooleans() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("[true,false]"));
-        reader.beginArray();
-        assertEquals(true, reader.nextBoolean());
-        assertEquals(false, reader.nextBoolean());
-        reader.endArray();
-        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
-    }
-
-    public void testMixedCaseLiterals() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("[True,TruE,False,FALSE,NULL,nulL]"));
-        reader.beginArray();
-        assertEquals(true, reader.nextBoolean());
-        assertEquals(true, reader.nextBoolean());
-        assertEquals(false, reader.nextBoolean());
-        assertEquals(false, reader.nextBoolean());
-        reader.nextNull();
-        reader.nextNull();
-        reader.endArray();
-        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
-    }
-
-    public void testMissingValue() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("{\"a\":}"));
-        reader.beginObject();
-        assertEquals("a", reader.nextName());
-        try {
-            reader.nextString();
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testPrematureEndOfInput() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("{\"a\":true,"));
-        reader.beginObject();
-        assertEquals("a", reader.nextName());
-        assertEquals(true, reader.nextBoolean());
-        try {
-            reader.nextName();
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testPrematurelyClosed() throws IOException {
-        try {
-            JsonReader reader = new JsonReader(new StringReader("{\"a\":[]}"));
-            reader.beginObject();
-            reader.close();
-            reader.nextName();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-
-        try {
-            JsonReader reader = new JsonReader(new StringReader("{\"a\":[]}"));
-            reader.close();
-            reader.beginObject();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-
-        try {
-            JsonReader reader = new JsonReader(new StringReader("{\"a\":true}"));
-            reader.beginObject();
-            reader.nextName();
-            reader.peek();
-            reader.close();
-            reader.nextBoolean();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-    }
-
-    public void testNextFailuresDoNotAdvance() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("{\"a\":true}"));
-        reader.beginObject();
-        try {
-            reader.nextString();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-        assertEquals("a", reader.nextName());
-        try {
-            reader.nextName();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-        try {
-            reader.beginArray();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-        try {
-            reader.endArray();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-        try {
-            reader.beginObject();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-        try {
-            reader.endObject();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-        assertEquals(true, reader.nextBoolean());
-        try {
-            reader.nextString();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-        try {
-            reader.nextName();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-        try {
-            reader.beginArray();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-        try {
-            reader.endArray();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-        reader.endObject();
-        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
-        reader.close();
-    }
-
-    public void testStringNullIsNotNull() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("[\"null\"]"));
-        reader.beginArray();
-        try {
-            reader.nextNull();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-    }
-
-    public void testNullLiteralIsNotAString() throws IOException {
-       JsonReader reader = new JsonReader(new StringReader("[null]"));
-        reader.beginArray();
-        try {
-            reader.nextString();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-    }
-
-    public void testStrictNameValueSeparator() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("{\"a\"=true}"));
-        reader.beginObject();
-        assertEquals("a", reader.nextName());
-        try {
-            reader.nextBoolean();
-            fail();
-        } catch (IOException expected) {
-        }
-
-        reader = new JsonReader(new StringReader("{\"a\"=>true}"));
-        reader.beginObject();
-        assertEquals("a", reader.nextName());
-        try {
-            reader.nextBoolean();
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testLenientNameValueSeparator() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("{\"a\"=true}"));
-        reader.setLenient(true);
-        reader.beginObject();
-        assertEquals("a", reader.nextName());
-        assertEquals(true, reader.nextBoolean());
-
-        reader = new JsonReader(new StringReader("{\"a\"=>true}"));
-        reader.setLenient(true);
-        reader.beginObject();
-        assertEquals("a", reader.nextName());
-        assertEquals(true, reader.nextBoolean());
-    }
-
-    public void testStrictComments() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("[// comment \n true]"));
-        reader.beginArray();
-        try {
-            reader.nextBoolean();
-            fail();
-        } catch (IOException expected) {
-        }
-
-        reader = new JsonReader(new StringReader("[# comment \n true]"));
-        reader.beginArray();
-        try {
-            reader.nextBoolean();
-            fail();
-        } catch (IOException expected) {
-        }
-
-        reader = new JsonReader(new StringReader("[/* comment */ true]"));
-        reader.beginArray();
-        try {
-            reader.nextBoolean();
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testLenientComments() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("[// comment \n true]"));
-        reader.setLenient(true);
-        reader.beginArray();
-        assertEquals(true, reader.nextBoolean());
-
-        reader = new JsonReader(new StringReader("[# comment \n true]"));
-        reader.setLenient(true);
-        reader.beginArray();
-        assertEquals(true, reader.nextBoolean());
-
-        reader = new JsonReader(new StringReader("[/* comment */ true]"));
-        reader.setLenient(true);
-        reader.beginArray();
-        assertEquals(true, reader.nextBoolean());
-    }
-
-    public void testStrictUnquotedNames() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("{a:true}"));
-        reader.beginObject();
-        try {
-            reader.nextName();
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testLenientUnquotedNames() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("{a:true}"));
-        reader.setLenient(true);
-        reader.beginObject();
-        assertEquals("a", reader.nextName());
-    }
-
-    public void testStrictSingleQuotedNames() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("{'a':true}"));
-        reader.beginObject();
-        try {
-            reader.nextName();
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testLenientSingleQuotedNames() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("{'a':true}"));
-        reader.setLenient(true);
-        reader.beginObject();
-        assertEquals("a", reader.nextName());
-    }
-
-    public void testStrictUnquotedStrings() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("[a]"));
-        reader.beginArray();
-        try {
-            reader.nextString();
-            fail();
-        } catch (MalformedJsonException expected) {
-        }
-    }
-
-    public void testLenientUnquotedStrings() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("[a]"));
-        reader.setLenient(true);
-        reader.beginArray();
-        assertEquals("a", reader.nextString());
-    }
-
-    public void testStrictSingleQuotedStrings() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("['a']"));
-        reader.beginArray();
-        try {
-            reader.nextString();
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testLenientSingleQuotedStrings() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("['a']"));
-        reader.setLenient(true);
-        reader.beginArray();
-        assertEquals("a", reader.nextString());
-    }
-
-    public void testStrictSemicolonDelimitedArray() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("[true;true]"));
-        reader.beginArray();
-        try {
-            reader.nextBoolean();
-            reader.nextBoolean();
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testLenientSemicolonDelimitedArray() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("[true;true]"));
-        reader.setLenient(true);
-        reader.beginArray();
-        assertEquals(true, reader.nextBoolean());
-        assertEquals(true, reader.nextBoolean());
-    }
-
-    public void testStrictSemicolonDelimitedNameValuePair() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("{\"a\":true;\"b\":true}"));
-        reader.beginObject();
-        assertEquals("a", reader.nextName());
-        try {
-            reader.nextBoolean();
-            reader.nextName();
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testLenientSemicolonDelimitedNameValuePair() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("{\"a\":true;\"b\":true}"));
-        reader.setLenient(true);
-        reader.beginObject();
-        assertEquals("a", reader.nextName());
-        assertEquals(true, reader.nextBoolean());
-        assertEquals("b", reader.nextName());
-    }
-
-    public void testStrictUnnecessaryArraySeparators() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("[true,,true]"));
-        reader.beginArray();
-        assertEquals(true, reader.nextBoolean());
-        try {
-            reader.nextNull();
-            fail();
-        } catch (IOException expected) {
-        }
-
-        reader = new JsonReader(new StringReader("[,true]"));
-        reader.beginArray();
-        try {
-            reader.nextNull();
-            fail();
-        } catch (IOException expected) {
-        }
-
-        reader = new JsonReader(new StringReader("[true,]"));
-        reader.beginArray();
-        assertEquals(true, reader.nextBoolean());
-        try {
-            reader.nextNull();
-            fail();
-        } catch (IOException expected) {
-        }
-
-        reader = new JsonReader(new StringReader("[,]"));
-        reader.beginArray();
-        try {
-            reader.nextNull();
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testLenientUnnecessaryArraySeparators() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("[true,,true]"));
-        reader.setLenient(true);
-        reader.beginArray();
-        assertEquals(true, reader.nextBoolean());
-        reader.nextNull();
-        assertEquals(true, reader.nextBoolean());
-        reader.endArray();
-
-        reader = new JsonReader(new StringReader("[,true]"));
-        reader.setLenient(true);
-        reader.beginArray();
-        reader.nextNull();
-        assertEquals(true, reader.nextBoolean());
-        reader.endArray();
-
-        reader = new JsonReader(new StringReader("[true,]"));
-        reader.setLenient(true);
-        reader.beginArray();
-        assertEquals(true, reader.nextBoolean());
-        reader.nextNull();
-        reader.endArray();
-
-        reader = new JsonReader(new StringReader("[,]"));
-        reader.setLenient(true);
-        reader.beginArray();
-        reader.nextNull();
-        reader.nextNull();
-        reader.endArray();
-    }
-
-    public void testStrictMultipleTopLevelValues() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("[] []"));
-        reader.beginArray();
-        reader.endArray();
-        try {
-            reader.peek();
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testLenientMultipleTopLevelValues() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("[] true {}"));
-        reader.setLenient(true);
-        reader.beginArray();
-        reader.endArray();
-        assertEquals(true, reader.nextBoolean());
-        reader.beginObject();
-        reader.endObject();
-        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
-    }
-
-    public void testStrictTopLevelValueType() {
-        JsonReader reader = new JsonReader(new StringReader("true"));
-        try {
-            reader.nextBoolean();
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testLenientTopLevelValueType() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("true"));
-        reader.setLenient(true);
-        assertEquals(true, reader.nextBoolean());
-    }
-
-    public void testStrictNonExecutePrefix() {
-        JsonReader reader = new JsonReader(new StringReader(")]}'\n []"));
-        try {
-            reader.beginArray();
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testBomIgnoredAsFirstCharacterOfDocument() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("\ufeff[]"));
-        reader.beginArray();
-        reader.endArray();
-    }
-
-    public void testBomForbiddenAsOtherCharacterInDocument() throws IOException {
-        JsonReader reader = new JsonReader(new StringReader("[\ufeff]"));
-        reader.beginArray();
-        try {
-            reader.endArray();
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    public void testFailWithPosition() throws IOException {
-        testFailWithPosition("Expected literal value at line 6 column 3",
-                "[\n\n\n\n\n0,}]");
-    }
-
-    public void testFailWithPositionIsOffsetByBom() throws IOException {
-        testFailWithPosition("Expected literal value at line 1 column 4",
-                "\ufeff[0,}]");
-    }
-
-    public void testFailWithPositionGreaterThanBufferSize() throws IOException {
-        String spaces = repeat(' ', 8192);
-        testFailWithPosition("Expected literal value at line 6 column 3",
-                "[\n\n" + spaces + "\n\n\n0,}]");
-    }
-
-    private void testFailWithPosition(String message, String json) throws IOException {
-        JsonReader reader = new JsonReader(new StringReader(json));
-        reader.beginArray();
-        reader.nextInt();
-        try {
-            reader.peek();
-            fail();
-        } catch (IOException expected) {
-            assertEquals(message, expected.getMessage());
-        }
-    }
-
-    private String repeat(char c, int count) {
-        char[] array = new char[count];
-        Arrays.fill(array, c);
-        return new String(array);
-    }
-}
diff --git a/core/tests/coretests/src/android/util/JsonWriterTest.java b/core/tests/coretests/src/android/util/JsonWriterTest.java
deleted file mode 100644
index 1239a3c..0000000
--- a/core/tests/coretests/src/android/util/JsonWriterTest.java
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import junit.framework.TestCase;
-
-public final class JsonWriterTest extends TestCase {
-
-    public void testWrongTopLevelType() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        try {
-            jsonWriter.value("a");
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-    }
-
-    public void testTwoNames() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginObject();
-        jsonWriter.name("a");
-        try {
-            jsonWriter.name("a");
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-    }
-
-    public void testNameWithoutValue() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginObject();
-        jsonWriter.name("a");
-        try {
-            jsonWriter.endObject();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-    }
-
-    public void testValueWithoutName() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginObject();
-        try {
-            jsonWriter.value(true);
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-    }
-
-    public void testMultipleTopLevelValues() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginArray().endArray();
-        try {
-            jsonWriter.beginArray();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-    }
-
-    public void testBadNestingObject() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginArray();
-        jsonWriter.beginObject();
-        try {
-            jsonWriter.endArray();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-    }
-
-    public void testBadNestingArray() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginArray();
-        jsonWriter.beginArray();
-        try {
-            jsonWriter.endObject();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-    }
-
-    public void testNullName() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginObject();
-        try {
-            jsonWriter.name(null);
-            fail();
-        } catch (NullPointerException expected) {
-        }
-    }
-
-    public void testNullStringValue() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginObject();
-        jsonWriter.name("a");
-        jsonWriter.value((String) null);
-        jsonWriter.endObject();
-        assertEquals("{\"a\":null}", stringWriter.toString());
-    }
-
-    public void testNonFiniteDoubles() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginArray();
-        try {
-            jsonWriter.value(Double.NaN);
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-        try {
-            jsonWriter.value(Double.NEGATIVE_INFINITY);
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-        try {
-            jsonWriter.value(Double.POSITIVE_INFINITY);
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    public void testNonFiniteBoxedDoubles() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginArray();
-        try {
-            jsonWriter.value(new Double(Double.NaN));
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-        try {
-            jsonWriter.value(new Double(Double.NEGATIVE_INFINITY));
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-        try {
-            jsonWriter.value(new Double(Double.POSITIVE_INFINITY));
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    public void testDoubles() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginArray();
-        jsonWriter.value(-0.0);
-        jsonWriter.value(1.0);
-        jsonWriter.value(Double.MAX_VALUE);
-        jsonWriter.value(Double.MIN_VALUE);
-        jsonWriter.value(0.0);
-        jsonWriter.value(-0.5);
-        jsonWriter.value(Double.MIN_NORMAL);
-        jsonWriter.value(Math.PI);
-        jsonWriter.value(Math.E);
-        jsonWriter.endArray();
-        jsonWriter.close();
-        assertEquals("[-0.0,"
-                + "1.0,"
-                + "1.7976931348623157E308,"
-                + "4.9E-324,"
-                + "0.0,"
-                + "-0.5,"
-                + "2.2250738585072014E-308,"
-                + "3.141592653589793,"
-                + "2.718281828459045]", stringWriter.toString());
-    }
-
-    public void testLongs() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginArray();
-        jsonWriter.value(0);
-        jsonWriter.value(1);
-        jsonWriter.value(-1);
-        jsonWriter.value(Long.MIN_VALUE);
-        jsonWriter.value(Long.MAX_VALUE);
-        jsonWriter.endArray();
-        jsonWriter.close();
-        assertEquals("[0,"
-                + "1,"
-                + "-1,"
-                + "-9223372036854775808,"
-                + "9223372036854775807]", stringWriter.toString());
-    }
-
-    public void testNumbers() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginArray();
-        jsonWriter.value(new BigInteger("0"));
-        jsonWriter.value(new BigInteger("9223372036854775808"));
-        jsonWriter.value(new BigInteger("-9223372036854775809"));
-        jsonWriter.value(new BigDecimal("3.141592653589793238462643383"));
-        jsonWriter.endArray();
-        jsonWriter.close();
-        assertEquals("[0,"
-                + "9223372036854775808,"
-                + "-9223372036854775809,"
-                + "3.141592653589793238462643383]", stringWriter.toString());
-    }
-
-    public void testBooleans() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginArray();
-        jsonWriter.value(true);
-        jsonWriter.value(false);
-        jsonWriter.endArray();
-        assertEquals("[true,false]", stringWriter.toString());
-    }
-
-    public void testNulls() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginArray();
-        jsonWriter.nullValue();
-        jsonWriter.endArray();
-        assertEquals("[null]", stringWriter.toString());
-    }
-
-    public void testStrings() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginArray();
-        jsonWriter.value("a");
-        jsonWriter.value("a\"");
-        jsonWriter.value("\"");
-        jsonWriter.value(":");
-        jsonWriter.value(",");
-        jsonWriter.value("\b");
-        jsonWriter.value("\f");
-        jsonWriter.value("\n");
-        jsonWriter.value("\r");
-        jsonWriter.value("\t");
-        jsonWriter.value(" ");
-        jsonWriter.value("\\");
-        jsonWriter.value("{");
-        jsonWriter.value("}");
-        jsonWriter.value("[");
-        jsonWriter.value("]");
-        jsonWriter.value("\0");
-        jsonWriter.value("\u0019");
-        jsonWriter.endArray();
-        assertEquals("[\"a\","
-                + "\"a\\\"\","
-                + "\"\\\"\","
-                + "\":\","
-                + "\",\","
-                + "\"\\b\","
-                + "\"\\f\","
-                + "\"\\n\","
-                + "\"\\r\","
-                + "\"\\t\","
-                + "\" \","
-                + "\"\\\\\","
-                + "\"{\","
-                + "\"}\","
-                + "\"[\","
-                + "\"]\","
-                + "\"\\u0000\","
-                + "\"\\u0019\"]", stringWriter.toString());
-    }
-
-    public void testUnicodeLineBreaksEscaped() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginArray();
-        jsonWriter.value("\u2028 \u2029");
-        jsonWriter.endArray();
-        assertEquals("[\"\\u2028 \\u2029\"]", stringWriter.toString());
-    }
-
-    public void testEmptyArray() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginArray();
-        jsonWriter.endArray();
-        assertEquals("[]", stringWriter.toString());
-    }
-
-    public void testEmptyObject() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginObject();
-        jsonWriter.endObject();
-        assertEquals("{}", stringWriter.toString());
-    }
-
-    public void testObjectsInArrays() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginArray();
-        jsonWriter.beginObject();
-        jsonWriter.name("a").value(5);
-        jsonWriter.name("b").value(false);
-        jsonWriter.endObject();
-        jsonWriter.beginObject();
-        jsonWriter.name("c").value(6);
-        jsonWriter.name("d").value(true);
-        jsonWriter.endObject();
-        jsonWriter.endArray();
-        assertEquals("[{\"a\":5,\"b\":false},"
-                + "{\"c\":6,\"d\":true}]", stringWriter.toString());
-    }
-
-    public void testArraysInObjects() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginObject();
-        jsonWriter.name("a");
-        jsonWriter.beginArray();
-        jsonWriter.value(5);
-        jsonWriter.value(false);
-        jsonWriter.endArray();
-        jsonWriter.name("b");
-        jsonWriter.beginArray();
-        jsonWriter.value(6);
-        jsonWriter.value(true);
-        jsonWriter.endArray();
-        jsonWriter.endObject();
-        assertEquals("{\"a\":[5,false],"
-                + "\"b\":[6,true]}", stringWriter.toString());
-    }
-
-    public void testDeepNestingArrays() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        for (int i = 0; i < 20; i++) {
-            jsonWriter.beginArray();
-        }
-        for (int i = 0; i < 20; i++) {
-            jsonWriter.endArray();
-        }
-        assertEquals("[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]", stringWriter.toString());
-    }
-
-    public void testDeepNestingObjects() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginObject();
-        for (int i = 0; i < 20; i++) {
-            jsonWriter.name("a");
-            jsonWriter.beginObject();
-        }
-        for (int i = 0; i < 20; i++) {
-            jsonWriter.endObject();
-        }
-        jsonWriter.endObject();
-        assertEquals("{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":"
-                + "{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{"
-                + "}}}}}}}}}}}}}}}}}}}}}", stringWriter.toString());
-    }
-
-    public void testRepeatedName() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.beginObject();
-        jsonWriter.name("a").value(true);
-        jsonWriter.name("a").value(false);
-        jsonWriter.endObject();
-        // JsonWriter doesn't attempt to detect duplicate names
-        assertEquals("{\"a\":true,\"a\":false}", stringWriter.toString());
-    }
-
-    public void testPrettyPrintObject() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.setIndent("   ");
-
-        jsonWriter.beginObject();
-        jsonWriter.name("a").value(true);
-        jsonWriter.name("b").value(false);
-        jsonWriter.name("c").value(5.0);
-        jsonWriter.name("e").nullValue();
-        jsonWriter.name("f").beginArray();
-        jsonWriter.value(6.0);
-        jsonWriter.value(7.0);
-        jsonWriter.endArray();
-        jsonWriter.name("g").beginObject();
-        jsonWriter.name("h").value(8.0);
-        jsonWriter.name("i").value(9.0);
-        jsonWriter.endObject();
-        jsonWriter.endObject();
-
-        String expected = "{\n"
-                + "   \"a\": true,\n"
-                + "   \"b\": false,\n"
-                + "   \"c\": 5.0,\n"
-                + "   \"e\": null,\n"
-                + "   \"f\": [\n"
-                + "      6.0,\n"
-                + "      7.0\n"
-                + "   ],\n"
-                + "   \"g\": {\n"
-                + "      \"h\": 8.0,\n"
-                + "      \"i\": 9.0\n"
-                + "   }\n"
-                + "}";
-        assertEquals(expected, stringWriter.toString());
-    }
-
-    public void testPrettyPrintArray() throws IOException {
-        StringWriter stringWriter = new StringWriter();
-        JsonWriter jsonWriter = new JsonWriter(stringWriter);
-        jsonWriter.setIndent("   ");
-
-        jsonWriter.beginArray();
-        jsonWriter.value(true);
-        jsonWriter.value(false);
-        jsonWriter.value(5.0);
-        jsonWriter.nullValue();
-        jsonWriter.beginObject();
-        jsonWriter.name("a").value(6.0);
-        jsonWriter.name("b").value(7.0);
-        jsonWriter.endObject();
-        jsonWriter.beginArray();
-        jsonWriter.value(8.0);
-        jsonWriter.value(9.0);
-        jsonWriter.endArray();
-        jsonWriter.endArray();
-
-        String expected = "[\n"
-                + "   true,\n"
-                + "   false,\n"
-                + "   5.0,\n"
-                + "   null,\n"
-                + "   {\n"
-                + "      \"a\": 6.0,\n"
-                + "      \"b\": 7.0\n"
-                + "   },\n"
-                + "   [\n"
-                + "      8.0,\n"
-                + "      9.0\n"
-                + "   ]\n"
-                + "]";
-        assertEquals(expected, stringWriter.toString());
-    }
-}
diff --git a/core/tests/overlaytests/OverlayAppFirst/Android.mk b/core/tests/overlaytests/OverlayAppFirst/Android.mk
new file mode 100644
index 0000000..ee991fc
--- /dev/null
+++ b/core/tests/overlaytests/OverlayAppFirst/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_PACKAGE_NAME := com.android.overlaytest.first_app_overlay
+
+include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/OverlayAppFirst/AndroidManifest.xml b/core/tests/overlaytests/OverlayAppFirst/AndroidManifest.xml
new file mode 100644
index 0000000..ec10bbc
--- /dev/null
+++ b/core/tests/overlaytests/OverlayAppFirst/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.overlaytest.first_app_overlay"
+        android:versionCode="1"
+        android:versionName="1.0">
+        <overlay android:targetPackage="com.android.overlaytest" android:priority="1"/>
+</manifest>
diff --git a/core/tests/overlaytests/OverlayTestOverlay/res/drawable-nodpi/default_wallpaper.jpg b/core/tests/overlaytests/OverlayAppFirst/res/drawable-nodpi/drawable.jpg
similarity index 100%
rename from core/tests/overlaytests/OverlayTestOverlay/res/drawable-nodpi/default_wallpaper.jpg
rename to core/tests/overlaytests/OverlayAppFirst/res/drawable-nodpi/drawable.jpg
Binary files differ
diff --git a/core/tests/overlaytests/OverlayAppFirst/res/raw/lorem_ipsum.txt b/core/tests/overlaytests/OverlayAppFirst/res/raw/lorem_ipsum.txt
new file mode 100644
index 0000000..756b0a3
--- /dev/null
+++ b/core/tests/overlaytests/OverlayAppFirst/res/raw/lorem_ipsum.txt
@@ -0,0 +1 @@
+Lorem ipsum: single overlay.
diff --git a/core/tests/overlaytests/OverlayAppFirst/res/values-sv/config.xml b/core/tests/overlaytests/OverlayAppFirst/res/values-sv/config.xml
new file mode 100644
index 0000000..9cdc73e
--- /dev/null
+++ b/core/tests/overlaytests/OverlayAppFirst/res/values-sv/config.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <integer name="matrix_100100">400</integer>
+    <integer name="matrix_100101">400</integer>
+    <integer name="matrix_100110">400</integer>
+    <integer name="matrix_100111">400</integer>
+    <integer name="matrix_101100">400</integer>
+    <integer name="matrix_101101">400</integer>
+    <integer name="matrix_101110">400</integer>
+    <integer name="matrix_101111">400</integer>
+    <integer name="matrix_110100">400</integer>
+    <integer name="matrix_110101">400</integer>
+    <integer name="matrix_110110">400</integer>
+    <integer name="matrix_110111">400</integer>
+    <integer name="matrix_111100">400</integer>
+    <integer name="matrix_111101">400</integer>
+    <integer name="matrix_111110">400</integer>
+    <integer name="matrix_111111">400</integer>
+</resources>
diff --git a/core/tests/overlaytests/OverlayAppFirst/res/values/config.xml b/core/tests/overlaytests/OverlayAppFirst/res/values/config.xml
new file mode 100644
index 0000000..972137a
--- /dev/null
+++ b/core/tests/overlaytests/OverlayAppFirst/res/values/config.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="str">single</string>
+    <string name="str2">single</string>
+    <integer name="matrix_101000">300</integer>
+    <integer name="matrix_101001">300</integer>
+    <integer name="matrix_101010">300</integer>
+    <integer name="matrix_101011">300</integer>
+    <integer name="matrix_101100">300</integer>
+    <integer name="matrix_101101">300</integer>
+    <integer name="matrix_101110">300</integer>
+    <integer name="matrix_101111">300</integer>
+    <integer name="matrix_111000">300</integer>
+    <integer name="matrix_111001">300</integer>
+    <integer name="matrix_111010">300</integer>
+    <integer name="matrix_111011">300</integer>
+    <integer name="matrix_111100">300</integer>
+    <integer name="matrix_111101">300</integer>
+    <integer name="matrix_111110">300</integer>
+    <integer name="matrix_111111">300</integer>
+    <bool name="usually_false">true</bool>
+    <integer-array name="fibonacci">
+        <item>21</item>
+        <item>13</item>
+        <item>8</item>
+        <item>5</item>
+        <item>3</item>
+        <item>2</item>
+        <item>1</item>
+        <item>1</item>
+    </integer-array>
+    <!-- The following integer does not exist in the original package. Idmap
+         generation should therefore ignore it. -->
+    <integer name="integer_not_in_original_package">0</integer>
+</resources>
diff --git a/core/tests/overlaytests/OverlayAppFirst/res/xml/integer.xml b/core/tests/overlaytests/OverlayAppFirst/res/xml/integer.xml
new file mode 100644
index 0000000..7f628d9
--- /dev/null
+++ b/core/tests/overlaytests/OverlayAppFirst/res/xml/integer.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<integer value="1"/>
diff --git a/core/tests/overlaytests/OverlayAppSecond/Android.mk b/core/tests/overlaytests/OverlayAppSecond/Android.mk
new file mode 100644
index 0000000..87402c43
--- /dev/null
+++ b/core/tests/overlaytests/OverlayAppSecond/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_PACKAGE_NAME := com.android.overlaytest.second_app_overlay
+
+include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/OverlayAppSecond/AndroidManifest.xml b/core/tests/overlaytests/OverlayAppSecond/AndroidManifest.xml
new file mode 100644
index 0000000..ed49863
--- /dev/null
+++ b/core/tests/overlaytests/OverlayAppSecond/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.overlaytest.second_app_overlay"
+        android:versionCode="1"
+        android:versionName="1.0">
+        <overlay android:targetPackage="com.android.overlaytest" android:priority="2"/>
+</manifest>
diff --git a/core/tests/overlaytests/OverlayAppSecond/res/raw/lorem_ipsum.txt b/core/tests/overlaytests/OverlayAppSecond/res/raw/lorem_ipsum.txt
new file mode 100644
index 0000000..613f5b6
--- /dev/null
+++ b/core/tests/overlaytests/OverlayAppSecond/res/raw/lorem_ipsum.txt
@@ -0,0 +1 @@
+Lorem ipsum: multiple overlays.
diff --git a/core/tests/overlaytests/OverlayAppSecond/res/values-sv/config.xml b/core/tests/overlaytests/OverlayAppSecond/res/values-sv/config.xml
new file mode 100644
index 0000000..ec4b6c0
--- /dev/null
+++ b/core/tests/overlaytests/OverlayAppSecond/res/values-sv/config.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <integer name="matrix_100001">600</integer>
+    <integer name="matrix_100011">600</integer>
+    <integer name="matrix_100101">600</integer>
+    <integer name="matrix_100111">600</integer>
+    <integer name="matrix_101001">600</integer>
+    <integer name="matrix_101011">600</integer>
+    <integer name="matrix_101101">600</integer>
+    <integer name="matrix_101111">600</integer>
+    <integer name="matrix_110001">600</integer>
+    <integer name="matrix_110011">600</integer>
+    <integer name="matrix_110101">600</integer>
+    <integer name="matrix_110111">600</integer>
+    <integer name="matrix_111001">600</integer>
+    <integer name="matrix_111011">600</integer>
+    <integer name="matrix_111101">600</integer>
+    <integer name="matrix_111111">600</integer>
+</resources>
diff --git a/core/tests/overlaytests/OverlayAppSecond/res/values/config.xml b/core/tests/overlaytests/OverlayAppSecond/res/values/config.xml
new file mode 100644
index 0000000..8b07216
--- /dev/null
+++ b/core/tests/overlaytests/OverlayAppSecond/res/values/config.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="str">multiple</string>
+    <integer name="matrix_100010">500</integer>
+    <integer name="matrix_100011">500</integer>
+    <integer name="matrix_100110">500</integer>
+    <integer name="matrix_100111">500</integer>
+    <integer name="matrix_101010">500</integer>
+    <integer name="matrix_101011">500</integer>
+    <integer name="matrix_101110">500</integer>
+    <integer name="matrix_101111">500</integer>
+    <integer name="matrix_110010">500</integer>
+    <integer name="matrix_110011">500</integer>
+    <integer name="matrix_110110">500</integer>
+    <integer name="matrix_110111">500</integer>
+    <integer name="matrix_111010">500</integer>
+    <integer name="matrix_111011">500</integer>
+    <integer name="matrix_111110">500</integer>
+    <integer name="matrix_111111">500</integer>
+    <bool name="usually_false">false</bool>
+</resources>
diff --git a/core/tests/overlaytests/OverlayAppSecond/res/xml/integer.xml b/core/tests/overlaytests/OverlayAppSecond/res/xml/integer.xml
new file mode 100644
index 0000000..f3370a6
--- /dev/null
+++ b/core/tests/overlaytests/OverlayAppSecond/res/xml/integer.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<integer value="2"/>
diff --git a/core/tests/overlaytests/OverlayTest/Android.mk b/core/tests/overlaytests/OverlayTest/Android.mk
index f7f67f6..4767e52 100644
--- a/core/tests/overlaytests/OverlayTest/Android.mk
+++ b/core/tests/overlaytests/OverlayTest/Android.mk
@@ -5,6 +5,10 @@
 
 LOCAL_PACKAGE_NAME := OverlayTest
 
+LOCAL_DEX_PREOPT := false
+
+LOCAL_MODULE_PATH := $(TARGET_OUT)/app
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/OverlayTest/res/drawable-nodpi/drawable.jpg b/core/tests/overlaytests/OverlayTest/res/drawable-nodpi/drawable.jpg
new file mode 100644
index 0000000..a3f14f3
--- /dev/null
+++ b/core/tests/overlaytests/OverlayTest/res/drawable-nodpi/drawable.jpg
Binary files differ
diff --git a/core/tests/overlaytests/OverlayTest/res/raw/lorem_ipsum.txt b/core/tests/overlaytests/OverlayTest/res/raw/lorem_ipsum.txt
new file mode 100644
index 0000000..cee7a92
--- /dev/null
+++ b/core/tests/overlaytests/OverlayTest/res/raw/lorem_ipsum.txt
@@ -0,0 +1 @@
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
diff --git a/core/tests/overlaytests/OverlayTest/res/values-sv/config.xml b/core/tests/overlaytests/OverlayTest/res/values-sv/config.xml
new file mode 100644
index 0000000..891853e
--- /dev/null
+++ b/core/tests/overlaytests/OverlayTest/res/values-sv/config.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <integer name="matrix_110000">200</integer>
+    <integer name="matrix_110001">200</integer>
+    <integer name="matrix_110010">200</integer>
+    <integer name="matrix_110011">200</integer>
+    <integer name="matrix_110100">200</integer>
+    <integer name="matrix_110101">200</integer>
+    <integer name="matrix_110110">200</integer>
+    <integer name="matrix_110111">200</integer>
+    <integer name="matrix_111000">200</integer>
+    <integer name="matrix_111001">200</integer>
+    <integer name="matrix_111010">200</integer>
+    <integer name="matrix_111011">200</integer>
+    <integer name="matrix_111100">200</integer>
+    <integer name="matrix_111101">200</integer>
+    <integer name="matrix_111110">200</integer>
+    <integer name="matrix_111111">200</integer>
+</resources>
diff --git a/core/tests/overlaytests/OverlayTest/res/values/config.xml b/core/tests/overlaytests/OverlayTest/res/values/config.xml
new file mode 100644
index 0000000..c692a26
--- /dev/null
+++ b/core/tests/overlaytests/OverlayTest/res/values/config.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="str">none</string>
+    <string name="str2">none</string>
+    <integer name="matrix_100000">100</integer>
+    <integer name="matrix_100001">100</integer>
+    <integer name="matrix_100010">100</integer>
+    <integer name="matrix_100011">100</integer>
+    <integer name="matrix_100100">100</integer>
+    <integer name="matrix_100101">100</integer>
+    <integer name="matrix_100110">100</integer>
+    <integer name="matrix_100111">100</integer>
+    <integer name="matrix_101000">100</integer>
+    <integer name="matrix_101001">100</integer>
+    <integer name="matrix_101010">100</integer>
+    <integer name="matrix_101011">100</integer>
+    <integer name="matrix_101100">100</integer>
+    <integer name="matrix_101101">100</integer>
+    <integer name="matrix_101110">100</integer>
+    <integer name="matrix_101111">100</integer>
+    <integer name="matrix_110000">100</integer>
+    <integer name="matrix_110001">100</integer>
+    <integer name="matrix_110010">100</integer>
+    <integer name="matrix_110011">100</integer>
+    <integer name="matrix_110100">100</integer>
+    <integer name="matrix_110101">100</integer>
+    <integer name="matrix_110110">100</integer>
+    <integer name="matrix_110111">100</integer>
+    <integer name="matrix_111000">100</integer>
+    <integer name="matrix_111001">100</integer>
+    <integer name="matrix_111010">100</integer>
+    <integer name="matrix_111011">100</integer>
+    <integer name="matrix_111100">100</integer>
+    <integer name="matrix_111101">100</integer>
+    <integer name="matrix_111110">100</integer>
+    <integer name="matrix_111111">100</integer>
+    <bool name="usually_false">false</bool>
+    <bool name="always_true">true</bool>
+    <integer-array name="fibonacci">
+        <item>1</item>
+        <item>1</item>
+        <item>2</item>
+        <item>3</item>
+        <item>5</item>
+        <item>8</item>
+        <item>13</item>
+        <item>21</item>
+    </integer-array>
+    <integer-array name="prime_numbers">
+        <item>2</item>
+        <item>3</item>
+        <item>5</item>
+        <item>7</item>
+        <item>11</item>
+        <item>13</item>
+        <item>17</item>
+        <item>19</item>
+    </integer-array>
+</resources>
diff --git a/core/tests/overlaytests/OverlayTest/res/xml/integer.xml b/core/tests/overlaytests/OverlayTest/res/xml/integer.xml
new file mode 100644
index 0000000..9383daa
--- /dev/null
+++ b/core/tests/overlaytests/OverlayTest/res/xml/integer.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<integer value="0"/>
diff --git a/core/tests/overlaytests/OverlayTest/src/com/android/overlaytest/OverlayBaseTest.java b/core/tests/overlaytests/OverlayTest/src/com/android/overlaytest/OverlayBaseTest.java
index 6211c1c..58b7db9 100644
--- a/core/tests/overlaytests/OverlayTest/src/com/android/overlaytest/OverlayBaseTest.java
+++ b/core/tests/overlaytests/OverlayTest/src/com/android/overlaytest/OverlayBaseTest.java
@@ -2,13 +2,21 @@
 
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
 import android.test.AndroidTestCase;
+import android.util.AttributeSet;
+import android.util.Xml;
+import java.io.BufferedReader;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.util.Locale;
 
 public abstract class OverlayBaseTest extends AndroidTestCase {
     private Resources mResources;
-    protected boolean mWithOverlay; // will be set by subclasses
+    protected int mMode; // will be set by subclasses
+    static final protected int MODE_NO_OVERLAY = 0;
+    static final protected int MODE_SINGLE_OVERLAY = 1;
+    static final protected int MODE_MULTIPLE_OVERLAYS = 2;
 
     protected void setUp() {
         mResources = getContext().getResources();
@@ -36,20 +44,82 @@
         mResources.updateConfiguration(config, mResources.getDisplayMetrics());
     }
 
-    private void assertResource(int resId, boolean ewo, boolean ew) throws Throwable {
-        boolean expected = mWithOverlay ? ew : ewo;
+    private boolean getExpected(boolean no, boolean so, boolean mo) {
+        switch (mMode) {
+            case MODE_NO_OVERLAY:
+                return no;
+            case MODE_SINGLE_OVERLAY:
+                return so;
+            case MODE_MULTIPLE_OVERLAYS:
+                return mo;
+            default:
+                fail("Unknown mode!");
+                return no;
+        }
+    }
+
+    private String getExpected(String no, String so, String mo) {
+        switch (mMode) {
+            case MODE_NO_OVERLAY:
+                return no;
+            case MODE_SINGLE_OVERLAY:
+                return so;
+            case MODE_MULTIPLE_OVERLAYS:
+                return mo;
+            default:
+                fail("Unknown mode!");
+                return no;
+        }
+    }
+
+    private int getExpected(int no, int so, int mo) {
+        switch (mMode) {
+            case MODE_NO_OVERLAY:
+                return no;
+            case MODE_SINGLE_OVERLAY:
+                return so;
+            case MODE_MULTIPLE_OVERLAYS:
+                return mo;
+            default:
+                fail("Unknown mode!");
+                return no;
+        }
+    }
+
+    private int[] getExpected(int[] no, int[] so, int[] mo) {
+        switch (mMode) {
+            case MODE_NO_OVERLAY:
+                return no;
+            case MODE_SINGLE_OVERLAY:
+                return so;
+            case MODE_MULTIPLE_OVERLAYS:
+                return mo;
+            default:
+                fail("Unknown mode!");
+                return no;
+        }
+    }
+
+    private void assertResource(int resId, boolean no, boolean so, boolean mo) throws Throwable {
+        boolean expected = getExpected(no, so, mo);
         boolean actual = mResources.getBoolean(resId);
         assertEquals(expected, actual);
     }
 
-    private void assertResource(int resId, String ewo, String ew) throws Throwable {
-        String expected = mWithOverlay ? ew : ewo;
+    private void assertResource(int resId, int no, int so, int mo) throws Throwable {
+        int expected = getExpected(no, so, mo);
+        int actual = mResources.getInteger(resId);
+        assertEquals(expected, actual);
+    }
+
+    private void assertResource(int resId, String no, String so, String mo) throws Throwable {
+        String expected = getExpected(no, so, mo);
         String actual = mResources.getString(resId);
         assertEquals(expected, actual);
     }
 
-    private void assertResource(int resId, int[] ewo, int[] ew) throws Throwable {
-        int[] expected = mWithOverlay ? ew : ewo;
+    private void assertResource(int resId, int[] no, int[] so, int[] mo) throws Throwable {
+        int[] expected = getExpected(no, so, mo);
         int[] actual = mResources.getIntArray(resId);
         assertEquals("length:", expected.length, actual.length);
         for (int i = 0; i < actual.length; ++i) {
@@ -57,62 +127,334 @@
         }
     }
 
+    public void testFrameworkBooleanOverlay() throws Throwable {
+        // config_annoy_dianne has the value:
+        // - true when no overlay exists (MODE_NO_OVERLAY)
+        // - false when a single overlay exists (MODE_SINGLE_OVERLAY)
+        // - false when multiple overlays exists (MODE_MULTIPLE_OVERLAYS)
+        final int resId = com.android.internal.R.bool.config_annoy_dianne;
+        assertResource(resId, true, false, false);
+    }
+
     public void testBooleanOverlay() throws Throwable {
-        // config_automatic_brightness_available has overlay (default config)
-        final int resId = com.android.internal.R.bool.config_automatic_brightness_available;
-        assertResource(resId, false, true);
+        // usually_false has the value:
+        // - false when no overlay exists (MODE_NO_OVERLAY)
+        // - true when a single overlay exists (MODE_SINGLE_OVERLAY)
+        // - false when multiple overlays exists (MODE_MULTIPLE_OVERLAYS)
+        final int resId = R.bool.usually_false;
+        assertResource(resId, false, true, false);
     }
 
     public void testBoolean() throws Throwable {
-        // config_annoy_dianne has no overlay
-        final int resId = com.android.internal.R.bool.config_annoy_dianne;
-        assertResource(resId, true, true);
-    }
-
-    public void testStringOverlay() throws Throwable {
-        // phoneTypeCar has an overlay (default config), which shouldn't shadow
-        // the Swedish translation
-        final int resId = com.android.internal.R.string.phoneTypeCar;
-        setLocale("sv_SE");
-        assertResource(resId, "Bil", "Bil");
-    }
-
-    public void testStringSwedishOverlay() throws Throwable {
-        // phoneTypeWork has overlay (no default config, only for lang=sv)
-        final int resId = com.android.internal.R.string.phoneTypeWork;
-        setLocale("en_US");
-        assertResource(resId, "Work", "Work");
-        setLocale("sv_SE");
-        assertResource(resId, "Arbete", "Jobb");
-    }
-
-    public void testString() throws Throwable {
-        // phoneTypeHome has no overlay
-        final int resId = com.android.internal.R.string.phoneTypeHome;
-        setLocale("en_US");
-        assertResource(resId, "Home", "Home");
-        setLocale("sv_SE");
-        assertResource(resId, "Hem", "Hem");
+        // always_true has no overlay
+        final int resId = R.bool.always_true;
+        assertResource(resId, true, true, true);
     }
 
     public void testIntegerArrayOverlay() throws Throwable {
-        // config_scrollBarrierVibePattern has overlay (default config)
-        final int resId = com.android.internal.R.array.config_scrollBarrierVibePattern;
-        assertResource(resId, new int[]{0, 15, 10, 10}, new int[]{100, 200, 300});
+        // fibonacci has values:
+        // - eight first values of Fibonacci sequence, when no overlay exists (MODE_NO_OVERLAY)
+        // - eight first values of Fibonacci sequence (reversed), for single and multiple overlays
+        //   (MODE_SINGLE_OVERLAY, MODE_MULTIPLE_OVERLAYS)
+        final int resId = R.array.fibonacci;
+        assertResource(resId,
+                new int[]{1, 1, 2, 3, 5, 8, 13, 21},
+                new int[]{21, 13, 8, 5, 3, 2, 1, 1},
+                new int[]{21, 13, 8, 5, 3, 2, 1, 1});
     }
 
     public void testIntegerArray() throws Throwable {
-        // config_virtualKeyVibePattern has no overlay
-        final int resId = com.android.internal.R.array.config_virtualKeyVibePattern;
-        final int[] expected = {0, 10, 20, 30};
-        assertResource(resId, expected, expected);
+        // prime_numbers has no overlay
+        final int resId = R.array.prime_numbers;
+        final int[] expected = {2, 3, 5, 7, 11, 13, 17, 19};
+        assertResource(resId, expected, expected, expected);
     }
 
-    public void testAsset() throws Throwable {
-        // drawable/default_background.jpg has overlay (default config)
-        final int resId = com.android.internal.R.drawable.default_wallpaper;
+    public void testDrawable() throws Throwable {
+        // drawable-nodpi/drawable has overlay (default config)
+        final int resId = R.drawable.drawable;
         int actual = calculateRawResourceChecksum(resId);
-        int expected = mWithOverlay ? 0x000051da : 0x0014ebce;
+        int expected = 0;
+        switch (mMode) {
+            case MODE_NO_OVERLAY:
+                expected = 0x00005665;
+                break;
+            case MODE_SINGLE_OVERLAY:
+            case MODE_MULTIPLE_OVERLAYS:
+                expected = 0x000051da;
+                break;
+            default:
+                fail("Unknown mode " + mMode);
+        }
         assertEquals(expected, actual);
     }
+
+    public void testAppString() throws Throwable {
+        final int resId = R.string.str;
+        assertResource(resId, "none", "single", "multiple");
+    }
+
+    public void testApp2() throws Throwable {
+        final int resId = R.string.str2; // only in base package and first app overlay
+        assertResource(resId, "none", "single", "single");
+    }
+
+    public void testAppXml() throws Throwable {
+        int expected = getExpected(0, 1, 2);
+        int actual = -1;
+        XmlResourceParser parser = mResources.getXml(R.xml.integer);
+        int type = parser.getEventType();
+        while (type != XmlResourceParser.END_DOCUMENT && actual == -1) {
+            if (type == XmlResourceParser.START_TAG && "integer".equals(parser.getName())) {
+                AttributeSet as = Xml.asAttributeSet(parser);
+                actual = as.getAttributeIntValue(null, "value", -1);
+            }
+            type = parser.next();
+        }
+        parser.close();
+        assertEquals(expected, actual);
+    }
+
+    public void testAppRaw() throws Throwable {
+        final int resId = R.raw.lorem_ipsum;
+
+        InputStream input = null;
+        BufferedReader reader = null;
+        String actual = "";
+        try {
+            input = mResources.openRawResource(resId);
+            reader = new BufferedReader(new InputStreamReader(input));
+            actual = reader.readLine();
+        } finally {
+            reader.close();
+            input.close();
+        }
+
+        final String no = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, " +
+            "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
+            "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip " +
+            "ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit " +
+            "esse cillum dolore eu fugiat nulla pariatur. " +
+            "Excepteur sint occaecat cupidatat non proident, " +
+            "sunt in culpa qui officia deserunt mollit anim id est laborum.";
+        final String so = "Lorem ipsum: single overlay.";
+        final String mo = "Lorem ipsum: multiple overlays.";
+
+        assertEquals(getExpected(no, so, mo), actual);
+    }
+
+    /*
+     * testMatrix* tests
+     *
+     * The naming convention textMatrixABCDEF refers to in which packages and
+     * which configurations a resource is defined (1 if the resource is
+     * defined). If defined, a slot is always given the same value.
+     *
+     * SLOT  PACKAGE           CONFIGURATION  VALUE
+     * A     target package    (default)      100
+     * B     target package    -sv            200
+     * C     OverlayAppFirst   (default)      300
+     * D     OverlayAppFirst   -sv            400
+     * E     OverlayAppSecond  (default)      500
+     * F     OverlayAppSecond  -sv            600
+     *
+     * Example: in testMatrix101110, the base package defines the
+     * R.integer.matrix101110 resource for the default configuration (value
+     * 100), OverlayAppFirst defines it for both default and Swedish
+     * configurations (values 300 and 400, respectively), and OverlayAppSecond
+     * defines it for the default configuration (value 500). If both overlays
+     * are loaded, the expected value after setting the language to Swedish is
+     * 400.
+     */
+    public void testMatrix100000() throws Throwable {
+        final int resId = R.integer.matrix_100000;
+        setLocale("sv_SE");
+        assertResource(resId, 100, 100, 100);
+    }
+
+    public void testMatrix100001() throws Throwable {
+        final int resId = R.integer.matrix_100001;
+        setLocale("sv_SE");
+        assertResource(resId, 100, 100, 600);
+    }
+
+    public void testMatrix100010() throws Throwable {
+        final int resId = R.integer.matrix_100010;
+        setLocale("sv_SE");
+        assertResource(resId, 100, 100, 500);
+    }
+
+    public void testMatrix100011() throws Throwable {
+        final int resId = R.integer.matrix_100011;
+        setLocale("sv_SE");
+        assertResource(resId, 100, 100, 600);
+    }
+
+    public void testMatrix100100() throws Throwable {
+        final int resId = R.integer.matrix_100100;
+        setLocale("sv_SE");
+        assertResource(resId, 100, 400, 400);
+    }
+
+    public void testMatrix100101() throws Throwable {
+        final int resId = R.integer.matrix_100101;
+        setLocale("sv_SE");
+        assertResource(resId, 100, 400, 600);
+    }
+
+    public void testMatrix100110() throws Throwable {
+        final int resId = R.integer.matrix_100110;
+        setLocale("sv_SE");
+        assertResource(resId, 100, 400, 400);
+    }
+
+    public void testMatrix100111() throws Throwable {
+        final int resId = R.integer.matrix_100111;
+        setLocale("sv_SE");
+        assertResource(resId, 100, 400, 600);
+    }
+
+    public void testMatrix101000() throws Throwable {
+        final int resId = R.integer.matrix_101000;
+        setLocale("sv_SE");
+        assertResource(resId, 100, 300, 300);
+    }
+
+    public void testMatrix101001() throws Throwable {
+        final int resId = R.integer.matrix_101001;
+        setLocale("sv_SE");
+        assertResource(resId, 100, 300, 600);
+    }
+
+    public void testMatrix101010() throws Throwable {
+        final int resId = R.integer.matrix_101010;
+        setLocale("sv_SE");
+        assertResource(resId, 100, 300, 500);
+    }
+
+    public void testMatrix101011() throws Throwable {
+        final int resId = R.integer.matrix_101011;
+        setLocale("sv_SE");
+        assertResource(resId, 100, 300, 600);
+    }
+
+    public void testMatrix101100() throws Throwable {
+        final int resId = R.integer.matrix_101100;
+        setLocale("sv_SE");
+        assertResource(resId, 100, 400, 400);
+    }
+
+    public void testMatrix101101() throws Throwable {
+        final int resId = R.integer.matrix_101101;
+        setLocale("sv_SE");
+        assertResource(resId, 100, 400, 600);
+    }
+
+    public void testMatrix101110() throws Throwable {
+        final int resId = R.integer.matrix_101110;
+        setLocale("sv_SE");
+        assertResource(resId, 100, 400, 400);
+    }
+
+    public void testMatrix101111() throws Throwable {
+        final int resId = R.integer.matrix_101111;
+        setLocale("sv_SE");
+        assertResource(resId, 100, 400, 600);
+    }
+
+    public void testMatrix110000() throws Throwable {
+        final int resId = R.integer.matrix_110000;
+        setLocale("sv_SE");
+        assertResource(resId, 200, 200, 200);
+    }
+
+    public void testMatrix110001() throws Throwable {
+        final int resId = R.integer.matrix_110001;
+        setLocale("sv_SE");
+        assertResource(resId, 200, 200, 600);
+    }
+
+    public void testMatrix110010() throws Throwable {
+        final int resId = R.integer.matrix_110010;
+        setLocale("sv_SE");
+        assertResource(resId, 200, 200, 200);
+    }
+
+    public void testMatrix110011() throws Throwable {
+        final int resId = R.integer.matrix_110011;
+        setLocale("sv_SE");
+        assertResource(resId, 200, 200, 600);
+    }
+
+    public void testMatrix110100() throws Throwable {
+        final int resId = R.integer.matrix_110100;
+        setLocale("sv_SE");
+        assertResource(resId, 200, 400, 400);
+    }
+
+    public void testMatrix110101() throws Throwable {
+        final int resId = R.integer.matrix_110101;
+        setLocale("sv_SE");
+        assertResource(resId, 200, 400, 600);
+    }
+
+    public void testMatrix110110() throws Throwable {
+        final int resId = R.integer.matrix_110110;
+        setLocale("sv_SE");
+        assertResource(resId, 200, 400, 400);
+    }
+
+    public void testMatrix110111() throws Throwable {
+        final int resId = R.integer.matrix_110111;
+        setLocale("sv_SE");
+        assertResource(resId, 200, 400, 600);
+    }
+
+    public void testMatrix111000() throws Throwable {
+        final int resId = R.integer.matrix_111000;
+        setLocale("sv_SE");
+        assertResource(resId, 200, 200, 200);
+    }
+
+    public void testMatrix111001() throws Throwable {
+        final int resId = R.integer.matrix_111001;
+        setLocale("sv_SE");
+        assertResource(resId, 200, 200, 600);
+    }
+
+    public void testMatrix111010() throws Throwable {
+        final int resId = R.integer.matrix_111010;
+        setLocale("sv_SE");
+        assertResource(resId, 200, 200, 200);
+    }
+
+    public void testMatrix111011() throws Throwable {
+        final int resId = R.integer.matrix_111011;
+        setLocale("sv_SE");
+        assertResource(resId, 200, 200, 600);
+    }
+
+    public void testMatrix111100() throws Throwable {
+        final int resId = R.integer.matrix_111100;
+        setLocale("sv_SE");
+        assertResource(resId, 200, 400, 400);
+    }
+
+    public void testMatrix111101() throws Throwable {
+        final int resId = R.integer.matrix_111101;
+        setLocale("sv_SE");
+        assertResource(resId, 200, 400, 600);
+    }
+
+    public void testMatrix111110() throws Throwable {
+        final int resId = R.integer.matrix_111110;
+        setLocale("sv_SE");
+        assertResource(resId, 200, 400, 400);
+    }
+
+    public void testMatrix111111() throws Throwable {
+        final int resId = R.integer.matrix_111111;
+        setLocale("sv_SE");
+        assertResource(resId, 200, 400, 600);
+    }
 }
diff --git a/core/tests/overlaytests/OverlayTest/src/com/android/overlaytest/WithMultipleOverlaysTest.java b/core/tests/overlaytests/OverlayTest/src/com/android/overlaytest/WithMultipleOverlaysTest.java
new file mode 100644
index 0000000..e104f5a
--- /dev/null
+++ b/core/tests/overlaytests/OverlayTest/src/com/android/overlaytest/WithMultipleOverlaysTest.java
@@ -0,0 +1,7 @@
+package com.android.overlaytest;
+
+public class WithMultipleOverlaysTest extends OverlayBaseTest {
+    public WithMultipleOverlaysTest() {
+        mMode = MODE_MULTIPLE_OVERLAYS;
+    }
+}
diff --git a/core/tests/overlaytests/OverlayTest/src/com/android/overlaytest/WithOverlayTest.java b/core/tests/overlaytests/OverlayTest/src/com/android/overlaytest/WithOverlayTest.java
index 1292d03..816a476 100644
--- a/core/tests/overlaytests/OverlayTest/src/com/android/overlaytest/WithOverlayTest.java
+++ b/core/tests/overlaytests/OverlayTest/src/com/android/overlaytest/WithOverlayTest.java
@@ -2,6 +2,6 @@
 
 public class WithOverlayTest extends OverlayBaseTest {
     public WithOverlayTest() {
-        mWithOverlay = true;
+        mMode = MODE_SINGLE_OVERLAY;
     }
 }
diff --git a/core/tests/overlaytests/OverlayTest/src/com/android/overlaytest/WithoutOverlayTest.java b/core/tests/overlaytests/OverlayTest/src/com/android/overlaytest/WithoutOverlayTest.java
index 630ff8f..318cccc 100644
--- a/core/tests/overlaytests/OverlayTest/src/com/android/overlaytest/WithoutOverlayTest.java
+++ b/core/tests/overlaytests/OverlayTest/src/com/android/overlaytest/WithoutOverlayTest.java
@@ -2,6 +2,6 @@
 
 public class WithoutOverlayTest extends OverlayBaseTest {
     public WithoutOverlayTest() {
-        mWithOverlay = false;
+        mMode = MODE_NO_OVERLAY;
     }
 }
diff --git a/core/tests/overlaytests/OverlayTestOverlay/AndroidManifest.xml b/core/tests/overlaytests/OverlayTestOverlay/AndroidManifest.xml
index bcbb0d1..f8b6c7b 100644
--- a/core/tests/overlaytests/OverlayTestOverlay/AndroidManifest.xml
+++ b/core/tests/overlaytests/OverlayTestOverlay/AndroidManifest.xml
@@ -2,5 +2,5 @@
         package="com.android.overlaytest.overlay"
         android:versionCode="1"
         android:versionName="1.0">
-    <overlay-package android:name="android"/>
+        <overlay android:targetPackage="android" android:priority="1"/>
 </manifest>
diff --git a/core/tests/overlaytests/OverlayTestOverlay/res/values-sv/config.xml b/core/tests/overlaytests/OverlayTestOverlay/res/values-sv/config.xml
deleted file mode 100644
index bc52367..0000000
--- a/core/tests/overlaytests/OverlayTestOverlay/res/values-sv/config.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="phoneTypeWork">Jobb</string>
-</resources>
diff --git a/core/tests/overlaytests/OverlayTestOverlay/res/values/config.xml b/core/tests/overlaytests/OverlayTestOverlay/res/values/config.xml
index 794f475..c1e3de1 100644
--- a/core/tests/overlaytests/OverlayTestOverlay/res/values/config.xml
+++ b/core/tests/overlaytests/OverlayTestOverlay/res/values/config.xml
@@ -1,13 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-    <bool name="config_automatic_brightness_available">true</bool>
-    <string name="phoneTypeCar">Automobile</string>
-    <integer-array name="config_scrollBarrierVibePattern">
-        <item>100</item>
-        <item>200</item>
-        <item>300</item>
-    </integer-array>
-    <!-- The following integer does not exist in the original package. Idmap
-         generation should therefore ignore it. -->
-    <integer name="integer_not_in_original_package">0</integer>
+    <bool name="config_annoy_dianne">false</bool>
 </resources>
diff --git a/core/tests/overlaytests/README b/core/tests/overlaytests/README
deleted file mode 100644
index 4b3e6f2..0000000
--- a/core/tests/overlaytests/README
+++ /dev/null
@@ -1,15 +0,0 @@
-Unit tests for runtime resource overlay
-=======================================
-
-As of this writing, runtime resource overlay is only triggered for
-/system/framework/framework-res.apk. Because of this, installation of
-overlay packages require the Android platform be rebooted. However, the
-regular unit tests (triggered via development/testrunner/runtest.py)
-cannot handle reboots. As a workaround, this directory contains a shell
-script which will trigger the tests in a non-standard way.
-
-Once runtime resource overlay may be applied to applications, the tests
-in this directory should be moved to core/tests/coretests. Also, by
-applying runtime resource overlay to a dedicated test application, the
-test cases would not need to assume default values for non-overlaid
-resources.
diff --git a/core/tests/overlaytests/runtests.sh b/core/tests/overlaytests/runtests.sh
deleted file mode 100755
index 0a721ad40..0000000
--- a/core/tests/overlaytests/runtests.sh
+++ /dev/null
@@ -1,129 +0,0 @@
-#!/bin/bash
-
-adb="adb"
-if [[ $# -gt 0 ]]; then
-	adb="adb $*" # for setting -e, -d or -s <serial>
-fi
-
-function atexit()
-{
-	local retval=$?
-
-	if [[ $retval -eq 0 ]]; then
-		rm $log
-	else
-		echo "There were errors, please check log at $log"
-	fi
-}
-
-log=$(mktemp)
-trap "atexit" EXIT
-
-function compile_module()
-{
-	local android_mk="$1"
-
-	echo "Compiling .${android_mk:${#PWD}}"
-	ONE_SHOT_MAKEFILE="$android_mk" make -C "../../../../../" files | tee -a $log
-	if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
-		exit 1
-	fi
-}
-
-function wait_for_boot_completed()
-{
-	echo "Rebooting device"
-	$adb wait-for-device logcat -c
-	$adb wait-for-device logcat | grep -m 1 -e 'PowerManagerService.*bootCompleted' >/dev/null
-}
-
-function mkdir_if_needed()
-{
-	local path="$1"
-
-	if [[ "${path:0:1}" != "/" ]]; then
-		echo "mkdir_if_needed: error: path '$path' does not begin with /" | tee -a $log
-		exit 1
-	fi
-
-	local basename=$(basename "$path")
-	local dirname=$(dirname "$path")
-	local t=$($adb shell ls -l $dirname | tr -d '\r' | grep -e "${basename}$" | grep -oe '^.')
-
-	case "$t" in
-		d) # File exists, and is a directory ...
-			# do nothing
-			;;
-		l) # ... (or symbolic link possibly to a directory).
-			# do nothing
-			;;
-		"") # File does not exist.
-			mkdir_if_needed "$dirname"
-			$adb shell mkdir "$path"
-			;;
-		*) # File exists, but is not a directory.
-			echo "mkdir_if_needed: file '$path' exists, but is not a directory" | tee -a $log
-			exit 1
-			;;
-	esac
-}
-
-function disable_overlay()
-{
-	echo "Disabling overlay"
-	$adb shell rm /vendor/overlay/framework/framework-res.apk
-	$adb shell rm /data/resource-cache/vendor@overlay@framework@framework-res.apk@idmap
-}
-
-function enable_overlay()
-{
-	echo "Enabling overlay"
-	mkdir_if_needed "/system/vendor"
-	mkdir_if_needed "/vendor/overlay/framework"
-	$adb shell ln -s /data/app/com.android.overlaytest.overlay.apk /vendor/overlay/framework/framework-res.apk
-}
-
-function instrument()
-{
-	local class="$1"
-
-	echo "Instrumenting $class"
-	$adb shell am instrument -w -e class $class com.android.overlaytest/android.test.InstrumentationTestRunner | tee -a $log
-}
-
-function remount()
-{
-	echo "Remounting file system writable"
-	$adb remount | tee -a $log
-}
-
-function sync()
-{
-	echo "Syncing to device"
-	$adb sync data | tee -a $log
-}
-
-# some commands require write access, remount once and for all
-remount
-
-# build and sync
-compile_module "$PWD/OverlayTest/Android.mk"
-compile_module "$PWD/OverlayTestOverlay/Android.mk"
-sync
-
-# instrument test (without overlay)
-$adb shell stop
-disable_overlay
-$adb shell start
-wait_for_boot_completed
-instrument "com.android.overlaytest.WithoutOverlayTest"
-
-# instrument test (with overlay)
-$adb shell stop
-enable_overlay
-$adb shell start
-wait_for_boot_completed
-instrument "com.android.overlaytest.WithOverlayTest"
-
-# cleanup
-exit $(grep -c -e '^FAILURES' $log)
diff --git a/core/tests/overlaytests/testrunner.py b/core/tests/overlaytests/testrunner.py
new file mode 100755
index 0000000..4f94373
--- /dev/null
+++ b/core/tests/overlaytests/testrunner.py
@@ -0,0 +1,679 @@
+#!/usr/bin/python
+import hashlib
+import optparse
+import os
+import re
+import shlex
+import subprocess
+import sys
+import threading
+import time
+
+TASK_COMPILATION = 'compile'
+TASK_DISABLE_OVERLAYS = 'disable overlays'
+TASK_ENABLE_MULTIPLE_OVERLAYS = 'enable multiple overlays'
+TASK_ENABLE_SINGLE_OVERLAY = 'enable single overlay'
+TASK_FILE_EXISTS_TEST = 'test (file exists)'
+TASK_GREP_IDMAP_TEST = 'test (grep idmap)'
+TASK_MD5_TEST = 'test (md5)'
+TASK_IDMAP_PATH = 'idmap --path'
+TASK_IDMAP_SCAN = 'idmap --scan'
+TASK_INSTRUMENTATION = 'instrumentation'
+TASK_INSTRUMENTATION_TEST = 'test (instrumentation)'
+TASK_MKDIR = 'mkdir'
+TASK_PUSH = 'push'
+TASK_ROOT = 'root'
+TASK_REMOUNT = 'remount'
+TASK_RM = 'rm'
+TASK_SETUP_IDMAP_PATH = 'setup idmap --path'
+TASK_SETUP_IDMAP_SCAN = 'setup idmap --scan'
+TASK_START = 'start'
+TASK_STOP = 'stop'
+
+adb = 'adb'
+
+def _adb_shell(cmd):
+    argv = shlex.split(adb + " shell '" + cmd + "; echo $?'")
+    proc = subprocess.Popen(argv, bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    (stdout, stderr) = proc.communicate()
+    (stdout, stderr) = (stdout.replace('\r', ''), stderr.replace('\r', ''))
+    tmp = stdout.rsplit('\n', 2)
+    if len(tmp) == 2:
+        stdout == ''
+        returncode = int(tmp[0])
+    else:
+        stdout = tmp[0] + '\n'
+        returncode = int(tmp[1])
+    return returncode, stdout, stderr
+
+class VerbosePrinter:
+    class Ticker(threading.Thread):
+        def _print(self):
+            s = '\r' + self.text + '[' + '.' * self.i + ' ' * (4 - self.i) + ']'
+            sys.stdout.write(s)
+            sys.stdout.flush()
+            self.i = (self.i + 1) % 5
+
+        def __init__(self, cond_var, text):
+            threading.Thread.__init__(self)
+            self.text = text
+            self.setDaemon(True)
+            self.cond_var = cond_var
+            self.running = False
+            self.i = 0
+            self._print()
+            self.running = True
+
+        def run(self):
+            self.cond_var.acquire()
+            while True:
+                self.cond_var.wait(0.25)
+                running = self.running
+                if not running:
+                    break
+                self._print()
+            self.cond_var.release()
+
+        def stop(self):
+            self.cond_var.acquire()
+            self.running = False
+            self.cond_var.notify_all()
+            self.cond_var.release()
+
+    def _start_ticker(self):
+        self.ticker = VerbosePrinter.Ticker(self.cond_var, self.text)
+        self.ticker.start()
+
+    def _stop_ticker(self):
+        self.ticker.stop()
+        self.ticker.join()
+        self.ticker = None
+
+    def _format_begin(self, type, name):
+        N = self.width - len(type) - len(' [    ] ')
+        fmt = '%%s %%-%ds ' % N
+        return fmt % (type, name)
+
+    def __init__(self, use_color):
+        self.cond_var = threading.Condition()
+        self.ticker = None
+        if use_color:
+            self.color_RED = '\033[1;31m'
+            self.color_red = '\033[0;31m'
+            self.color_reset = '\033[0;37m'
+        else:
+            self.color_RED = ''
+            self.color_red = ''
+            self.color_reset = ''
+
+        argv = shlex.split('stty size') # get terminal width
+        proc = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        (stdout, stderr) = proc.communicate()
+        if proc.returncode == 0:
+            (h, w) = stdout.split()
+            self.width = int(w)
+        else:
+            self.width = 72 # conservative guesstimate
+
+    def begin(self, type, name):
+        self.text = self._format_begin(type, name)
+        sys.stdout.write(self.text + '[    ]')
+        sys.stdout.flush()
+        self._start_ticker()
+
+    def end_pass(self, type, name):
+        self._stop_ticker()
+        sys.stdout.write('\r' + self.text + '[ OK ]\n')
+        sys.stdout.flush()
+
+    def end_fail(self, type, name, msg):
+        self._stop_ticker()
+        sys.stdout.write('\r' + self.color_RED + self.text + '[FAIL]\n')
+        sys.stdout.write(self.color_red)
+        sys.stdout.write(msg)
+        sys.stdout.write(self.color_reset)
+        sys.stdout.flush()
+
+class QuietPrinter:
+    def begin(self, type, name):
+        pass
+
+    def end_pass(self, type, name):
+        sys.stdout.write('PASS ' + type + ' ' + name + '\n')
+        sys.stdout.flush()
+
+    def end_fail(self, type, name, msg):
+        sys.stdout.write('FAIL ' + type + ' ' + name + '\n')
+        sys.stdout.flush()
+
+class CompilationTask:
+    def __init__(self, makefile):
+        self.makefile = makefile
+
+    def get_type(self):
+        return TASK_COMPILATION
+
+    def get_name(self):
+        return self.makefile
+
+    def execute(self):
+        os.putenv('ONE_SHOT_MAKEFILE', os.getcwd() + "/" + self.makefile)
+        argv = shlex.split('make -C "../../../../../" files')
+        proc = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        (stdout, stderr) = proc.communicate()
+        return proc.returncode, stdout, stderr
+
+class InstrumentationTask:
+    def __init__(self, instrumentation_class):
+        self.instrumentation_class = instrumentation_class
+
+    def get_type(self):
+        return TASK_INSTRUMENTATION
+
+    def get_name(self):
+        return self.instrumentation_class
+
+    def execute(self):
+        return _adb_shell('am instrument -r -w -e class %s com.android.overlaytest/android.test.InstrumentationTestRunner' % self.instrumentation_class)
+
+class PushTask:
+    def __init__(self, src, dest):
+        self.src = src
+        self.dest = dest
+
+    def get_type(self):
+        return TASK_PUSH
+
+    def get_name(self):
+        return "%s -> %s" % (self.src, self.dest)
+
+    def execute(self):
+        src = os.getenv('OUT') + "/" + self.src
+        argv = shlex.split(adb + ' push %s %s' % (src, self.dest))
+        proc = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        (stdout, stderr) = proc.communicate()
+        return proc.returncode, stdout, stderr
+
+class MkdirTask:
+    def __init__(self, path):
+        self.path = path
+
+    def get_type(self):
+        return TASK_MKDIR
+
+    def get_name(self):
+        return self.path
+
+    def execute(self):
+        return _adb_shell('mkdir -p %s' % self.path)
+
+class RmTask:
+    def __init__(self, path):
+        self.path = path
+
+    def get_type(self):
+        return TASK_RM
+
+    def get_name(self):
+        return self.path
+
+    def execute(self):
+        returncode, stdout, stderr = _adb_shell('ls %s' % self.path)
+        if returncode != 0 and stdout.endswith(': No such file or directory\n'):
+            return 0, "", ""
+        return _adb_shell('rm -r %s' % self.path)
+
+class IdmapPathTask:
+    def __init__(self, path_target_apk, path_overlay_apk, path_idmap):
+        self.path_target_apk = path_target_apk
+        self.path_overlay_apk = path_overlay_apk
+        self.path_idmap = path_idmap
+
+    def get_type(self):
+        return TASK_IDMAP_PATH
+
+    def get_name(self):
+        return self.path_idmap
+
+    def execute(self):
+        return _adb_shell('su system idmap --path "%s" "%s" "%s"' % (self.path_target_apk, self.path_overlay_apk, self.path_idmap))
+
+class IdmapScanTask:
+    def __init__(self, overlay_dir, target_pkg_name, target_pkg, idmap_dir, symlink_dir):
+        self.overlay_dir = overlay_dir
+        self.target_pkg_name = target_pkg_name
+        self.target_pkg = target_pkg
+        self.idmap_dir = idmap_dir
+        self.symlink_dir = symlink_dir
+
+    def get_type(self):
+        return TASK_IDMAP_SCAN
+
+    def get_name(self):
+        return self.target_pkg_name
+
+    def execute(self):
+        return _adb_shell('su system idmap --scan "%s" "%s" "%s" "%s"' % (self.overlay_dir, self.target_pkg_name, self.target_pkg, self.idmap_dir))
+
+class FileExistsTest:
+    def __init__(self, path):
+        self.path = path
+
+    def get_type(self):
+        return TASK_FILE_EXISTS_TEST
+
+    def get_name(self):
+        return self.path
+
+    def execute(self):
+        return _adb_shell('ls %s' % self.path)
+
+class GrepIdmapTest:
+    def __init__(self, path_idmap, pattern, expected_n):
+        self.path_idmap = path_idmap
+        self.pattern = pattern
+        self.expected_n = expected_n
+
+    def get_type(self):
+        return TASK_GREP_IDMAP_TEST
+
+    def get_name(self):
+        return self.pattern
+
+    def execute(self):
+        returncode, stdout, stderr = _adb_shell('idmap --inspect %s' % self.path_idmap)
+        if returncode != 0:
+            return returncode, stdout, stderr
+        all_matches = re.findall('\s' + self.pattern + '$', stdout, flags=re.MULTILINE)
+        if len(all_matches) != self.expected_n:
+            return 1, 'pattern=%s idmap=%s expected=%d found=%d\n' % (self.pattern, self.path_idmap, self.expected_n, len(all_matches)), ''
+        return 0, "", ""
+
+class Md5Test:
+    def __init__(self, path, expected_content):
+        self.path = path
+        self.expected_md5 = hashlib.md5(expected_content).hexdigest()
+
+    def get_type(self):
+        return TASK_MD5_TEST
+
+    def get_name(self):
+        return self.path
+
+    def execute(self):
+        returncode, stdout, stderr = _adb_shell('md5 %s' % self.path)
+        if returncode != 0:
+            return returncode, stdout, stderr
+        actual_md5 = stdout.split()[0]
+        if actual_md5 != self.expected_md5:
+            return 1, 'expected %s, got %s\n' % (self.expected_md5, actual_md5), ''
+        return 0, "", ""
+
+class StartTask:
+    def get_type(self):
+        return TASK_START
+
+    def get_name(self):
+        return ""
+
+    def execute(self):
+        (returncode, stdout, stderr) = _adb_shell('start')
+        if returncode != 0:
+            return returncode, stdout, stderr
+
+        while True:
+            (returncode, stdout, stderr) = _adb_shell('getprop dev.bootcomplete')
+            if returncode != 0:
+                return returncode, stdout, stderr
+            if stdout.strip() == "1":
+                break
+            time.sleep(0.5)
+
+        return 0, "", ""
+
+class StopTask:
+    def get_type(self):
+        return TASK_STOP
+
+    def get_name(self):
+        return ""
+
+    def execute(self):
+        (returncode, stdout, stderr) = _adb_shell('stop')
+        if returncode != 0:
+            return returncode, stdout, stderr
+        return _adb_shell('setprop dev.bootcomplete 0')
+
+class RootTask:
+    def get_type(self):
+        return TASK_ROOT
+
+    def get_name(self):
+        return ""
+
+    def execute(self):
+        (returncode, stdout, stderr) = _adb_shell('getprop service.adb.root 0')
+        if returncode != 0:
+            return returncode, stdout, stderr
+        if stdout.strip() == '1': # already root
+            return 0, "", ""
+
+        argv = shlex.split(adb + ' root')
+        proc = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        (stdout, stderr) = proc.communicate()
+        if proc.returncode != 0:
+            return proc.returncode, stdout, stderr
+
+        argv = shlex.split(adb + ' wait-for-device')
+        proc = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        (stdout, stderr) = proc.communicate()
+        return proc.returncode, stdout, stderr
+
+class RemountTask:
+    def get_type(self):
+        return TASK_REMOUNT
+
+    def get_name(self):
+        return ""
+
+    def execute(self):
+        argv = shlex.split(adb + ' remount')
+        proc = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        (stdout, stderr) = proc.communicate()
+        # adb remount returns 0 even if the operation failed, so check stdout
+        if stdout.startswith('remount failed:'):
+            return 1, stdout, stderr
+        return proc.returncode, stdout, stderr
+
+class CompoundTask:
+    def __init__(self, type, tasks):
+        self.type = type
+        self.tasks = tasks
+
+    def get_type(self):
+        return self.type
+
+    def get_name(self):
+        return ""
+
+    def execute(self):
+        for t in self.tasks:
+            (returncode, stdout, stderr) = t.execute()
+            if returncode != 0:
+                return returncode, stdout, stderr
+        return 0, "", ""
+
+def _create_disable_overlays_task():
+    tasks = [
+        RmTask("/vendor/overlay/framework_a.apk"),
+        RmTask("/vendor/overlay/framework_b.apk"),
+        RmTask("/data/resource-cache/vendor@overlay@framework_a.apk@idmap"),
+        RmTask("/data/resource-cache/vendor@overlay@framework_b.apk@idmap"),
+        RmTask("/vendor/overlay/app_a.apk"),
+        RmTask("/vendor/overlay/app_b.apk"),
+        RmTask("/data/resource-cache/vendor@overlay@app_a.apk@idmap"),
+        RmTask("/data/resource-cache/vendor@overlay@app_b.apk@idmap"),
+    ]
+    return CompoundTask(TASK_DISABLE_OVERLAYS, tasks)
+
+def _create_enable_single_overlay_task():
+    tasks = [
+        _create_disable_overlays_task(),
+        MkdirTask('/system/vendor'),
+        MkdirTask('/vendor/overlay'),
+        PushTask('/data/app/com.android.overlaytest.overlay.apk', '/vendor/overlay/framework_a.apk'),
+        PushTask('/data/app/com.android.overlaytest.first_app_overlay.apk', '/vendor/overlay/app_a.apk'),
+    ]
+    return CompoundTask(TASK_ENABLE_SINGLE_OVERLAY, tasks)
+
+def _create_enable_multiple_overlays_task():
+    tasks = [
+        _create_disable_overlays_task(),
+        MkdirTask('/system/vendor'),
+        MkdirTask('/vendor/overlay'),
+
+        PushTask('/data/app/com.android.overlaytest.overlay.apk', '/vendor/overlay/framework_b.apk'),
+        PushTask('/data/app/com.android.overlaytest.first_app_overlay.apk', '/vendor/overlay/app_a.apk'),
+        PushTask('/data/app/com.android.overlaytest.second_app_overlay.apk', '/vendor/overlay/app_b.apk'),
+    ]
+    return CompoundTask(TASK_ENABLE_MULTIPLE_OVERLAYS, tasks)
+
+def _create_setup_idmap_path_task(idmaps, symlinks):
+    tasks = [
+        _create_enable_single_overlay_task(),
+        RmTask(symlinks),
+        RmTask(idmaps),
+        MkdirTask(idmaps),
+        MkdirTask(symlinks),
+    ]
+    return CompoundTask(TASK_SETUP_IDMAP_PATH, tasks)
+
+def _create_setup_idmap_scan_task(idmaps, symlinks):
+    tasks = [
+        _create_enable_single_overlay_task(),
+        RmTask(symlinks),
+        RmTask(idmaps),
+        MkdirTask(idmaps),
+        MkdirTask(symlinks),
+        _create_enable_multiple_overlays_task(),
+    ]
+    return CompoundTask(TASK_SETUP_IDMAP_SCAN, tasks)
+
+def _handle_instrumentation_task_output(stdout, printer):
+    regex_status_code = re.compile(r'^INSTRUMENTATION_STATUS_CODE: -?(\d+)')
+    regex_name = re.compile(r'^INSTRUMENTATION_STATUS: test=(.*)')
+    regex_begin_stack = re.compile(r'^INSTRUMENTATION_STATUS: stack=(.*)')
+    regex_end_stack = re.compile(r'^$')
+
+    failed_tests = 0
+    current_test = None
+    current_stack = []
+    mode_stack = False
+    for line in stdout.split("\n"):
+        line = line.rstrip() # strip \r from adb output
+        m = regex_status_code.match(line)
+        if m:
+            c = int(m.group(1))
+            if c == 1:
+                printer.begin(TASK_INSTRUMENTATION_TEST, current_test)
+            elif c == 0:
+                printer.end_pass(TASK_INSTRUMENTATION_TEST, current_test)
+            else:
+                failed_tests += 1
+                current_stack.append("\n")
+                msg = "\n".join(current_stack)
+                printer.end_fail(TASK_INSTRUMENTATION_TEST, current_test, msg.rstrip() + '\n')
+            continue
+
+        m = regex_name.match(line)
+        if m:
+            current_test = m.group(1)
+            continue
+
+        m = regex_begin_stack.match(line)
+        if m:
+            mode_stack = True
+            current_stack = []
+            current_stack.append("  " + m.group(1))
+            continue
+
+        m = regex_end_stack.match(line)
+        if m:
+            mode_stack = False
+            continue
+
+        if mode_stack:
+            current_stack.append("    " + line.strip())
+
+    return failed_tests
+
+def _set_adb_device(option, opt, value, parser):
+    global adb
+    if opt == '-d' or opt == '--device':
+        adb = 'adb -d'
+    if opt == '-e' or opt == '--emulator':
+        adb = 'adb -e'
+    if opt == '-s' or opt == '--serial':
+        adb = 'adb -s ' + value
+
+def _create_opt_parser():
+    parser = optparse.OptionParser()
+    parser.add_option('-d', '--device', action='callback', callback=_set_adb_device,
+            help='pass -d to adb')
+    parser.add_option('-e', '--emulator', action='callback', callback=_set_adb_device,
+            help='pass -e to adb')
+    parser.add_option('-s', '--serial', type="str", action='callback', callback=_set_adb_device,
+            help='pass -s <serical> to adb')
+    parser.add_option('-C', '--no-color', action='store_false',
+            dest='use_color', default=True,
+            help='disable color escape sequences in output')
+    parser.add_option('-q', '--quiet', action='store_true',
+            dest='quiet_mode', default=False,
+            help='quiet mode, output only results')
+    parser.add_option('-b', '--no-build', action='store_false',
+            dest='do_build', default=True,
+            help='do not rebuild test projects')
+    parser.add_option('-k', '--continue', action='store_true',
+            dest='do_continue', default=False,
+            help='do not rebuild test projects')
+    parser.add_option('-i', '--test-idmap', action='store_true',
+            dest='test_idmap', default=False,
+            help='run tests for single overlay')
+    parser.add_option('-0', '--test-no-overlay', action='store_true',
+            dest='test_no_overlay', default=False,
+            help='run tests without any overlay')
+    parser.add_option('-1', '--test-single-overlay', action='store_true',
+            dest='test_single_overlay', default=False,
+            help='run tests for single overlay')
+    parser.add_option('-2', '--test-multiple-overlays', action='store_true',
+            dest='test_multiple_overlays', default=False,
+            help='run tests for multiple overlays')
+    return parser
+
+if __name__ == '__main__':
+    opt_parser = _create_opt_parser()
+    opts, args = opt_parser.parse_args(sys.argv[1:])
+    if not opts.test_idmap and not opts.test_no_overlay and not opts.test_single_overlay and not opts.test_multiple_overlays:
+        opts.test_idmap = True
+        opts.test_no_overlay = True
+        opts.test_single_overlay = True
+        opts.test_multiple_overlays = True
+    if len(args) > 0:
+        opt_parser.error("unexpected arguments: %s" % " ".join(args))
+        # will never reach this: opt_parser.error will call sys.exit
+
+    if opts.quiet_mode:
+        printer = QuietPrinter()
+    else:
+        printer = VerbosePrinter(opts.use_color)
+    tasks = []
+
+    # must be in the same directory as this script for compilation tasks to work
+    script = sys.argv[0]
+    dirname = os.path.dirname(script)
+    wd = os.path.realpath(dirname)
+    os.chdir(wd)
+
+    # build test cases
+    if opts.do_build:
+        tasks.append(CompilationTask('OverlayTest/Android.mk'))
+        tasks.append(CompilationTask('OverlayTestOverlay/Android.mk'))
+        tasks.append(CompilationTask('OverlayAppFirst/Android.mk'))
+        tasks.append(CompilationTask('OverlayAppSecond/Android.mk'))
+
+    # remount filesystem, install test project
+    tasks.append(RootTask())
+    tasks.append(RemountTask())
+    tasks.append(PushTask('/system/app/OverlayTest.apk', '/system/app/OverlayTest.apk'))
+
+    # test idmap
+    if opts.test_idmap:
+        idmaps='/data/local/tmp/idmaps'
+        symlinks='/data/local/tmp/symlinks'
+
+        # idmap --path
+        tasks.append(StopTask())
+        tasks.append(_create_setup_idmap_path_task(idmaps, symlinks))
+        tasks.append(StartTask())
+        tasks.append(IdmapPathTask('/vendor/overlay/framework_a.apk', '/system/framework/framework-res.apk', idmaps + '/a.idmap'))
+        tasks.append(FileExistsTest(idmaps + '/a.idmap'))
+        tasks.append(GrepIdmapTest(idmaps + '/a.idmap', 'bool/config_annoy_dianne', 1))
+
+        # idmap --scan
+        idmap = idmaps + '/vendor@overlay@framework_b.apk@idmap'
+        tasks.append(StopTask())
+        tasks.append(_create_setup_idmap_scan_task(idmaps, symlinks))
+        tasks.append(StartTask())
+        tasks.append(IdmapScanTask('/vendor/overlay', 'android', '/system/framework/framework-res.apk', idmaps, symlinks))
+        tasks.append(FileExistsTest(idmap))
+        tasks.append(GrepIdmapTest(idmap, 'bool/config_annoy_dianne', 1))
+
+        # overlays.list
+        overlays_list_path = '/data/resource-cache/overlays.list'
+        expected_content = '''\
+/vendor/overlay/framework_b.apk /data/resource-cache/vendor@overlay@framework_b.apk@idmap
+'''
+        tasks.append(FileExistsTest(overlays_list_path))
+        tasks.append(Md5Test(overlays_list_path, expected_content))
+
+        # idmap cleanup
+        tasks.append(RmTask(symlinks))
+        tasks.append(RmTask(idmaps))
+
+    # test no overlay
+    if opts.test_no_overlay:
+        tasks.append(StopTask())
+        tasks.append(_create_disable_overlays_task())
+        tasks.append(StartTask())
+        tasks.append(InstrumentationTask('com.android.overlaytest.WithoutOverlayTest'))
+
+    # test single overlay
+    if opts.test_single_overlay:
+        tasks.append(StopTask())
+        tasks.append(_create_enable_single_overlay_task())
+        tasks.append(StartTask())
+        tasks.append(InstrumentationTask('com.android.overlaytest.WithOverlayTest'))
+
+    # test multiple overlays
+    if opts.test_multiple_overlays:
+        tasks.append(StopTask())
+        tasks.append(_create_enable_multiple_overlays_task())
+        tasks.append(StartTask())
+        tasks.append(InstrumentationTask('com.android.overlaytest.WithMultipleOverlaysTest'))
+
+    ignored_errors = 0
+    for t in tasks:
+        type = t.get_type()
+        name = t.get_name()
+        if type == TASK_INSTRUMENTATION:
+            # InstrumentationTask will run several tests, but we want it
+            # to appear as if each test was run individually. Calling
+            # "am instrument" with a single test method is prohibitively
+            # expensive, so let's instead post-process the output to
+            # emulate individual calls.
+            retcode, stdout, stderr = t.execute()
+            if retcode != 0:
+                printer.begin(TASK_INSTRUMENTATION, name)
+                printer.end_fail(TASK_INSTRUMENTATION, name, stderr)
+                sys.exit(retcode)
+            retcode = _handle_instrumentation_task_output(stdout, printer)
+            if retcode != 0:
+                if not opts.do_continue:
+                    sys.exit(retcode)
+                else:
+                    ignored_errors += retcode
+        else:
+            printer.begin(type, name)
+            retcode, stdout, stderr = t.execute()
+            if retcode == 0:
+                printer.end_pass(type, name)
+            if retcode != 0:
+                if len(stderr) == 0:
+                    # hope for output from stdout instead (true for eg adb shell rm)
+                    stderr = stdout
+                printer.end_fail(type, name, stderr)
+                if not opts.do_continue:
+                    sys.exit(retcode)
+                else:
+                    ignored_errors += retcode
+    sys.exit(ignored_errors)
diff --git a/data/keyboards/Generic.kcm b/data/keyboards/Generic.kcm
index 695a74f..01d22ee 100644
--- a/data/keyboards/Generic.kcm
+++ b/data/keyboards/Generic.kcm
@@ -477,4 +477,128 @@
     ctrl:                               fallback MENU
 }
 
-### Gamepad buttons are handled by the view root ###
+### Gamepad buttons ###
+
+key BUTTON_A {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_B {
+    base:                               fallback BACK
+}
+
+key BUTTON_C {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_X {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_Y {
+    base:                               fallback BACK
+}
+
+key BUTTON_Z {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_L1 {
+    base:                               none
+}
+
+key BUTTON_R1 {
+    base:                               none
+}
+
+key BUTTON_L2 {
+    base:                               none
+}
+
+key BUTTON_R2 {
+    base:                               none
+}
+
+key BUTTON_THUMBL {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_THUMBR {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_START {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_SELECT {
+    base:                               fallback MENU
+}
+
+key BUTTON_MODE {
+    base:                               fallback MENU
+}
+
+key BUTTON_1 {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_2 {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_3 {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_4 {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_5 {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_6 {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_7 {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_8 {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_9 {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_10 {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_11 {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_12 {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_13 {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_14 {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_15 {
+    base:                               fallback DPAD_CENTER
+}
+
+key BUTTON_16 {
+    base:                               fallback DPAD_CENTER
+}
diff --git a/docs/html/design/building-blocks/buttons.jd b/docs/html/design/building-blocks/buttons.jd
index 2a77e24..3a34601 100644
--- a/docs/html/design/building-blocks/buttons.jd
+++ b/docs/html/design/building-blocks/buttons.jd
@@ -9,7 +9,7 @@
   </div>
 </a>
 
-<p>A button consists of text and/or an image that clearly communicates what action
+<p itemprop="description">A button consists of text and/or an image that clearly communicates what action
   will occur when the user touches it. A button can have an image, text, or both.
 </p>
 
diff --git a/docs/html/design/building-blocks/dialogs.jd b/docs/html/design/building-blocks/dialogs.jd
index f9897f4..53d99b8 100644
--- a/docs/html/design/building-blocks/dialogs.jd
+++ b/docs/html/design/building-blocks/dialogs.jd
@@ -9,7 +9,7 @@
   </div>
 </a>
 
-<p>Dialogs prompt the user for decisions or additional information required by the app to continue a
+<p itemprop="description">Dialogs prompt the user for decisions or additional information required by the app to continue a
 task. Such requests can range from simple Cancel/OK decisions to more complex layouts asking the
 user to adjust settings or enter text.</p>
 
diff --git a/docs/html/design/building-blocks/grid-lists.jd b/docs/html/design/building-blocks/grid-lists.jd
index cef7514..d98637cc 100644
--- a/docs/html/design/building-blocks/grid-lists.jd
+++ b/docs/html/design/building-blocks/grid-lists.jd
@@ -11,7 +11,7 @@
   </div>
 </a>
 
-<p>Grid lists are an alternative to standard list views. They are best suited for showing data sets
+<p itemprop="description">Grid lists are an alternative to standard list views. They are best suited for showing data sets
 that represent themselves through images. In contrast to simple lists, grid lists may scroll either
 vertically or horizontally.</p>
 
diff --git a/docs/html/design/building-blocks/index.jd b/docs/html/design/building-blocks/index.jd
index e554775..7fb0e55 100644
--- a/docs/html/design/building-blocks/index.jd
+++ b/docs/html/design/building-blocks/index.jd
@@ -18,7 +18,8 @@
 
 <div id="landing-graphic-container">
   <div id="text-overlay">
-    Your inventory of ready-to-use elements for creating outstanding apps.
+    <span itemprop="description">Your inventory of ready-to-use elements for creating
+    outstanding apps.</span>
     <br><br>
     <a href="{@docRoot}design/building-blocks/tabs.html" class="landing-page-link">Tabs</a>
   </div>
diff --git a/docs/html/design/building-blocks/lists.jd b/docs/html/design/building-blocks/lists.jd
index 54fa442..4949d00 100644
--- a/docs/html/design/building-blocks/lists.jd
+++ b/docs/html/design/building-blocks/lists.jd
@@ -9,7 +9,7 @@
   </div>
 </a>
 
-<p>Lists present multiple line items in a vertical arrangement. They can be used for data selection as
+<p itemprop="description">Lists present multiple line items in a vertical arrangement. They can be used for data selection as
 well as drilldown navigation.</p>
 
 <div class="vspace size-1">&nbsp;</div>
diff --git a/docs/html/design/building-blocks/pickers.jd b/docs/html/design/building-blocks/pickers.jd
index 860a126..fb5e287 100644
--- a/docs/html/design/building-blocks/pickers.jd
+++ b/docs/html/design/building-blocks/pickers.jd
@@ -9,7 +9,7 @@
   </div>
 </a>
 
-<p>Pickers provide a simple way to select a single value from a set. In addition to touching the
+<p itemprop="description">Pickers provide a simple way to select a single value from a set. In addition to touching the
 up/down arrow buttons, it's possible to set the desired value from the keyboard or via a swipe
 gesture.</p>
 
diff --git a/docs/html/design/building-blocks/spinners.jd b/docs/html/design/building-blocks/spinners.jd
index f8d92d4..f7d80e7 100644
--- a/docs/html/design/building-blocks/spinners.jd
+++ b/docs/html/design/building-blocks/spinners.jd
@@ -9,7 +9,7 @@
   </div>
 </a>
 
-<p>Spinners provide a quick way to select one value from a set. In the default state, a spinner shows
+<p itemprop="description">Spinners provide a quick way to select one value from a set. In the default state, a spinner shows
 its currently selected value. Touching the spinner displays a dropdown menu with all other available
 values, from which the user can select a new one.</p>
 
diff --git a/docs/html/design/building-blocks/switches.jd b/docs/html/design/building-blocks/switches.jd
index b294689..d435657 100644
--- a/docs/html/design/building-blocks/switches.jd
+++ b/docs/html/design/building-blocks/switches.jd
@@ -16,7 +16,7 @@
   </div>
 </a>
 
-<p>Checkboxes allow the user to select multiple options from a set. Avoid using a single checkbox to
+<p itemprop="description">Checkboxes allow the user to select multiple options from a set. Avoid using a single checkbox to
 turn an option off or on. Instead, use an on/off switch.</p>
 
   <img src="{@docRoot}design/media/switches_checkboxes.png">
diff --git a/docs/html/design/building-blocks/tabs.jd b/docs/html/design/building-blocks/tabs.jd
index 1fa3461..93818c3 100644
--- a/docs/html/design/building-blocks/tabs.jd
+++ b/docs/html/design/building-blocks/tabs.jd
@@ -11,7 +11,7 @@
   </div>
 </a>
 
-<p>Tabs in the action bar make it easy to explore and switch between different views or functional
+<p itemprop="description">Tabs in the action bar make it easy to explore and switch between different views or functional
 aspects of your app, or to browse categorized data sets.</p>
 
 <p>For details on using gestures to move between tabs, see the <a href="{@docRoot}design/patterns/swipe-views.html">Swipe Views</a> pattern.</p>
diff --git a/docs/html/design/building-blocks/text-fields.jd b/docs/html/design/building-blocks/text-fields.jd
index 4545bfb..e109d5f 100644
--- a/docs/html/design/building-blocks/text-fields.jd
+++ b/docs/html/design/building-blocks/text-fields.jd
@@ -9,7 +9,7 @@
   </div>
 </a>
 
-<p>Text fields allow the user to type text into your app. They can be either single line or multi-line.
+<p itemprop="description">Text fields allow the user to type text into your app. They can be either single line or multi-line.
 Touching a text field places the cursor and automatically displays the keyboard. In addition to
 typing, text fields allow for a variety of other activities, such as text selection (cut, copy,
 paste) and data lookup via auto-completion.</p>
diff --git a/docs/html/design/get-started/creative-vision.jd b/docs/html/design/get-started/creative-vision.jd
index c57b185..1ce305a 100644
--- a/docs/html/design/get-started/creative-vision.jd
+++ b/docs/html/design/get-started/creative-vision.jd
@@ -5,7 +5,12 @@
 
 <div class="vspace size-1">&nbsp;</div>
 
-<p>We focused the design of Android around three overarching goals, which apply to our core apps as well as the system at large. As you design apps to work with Android, consider these goals:</p>
+<p itemprop="description">
+  We focused the design of Android around three overarching goals, which apply
+  to our core apps as well as the system at large. As you design apps to work
+  with Android, consider these goals: <em>Enchant me</em>, <em>Simplify my
+  life</em>, and <em>Make me amazing</em>
+</p>
 
 <div class="vspace size-1">&nbsp;</div>
 
diff --git a/docs/html/design/index.jd b/docs/html/design/index.jd
index 8f73d9c..9ba32dd 100644
--- a/docs/html/design/index.jd
+++ b/docs/html/design/index.jd
@@ -22,7 +22,8 @@
 
 <div id="landing-graphic-container">
   <div id="text-overlay">
-    Welcome to <strong>Android Design</strong>, your place for learning how to design exceptional Android apps.
+    <span itemprop="description">Welcome to <strong>Android Design</strong>, your place for
+    learning how to design exceptional Android apps.</span>
     <br><br>
     Want to know what <strong>Android 4.4 KitKat</strong> has for designers? See <a href="{@docRoot}design/patterns/new.html">New in Android</a>.<br><br>
     <a href="/design/get-started/creative-vision.html" class="landing-page-link">Creative Vision</a>
diff --git a/docs/html/design/patterns/accessibility.jd b/docs/html/design/patterns/accessibility.jd
index 50c82fe..aaa6f16 100644
--- a/docs/html/design/patterns/accessibility.jd
+++ b/docs/html/design/patterns/accessibility.jd
@@ -1,5 +1,6 @@
 page.title=Accessibility
-page.tags=accessibility,navigation,input
+page.tags="accessibility","navigation","input"
+page.metaDescription=Design an app that's universally accessible to people with visual impairment, color deficiency, hearing loss, and limited dexterity.
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}training/accessibility/index.html">
@@ -86,4 +87,4 @@
   <li>Provide alternatives to affordances that time out</li>
   <li>Use standard framework controls or enable TalkBack for custom controls</li>
   <li>Try it out yourself</li>
-</ul>
+</ul>
\ No newline at end of file
diff --git a/docs/html/design/patterns/actionbar.jd b/docs/html/design/patterns/actionbar.jd
index f0104b5..a1adbd3 100644
--- a/docs/html/design/patterns/actionbar.jd
+++ b/docs/html/design/patterns/actionbar.jd
@@ -1,5 +1,6 @@
 page.title=Action Bar
-page.tags=actionbar,navigation
+page.tags="actionbar","navigation"
+page.metaDescription=The Action bar is an essential design element for all apps. Learn about what the action bar can do and how to use it in your apps.
 @jd:body
 
 <img src="{@docRoot}design/media/action_bar_pattern_overview.png">
@@ -277,4 +278,4 @@
 <p>Sometimes it is important to display contextual information for your app that's always visible.
 Examples are the number of unread messages in a messaging inbox view or the Now Playing information
 in a music player. Carefully plan which important information you would like to display and
-structure your action bars accordingly.</p>
+structure your action bars accordingly.</p>
\ No newline at end of file
diff --git a/docs/html/design/patterns/compatibility.jd b/docs/html/design/patterns/compatibility.jd
index 5a1562c..dfc52c0 100644
--- a/docs/html/design/patterns/compatibility.jd
+++ b/docs/html/design/patterns/compatibility.jd
@@ -1,5 +1,6 @@
 page.title=Backwards Compatibility
-page.tags=support
+page.tags="support"
+page.metaDescription=Notes on how Android 4.x adapts UI designed for older hardware and OS versions.
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}training/basics/supporting-devices/index.html">
diff --git a/docs/html/design/patterns/help.jd b/docs/html/design/patterns/help.jd
index bf708b1..97949e2 100644
--- a/docs/html/design/patterns/help.jd
+++ b/docs/html/design/patterns/help.jd
@@ -6,7 +6,7 @@
 
 <p>Some of your users will run into questions or problems along the way. They'll be looking for answers <strong>within your app</strong>, and if they don't find them quickly, they may leave and never come back.</p>
 
-<p>This page covers design patterns for making help accessible in your app and tips for creating help content for users who are eager for assistance.</p>
+<p itemprop="description">This page covers design patterns for making help accessible in your app and tips for creating help content for users who are eager for assistance.</p>
 
 <h2 id="your-app">Designing Help into Your App</h2>
 
diff --git a/docs/html/design/patterns/index.jd b/docs/html/design/patterns/index.jd
index 4416de1..e091a29 100644
--- a/docs/html/design/patterns/index.jd
+++ b/docs/html/design/patterns/index.jd
@@ -18,7 +18,8 @@
 
 <div id="landing-graphic-container">
   <div id="text-overlay">
-    Design apps that behave in a consistent, predictable fashion.
+    <span itemprop="description">Design apps that behave in a consistent, predictable
+    fashion.</span>
     <br><br>
     <a href="{@docRoot}design/patterns/new.html" class="landing-page-link">New in Android</a>
   </div>
diff --git a/docs/html/design/patterns/multi-pane-layouts.jd b/docs/html/design/patterns/multi-pane-layouts.jd
index ff2dd4e..c207006 100644
--- a/docs/html/design/patterns/multi-pane-layouts.jd
+++ b/docs/html/design/patterns/multi-pane-layouts.jd
@@ -1,5 +1,6 @@
 page.title=Multi-pane Layouts
-page.tags=tablet,navigation,layout,fragment
+page.tags="tablet","navigation","layout","fragment"
+page.metaDescription=Android devices come in many different screen sizes and types. Multi-pane layouts help you provide a balanced and aesthetically pleasing layout across the range of Android devices.
 @jd:body
 
 
@@ -10,9 +11,11 @@
   </div>
 </a>
 
-<p>When writing an app for Android, keep in mind that Android devices come in many different screen
-sizes and types. Make sure that your app consistently provides a balanced and aesthetically pleasing
-layout by adjusting its content to varying screen sizes and orientations.</p>
+<p>When writing an app for Android, keep in mind that Android devices
+come in many different screen sizes and types. Make sure that your app consistently provides a
+balanced and aesthetically pleasing layout by adjusting its content to varying screen sizes and
+orientations.</p>
+
 <p><em>Panels</em> are a great way for your app to achieve this. They allow you to combine multiple views into
 one compound view when a lot of horizontal screen real estate is available and by splitting them up
 when less space is available.</p>
diff --git a/docs/html/design/patterns/navigation.jd b/docs/html/design/patterns/navigation.jd
index 08828e8..3edf6ba 100644
--- a/docs/html/design/patterns/navigation.jd
+++ b/docs/html/design/patterns/navigation.jd
@@ -9,7 +9,7 @@
   </div>
 </a>
 
-<p>Consistent navigation is an essential component of the overall user experience. Few things frustrate
+<p itemprop="description">Consistent navigation is an essential component of the overall user experience. Few things frustrate
 users more than basic navigation that behaves in inconsistent and unexpected ways. Android 3.0
 introduced significant changes to the global navigation behavior. Thoughtfully following the
 guidelines for Back and Up will make your app's navigation predictable and reliable for your users.</p>
diff --git a/docs/html/design/patterns/notifications.jd b/docs/html/design/patterns/notifications.jd
index 80f1b0e..41f9190 100644
--- a/docs/html/design/patterns/notifications.jd
+++ b/docs/html/design/patterns/notifications.jd
@@ -8,7 +8,7 @@
   </div>
 </a>
 
-<p>The notification system allows your app to keep the user informed about events, such as new chat messages or a calendar event. Think of notifications as a news channel that alerts the user to important events as they happen or a log that chronicles events while the user is not paying attention.</p>
+<p itemprop="description">The notification system allows your app to keep the user informed about events, such as new chat messages or a calendar event. Think of notifications as a news channel that alerts the user to important events as they happen or a log that chronicles events while the user is not paying attention.</p>
 
 <h4>New in Jelly Bean</h4>
 <p>In Jelly Bean, notifications received their most important structural and functional update since the beginning of Android.</p>
diff --git a/docs/html/design/patterns/selection.jd b/docs/html/design/patterns/selection.jd
index ee46795..be31677 100644
--- a/docs/html/design/patterns/selection.jd
+++ b/docs/html/design/patterns/selection.jd
@@ -35,9 +35,9 @@
   </div>
 </div>
 
-<h4>Using the contextual action bar (CAB)</h4>
-<p>The selection CAB is a temporary action bar that overlays your app's current action bar while data
-is selected. It appears after the user long presses on a selectable data item.</p>
+<h4>Using the contextual action bar</h4>
+<p itemprop="description">The contextual action bar (CAB) is a temporary action bar that overlays your app's current action bar while data
+is selected. It appears after the user long-presses on a selectable data item.</p>
 
 <img src="{@docRoot}design/media/selection_cab_big.png">
 
diff --git a/docs/html/design/patterns/settings.jd b/docs/html/design/patterns/settings.jd
index a09193d..e3a3f05 100644
--- a/docs/html/design/patterns/settings.jd
+++ b/docs/html/design/patterns/settings.jd
@@ -9,7 +9,7 @@
   </div>
 </a>
 
-<p>Settings is a place in your app where users indicate their preferences for how your app should
+<p itemprop="description">Settings is a place in your app where users indicate their preferences for how your app should
 behave. This benefits users because:</p>
 
 <ul>
diff --git a/docs/html/design/patterns/swipe-views.jd b/docs/html/design/patterns/swipe-views.jd
index 89397ae..af5c9dc 100644
--- a/docs/html/design/patterns/swipe-views.jd
+++ b/docs/html/design/patterns/swipe-views.jd
@@ -9,7 +9,7 @@
   </div>
 </a>
 
-<p>Efficient navigation is one of the cornerstones of a well-designed app. While apps are generally
+<p itemprop="description">Efficient navigation is one of the cornerstones of a well-designed app. While apps are generally
 built in a hierarchical fashion, there are instances where horizontal navigation can flatten
 vertical hierarchies and make access to related data items faster and more enjoyable. Swipe views
 allow the user to efficiently move from item to item using a simple gesture and thereby make
diff --git a/docs/html/design/patterns/widgets.jd b/docs/html/design/patterns/widgets.jd
index 953c125..654cf37 100644
--- a/docs/html/design/patterns/widgets.jd
+++ b/docs/html/design/patterns/widgets.jd
@@ -9,7 +9,7 @@
   </div>
 </a>
 
-<p>Widgets are an essential aspect of home screen customization. You can imagine them as "at-a-glance" views of an app's most important data and functionality that is accessible right from the user's home screen. Users can move widgets across their home screen panels, and, if supported, resize them to tailor the amount of information within a widget to their preference.</p>
+<p itemprop="description">Widgets are an essential aspect of home screen customization. You can imagine them as "at-a-glance" views of an app's most important data and functionality that is accessible right from the user's home screen. Users can move widgets across their home screen panels, and, if supported, resize them to tailor the amount of information within a widget to their preference.</p>
 
 <h2>Widget types</h2>
 <p>As you begin planning your widget, think about what kind of widget you're trying to build. Widgets typically fall into one of the following categories:</p>
diff --git a/docs/html/design/style/iconography.jd b/docs/html/design/style/iconography.jd
index 5dde600..d8d8c76 100644
--- a/docs/html/design/style/iconography.jd
+++ b/docs/html/design/style/iconography.jd
@@ -1,5 +1,7 @@
 page.title=Iconography
-page.tags=icons
+page.tags="icons"
+meta.tags="icons, googleplay, listing, branding"
+page.titleFriendly=Guidelines for creating your app's icons
 @jd:body
 
 <img src="{@docRoot}design/media/iconography_overview.png">
diff --git a/docs/html/design/style/index.jd b/docs/html/design/style/index.jd
index 74d085b..f88fdb8 100644
--- a/docs/html/design/style/index.jd
+++ b/docs/html/design/style/index.jd
@@ -18,7 +18,8 @@
 
 <div id="landing-graphic-container">
   <div id="text-overlay">
-    Build visually compelling apps that look great on any device. 
+    <span itemprop="description">Build visually compelling apps that look great on any
+    device.</span>
     <br><br>
     <a href="{@docRoot}design/style/devices-displays.html" class="landing-page-link">Devices and Displays</a>
   </div>
diff --git a/docs/html/distribute/googleplay/spotlight/index.jd b/docs/html/distribute/googleplay/spotlight/index.jd
index 6f92c78b..fc2e162 100644
--- a/docs/html/distribute/googleplay/spotlight/index.jd
+++ b/docs/html/distribute/googleplay/spotlight/index.jd
@@ -1,4 +1,7 @@
 page.title=Spotlight
+page.tags="videos, google play, monetize, inapp"
+meta.tags="stories, googleplay, monetizing, landing"
+page.image=/images/video-kiwi.jpg
 walkthru=0
 header.hide=0
 
@@ -26,7 +29,7 @@
           <div style="width:700px;">
           <p style="margin-top:26px;
                     margin-bottom:12px;">
-          Android-first developer <a href="//play.google.com/store/apps/developer?id=Kiwi,+Inc." target="_android">Kiwi, Inc.</a> has five of the top 25 grossing games on Google Play, including <a href="https://play.google.com/store/apps/details?id=com.kiwi.shipwrecked" target="_android">Shipwrecked: Lost Island</a>, <a href="https://play.google.com/store/apps/details?id=com.kiwi.monsterpark" target="_android">Monsterama Park</a>, and <a href="https://play.google.com/store/apps/details?id=com.kiwi.mysteryestate" target="_android">Hidden Object: Mystery Estate</a>. Hear how Google Play helped them double revenue every six months with features like instant updates, staged rollouts, and more.</p>
+          Android-first developer <a href="//play.google.com/store/apps/developer?id=Kiwi,+Inc." target="_android">Kiwi, Inc.</a> has had 5 titles in the top 25 grossing on Google Play, including <a href="https://play.google.com/store/apps/details?id=com.kiwi.shipwrecked" target="_android">Shipwrecked: Lost Island</a>, <a href="https://play.google.com/store/apps/details?id=com.kiwi.monsterpark" target="_android">Monsterama Park</a>, and <a href="https://play.google.com/store/apps/details?id=com.kiwi.mysteryestate" target="_android">Hidden Object: Mystery Estate</a>. Hear how Google Play helped them double revenue every six months with features like instant updates, staged rollouts, and more.</p>
            </div>
            <iframe style="float:left;
              margin-right:24px;
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 18b234e..73d5b74 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -367,6 +367,9 @@
             <li><a href="<?cs var:toroot ?>guide/topics/media/mediaplayer.html">
                   <span class="en">Media Playback</span></a>
                 </li>
+            <li><a href="<?cs var:toroot ?>guide/topics/media/mediarouter.html">
+                  <span class="en">MediaRouter</span></a>
+                </li>
             <li><a href="<?cs var:toroot ?>guide/appendix/media-formats.html">
                    <span class="en">Supported Media Formats</span></a>
                 </li>
diff --git a/docs/html/guide/topics/manifest/action-element.jd b/docs/html/guide/topics/manifest/action-element.jd
index 037d0dc..54ee6ae 100644
--- a/docs/html/guide/topics/manifest/action-element.jd
+++ b/docs/html/guide/topics/manifest/action-element.jd
@@ -12,7 +12,7 @@
 
 <p>
 <dt>description:</dt>
-<dd>Adds an action to an intent filter. 
+<dd itemprop="description">Adds an action to an intent filter.
 An <code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code> element must contain 
 one or more {@code &lt;action&gt;} elements.  If it doesn't contain any, no
 Intent objects will get through the filter.  See 
diff --git a/docs/html/guide/topics/manifest/activity-alias-element.jd b/docs/html/guide/topics/manifest/activity-alias-element.jd
index d3df08b..343b02e 100644
--- a/docs/html/guide/topics/manifest/activity-alias-element.jd
+++ b/docs/html/guide/topics/manifest/activity-alias-element.jd
@@ -23,7 +23,7 @@
 <br/><code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>An alias for an activity, named by the {@code targetActivity} 
+<dd itemprop="description">An alias for an activity, named by the {@code targetActivity}
 attribute.  The target must be in the same application as the
 alias and it must be declared before the alias in the manifest.
 
diff --git a/docs/html/guide/topics/manifest/activity-element.jd b/docs/html/guide/topics/manifest/activity-element.jd
index 8df1fdf..bd1edc2 100644
--- a/docs/html/guide/topics/manifest/activity-element.jd
+++ b/docs/html/guide/topics/manifest/activity-element.jd
@@ -54,7 +54,7 @@
 <br/><code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Declares an activity (an {@link android.app.Activity} subclass) that
+<dd itemprop="description">Declares an activity (an {@link android.app.Activity} subclass) that
 implements part of the application's visual user interface.  All activities
 must be represented by {@code &lt;activity&gt;}
 elements in the manifest file.  Any that are not declared there will not be seen
diff --git a/docs/html/guide/topics/manifest/application-element.jd b/docs/html/guide/topics/manifest/application-element.jd
index 46500aa..28deed9 100644
--- a/docs/html/guide/topics/manifest/application-element.jd
+++ b/docs/html/guide/topics/manifest/application-element.jd
@@ -47,7 +47,7 @@
 <br/><code><a href="{@docRoot}guide/topics/manifest/uses-library-element.html">&lt;uses-library&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>The declaration of the application.  This element contains subelements 
+<dd itemprop="description">The declaration of the application.  This element contains subelements
 that declare each of the application's components and has attributes 
 that can affect all the components.  Many of these attributes (such as 
 {@code icon}, {@code label}, {@code permission}, {@code process}, 
diff --git a/docs/html/guide/topics/manifest/category-element.jd b/docs/html/guide/topics/manifest/category-element.jd
index a4b93ee..563ed10 100644
--- a/docs/html/guide/topics/manifest/category-element.jd
+++ b/docs/html/guide/topics/manifest/category-element.jd
@@ -11,7 +11,7 @@
 <dd><code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Adds a category name to an intent filter.  See 
+<dd itemprop="description">Adds a category name to an intent filter.  See
 <a href="{@docRoot}guide/components/intents-filters.html">Intents and 
 Intent Filters</a> for details on intent filters and the role of category
 specifications within a filter.</dd>
diff --git a/docs/html/guide/topics/manifest/compatible-screens-element.jd b/docs/html/guide/topics/manifest/compatible-screens-element.jd
index 00cbfe5..3606b15 100644
--- a/docs/html/guide/topics/manifest/compatible-screens-element.jd
+++ b/docs/html/guide/topics/manifest/compatible-screens-element.jd
@@ -20,7 +20,7 @@
 href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Specifies each screen configuration with which the application is compatible. Only one instance
+<dd itemprop="description">Specifies each screen configuration with which the application is compatible. Only one instance
 of the {@code &lt;compatible-screens&gt;} element is allowed in the manifest, but it can
 contain multiple <code>&lt;screen&gt;</code> elements. Each <code>&lt;screen&gt;</code> element
 specifies a specific screen size-density combination with which the application is compatible.
diff --git a/docs/html/guide/topics/manifest/data-element.jd b/docs/html/guide/topics/manifest/data-element.jd
index 27950d0..ecba508 100644
--- a/docs/html/guide/topics/manifest/data-element.jd
+++ b/docs/html/guide/topics/manifest/data-element.jd
@@ -18,7 +18,7 @@
 <dd><code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Adds a data specification to an intent filter.  The specification can
+<dd itemprop="description">Adds a data specification to an intent filter.  The specification can
 be just a data type (the <code><a href="{@docRoot}guide/topics/manifest/data-element.html#mime">mimeType</a></code> attribute),
 just a URI, or both a data type and a URI.  A URI is specified by separate
 attributes for each of its parts:
diff --git a/docs/html/guide/topics/manifest/grant-uri-permission-element.jd b/docs/html/guide/topics/manifest/grant-uri-permission-element.jd
index dc98cbb..2179359 100644
--- a/docs/html/guide/topics/manifest/grant-uri-permission-element.jd
+++ b/docs/html/guide/topics/manifest/grant-uri-permission-element.jd
@@ -13,7 +13,7 @@
 <dd><code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Specifies which data subsets of the parent content provider permission
+<dd itemprop="description">Specifies which data subsets of the parent content provider permission
 can be granted for.  Data subsets are indicated by the path part of a 
 {@code content:} URI.  (The authority part of the URI identifies the
 content provider.)  
diff --git a/docs/html/guide/topics/manifest/instrumentation-element.jd b/docs/html/guide/topics/manifest/instrumentation-element.jd
index 9408b84..74be559 100644
--- a/docs/html/guide/topics/manifest/instrumentation-element.jd
+++ b/docs/html/guide/topics/manifest/instrumentation-element.jd
@@ -16,7 +16,7 @@
 <dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Declares an {@link android.app.Instrumentation} class that enables you
+<dd itemprop="description">Declares an {@link android.app.Instrumentation} class that enables you
 to monitor an application's interaction with the system.  The Instrumentation
 object is instantiated before any of the application's components.</dd>
 
diff --git a/docs/html/guide/topics/manifest/intent-filter-element.jd b/docs/html/guide/topics/manifest/intent-filter-element.jd
index 68da981..14b4e03 100644
--- a/docs/html/guide/topics/manifest/intent-filter-element.jd
+++ b/docs/html/guide/topics/manifest/intent-filter-element.jd
@@ -25,7 +25,7 @@
 <br/><code><a href="{@docRoot}guide/topics/manifest/data-element.html">&lt;data&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Specifies the types of intents that an activity, service, or broadcast 
+<dd itemprop="description">Specifies the types of intents that an activity, service, or broadcast
 receiver can respond to.  An intent filter declares the capabilities of its
 parent component &mdash; what an activity or service can do and what types 
 of broadcasts a receiver can handle.  It opens the component to receiving 
diff --git a/docs/html/guide/topics/manifest/manifest-element.jd b/docs/html/guide/topics/manifest/manifest-element.jd
index 12690d2..20dc4ea 100644
--- a/docs/html/guide/topics/manifest/manifest-element.jd
+++ b/docs/html/guide/topics/manifest/manifest-element.jd
@@ -39,7 +39,7 @@
 
 <p>
 <dt>description:</dt>
-<dd>The root element of the AndroidManifest.xml file.  It must 
+<dd itemprop="description">The root element of the AndroidManifest.xml file.  It must
 contain an <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element 
 and specify {@code xmlns:android} and {@code package} attributes.</dd>
 
diff --git a/docs/html/guide/topics/manifest/manifest-intro.jd b/docs/html/guide/topics/manifest/manifest-intro.jd
index 76fe2a2..d2a9308 100644
--- a/docs/html/guide/topics/manifest/manifest-intro.jd
+++ b/docs/html/guide/topics/manifest/manifest-intro.jd
@@ -20,11 +20,11 @@
 </div>
 
 <p>
-Every application must have an AndroidManifest.xml file (with precisely that 
-name) in its root directory.  The manifest presents essential information about 
-the application to the Android system, information the system must have before 
-it can run any of the application's code.  Among other things, the manifest 
-does the following:
+  Every application must have an AndroidManifest.xml file (with precisely that
+  name) in its root directory. <span itemprop="description">The manifest file
+  presents essential information about your app to the Android system,
+  information the system must have before it can run any of the app's
+  code.</span> Among other things, the manifest does the following:
 </p>
 
 <ul>
diff --git a/docs/html/guide/topics/manifest/meta-data-element.jd b/docs/html/guide/topics/manifest/meta-data-element.jd
index ee80c84..241153b 100644
--- a/docs/html/guide/topics/manifest/meta-data-element.jd
+++ b/docs/html/guide/topics/manifest/meta-data-element.jd
@@ -18,7 +18,7 @@
 <br/><code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>
 
 <dt>description:</dt>
-<dd>A name-value pair for an item of additional, arbitrary data that can 
+<dd itemprop="description">A name-value pair for an item of additional, arbitrary data that can
 be supplied to the parent component.  A component element can contain any 
 number of {@code &lt;meta-data&gt;} subelements.  The values from all of
 them are collected in a single {@link android.os.Bundle} object and made 
diff --git a/docs/html/guide/topics/manifest/path-permission-element.jd b/docs/html/guide/topics/manifest/path-permission-element.jd
index e644d68..cdaf82b 100644
--- a/docs/html/guide/topics/manifest/path-permission-element.jd
+++ b/docs/html/guide/topics/manifest/path-permission-element.jd
@@ -23,7 +23,7 @@
 -->
 
 <dt>description:</dt>
-<dd>Defines the path and required permissions for a specific subset of data
+<dd itemprop="description">Defines the path and required permissions for a specific subset of data
 within a content provider. This element can be
 specified multiple times to supply multiple paths.
 
diff --git a/docs/html/guide/topics/manifest/permission-element.jd b/docs/html/guide/topics/manifest/permission-element.jd
index a23fb4b..4bb5f6a 100644
--- a/docs/html/guide/topics/manifest/permission-element.jd
+++ b/docs/html/guide/topics/manifest/permission-element.jd
@@ -17,7 +17,7 @@
 <dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Declares a security permission that can be used to limit access 
+<dd itemprop="description">Declares a security permission that can be used to limit access
 to specific components or features of this or other applications.  
 See the <a href="{@docRoot}guide/topics/manifest/manifest-intro.html#perms">Permissions</a>
 section in the introduction,
diff --git a/docs/html/guide/topics/manifest/permission-group-element.jd b/docs/html/guide/topics/manifest/permission-group-element.jd
index fc1de1f..3221d4b 100644
--- a/docs/html/guide/topics/manifest/permission-group-element.jd
+++ b/docs/html/guide/topics/manifest/permission-group-element.jd
@@ -14,7 +14,7 @@
 <dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Declares a name for a logical grouping of related permissions.  Individual 
+<dd itemprop="description">Declares a name for a logical grouping of related permissions.  Individual
 permission join the group through the {@code permissionGroup} attribute of the
 <code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code> element.  Members of a group are
 presented together in the user interface.
diff --git a/docs/html/guide/topics/manifest/permission-tree-element.jd b/docs/html/guide/topics/manifest/permission-tree-element.jd
index a9c00cd..21d7352 100644
--- a/docs/html/guide/topics/manifest/permission-tree-element.jd
+++ b/docs/html/guide/topics/manifest/permission-tree-element.jd
@@ -13,7 +13,7 @@
 <dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Declares the base name for a tree of permissions.  The application takes 
+<dd itemprop="description">Declares the base name for a tree of permissions.  The application takes
 ownership of all names within the tree.  It can dynamically add new permissions 
 to the tree by calling <code>{@link android.content.pm.PackageManager#addPermission PackageManager.addPermission()}</code>.  Names within the tree are separated by
 periods ('{@code .}').  For example, if the base name is
diff --git a/docs/html/guide/topics/manifest/provider-element.jd b/docs/html/guide/topics/manifest/provider-element.jd
index 6cf6843..f3ffd58 100644
--- a/docs/html/guide/topics/manifest/provider-element.jd
+++ b/docs/html/guide/topics/manifest/provider-element.jd
@@ -36,7 +36,7 @@
 <br/><code><a href="{@docRoot}guide/topics/manifest/path-permission-element.html">&lt;path-permission&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>
+<dd itemprop="description">
     Declares a content provider component. A content provider is a subclass of 
     {@link android.content.ContentProvider} that supplies structured access to data managed by the 
     application.  All content providers in your application must be defined in a 
diff --git a/docs/html/guide/topics/manifest/receiver-element.jd b/docs/html/guide/topics/manifest/receiver-element.jd
index 8416c0c..df2437e 100644
--- a/docs/html/guide/topics/manifest/receiver-element.jd
+++ b/docs/html/guide/topics/manifest/receiver-element.jd
@@ -23,7 +23,7 @@
 <br/><code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Declares a broadcast receiver (a {@link android.content.BroadcastReceiver} 
+<dd itemprop="description">Declares a broadcast receiver (a {@link android.content.BroadcastReceiver}
 subclass) as one of the application's components.  Broadcast receivers enable 
 applications to receive intents that are broadcast by the system or by other 
 applications, even when other components of the application are not running.
diff --git a/docs/html/guide/topics/manifest/service-element.jd b/docs/html/guide/topics/manifest/service-element.jd
index 14eed67..2213b72 100644
--- a/docs/html/guide/topics/manifest/service-element.jd
+++ b/docs/html/guide/topics/manifest/service-element.jd
@@ -24,7 +24,7 @@
 <br/><code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Declares a service (a {@link android.app.Service} subclass) as one 
+<dd itemprop="description">Declares a service (a {@link android.app.Service} subclass) as one
 of the application's components.  Unlike activities, services lack a 
 visual user interface.  They're used to implement long-running background 
 operations or a rich communications API that can be called by other 
diff --git a/docs/html/guide/topics/manifest/supports-gl-texture-element.jd b/docs/html/guide/topics/manifest/supports-gl-texture-element.jd
index fa39317..ab751c2 100644
--- a/docs/html/guide/topics/manifest/supports-gl-texture-element.jd
+++ b/docs/html/guide/topics/manifest/supports-gl-texture-element.jd
@@ -34,7 +34,7 @@
 <dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Declares a single GL texture compression format that is supported by
+<dd itemprop="description">Declares a single GL texture compression format that is supported by
 the application.
 
 <p>An application "supports" a GL texture compression format if it is capable of
diff --git a/docs/html/guide/topics/manifest/supports-screens-element.jd b/docs/html/guide/topics/manifest/supports-screens-element.jd
index ae14121..bbeceb7 100644
--- a/docs/html/guide/topics/manifest/supports-screens-element.jd
+++ b/docs/html/guide/topics/manifest/supports-screens-element.jd
@@ -24,7 +24,7 @@
 <dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Lets you specify the screen sizes your application supports and enable <a
+<dd itemprop="description">Lets you specify the screen sizes your application supports and enable <a
 href="{@docRoot}guide/practices/screen-compat-mode.html">screen compatibility mode</a> for screens
 larger than what your application supports. It's important that you always use this element in your
 application to specify the screen sizes your application supports.
diff --git a/docs/html/guide/topics/manifest/uses-configuration-element.jd b/docs/html/guide/topics/manifest/uses-configuration-element.jd
index e9a0ba4..15fd49c1 100644
--- a/docs/html/guide/topics/manifest/uses-configuration-element.jd
+++ b/docs/html/guide/topics/manifest/uses-configuration-element.jd
@@ -27,7 +27,7 @@
 <dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Indicates what hardware and software features the application requires.
+<dd itemprop="description">Indicates what hardware and software features the application requires.
 For example, an application might specify that it requires a physical keyboard
 or a particular navigation device, like a trackball.  The specification is
 used to avoid installing the application on devices where it will not work.
diff --git a/docs/html/guide/topics/manifest/uses-feature-element.jd b/docs/html/guide/topics/manifest/uses-feature-element.jd
index 884eeb5..4057736 100644
--- a/docs/html/guide/topics/manifest/uses-feature-element.jd
+++ b/docs/html/guide/topics/manifest/uses-feature-element.jd
@@ -62,7 +62,7 @@
 href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Declares a single hardware or software feature that is used by the
+<dd itemprop="description">Declares a single hardware or software feature that is used by the
 application.
 
 <p>The purpose of a <code>&lt;uses-feature&gt;</code> declaration is to inform
@@ -549,11 +549,15 @@
 </td>
     </tr>
     <tr>
-       <td>Bluetooth</td>
-       <td><code>android.hardware.bluetooth</td>
+       <td rowspan="2">Bluetooth</td>
+       <td><code>android.hardware.bluetooth</code></td>
        <td>The application uses Bluetooth radio features in the device.</td>
-       <td>If your app uses Bluetooth Low Energy, also declare
-       {@code android.software.bluetooth_le}.</td>
+       <td></td>
+    </tr>
+    <tr>
+       <td><code>android.hardware.bluetooth_le</code></td>
+       <td>The application uses Bluetooth Low Energy radio features in the device.</td>
+       <td></td>
     </tr>
     <tr>
        <td rowspan="5">Camera</td>
@@ -586,6 +590,13 @@
 </tr>
 
 <tr>
+  <td>Infrared</td>
+  <td><code>android.hardware.consumerir</code></td>
+  <td>The application uses the consumer IR capabilities on the device.</td>
+  <td></td>
+</tr>
+
+<tr>
   <td rowspan="3">Location</td>
   <td><code>android.hardware.location</code></td>
   <td>The application uses one or more features on the device for determining
@@ -613,13 +624,18 @@
   <td></td>
 </tr>
 <tr>
-  <td>NFC</td>
+  <td rowspan="2">NFC</td>
   <td><code>android.hardware.nfc</td>
   <td>The application uses Near Field Communications radio features in the device.</td>
   <td></td>
 </tr>
 <tr>
-  <td rowspan="6">Sensors</td>
+  <td><code>android.hardware.nfc.hce</code></td>
+  <td>The application uses the NFC card emulation feature in the device.</td>
+  <td></td>
+</tr>
+<tr>
+  <td rowspan="8">Sensors</td>
   <td><code>android.hardware.sensor.accelerometer</code></td>
   <td>The application uses motion readings from an accelerometer on the
 device.</td>
@@ -651,6 +667,16 @@
   <td>The application uses the device's proximity sensor.</td>
   <td></td>
 </tr>
+<tr>
+  <td><code>android.hardware.sensor.stepcounter</code></td>
+  <td>The application uses the device's step counter.</td>
+  <td></td>
+</tr>
+<tr>
+  <td><code>android.hardware.sensor.stepdetector</code></td>
+  <td>The application uses the device's step detector.</td>
+  <td></td>
+</tr>
 
 <tr>
   <td rowspan="2">Screen</td>
@@ -828,11 +854,15 @@
 </tr>
 
 <tr>
-  <td>Wifi</td>
+  <td rowspan="2">Wi-Fi</td>
   <td><code>android.hardware.wifi</code></td>
-  <td>The application uses 802.11 networking (wifi) features on the device.</td>
+  <td>The application uses 802.11 networking (Wi-Fi) features on the device.</td>
   <td></td>
 </tr>
+<tr>
+  <td><code>android.hardware.wifi.direct</code></td>
+  <td>The application uses the Wi-Fi Direct networking features on the device.</td>
+</tr>
 
   </table>
 
@@ -857,11 +887,9 @@
   that include a Home screen or similar location where users can embed App Widgets.</td>
 </tr>
 <tr>
-  <td>Bluetooth Low Energy</td>
-  <td><code>android.software.bluetooth_le</code></td>
-  <td><p>The application uses Bluetooth Low Energy APIs and should be installed only on devices
-  that are capable of communicating with other devices via Bluetooth Low Energy.
-   <p>This implicitly also declares the {@code android.hardware.bluetooth} feature.</td>
+  <td>Device Management</td>
+  <td><code>android.software.device_admin</code></td>
+  <td>The application uses device policy enforcement via device administrators.</td>
 </tr>
 <tr>
   <td>Home Screen</td>
@@ -1056,7 +1084,7 @@
 </tr>
 
 <tr>
-  <td rowspan="3">Wifi</td>
+  <td rowspan="3">Wi-Fi</td>
   <td><code>ACCESS_WIFI_STATE</code></td>
   <td><code>android.hardware.wifi</code></td>
 <!--  <td></td> -->
diff --git a/docs/html/guide/topics/manifest/uses-library-element.jd b/docs/html/guide/topics/manifest/uses-library-element.jd
index 253807e..aa7ca82 100644
--- a/docs/html/guide/topics/manifest/uses-library-element.jd
+++ b/docs/html/guide/topics/manifest/uses-library-element.jd
@@ -31,7 +31,7 @@
     </code>
 </dd>
 <dt>description:</dt>
-<dd>
+<dd itemprop="descridption">
     Specifies a shared library that the application must be linked against.
     This element tells the system to include the library's code in the class
     loader for the package.
diff --git a/docs/html/guide/topics/manifest/uses-permission-element.jd b/docs/html/guide/topics/manifest/uses-permission-element.jd
index bd7091e..9394114 100644
--- a/docs/html/guide/topics/manifest/uses-permission-element.jd
+++ b/docs/html/guide/topics/manifest/uses-permission-element.jd
@@ -42,7 +42,7 @@
 <dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Requests a permission that the application must be granted in 
+<dd itemprop="description">Requests a permission that the application must be granted in
 order for it to operate correctly.  Permissions are granted by the user when the 
 application is installed, not while it's running.
 
diff --git a/docs/html/guide/topics/manifest/uses-sdk-element.jd b/docs/html/guide/topics/manifest/uses-sdk-element.jd
index c88e6be..79a37f0 100644
--- a/docs/html/guide/topics/manifest/uses-sdk-element.jd
+++ b/docs/html/guide/topics/manifest/uses-sdk-element.jd
@@ -48,7 +48,7 @@
 <dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>Lets you express an application's compatibility with one or more versions of the Android platform,
+<dd itemprop="description"><p>  Lets you express an application's compatibility with one or more versions of the Android platform,
 by means of an API Level integer. The API Level expressed by an application will be compared to the
 API Level of a given Android system, which may vary among different Android devices.
 </p>
diff --git a/docs/html/guide/topics/media/mediarouter.jd b/docs/html/guide/topics/media/mediarouter.jd
new file mode 100644
index 0000000..1b10265
--- /dev/null
+++ b/docs/html/guide/topics/media/mediarouter.jd
@@ -0,0 +1,670 @@
+page.title=MediaRouter
+page.tags="cast","chromecast","wireless display","miracast"
+@jd:body
+
+<div id="qv-wrapper">
+  <div id="qv">
+    <h2>In this document</h2>
+    <ol>
+      <li><a href="#overview">Overview</a>
+        <ol>
+          <li><a href="#mr-packages">Media router packages</a></li>
+        </ol>
+      </li>
+      <li><a href="#cast-ui">Cast User Interface</a>
+        <ol>
+          <li><a href="#cast-button">Cast button</a></li>
+          <li><a href="#selector">Media route selector</a></li>
+        </ol>
+      </li>
+      <li><a href="#media-routes">Connecting to Media Routes</a>
+        <ol>
+          <li><a href="#create-mr-callback">Creating a MediaRouter callback</a></li>
+          <li><a href="#attach-mr-callback">Attaching a callback to MediaRouter</a></li>
+        </ol>
+      <li><a href="#remote-playback">Remote Playback</a></li>
+      <li><a href="#secondary-output">Secondary Output</a>
+        <ol>
+          <li><a href="#pres-obj">Creating a Presentation object</a></li>
+          <li><a href="#pres-cntrlr">Creating a Presentation controller</a></li>
+        </ol>
+      </li>
+    </ol>
+    <h2>Key Classes</h2>
+    <ol>
+      <li>{@link android.support.v7.media.MediaRouter}</li>
+      <li>{@link android.support.v7.media.MediaRouter.Callback}</li>
+      <li>{@link android.support.v7.media.MediaRouteProvider}</li>
+    </ol>
+  </div>
+</div>
+
+<p>As users connect their televisions, home theater systems and music players with wireless
+  technologies, they want to be able to play content from Android apps on these larger,
+  louder devices. Enabling this kind of playback can turn your one-device, one-user app
+  into a shared experience that delights and inspires multiple users.</p>
+
+<p>The Android media router APIs are designed to enable media display and playback on these
+  secondary devices. There are two main approaches you can use to play content using these
+  APIs:</p>
+
+<ul>
+  <li><strong>Remote Playback</strong>  &mdash; This approach uses the receiving device to handle
+  the content data retrieval, decoding, and playback, while an Android device in the user's hand
+  is used as a remote control. This approach is used by Android apps that support
+  <a href="https://developers.google.com/cast/">Google Cast</a>.</li>
+  <li><strong>Secondary Output</strong> &mdash; With this approach, your app retrieves, renders
+  and streams video or music directly to the receiving device. This approach is used to support
+  Wireless Display output
+  on Android.</li>
+</ul>
+
+<p>This guide explains how your app can deliver media to secondary playback devices using either
+  of these approaches.</p>
+
+
+<h2 id="overview">Overview</h2>
+
+<p>The media router APIs enable a broad range of media output to playback equipment connected to
+  Android devices through wireless and wired means. To enable these connections,
+  the media router framework abstracts the logical paths for audio and video output for an Android
+  device. This architecture allows your app to quickly channel media content to
+  connected playback devices such as home theaters and sound systems that provide Android media
+  route support.</p>
+
+<p>In order to use this framework within your app, you must get an instance
+  of the {@link android.support.v7.media.MediaRouter} framework object and attach a {@link
+  android.support.v7.media.MediaRouter.Callback} object to listen for events in
+  available media routes. Content channelled through a media route passes through the route's
+  associated {@link android.support.v7.media.MediaRouteProvider} (except in a few special cases,
+  such as a Bluetooth output device). The following diagram provides a high-level view of the
+  classes your app can use to play content with the media router framework.
+</p>
+
+<img src="{@docRoot}images/mediarouter/mediarouter-framework.png" alt="" id="figure1"/>
+<p class="img-caption">
+  <strong>Figure 1.</strong> Overview of key media router classes used by apps.
+</p>
+
+<p>Manufacturers of media playback hardware that is not supported by the media router framework
+  can add support for their devices by implementing a
+  {@link android.support.v7.media.MediaRouteProvider} and distributing it as an application.
+  For more information on implementing a media route provider, see the {@link
+  android.support.v7.media.MediaRouteProvider} reference documentation and the v7-mediarouter
+  support library sample {@code &lt;sdk&gt;/extras/android/compatibility/v7/mediarouter}.
+</p>
+
+
+<h3 id="mr-packages">Media router packages</h3>
+
+<p>The media router APIs are provided as part of the Android Support Library version 18 and
+  higher, in the
+  <a href="{@docRoot}tools/support-library/features.html#v7-mediarouter">v7-mediarouter support
+  library</a>. Specifically, you should use the classes in the {@link android.support.v7.media}
+  package for media router functions. These APIs are compatible with devices running Android 2.1
+  (API level 7) and higher.
+</p>
+
+<p class="note">
+  <strong>Note:</strong> There is another set of media router APIs provided in the
+  {@link android.media} that have been superseded by the v7-mediarouter support library.
+  You <em>should not</em> use the {@link android.media} classes for media router functions.
+</p>
+
+<p>In order to use the {@link android.support.v7.media} media router classes, you must add
+  the <a href="{@docRoot}tools/support-library/features.html#v7-mediarouter">v7-mediarouter
+  support library package</a> to your app development project.
+</p>
+
+
+<h2 id="cast-ui">Cast User Interface</h2>
+
+<p>
+  Android apps that implement the media router API should include a Cast button
+  as part of their user interface, to allow users to select a media route to play media on
+  a secondary output device. The media router framework provides a standard interface for
+  the button, which you should use to help users recognize and use the feature in your app.
+  Figure 2 illustrates how the Cast button should appear in an app.
+</p>
+
+<img src="{@docRoot}images/mediarouter/mediarouter-actionbar.png" alt="" width="428" id="figure2"/>
+<p class="img-caption">
+  <strong>Figure 2.</strong> A Cast button shown on the right side of the action bar.
+</p>
+
+<p class="caution">
+  <strong>Caution:</strong> When implementing an activity that provides a media router interface
+  you <em>must</em> extend either {@link android.support.v7.app.ActionBarActivity}
+  or {@link android.support.v4.app.FragmentActivity} from the Android Support Library, even if
+  your {@code android:minSdkVersion} is API 11 or higher.
+</p>
+
+
+<h3 id="cast-button">Cast button</h3>
+
+<p>The recommended way to implement the Cast button user interface is to extend your activity
+  from {@link android.support.v7.app.ActionBarActivity} and use the {@link
+  android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} method to add an options menu.
+  The Cast button must use the {@link android.support.v7.app.MediaRouteActionProvider} class
+  as its action:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"
+      xmlns:app="http://schemas.android.com/apk/res-auto"
+      &gt;
+
+    &lt;item android:id="@+id/media_route_menu_item"
+        android:title="@string/media_route_menu_title"
+        <strong>app:actionProviderClass="android.support.v7.app.MediaRouteActionProvider"</strong>
+        app:showAsAction="always"
+    /&gt;
+&lt;/menu&gt;
+</pre>
+
+<p>For more information about implementing the action bar in your app,
+  see the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a>
+  developer guide.
+</p>
+
+<p>Once you have added the Cast button to your user interface, you must attach a media
+  route selector object. Building a selector is discussed in the next section.
+</p>
+
+<p>If you do not want a menu in your action bar, you can also add a Cast button to your app using
+  {@link android.support.v7.app.MediaRouteButton}. If you choose this approach, you should add
+  this button to your app's action bar according to the
+  <a href="https://developers.google.com/cast/docs/design_checklist">Google Cast Design
+  Checklist</a>. You must also attach a media route selector to the button using the
+  {@link android.support.v7.app.MediaRouteButton#setRouteSelector setRouteSelector()} method.
+</p>
+
+<p>For guidelines on incorporating the Cast button into your application, review the
+  <a href="https://developers.google.com/cast/docs/design_checklist">Google Cast Design
+  Checklist</a>.</p>
+
+
+<h3 id="selector">Media route selector</h3>
+
+<p>When a user presses the Cast button, the media router framework looks for available media
+  routes and presents a list of choices to the user, as shown in figure 3.</p>
+
+<img src="{@docRoot}images/mediarouter/mediarouter-selector-ui.png" alt="" width="500" id="figure3"/>
+<p class="img-caption">
+  <strong>Figure 3.</strong> A list of available media routes, shown after pressing the Cast button.
+</p>
+
+
+<p>The <em>types</em> of media routes that appear on this list&mdash;Remote Playback, Secondary
+  Output or others&mdash;are defined by your app.You define these type by creating a {@link
+  android.support.v7.media.MediaRouteSelector}, which accepts {@link
+  android.support.v7.media.MediaControlIntent} objects provided by the framework and other media
+  route providers created by you or other developers. The framework-provided route categories are as
+  follows:
+</p>
+
+<ul>
+  <li>{@link android.support.v7.media.MediaControlIntent#CATEGORY_LIVE_AUDIO
+    CATEGORY_LIVE_AUDIO} &mdash; Output of audio to a secondary output device, such as a
+    wireless-enabled music system.</li>
+  <li>{@link android.support.v7.media.MediaControlIntent#CATEGORY_LIVE_VIDEO
+    CATEGORY_LIVE_VIDEO} &mdash; Output of video to a secondary output device, such as Wireless
+    Display devices.</li>
+  <li>{@link android.support.v7.media.MediaControlIntent#CATEGORY_REMOTE_PLAYBACK
+    CATEGORY_REMOTE_PLAYBACK} &mdash; Play video or audio on a separate device that supports the
+    <a href="https://developers.google.com/cast/">Google Cast</a> remote control protocol, such
+    as <a href="https://www.google.com/url?q=http://www.google.com/chromecast">Chromecast</a>.
+    </li>
+</ul>
+
+<p>When creating a {@link android.support.v7.media.MediaRouteSelector} object, use the
+  {@link android.support.v7.media.MediaRouteSelector.Builder} class to create the object and set
+  the media playback categories (control categories), as shown
+  in the following code sample:</p>
+
+<pre>
+public class MediaRouterPlaybackActivity extends ActionBarActivity {
+    private MediaRouteSelector mSelector;
+
+    &#64;Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        // Create a route selector for the type of routes your app supports.
+        <strong>mSelector = new MediaRouteSelector.Builder()
+                // These are the framework-supported intents
+                .addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
+                .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
+                .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)</strong>
+                .build();
+    }
+}
+</pre>
+
+<p>The media router framework uses this selector object to provide an interface for selecting
+  media routes that your app supports, as shown in figure 3. Once you have defined this selector,
+  you attach it to the {@link android.support.v7.app.MediaRouteActionProvider} object associated
+  with the Cast menu item, as shown in the following code sample:</p>
+
+<pre>
+&#64;Override
+public boolean onCreateOptionsMenu(Menu menu) {
+    super.onCreateOptionsMenu(menu);
+
+    // Inflate the menu and configure the media router action provider.
+    getMenuInflater().inflate(R.menu.sample_media_router_menu, menu);
+
+    // Attach the MediaRouteSelector to the menu item
+    MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item);
+    MediaRouteActionProvider mediaRouteActionProvider =
+            (MediaRouteActionProvider)MenuItemCompat.getActionProvider(
+            mediaRouteMenuItem);
+    <strong>mediaRouteActionProvider.setRouteSelector(mSelector);</strong>
+
+    // Return true to show the menu.
+    return true;
+}
+</pre>
+
+<p>Once you have made these changes to your app, you might expect the Cast button to appear in your
+  activity. Alas, it does not (unless your device is already paired with a Wireless Display). In
+  most cases, you must also connect with the media route framework, which is discussed in the next
+  section.
+</p>
+
+
+<h2 id="media-routes">Connecting to Media Routes</h2>
+
+<p>In order to connect to a media route selected by the user, your app must obtain the {@link
+  android.support.v7.media.MediaRouter} framework object and then attach a {@link
+  android.support.v7.media.MediaRouter.Callback} object. The callback object receives messages
+  from the media router framework when a route selected, changed or disconnected by the user.</p>
+
+<p>To obtain an instance of the {@link android.support.v7.media.MediaRouter} framework object,
+  call {@link android.support.v7.media.MediaRouter#getInstance MediaRouter.getInstance()}
+  from the {@link android.app.Activity#onCreate onCreate()} method of an activity that supports
+  the media router API.</p>
+
+<p class="note">
+  <strong>Note:</strong> The {@link android.support.v7.media.MediaRouter} object is a singleton
+  that is maintained by the framework. However, once your application obtains an instance of the
+  object you must retain that instance until your application terminates to prevent it from being
+  garbage collected.
+</p>
+
+
+<h3 id="create-mr-callback">Creating a MediaRouter callback</h3>
+
+<p>The media router framework communicates with an app through a callback object that
+  you attach to the {@link android.support.v7.media.MediaRouter} framework object. An app
+  that uses the media router framework must extend the {@link
+  android.support.v7.media.MediaRouter.Callback} object to receive messages when a media route is
+  connected and provide content to the connected device through that route.</p>
+
+<p>There are several methods in the callback that can be overwritten to receive messages about
+  media router events. At the minimum, your implementation of the {@link
+  android.support.v7.media.MediaRouter.Callback} class should override the following
+  methods:</p>
+
+<ul>
+  <li>{@link android.support.v7.media.MediaRouter.Callback#onRouteSelected onRouteSelected()}
+    &mdash; Called when the user connects to a media router output device.</li>
+  <li>{@link android.support.v7.media.MediaRouter.Callback#onRouteUnselected
+    onRouteUnselected()} &mdash; Called when the user disconnects from a media router output device.</li>
+  <li>{@link android.support.v7.media.MediaRouter.Callback#onRoutePresentationDisplayChanged
+    onRoutePresentationDisplayChanged()} &mdash; Called when the presentation display changes its
+    display metrics, such as changing from 720 pixel to 1080 pixel resolution.</li>
+</ul>
+
+<p>The methods of your {@link android.support.v7.media.MediaRouter.Callback}
+  implementation are the first opportunity to determine if the connected route is a remote playback
+  device, such as Chromecast, or a secondary output device, such as a Wireless Display device.
+  If your app supports both device types, then your implementation should branch here, as
+  shown in this sample code:</p>
+
+<pre>
+private final MediaRouter.Callback mMediaRouterCallback =
+        new MediaRouter.Callback() {
+
+    &#64;Override
+    public void onRouteSelected(MediaRouter router, RouteInfo route) {
+        Log.d(TAG, "onRouteSelected: route=" + route);
+
+        if (route.supportsControlCategory(
+            MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)){
+            // remote playback device
+            updateRemotePlayer(route);
+        } else {
+            // secondary output device
+            updatePresentation(route);
+        }
+    }
+
+    &#64;Override
+    public void onRouteUnselected(MediaRouter router, RouteInfo route) {
+        Log.d(TAG, "onRouteUnselected: route=" + route);
+
+        if (route.supportsControlCategory(
+            MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)){
+            // remote playback device
+            updateRemotePlayer(route);
+        } else {
+            // secondary output device
+            updatePresentation(route);
+        }
+    }
+
+    &#64;Override
+    public void onRoutePresentationDisplayChanged(
+            MediaRouter router, RouteInfo route) {
+        Log.d(TAG, "onRoutePresentationDisplayChanged: route=" + route);
+
+        if (route.supportsControlCategory(
+            MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)){
+            // remote playback device
+            updateRemotePlayer(route);
+        } else {
+            // secondary output device
+            updatePresentation(route);
+        }
+    }
+}
+</pre>
+
+<p>After defining your callback object for the media router, you still need to attach it to
+  the main media router framework object. The next section discusses the appropriate way to attach
+  your callbacks for media routes.</p>
+
+
+<h3 id="attach-mr-callback">Attaching a callback to MediaRouter</h3>
+
+<p>Since media routes are a shared interface, your app must attach and detach your
+  {@link android.support.v7.media.MediaRouter.Callback} object as your app starts up and shuts
+  down. To accomplish this, you must add and remove your app's
+  callback object from the media router framework as part of your app's activity lifecycle. This
+  approach allows other apps to make use of media route outputs while your app
+  is in the background or not running.</p>
+
+<p class="note">
+  <strong>Note:</strong> If you are writing a music playback app and want to allow music to play
+  while your app is in the background, you must build a {@link android.app.Service} for playback
+  and connect that service and it's lifecycle to the media router framework.
+</p>
+
+<p>The following code sample demonstrates how to use the lifecycle methods to appropriately
+  add and remove your app's media router callback object:</p>
+
+<pre>
+public class MediaRouterPlaybackActivity extends ActionBarActivity {
+    private MediaRouter mMediaRouter;
+    private MediaRouteSelector mSelector;
+    private Callback mMediaRouterCallback;
+
+    // your app works with so the framework can discover them.
+    &#64;Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        // Get the media router service.
+        mMediaRouter = MediaRouter.getInstance(this);
+        ...
+    }
+
+    // Add the callback on start to tell the media router what kinds of routes
+    // your app works with so the framework can discover them.
+    &#64;Override
+    public void onStart() {
+        mMediaRouter.addCallback(mSelector, mMediaRouterCallback,
+                MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
+        super.onStart();
+    }
+
+    // Remove the selector on stop to tell the media router that it no longer
+    // needs to discover routes for your app.
+    &#64;Override
+    public void onStop() {
+        mMediaRouter.removeCallback(mMediaRouterCallback);
+        super.onStop();
+    }
+    ...
+}
+</pre>
+
+<p>You should add and remove the media router callback only in the {@link
+  android.app.Activity#onStart onStart()} and {@link android.app.Activity#onStop onStop()}
+  lifecycle methods. Do not include these calls in the {@link android.app.Activity#onResume
+  onResume()} or {@link android.app.Activity#onPause onPause()} methods.
+</p>
+
+<p class="note">
+  <strong>Note:</strong> The media route framework also provides a
+  {@link android.support.v7.app.MediaRouteDiscoveryFragment} class which takes care of adding and
+  removing the call back for an activity.
+</p>
+
+<p>Now when you run your application, you should see a Cast button appear in your activity.
+  When you press the button the media router framework, a route selection dialog appears as shown
+  in figure 3, allowing your user to select an available media route. Make sure you have a
+  supported device available on your local network when testing this interface.</p>
+
+<p class="note">
+  <strong>Note:</strong> In order for Wireless Display routes to show up in the media route
+  selection dialog, users must enable this option in the Settings app. The option is under
+  the <em>Display</em> category and is called <em>Cast screen</em> on Android 4.4 (KitKat) and higher
+  devices and <em>Wireless Display</em> on Android 4.2.x (Jelly Bean) devices. For more information
+  on enabling this feature see this
+  <a href="https://support.google.com/nexus/answer/2865484">Wireless display</a> support page.
+</p>
+
+
+<h2 id="remote-playback">Remote Playback</h2>
+
+<p>The remote playback approach sends control commands to a secondary device to initiate playback
+  and to control playback that is in progress (pause, rewind, fast-forward, volume up and down).
+  Using this approach, the receiving device (such as a Chromecast) is responsible for retrieving
+  and rendering content.</p>
+
+<p>When your app supports this type of media route, you must create a {@link
+  android.support.v7.media.RemotePlaybackClient} object using a remote playback {@link
+  android.support.v7.media.MediaRouter.RouteInfo} object received through your app's
+  {@link android.support.v7.media.MediaRouter.Callback} object. The following sample
+  code demonstrates a controller method that creates a new remote playback client and sends it a
+  video for playback:</p>
+
+<pre>
+private void updateRemotePlayer(RouteInfo route) {
+    // Changed route: tear down previous client
+    if (mRoute != null && mRemotePlaybackClient != null) {
+        mRemotePlaybackClient.release();
+        mRemotePlaybackClient = null;
+    }
+
+    // Save new route
+    mRoute = route;
+
+    // Attach new playback client
+    mRemotePlaybackClient = new RemotePlaybackClient(this, mRoute);
+
+    // Send file for playback
+    mRemotePlaybackClient.play(Uri.parse(
+            "http://archive.org/download/Sintel/sintel-2048-stereo_512kb.mp4"),
+            "video/mp4", null, 0, null, new ItemActionCallback() {
+
+            &#64;Override
+            public void onResult(Bundle data, String sessionId,
+                    MediaSessionStatus sessionStatus,
+                    String itemId, MediaItemStatus itemStatus) {
+                logStatus("play: succeeded for item " + itemId);
+            }
+
+            &#64;Override
+            public void onError(String error, int code, Bundle data) {
+                logStatus("play: failed - error:"+ code +" - "+ error);
+            }
+        });
+    }
+}
+</pre>
+
+<p>The {@link android.support.v7.media.RemotePlaybackClient} class provides additional methods
+  for managing content playback. Here are a few of the key playback methods from the {@link
+  android.support.v7.media.RemotePlaybackClient} class:</p>
+
+<ul>
+  <li>{@link android.support.v7.media.RemotePlaybackClient#play play()} &mdash; Play a specific
+    media file, specified by a {@link android.net.Uri}.</li>
+  <li>{@link android.support.v7.media.RemotePlaybackClient#pause pause()} &mdash; Pause the
+    currently playing media track.</li>
+  <li>{@link android.support.v7.media.RemotePlaybackClient#resume resume()} &mdash; Continue
+    playing the current track after a pause command.</li>
+  <li>{@link android.support.v7.media.RemotePlaybackClient#seek seek()} &mdash; Move to a specific
+    position in the current track.</li>
+  <li>{@link android.support.v7.media.RemotePlaybackClient#release release()} &mdash; Tear down the
+    connection from your app to the remote playback device.</li>
+</ul>
+
+<p>You can use these methods to attach actions to playback controls you provide in your
+  app. Most of these methods also allow you to include a callback object so you can monitor
+  the progress of the playback task or control request.</p>
+
+<p>
+  The {@link android.support.v7.media.RemotePlaybackClient} class also supports queueing of
+  multiple media items for playback and management of the media queue. For a comprehensive sample
+  implementation of these features, see {@code SampleMediaRouterActivity} and its associated
+  classes in the v7 mediarouter support library sample
+  {@code &lt;sdk&gt;/extras/android/compatibility/v7/mediarouter}.
+</p>
+
+<p>
+  For additional information on using the Google Cast API for Chromecast devices, see the
+  <a href="http://developers.google.com/cast/">Google Cast</a> developer documentation.
+</p>
+
+
+<h2 id="secondary-output">Secondary Output</h2>
+
+<p>The secondary output approach sends prepared media content to a connected secondary device
+  for playback. Secondary devices can include televisions or wireless sound systems and can be
+  attached through wireless protocols or wires, such as an HDMI cable. With this approach, your
+  app is responsible for processing media content for playback (downloading, decoding,
+  synchronization of audio and video tracks), while the secondary device only outputs the content
+  in its final form.</p>
+
+<p class="note">
+  <strong>Note:</strong> Using the secondary output display routes with the media router framework
+  requires classes that are available only in Android 4.2 (API level 17) and higher, specifically the
+  {@link android.app.Presentation} class. If you are building an app that supports both
+  remote playback and secondary output devices, you must include checks that disable this code
+  below the supported Android version level.
+</p>
+
+
+<h3 id="pres-obj">Creating a Presentation object</h3>
+
+<p>When using a secondary output display with the media router framework, you create a {@link
+  android.app.Presentation} object that contains the content you want to show on that display. The
+  {@link android.app.Presentation} is extended from the {@link android.app.Dialog} class, so can
+  add layouts and views to a {@link android.app.Presentation}.</p>
+
+<p>You should be aware that the {@link android.app.Presentation} object has its own
+  {@link android.content.Context} and
+  {@link android.content.res.Resources},
+  separate from the app activity that created the object. Having a secondary
+  context is required, because the content of the {@link android.app.Presentation} is drawn on a
+  display that is separate from your app's display on the local Android device.
+  Specifically, the secondary display needs a separate context because it may need to load
+  resources based on its specific screen metrics.</p>
+
+<p>The following code sample shows a minimal implementation of a
+  {@link android.app.Presentation} object, including a {@link android.opengl.GLSurfaceView}
+  object.</p>
+
+<pre>
+public class SamplePresentation extends Presentation {
+    public SamplePresentation(Context outerContext, Display display) {
+        super(outerContext, display);
+    }
+
+    &#64;Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        // Notice that we get resources from the context of the Presentation
+        Resources resources = getContext().getResources();
+
+        // Inflate a layout.
+        setContentView(R.layout.presentation_with_media_router_content);
+
+        // Add presentation content here:
+        // Set up a surface view for visual interest
+        mSurfaceView = (GLSurfaceView)findViewById(R.id.surface_view);
+        mSurfaceView.setRenderer(new CubeRenderer(false));
+    }
+}
+</pre>
+
+
+<h3 id="pres-cntrlr">Creating a Presentation controller</h3>
+
+<p>In order to display a {@link android.app.Presentation} object, you should write a
+  controller layer that handles responses to the messages received by the {@link
+  android.support.v7.media.MediaRouter.Callback} object and manages the creation and
+  removal of the {@link android.app.Presentation} object. The controller layer should also handle
+  attaching presentations to a selected {@link android.view.Display} object, which represents the
+  separate physical display device chosen by the user. The controller layer can simply be a method
+  in the activity that supports a secondary display.</p>
+
+<p>The following code sample shows a controller layer for a {@link android.app.Presentation}
+  implemented as a single method. This method handles dismissing invalid presentations when a
+  {@link android.view.Display} is unselected or disconnected, and creates the {@link
+  android.app.Presentation} object when a display device is connected.</p>
+
+<pre>
+private void updatePresentation(RouteInfo route) {
+    // Get its Display if a valid route has been selected
+    Display selectedDisplay = null;
+    if (route != null) {
+        selectedDisplay = route.getPresentationDisplay();
+    }
+
+    // Dismiss the current presentation if the display has changed or no new
+    // route has been selected
+    if (mPresentation != null && mPresentation.getDisplay() != selectedDisplay) {
+        mPresentation.dismiss();
+            mPresentation = null;
+    }
+
+    // Show a new presentation if the previous one has been dismissed and a
+    // route has been selected.
+    if (mPresentation == null && selectedDisplay != null) {
+        // Initialize a new Presentation for the Display
+        mPresentation = new SamplePresentation(this, selectedDisplay);
+        mPresentation.setOnDismissListener(
+                new DialogInterface.OnDismissListener() {
+                    // Listen for presentation dismissal and then remove it
+                    &#64;Override
+                    public void onDismiss(DialogInterface dialog) {
+                        if (dialog == mPresentation) {
+                            mPresentation = null;
+                        }
+                    }
+                });
+
+        // Try to show the presentation, this might fail if the display has
+        // gone away in the meantime
+        try {
+            mPresentation.show();
+        } catch (WindowManager.InvalidDisplayException ex) {
+            // Couldn't show presentation - display was already removed
+            mPresentation = null;
+        }
+    }
+}
+</pre>
+
+<p class="note">
+  <strong>Note:</strong> When the a user connects to a Wireless Display, the media router
+  framework automatically provides a notification that it is displaying screen content on a
+  connected device.
+</p>
diff --git a/docs/html/images/mediarouter/mediarouter-actionbar.png b/docs/html/images/mediarouter/mediarouter-actionbar.png
new file mode 100644
index 0000000..f167054
--- /dev/null
+++ b/docs/html/images/mediarouter/mediarouter-actionbar.png
Binary files differ
diff --git a/docs/html/images/mediarouter/mediarouter-framework.png b/docs/html/images/mediarouter/mediarouter-framework.png
new file mode 100644
index 0000000..3541e1a
--- /dev/null
+++ b/docs/html/images/mediarouter/mediarouter-framework.png
Binary files differ
diff --git a/docs/html/images/mediarouter/mediarouter-selector-ui.png b/docs/html/images/mediarouter/mediarouter-selector-ui.png
new file mode 100644
index 0000000..acc39ca
--- /dev/null
+++ b/docs/html/images/mediarouter/mediarouter-selector-ui.png
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index d976c1e..5d1788a 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -57,7 +57,7 @@
                     </div>
                     <div class="content-right col-4">
                     <h1 style="white-space:nowrap;line-height:1.2em;">Developer Story: <br />Kiwi, Inc.</h1>
-                    <p>Game developer Kiwi has five of the top 25 grossing titles on Google Play. Hear how Google Play
+                    <p>Game developer Kiwi has had five titles in the top 25 grossing on Google Play. Hear how Google Play
                       has helped them double revenue every six months.</p>
                       <p><a href="{@docRoot}distribute/googleplay/spotlight/index.html" class="button">Watch more videos </a></p>
                     </div>
diff --git a/docs/html/samples/renderscript.jd b/docs/html/samples/renderscript.jd
new file mode 100644
index 0000000..2adec4d
--- /dev/null
+++ b/docs/html/samples/renderscript.jd
@@ -0,0 +1,11 @@
+page.title=Renderscript
+@jd:body
+
+
+<div id="samples" class="renderscript">
+</div>
+
+
+<script>
+  $(document).ready(showSamples);
+</script>
diff --git a/docs/html/samples/sensors.jd b/docs/html/samples/sensors.jd
new file mode 100644
index 0000000..c3a764f
--- /dev/null
+++ b/docs/html/samples/sensors.jd
@@ -0,0 +1,11 @@
+page.title=Sensors
+@jd:body
+
+
+<div id="samples" class="sensors">
+</div>
+
+
+<script>
+  $(document).ready(showSamples);
+</script>
diff --git a/docs/html/tools/revisions/build-tools.jd b/docs/html/tools/revisions/build-tools.jd
index 1da51b5..749808f 100644
--- a/docs/html/tools/revisions/build-tools.jd
+++ b/docs/html/tools/revisions/build-tools.jd
@@ -74,10 +74,36 @@
 revisions of the Build Tools are available in your SDK, refer to the <em>Installed Packages</em>
 listing in the Android SDK Manager.</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=""/>Build Tools, Revision 19.0.2</a> <em>(February 2014)</em>
+  </p>
+  <div class="toggle-content-toggleme">
+
+    <dl>
+      <dt>Fixed RenderScript build issues:</dt>
+      <dd>
+        <ul>
+          <li>Fixed a problem with RenderScript bitcode encoding.
+            (<a href="http://b.android.com/64775">Issue 64775</a>)
+          </li>
+          <li>Fixed a problem with RenderScript missing math symbols
+            (<a href="http://b.android.com/64110">Issue 64110</a>)
+          </li>
+        </ul>
+      </dd>
+    </dl>
+    <p></p>
+
+  </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=""/>Build Tools, Revision 19.0.1</a> <em>(December 2013)</em>
   </p>
   <div class="toggle-content-toggleme">
diff --git a/docs/html/tools/revisions/platforms.jd b/docs/html/tools/revisions/platforms.jd
index c5d1ef6..99a271f 100644
--- a/docs/html/tools/revisions/platforms.jd
+++ b/docs/html/tools/revisions/platforms.jd
@@ -87,19 +87,34 @@
 </div>
 
 
+
 <h3 id="gsi-4.4">Google APIs System Image</h3>
 
 <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="" />Revision 3</a> <em>(February 2014)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <p>This release includes
+    <a href="{@docRoot}google/play-services/index.html">Google Play services</a> version 4.2.42,
+    allowing you to test your application in an emulator using the latest Google Play services.</p>
+
+  </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="" />Revision 2</a> <em>(December 2013)</em>
   </p>
 
   <div class="toggle-content-toggleme">
 
-    <p>Maintenance release. This release includes
-    <a href="{@docRoot}google/play-services/index.html">Google Play services</a> version 4.0.33,
-    allowing you to test your application in an emulator using the latest Google Play services.</p>
+    <p>This release includes
+    <a href="{@docRoot}google/play-services/index.html">Google Play services</a> version 4.0.33.</p>
 
   </div>
 </div>
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index e654db1..331a34e 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -32,6 +32,7 @@
 import android.graphics.RectF;
 import android.graphics.Shader;
 import android.graphics.SweepGradient;
+import android.os.Build;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.TypedValue;
@@ -112,6 +113,15 @@
      */
     public static final int SWEEP_GRADIENT  = 2;
 
+    /** Radius is in pixels. */
+    private static final int RADIUS_TYPE_PIXELS = 0;
+
+    /** Radius is a fraction of the base size. */
+    private static final int RADIUS_TYPE_FRACTION = 1;
+
+    /** Radius is a fraction of the bounds size. */
+    private static final int RADIUS_TYPE_FRACTION_PARENT = 2;
+
     private GradientState mGradientState;
     
     private final Paint mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -130,6 +140,9 @@
     private Path mRingPath;
     private boolean mPathIsDirty = true;
 
+    /** Current gradient radius, valid when {@link #mRectIsDirty} is false. */
+    private float mGradientRadius;
+
     /**
      * Controls how the gradient is oriented relative to the drawable's bounds
      */
@@ -401,12 +414,27 @@
      * @see #setGradientType(int) 
      */
     public void setGradientRadius(float gradientRadius) {
-        mGradientState.setGradientRadius(gradientRadius);
+        mGradientState.setGradientRadius(gradientRadius, TypedValue.COMPLEX_UNIT_PX);
         mRectIsDirty = true;
         invalidateSelf();
     }
 
     /**
+     * Returns the radius of the gradient in pixels. The radius is valid only
+     * when the gradient type is set to {@link #RADIAL_GRADIENT}.
+     *
+     * @return Radius in pixels.
+     */
+    public float getGradientRadius() {
+        if (mGradientState.mGradient != RADIAL_GRADIENT) {
+            return 0;
+        }
+
+        ensureValidRect();
+        return mGradientRadius;
+    }
+
+    /**
      * <p>Sets whether or not this drawable will honor its <code>level</code>
      * property.</p>
      * <p><strong>Note</strong>: changing this property will affect all instances
@@ -872,11 +900,27 @@
                     x0 = r.left + (r.right - r.left) * st.mCenterX;
                     y0 = r.top + (r.bottom - r.top) * st.mCenterY;
 
-                    final float level = st.mUseLevel ? (float) getLevel() / 10000.0f : 1.0f;
+                    float radius = st.mGradientRadius;
+                    if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION) {
+                        radius *= Math.min(st.mWidth, st.mHeight);
+                    } else if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION_PARENT) {
+                        radius *= Math.min(r.width(), r.height());
+                    }
 
-                    mFillPaint.setShader(new RadialGradient(x0, y0,
-                            level * st.mGradientRadius, colors, null,
-                            Shader.TileMode.CLAMP));
+                    if (st.mUseLevel) {
+                        radius *= getLevel() / 10000.0f;
+                    }
+
+                    mGradientRadius = radius;
+
+                    if (radius == 0) {
+                        // We can't have a shader with zero radius, so let's
+                        // have a very, very small radius.
+                        radius = 0.001f;
+                    }
+
+                    mFillPaint.setShader(new RadialGradient(
+                            x0, y0, radius, colors, null, Shader.TileMode.CLAMP));
                 } else if (st.mGradient == SWEEP_GRADIENT) {
                     x0 = r.left + (r.right - r.left) * st.mCenterX;
                     y0 = r.top + (r.bottom - r.top) * st.mCenterY;
@@ -1051,12 +1095,28 @@
                         break;
                     }
                 } else {
-                    TypedValue tv = a.peekValue(
+                    final TypedValue tv = a.peekValue(
                             com.android.internal.R.styleable.GradientDrawableGradient_gradientRadius);
                     if (tv != null) {
-                        boolean radiusRel = tv.type == TypedValue.TYPE_FRACTION;
-                        st.mGradientRadius = radiusRel ?
-                                tv.getFraction(1.0f, 1.0f) : tv.getFloat();
+                        final float radius;
+                        final int radiusType;
+                        if (tv.type == TypedValue.TYPE_FRACTION) {
+                            radius = tv.getFraction(1.0f, 1.0f);
+
+                            final int unit = (tv.data >> TypedValue.COMPLEX_UNIT_SHIFT)
+                                    & TypedValue.COMPLEX_UNIT_MASK;
+                            if (unit == TypedValue.COMPLEX_UNIT_FRACTION_PARENT) {
+                                radiusType = RADIUS_TYPE_FRACTION_PARENT;
+                            } else {
+                                radiusType = RADIUS_TYPE_FRACTION;
+                            }
+                        } else {
+                            radius = tv.getDimension(r.getDisplayMetrics());
+                            radiusType = RADIUS_TYPE_PIXELS;
+                        }
+
+                        st.mGradientRadius = radius;
+                        st.mGradientRadiusType = radiusType;
                     } else if (gradientType == RADIAL_GRADIENT) {
                         throw new XmlPullParserException(
                                 a.getPositionDescription()
@@ -1218,6 +1278,7 @@
         private float mCenterX = 0.5f;
         private float mCenterY = 0.5f;
         private float mGradientRadius = 0.5f;
+        private int mGradientRadiusType = RADIUS_TYPE_PIXELS;
         private boolean mUseLevel;
         private boolean mUseLevelForShape;
         private boolean mOpaque;
@@ -1259,6 +1320,7 @@
             mCenterX = state.mCenterX;
             mCenterY = state.mCenterY;
             mGradientRadius = state.mGradientRadius;
+            mGradientRadiusType = state.mGradientRadiusType;
             mUseLevel = state.mUseLevel;
             mUseLevelForShape = state.mUseLevelForShape;
             mOpaque = state.mOpaque;
@@ -1375,8 +1437,9 @@
             mHeight = height;
         }
 
-        public void setGradientRadius(float gradientRadius) {
+        public void setGradientRadius(float gradientRadius, int type) {
             mGradientRadius = gradientRadius;
+            mGradientRadiusType = type;
         }
     }
 
diff --git a/include/androidfw/AssetManager.h b/include/androidfw/AssetManager.h
index 503377c..a13dd16 100644
--- a/include/androidfw/AssetManager.h
+++ b/include/androidfw/AssetManager.h
@@ -70,6 +70,12 @@
 class AssetManager : public AAssetManager {
 public:
     static const char* RESOURCES_FILENAME;
+    static const char* IDMAP_BIN;
+    static const char* OVERLAY_DIR;
+    static const char* TARGET_PACKAGE_NAME;
+    static const char* TARGET_APK_PATH;
+    static const char* IDMAP_DIR;
+
     typedef enum CacheMode {
         CACHE_UNKNOWN = 0,
         CACHE_OFF,          // don't try to cache file locations
@@ -94,6 +100,7 @@
      * newly-added asset source.
      */
     bool addAssetPath(const String8& path, int32_t* cookie);
+    bool addOverlayPath(const String8& path, int32_t* cookie);
 
     /*                                                                       
      * Convenience for adding the standard system assets.  Uses the
@@ -272,19 +279,14 @@
     void setLocaleLocked(const char* locale);
     void updateResourceParamsLocked() const;
 
-    bool createIdmapFileLocked(const String8& originalPath, const String8& overlayPath,
-                               const String8& idmapPath);
-
-    bool isIdmapStaleLocked(const String8& originalPath, const String8& overlayPath,
-                            const String8& idmapPath);
-
     Asset* openIdmapLocked(const struct asset_path& ap) const;
 
-    bool getZipEntryCrcLocked(const String8& zipPath, const char* entryFilename, uint32_t* pCrc);
+    void addSystemOverlays(const char* pathOverlaysList, const String8& targetPackagePath,
+            ResTable* sharedRes, size_t offset) const;
 
     class SharedZip : public RefBase {
     public:
-        static sp<SharedZip> get(const String8& path);
+        static sp<SharedZip> get(const String8& path, bool createIfNotPresent = true);
 
         ZipFileRO* getZip();
 
@@ -295,6 +297,9 @@
         ResTable* setResourceTable(ResTable* res);
         
         bool isUpToDate();
+
+        void addOverlay(const asset_path& ap);
+        bool getOverlay(size_t idx, asset_path* out) const;
         
     protected:
         ~SharedZip();
@@ -310,6 +315,8 @@
         Asset* mResourceTableAsset;
         ResTable* mResourceTable;
 
+        Vector<asset_path> mOverlays;
+
         static Mutex gLock;
         static DefaultKeyedVector<String8, wp<SharedZip> > gOpen;
     };
@@ -342,6 +349,9 @@
         static String8 getPathName(const char* path);
 
         bool isUpToDate();
+
+        void addOverlay(const String8& path, const asset_path& overlay);
+        bool getOverlay(const String8& path, size_t idx, asset_path* out) const;
         
     private:
         void closeZip(int idx);
diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h
index 0f51826..a0bae12 100644
--- a/include/androidfw/ResourceTypes.h
+++ b/include/androidfw/ResourceTypes.h
@@ -1638,39 +1638,21 @@
     // Return value: on success: NO_ERROR; caller is responsible for free-ing
     // outData (using free(3)). On failure, any status_t value other than
     // NO_ERROR; the caller should not free outData.
-    status_t createIdmap(const ResTable& overlay, uint32_t targetCrc, uint32_t overlayCrc,
-                         void** outData, size_t* outSize) const;
-
     status_t createIdmap(const ResTable& overlay,
             uint32_t targetCrc, uint32_t overlayCrc,
             const char* targetPath, const char* overlayPath,
-            void** outData, size_t* outSize) const
-    {
-        (void)targetPath;
-        (void)overlayPath;
-        return createIdmap(overlay, targetCrc, overlayCrc, outData, outSize);
-    }
+            void** outData, size_t* outSize) const;
 
     enum {
-        IDMAP_HEADER_SIZE_BYTES = 3 * sizeof(uint32_t),
+        IDMAP_HEADER_SIZE_BYTES = 3 * sizeof(uint32_t) + 2 * 256,
     };
     // Retrieve idmap meta-data.
     //
     // This function only requires the idmap header (the first
     // IDMAP_HEADER_SIZE_BYTES) bytes of an idmap file.
     static bool getIdmapInfo(const void* idmap, size_t size,
-                             uint32_t* pTargetCrc, uint32_t* pOverlayCrc);
-
-    static bool getIdmapInfo(const void* idmap, size_t size,
             uint32_t* pTargetCrc, uint32_t* pOverlayCrc,
-            String8* pTargetPath, String8* pOverlayPath)
-    {
-        if (*pTargetPath)
-            *pTargetPath = String8();
-        if (*pOverlayPath)
-            *pOverlayPath = String8();
-        return getIdmapInfo(idmap, size, pTargetCrc, pOverlayCrc);
-    }
+            String8* pTargetPath, String8* pOverlayPath);
 
     void print(bool inclValues) const;
     static String8 normalizeForOutput(const char* input);
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index a24a8b3..64363d4 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -41,10 +41,8 @@
 #include <assert.h>
 #include <dirent.h>
 #include <errno.h>
-#include <fcntl.h>
+#include <string.h> // strerror
 #include <strings.h>
-#include <sys/stat.h>
-#include <unistd.h>
 
 #ifndef TEMP_FAILURE_RETRY
 /* Used to retry syscalls that can return EINTR. */
@@ -75,7 +73,7 @@
 static const char* kAssetsRoot = "assets";
 static const char* kAppZipName = NULL; //"classes.jar";
 static const char* kSystemAssets = "framework/framework-res.apk";
-static const char* kIdmapCacheDir = "resource-cache";
+static const char* kResourceCache = "resource-cache";
 
 static const char* kExcludeExtension = ".EXCLUDE";
 
@@ -84,15 +82,19 @@
 static volatile int32_t gCount = 0;
 
 const char* AssetManager::RESOURCES_FILENAME = "resources.arsc";
+const char* AssetManager::IDMAP_BIN = "/system/bin/idmap";
+const char* AssetManager::OVERLAY_DIR = "/vendor/overlay";
+const char* AssetManager::TARGET_PACKAGE_NAME = "android";
+const char* AssetManager::TARGET_APK_PATH = "/system/framework/framework-res.apk";
+const char* AssetManager::IDMAP_DIR = "/data/resource-cache";
 
 namespace {
-    // Transform string /a/b/c.apk to /data/resource-cache/a@b@c.apk@idmap
     String8 idmapPathForPackagePath(const String8& pkgPath)
     {
         const char* root = getenv("ANDROID_DATA");
         LOG_ALWAYS_FATAL_IF(root == NULL, "ANDROID_DATA not set");
         String8 path(root);
-        path.appendPath(kIdmapCacheDir);
+        path.appendPath(kResourceCache);
 
         char buf[256]; // 256 chars should be enough for anyone...
         strncpy(buf, pkgPath.string(), 255);
@@ -210,37 +212,78 @@
         *cookie = static_cast<int32_t>(mAssetPaths.size());
     }
 
-    // add overlay packages for /system/framework; apps are handled by the
-    // (Java) package manager
-    if (strncmp(path.string(), "/system/framework/", 18) == 0) {
-        // When there is an environment variable for /vendor, this
-        // should be changed to something similar to how ANDROID_ROOT
-        // and ANDROID_DATA are used in this file.
-        String8 overlayPath("/vendor/overlay/framework/");
-        overlayPath.append(path.getPathLeaf());
-        if (TEMP_FAILURE_RETRY(access(overlayPath.string(), R_OK)) == 0) {
-            asset_path oap;
-            oap.path = overlayPath;
-            oap.type = ::getFileType(overlayPath.string());
-            bool addOverlay = (oap.type == kFileTypeRegular); // only .apks supported as overlay
-            if (addOverlay) {
-                oap.idmap = idmapPathForPackagePath(overlayPath);
-
-                if (isIdmapStaleLocked(ap.path, oap.path, oap.idmap)) {
-                    addOverlay = createIdmapFileLocked(ap.path, oap.path, oap.idmap);
-                }
-            }
-            if (addOverlay) {
-                mAssetPaths.add(oap);
-            } else {
-                ALOGW("failed to add overlay package %s\n", overlayPath.string());
-            }
-        }
+#ifdef HAVE_ANDROID_OS
+    // Load overlays, if any
+    asset_path oap;
+    for (size_t idx = 0; mZipSet.getOverlay(ap.path, idx, &oap); idx++) {
+        mAssetPaths.add(oap);
     }
+#endif
 
     return true;
 }
 
+bool AssetManager::addOverlayPath(const String8& packagePath, int32_t* cookie)
+{
+    const String8 idmapPath = idmapPathForPackagePath(packagePath);
+
+    AutoMutex _l(mLock);
+
+    for (size_t i = 0; i < mAssetPaths.size(); ++i) {
+        if (mAssetPaths[i].idmap == idmapPath) {
+           *cookie = static_cast<int32_t>(i + 1);
+            return true;
+         }
+     }
+
+    Asset* idmap = NULL;
+    if ((idmap = openAssetFromFileLocked(idmapPath, Asset::ACCESS_BUFFER)) == NULL) {
+        ALOGW("failed to open idmap file %s\n", idmapPath.string());
+        return false;
+    }
+
+    String8 targetPath;
+    String8 overlayPath;
+    if (!ResTable::getIdmapInfo(idmap->getBuffer(false), idmap->getLength(),
+                NULL, NULL, &targetPath, &overlayPath)) {
+        ALOGW("failed to read idmap file %s\n", idmapPath.string());
+        delete idmap;
+        return false;
+    }
+    delete idmap;
+
+    if (overlayPath != packagePath) {
+        ALOGW("idmap file %s inconcistent: expected path %s does not match actual path %s\n",
+                idmapPath.string(), packagePath.string(), overlayPath.string());
+        return false;
+    }
+    if (access(targetPath.string(), R_OK) != 0) {
+        ALOGW("failed to access file %s: %s\n", targetPath.string(), strerror(errno));
+        return false;
+    }
+    if (access(idmapPath.string(), R_OK) != 0) {
+        ALOGW("failed to access file %s: %s\n", idmapPath.string(), strerror(errno));
+        return false;
+    }
+    if (access(overlayPath.string(), R_OK) != 0) {
+        ALOGW("failed to access file %s: %s\n", overlayPath.string(), strerror(errno));
+        return false;
+    }
+
+    asset_path oap;
+    oap.path = overlayPath;
+    oap.type = ::getFileType(overlayPath.string());
+    oap.idmap = idmapPath;
+#if 0
+    ALOGD("Overlay added: targetPath=%s overlayPath=%s idmapPath=%s\n",
+            targetPath.string(), overlayPath.string(), idmapPath.string());
+#endif
+    mAssetPaths.add(oap);
+    *cookie = static_cast<int32_t>(mAssetPaths.size());
+
+    return true;
+ }
+
 bool AssetManager::createIdmap(const char* targetApkPath, const char* overlayApkPath,
         uint32_t targetCrc, uint32_t overlayCrc, uint32_t** outData, size_t* outSize)
 {
@@ -257,158 +300,13 @@
             ALOGW("failed to find resources.arsc in %s\n", ap.path.string());
             return false;
         }
-        tables[i].add(ass, 1, false);
+        tables[i].add(ass, 1, false /* copyData */, NULL /* idMap */);
     }
 
     return tables[0].createIdmap(tables[1], targetCrc, overlayCrc,
             targetApkPath, overlayApkPath, (void**)outData, outSize) == NO_ERROR;
 }
 
-bool AssetManager::isIdmapStaleLocked(const String8& originalPath, const String8& overlayPath,
-                                      const String8& idmapPath)
-{
-    struct stat st;
-    if (TEMP_FAILURE_RETRY(stat(idmapPath.string(), &st)) == -1) {
-        if (errno == ENOENT) {
-            return true; // non-existing idmap is always stale
-        } else {
-            ALOGW("failed to stat file %s: %s\n", idmapPath.string(), strerror(errno));
-            return false;
-        }
-    }
-    if (st.st_size < ResTable::IDMAP_HEADER_SIZE_BYTES) {
-        ALOGW("file %s has unexpectedly small size=%zd\n", idmapPath.string(), (size_t)st.st_size);
-        return false;
-    }
-    int fd = TEMP_FAILURE_RETRY(::open(idmapPath.string(), O_RDONLY));
-    if (fd == -1) {
-        ALOGW("failed to open file %s: %s\n", idmapPath.string(), strerror(errno));
-        return false;
-    }
-    char buf[ResTable::IDMAP_HEADER_SIZE_BYTES];
-    ssize_t bytesLeft = ResTable::IDMAP_HEADER_SIZE_BYTES;
-    for (;;) {
-        ssize_t r = TEMP_FAILURE_RETRY(read(fd, buf + ResTable::IDMAP_HEADER_SIZE_BYTES - bytesLeft,
-                                            bytesLeft));
-        if (r < 0) {
-            TEMP_FAILURE_RETRY(close(fd));
-            return false;
-        }
-        bytesLeft -= r;
-        if (bytesLeft == 0) {
-            break;
-        }
-    }
-    TEMP_FAILURE_RETRY(close(fd));
-
-    uint32_t cachedOriginalCrc, cachedOverlayCrc;
-    if (!ResTable::getIdmapInfo(buf, ResTable::IDMAP_HEADER_SIZE_BYTES,
-                                &cachedOriginalCrc, &cachedOverlayCrc)) {
-        return false;
-    }
-
-    uint32_t actualOriginalCrc, actualOverlayCrc;
-    if (!getZipEntryCrcLocked(originalPath, "resources.arsc", &actualOriginalCrc)) {
-        return false;
-    }
-    if (!getZipEntryCrcLocked(overlayPath, "resources.arsc", &actualOverlayCrc)) {
-        return false;
-    }
-    return cachedOriginalCrc != actualOriginalCrc || cachedOverlayCrc != actualOverlayCrc;
-}
-
-bool AssetManager::getZipEntryCrcLocked(const String8& zipPath, const char* entryFilename,
-                                        uint32_t* pCrc)
-{
-    asset_path ap;
-    ap.path = zipPath;
-    const ZipFileRO* zip = getZipFileLocked(ap);
-    if (zip == NULL) {
-        return false;
-    }
-    const ZipEntryRO entry = zip->findEntryByName(entryFilename);
-    if (entry == NULL) {
-        return false;
-    }
-
-    const bool gotInfo = zip->getEntryInfo(entry, NULL, NULL, NULL, NULL, NULL, (long*)pCrc);
-    zip->releaseEntry(entry);
-
-    return gotInfo;
-}
-
-bool AssetManager::createIdmapFileLocked(const String8& originalPath, const String8& overlayPath,
-                                         const String8& idmapPath)
-{
-    ALOGD("%s: originalPath=%s overlayPath=%s idmapPath=%s\n",
-         __FUNCTION__, originalPath.string(), overlayPath.string(), idmapPath.string());
-    ResTable tables[2];
-    const String8* paths[2] = { &originalPath, &overlayPath };
-    uint32_t originalCrc, overlayCrc;
-    bool retval = false;
-    ssize_t offset = 0;
-    int fd = 0;
-    uint32_t* data = NULL;
-    size_t size;
-
-    for (int i = 0; i < 2; ++i) {
-        asset_path ap;
-        ap.type = kFileTypeRegular;
-        ap.path = *paths[i];
-        Asset* ass = openNonAssetInPathLocked("resources.arsc", Asset::ACCESS_BUFFER, ap);
-        if (ass == NULL) {
-            ALOGW("failed to find resources.arsc in %s\n", ap.path.string());
-            goto error;
-        }
-        tables[i].add(ass, 1, false /* copyData */, NULL /* idMap */);
-    }
-
-    if (!getZipEntryCrcLocked(originalPath, "resources.arsc", &originalCrc)) {
-        ALOGW("failed to retrieve crc for resources.arsc in %s\n", originalPath.string());
-        goto error;
-    }
-    if (!getZipEntryCrcLocked(overlayPath, "resources.arsc", &overlayCrc)) {
-        ALOGW("failed to retrieve crc for resources.arsc in %s\n", overlayPath.string());
-        goto error;
-    }
-
-    if (tables[0].createIdmap(tables[1], originalCrc, overlayCrc,
-                              (void**)&data, &size) != NO_ERROR) {
-        ALOGW("failed to generate idmap data for file %s\n", idmapPath.string());
-        goto error;
-    }
-
-    // This should be abstracted (eg replaced by a stand-alone
-    // application like dexopt, triggered by something equivalent to
-    // installd).
-    fd = TEMP_FAILURE_RETRY(::open(idmapPath.string(), O_WRONLY | O_CREAT | O_TRUNC, 0644));
-    if (fd == -1) {
-        ALOGW("failed to write idmap file %s (open: %s)\n", idmapPath.string(), strerror(errno));
-        goto error_free;
-    }
-    for (;;) {
-        ssize_t written = TEMP_FAILURE_RETRY(write(fd, data + offset, size));
-        if (written < 0) {
-            ALOGW("failed to write idmap file %s (write: %s)\n", idmapPath.string(),
-                 strerror(errno));
-            goto error_close;
-        }
-        size -= (size_t)written;
-        offset += written;
-        if (size == 0) {
-            break;
-        }
-    }
-
-    retval = true;
-error_close:
-    TEMP_FAILURE_RETRY(close(fd));
-error_free:
-    free(data);
-error:
-    return retval;
-}
-
 bool AssetManager::addDefaultAssets()
 {
     const char* root = getenv("ANDROID_ROOT");
@@ -676,6 +574,10 @@
                 // which we want to avoid parsing every time.
                 sharedRes = const_cast<AssetManager*>(this)->
                     mZipSet.getZipResourceTable(ap.path);
+                if (sharedRes != NULL) {
+                    // skip ahead the number of system overlay packages preloaded
+                    i += sharedRes->getTableCount() - 1;
+                }
             }
             if (sharedRes == NULL) {
                 ass = const_cast<AssetManager*>(this)->
@@ -699,6 +601,14 @@
                     ALOGV("Creating shared resources for %s", ap.path.string());
                     sharedRes = new ResTable();
                     sharedRes->add(ass, i + 1, false, idmap);
+#ifdef HAVE_ANDROID_OS
+                    const char* data = getenv("ANDROID_DATA");
+                    LOG_ALWAYS_FATAL_IF(data == NULL, "ANDROID_DATA not set");
+                    String8 overlaysListPath(data);
+                    overlaysListPath.appendPath(kResourceCache);
+                    overlaysListPath.appendPath("overlays.list");
+                    addSystemOverlays(overlaysListPath.string(), ap.path, sharedRes, i);
+#endif
                     sharedRes = const_cast<AssetManager*>(this)->
                         mZipSet.setZipResourceTable(ap.path, sharedRes);
                 }
@@ -773,6 +683,46 @@
     return ass;
 }
 
+void AssetManager::addSystemOverlays(const char* pathOverlaysList,
+        const String8& targetPackagePath, ResTable* sharedRes, size_t offset) const
+{
+    FILE* fin = fopen(pathOverlaysList, "r");
+    if (fin == NULL) {
+        return;
+    }
+
+    char buf[1024];
+    while (fgets(buf, sizeof(buf), fin)) {
+        // format of each line:
+        //   <path to apk><space><path to idmap><newline>
+        char* space = strchr(buf, ' ');
+        char* newline = strchr(buf, '\n');
+        asset_path oap;
+
+        if (space == NULL || newline == NULL || newline < space) {
+            continue;
+        }
+
+        oap.path = String8(buf, space - buf);
+        oap.type = kFileTypeRegular;
+        oap.idmap = String8(space + 1, newline - space - 1);
+
+        Asset* oass = const_cast<AssetManager*>(this)->
+            openNonAssetInPathLocked("resources.arsc",
+                    Asset::ACCESS_BUFFER,
+                    oap);
+
+        if (oass != NULL) {
+            Asset* oidmap = openIdmapLocked(oap);
+            offset++;
+            sharedRes->add(oass, offset + 1, false, oidmap);
+            const_cast<AssetManager*>(this)->mAssetPaths.add(oap);
+            const_cast<AssetManager*>(this)->mZipSet.addOverlay(targetPackagePath, oap);
+        }
+    }
+    fclose(fin);
+}
+
 const ResTable& AssetManager::getResources(bool required) const
 {
     const ResTable* rt = getResTable(required);
@@ -1831,7 +1781,8 @@
     }
 }
 
-sp<AssetManager::SharedZip> AssetManager::SharedZip::get(const String8& path)
+sp<AssetManager::SharedZip> AssetManager::SharedZip::get(const String8& path,
+        bool createIfNotPresent)
 {
     AutoMutex _l(gLock);
     time_t modWhen = getFileModDate(path);
@@ -1839,6 +1790,9 @@
     if (zip != NULL && zip->mModWhen == modWhen) {
         return zip;
     }
+    if (zip == NULL && !createIfNotPresent) {
+        return NULL;
+    }
     zip = new SharedZip(path, modWhen);
     gOpen.add(path, zip);
     return zip;
@@ -1897,6 +1851,20 @@
     return mModWhen == modWhen;
 }
 
+void AssetManager::SharedZip::addOverlay(const asset_path& ap)
+{
+    mOverlays.add(ap);
+}
+
+bool AssetManager::SharedZip::getOverlay(size_t idx, asset_path* out) const
+{
+    if (idx >= mOverlays.size()) {
+        return false;
+    }
+    *out = mOverlays[idx];
+    return true;
+}
+
 AssetManager::SharedZip::~SharedZip()
 {
     //ALOGI("Destroying SharedZip %p %s\n", this, (const char*)mPath);
@@ -2020,6 +1988,22 @@
     return true;
 }
 
+void AssetManager::ZipSet::addOverlay(const String8& path, const asset_path& overlay)
+{
+    int idx = getIndex(path);
+    sp<SharedZip> zip = mZipFile[idx];
+    zip->addOverlay(overlay);
+}
+
+bool AssetManager::ZipSet::getOverlay(const String8& path, size_t idx, asset_path* out) const
+{
+    sp<SharedZip> zip = SharedZip::get(path, false);
+    if (zip == NULL) {
+        return false;
+    }
+    return zip->getOverlay(idx, out);
+}
+
 /*
  * Compute the zip file's index.
  *
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index be163c2..efb589a 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -279,11 +279,37 @@
     if (!assertIdmapHeader(map, mapSize)) {
         return UNKNOWN_ERROR;
     }
+    if (mapSize <= IDMAP_HEADER_SIZE + 1) {
+        ALOGW("corrupt idmap: map size %d too short\n", mapSize);
+        return UNKNOWN_ERROR;
+    }
+    uint32_t typeCount = *(map + IDMAP_HEADER_SIZE);
+    if (typeCount == 0) {
+        ALOGW("corrupt idmap: no types\n");
+        return UNKNOWN_ERROR;
+    }
+    if (IDMAP_HEADER_SIZE + 1 + typeCount > mapSize) {
+        ALOGW("corrupt idmap: number of types %d extends past idmap size %d\n", typeCount, mapSize);
+        return UNKNOWN_ERROR;
+    }
     const uint32_t* p = map + IDMAP_HEADER_SIZE + 1;
+    // find first defined type
     while (*p == 0) {
         ++p;
+        if (--typeCount == 0) {
+            ALOGW("corrupt idmap: types declared, none found\n");
+            return UNKNOWN_ERROR;
+        }
     }
-    *outId = (map[*p + IDMAP_HEADER_SIZE + 2] >> 24) & 0x000000ff;
+
+    // determine package id from first entry of first type
+    const uint32_t offset = *p + IDMAP_HEADER_SIZE + 2;
+    if (offset > mapSize) {
+        ALOGW("corrupt idmap: entry offset %d points outside map size %d\n", offset, mapSize);
+        return UNKNOWN_ERROR;
+    }
+    *outId = (map[offset] >> 24) & 0x000000ff;
+
     return NO_ERROR;
 }
 
@@ -5536,23 +5562,30 @@
     return NO_ERROR;
 }
 
-status_t ResTable::createIdmap(const ResTable& overlay, uint32_t originalCrc, uint32_t overlayCrc,
-                               void** outData, size_t* outSize) const
+status_t ResTable::createIdmap(const ResTable& overlay,
+        uint32_t targetCrc, uint32_t overlayCrc,
+        const char* targetPath, const char* overlayPath,
+        void** outData, size_t* outSize) const
 {
     // see README for details on the format of map
     if (mPackageGroups.size() == 0) {
+        ALOGW("idmap: target package has no package groups, cannot create idmap\n");
         return UNKNOWN_ERROR;
     }
     if (mPackageGroups[0]->packages.size() == 0) {
+        ALOGW("idmap: target package has no packages in its first package group, "
+                "cannot create idmap\n");
         return UNKNOWN_ERROR;
     }
 
     Vector<Vector<uint32_t> > map;
+    // overlaid packages are assumed to contain only one package group
     const PackageGroup* pg = mPackageGroups[0];
     const Package* pkg = pg->packages[0];
     size_t typeCount = pkg->types.size();
     // starting size is header + first item (number of types in map)
     *outSize = (IDMAP_HEADER_SIZE + 1) * sizeof(uint32_t);
+    // overlay packages are assumed to contain only one package group
     const String16 overlayPackage(overlay.mPackageGroups[0]->packages[0]->package->name);
     const uint32_t pkg_id = pkg->package->id << 24;
 
@@ -5628,8 +5661,22 @@
     }
     uint32_t* data = (uint32_t*)*outData;
     *data++ = htodl(IDMAP_MAGIC);
-    *data++ = htodl(originalCrc);
+    *data++ = htodl(targetCrc);
     *data++ = htodl(overlayCrc);
+    const char* paths[] = { targetPath, overlayPath };
+    for (int j = 0; j < 2; ++j) {
+        char* p = (char*)data;
+        const char* path = paths[j];
+        const size_t I = strlen(path);
+        if (I > 255) {
+            ALOGV("path exceeds expected 255 characters: %s\n", path);
+            return UNKNOWN_ERROR;
+        }
+        for (size_t i = 0; i < 256; ++i) {
+            *p++ = i < I ? path[i] : '\0';
+        }
+        data += 256 / sizeof(uint32_t);
+    }
     const size_t mapSize = map.size();
     *data++ = htodl(mapSize);
     size_t offset = mapSize;
@@ -5644,6 +5691,10 @@
             offset += N;
         }
     }
+    if (offset == mapSize) {
+        ALOGW("idmap: no resources in overlay package present in base package\n");
+        return UNKNOWN_ERROR;
+    }
     for (size_t i = 0; i < mapSize; ++i) {
         const Vector<uint32_t>& vector = map.itemAt(i);
         const size_t N = vector.size();
@@ -5665,14 +5716,25 @@
 }
 
 bool ResTable::getIdmapInfo(const void* idmap, size_t sizeBytes,
-                            uint32_t* pOriginalCrc, uint32_t* pOverlayCrc)
+                            uint32_t* pTargetCrc, uint32_t* pOverlayCrc,
+                            String8* pTargetPath, String8* pOverlayPath)
 {
     const uint32_t* map = (const uint32_t*)idmap;
     if (!assertIdmapHeader(map, sizeBytes)) {
         return false;
     }
-    *pOriginalCrc = map[1];
-    *pOverlayCrc = map[2];
+    if (pTargetCrc) {
+        *pTargetCrc = map[1];
+    }
+    if (pOverlayCrc) {
+        *pOverlayCrc = map[2];
+    }
+    if (pTargetPath) {
+        pTargetPath->setTo(reinterpret_cast<const char*>(map + 3));
+    }
+    if (pOverlayPath) {
+        pOverlayPath->setTo(reinterpret_cast<const char*>(map + 3 + 256 / sizeof(uint32_t)));
+    }
     return true;
 }
 
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 8bd9de0..21cf658 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -685,7 +685,8 @@
     propertyDirtyViewport = false;
     propertyEnable3d = false;
     propertyCameraDistance = 1.0f;
-    propertyShadowStrength = 0x3f;
+    propertyAmbientShadowStrength = 0x3f;
+    propertySpotShadowStrength = 0x3f;
 
     propertyLightPosXScale = 0.5f;
     propertyLightPosYScale = 0.0f;
@@ -704,9 +705,13 @@
         propertyDirtyViewport = true;
         ALOGD("camera dist multiplier = %.2f", propertyCameraDistance);
         return;
-    } else if (!strcmp(name, "shadowStrength")) {
-        propertyShadowStrength = atoi(value);
-        ALOGD("shadow strength = 0x%x out of 0xff", propertyShadowStrength);
+    } else if (!strcmp(name, "ambientShadowStrength")) {
+        propertyAmbientShadowStrength = atoi(value);
+        ALOGD("ambient shadow strength = 0x%x out of 0xff", propertyAmbientShadowStrength);
+        return;
+    } else if (!strcmp(name, "spotShadowStrength")) {
+        propertySpotShadowStrength = atoi(value);
+        ALOGD("spot shadow strength = 0x%x out of 0xff", propertySpotShadowStrength);
         return;
     } else if (!strcmp(name, "lightPosXScale")) {
         propertyLightPosXScale = fmin(fmax(atof(value), 0.0), 1.0);
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index e7ba9ac..2cc15cc 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -367,7 +367,8 @@
     float propertyLightPosXScale;
     float propertyLightPosYScale;
     float propertyLightPosZScale;
-    int propertyShadowStrength;
+    int propertyAmbientShadowStrength;
+    int propertySpotShadowStrength;
 
 private:
     enum OverdrawColorSet {
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index ed05d04..5d3d393 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -31,7 +31,6 @@
         , mLayer(layer)
         , mRenderer(renderer)
         , mCaches(Caches::getInstance()) {
-    mCaches.resourceCache.incrementRefcount(mLayer);
     mWidth = mLayer->layer.getWidth();
     mHeight = mLayer->layer.getHeight();
     mBlend = mLayer->isBlend();
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index 0350eef..9800c2f 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -34,6 +34,8 @@
 // of a render pass
 class DeferredLayerUpdater {
 public:
+    // Note that DeferredLayerUpdater assumes it is taking ownership of the layer
+    // and will not call incrementRef on it as a result.
     ANDROID_API DeferredLayerUpdater(Layer* layer, OpenGLRenderer* renderer = 0);
     ANDROID_API ~DeferredLayerUpdater();
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index fee916b..9b253a6 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -3214,7 +3214,6 @@
     mCaches.enableScissor();
 
     SkPaint paint;
-    paint.setARGB(mCaches.propertyShadowStrength, 0, 0, 0);
     paint.setAntiAlias(true); // want to use AlphaVertex
 
     // tessellate caster outline into a 2d polygon
@@ -3238,19 +3237,25 @@
     }
 
     // draw caster's shadows
-    VertexBuffer ambientShadowVertexBuffer;
-    ShadowTessellator::tessellateAmbientShadow(casterPolygon, casterVertexCount,
-            ambientShadowVertexBuffer);
-    drawVertexBuffer(ambientShadowVertexBuffer, &paint);
+    if (mCaches.propertyAmbientShadowStrength > 0) {
+        paint.setARGB(mCaches.propertyAmbientShadowStrength, 0, 0, 0);
+        VertexBuffer ambientShadowVertexBuffer;
+        ShadowTessellator::tessellateAmbientShadow(casterPolygon, casterVertexCount,
+                ambientShadowVertexBuffer);
+        drawVertexBuffer(ambientShadowVertexBuffer, &paint);
+    }
 
-    VertexBuffer spotShadowVertexBuffer;
-    Vector3 lightPosScale(mCaches.propertyLightPosXScale,
-            mCaches.propertyLightPosYScale, mCaches.propertyLightPosZScale);
-    ShadowTessellator::tessellateSpotShadow(casterPolygon, casterVertexCount,
-            lightPosScale, *currentTransform(), getWidth(), getHeight(),
-            spotShadowVertexBuffer);
+    if (mCaches.propertySpotShadowStrength > 0) {
+        paint.setARGB(mCaches.propertySpotShadowStrength, 0, 0, 0);
+        VertexBuffer spotShadowVertexBuffer;
+        Vector3 lightPosScale(mCaches.propertyLightPosXScale,
+                mCaches.propertyLightPosYScale, mCaches.propertyLightPosZScale);
+        ShadowTessellator::tessellateSpotShadow(casterPolygon, casterVertexCount,
+                lightPosScale, *currentTransform(), getWidth(), getHeight(),
+                spotShadowVertexBuffer);
 
-    drawVertexBuffer(spotShadowVertexBuffer, &paint);
+        drawVertexBuffer(spotShadowVertexBuffer, &paint);
+    }
 
     return DrawGlInfo::kStatusDrew;
 }
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 9fe3ac1..115786c 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -333,6 +333,10 @@
      * <p>
      * The application is responsible for calling release() on the Surface when
      * done.
+     * <p>
+     * The Surface must be rendered with a hardware-accelerated API, such as OpenGL ES.
+     * {@link android.view.Surface#lockCanvas(android.graphics.Rect)} may fail or produce
+     * unexpected results.
      */
     public native final Surface createInputSurface();
 
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 01485b8..72f3e1a 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1426,7 +1426,7 @@
         }
 
         int firstSlash = path.lastIndexOf('/');
-        if (firstSlash == 0) {
+        if (firstSlash <= 0) {
             return false;
         }
         String parent = path.substring(0,  firstSlash);
diff --git a/packages/BackupRestoreConfirmation/res/values-sw/strings.xml b/packages/BackupRestoreConfirmation/res/values-sw/strings.xml
index 619a6db..4e35b91 100644
--- a/packages/BackupRestoreConfirmation/res/values-sw/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sw/strings.xml
@@ -18,17 +18,17 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Kuhifadhi kikamilifu"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Kurejesha kila kitu"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Chelezo kamili la data iliyounganishwa kwenye eneo kazi la kompyuta limeombwa. Unataka kuruhusu hii kutendeka?\n\n Ikiwa hukuomba chelezo mwenyewe, usikubali uendeshaji kuendelea."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Ombi la kuhifadhi nakala rudufu kamili za data kwenye eneo kazi la kompyuta iliyounganishwa limewasilishwa. Ungependa shughuli hii ufanyike?\n\n Ikiwa sio wewe uliyewasilisha ombi hili, usikubali shughuli hii iendelee."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Hifadhi nakala ya data yangu"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Usicheleze"</string>
     <string name="restore_confirm_text" msgid="7499866728030461776">"Kurejesha kamili kwa data nzima kutoka kwa eneo kazi la kompyuta lililounganishwa limeombwa. Unataka kuruhusu hii kutendeka?\n\n Ikiwa hukuweza kurejesha upya mwenyewe, usiruhusu uendeshaji huu kuendelea. Hii itaweka upya data yoyote iliyo kwenye kifaa hiki sasa!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Rejesha upya data yangu"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Usirejeshe upya"</string>
-    <string name="current_password_text" msgid="8268189555578298067">"Tafadhali ingiza nenosiri lako la chelezo hapo chini:"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Tafadhali ingiza nenosiri unalotumia kuhifadhi nakala rudufu hapo chini:"</string>
     <string name="device_encryption_restore_text" msgid="1570864916855208992">"Tafadhali ingiza nenosiri la usimbaji fiche wa kifaa chako hapo chini."</string>
     <string name="device_encryption_backup_text" msgid="5866590762672844664">"Tafadhali ingiza nenosiri lako la msimbo fiche hapo chini. Pia litatumika kusimba fiche jalidi ya hifadhi."</string>
-    <string name="backup_enc_password_text" msgid="4981585714795233099">"Tafadhali ingiza nenosiri la kutumia kwa usimbaji fiche wa chelezo ya data kamili. Ikiwa hii itawachwa wazi, nenosiri lako la sasa litatumika:"</string>
-    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ikiwa unataka kusimba fiche data nzima ya kucheleza, ingiza nenosiri la hapo chini:"</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Tafadhali ingiza nenosiri la kutumia katika kusimba nakala rudufu kamili za data kwa njia fiche. Ikiwa hii itawachwa wazi, nenosiri lako la sasa litatumika:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ikiwa unataka kusimba kwa njia fiche nakala rudufu za data, ingiza nenosiri lililo hapo chini:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Ikiwa data iliyorejeshwa upya, tafadhali ingiza nenosiri lililo hapo chini:"</string>
     <string name="toast_backup_started" msgid="550354281452756121">"Inaanza kuhifadhi..."</string>
     <string name="toast_backup_ended" msgid="3818080769548726424">"Imemaliza kuhifadhi"</string>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
index baf520e..43165eb 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
@@ -330,7 +330,7 @@
 
     private boolean allowNotificationsOnSecureKeyguard() {
         ContentResolver cr = mContext.getContentResolver();
-        return Settings.Secure.getInt(cr, Settings.Secure.LOCK_SCREEN_ALLOW_NOTIFICATIONS, 0) == 1;
+        return Settings.Global.getInt(cr, Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0) == 1;
     }
 
     private KeyguardViewBase inflateKeyguardView(Bundle options, int layoutId) {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
index 914fdc4..e0ee4e0 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
@@ -151,13 +151,13 @@
 
     /**
      * Allow the user to expand the status bar when a SECURE keyguard is engaged
-     * and {@link Settings.Secure#LOCK_SCREEN_ALLOW_NOTIFICATIONS} is set
+     * and {@link Settings.Global#LOCK_SCREEN_SHOW_NOTIFICATIONS} is set
      * (private notifications will be masked).
      */
     private static final boolean ENABLE_SECURE_STATUS_BAR_EXPAND = true;
 
     /**
-     * Default value of {@link Settings.Secure#LOCK_SCREEN_ALLOW_NOTIFICATIONS}.
+     * Default value of {@link Settings.Global#LOCK_SCREEN_SHOW_NOTIFICATIONS}.
      */
     private static final boolean ALLOW_NOTIFICATIONS_DEFAULT = false;
 
@@ -258,7 +258,7 @@
     private int mLockSoundStreamId;
 
     /**
-     * Tracks value of {@link Settings.Secure#LOCK_SCREEN_ALLOW_NOTIFICATIONS}.
+     * Tracks value of {@link Settings.Global#LOCK_SCREEN_SHOW_NOTIFICATIONS}.
      */
     private boolean mAllowNotificationsWhenSecure;
 
@@ -913,9 +913,9 @@
 
         // note whether notification access should be allowed
         mAllowNotificationsWhenSecure = ENABLE_SECURE_STATUS_BAR_EXPAND
-                && 0 != Settings.Secure.getInt(
+                && 0 != Settings.Global.getInt(
                         mContext.getContentResolver(),
-                        Settings.Secure.LOCK_SCREEN_ALLOW_NOTIFICATIONS,
+                        Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS,
                         ALLOW_NOTIFICATIONS_DEFAULT ? 1 : 0);
 
         // if the keyguard is already showing, don't bother
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 91ae973..7ff52de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -46,6 +46,7 @@
 import android.service.notification.StatusBarNotification;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.SparseBooleanArray;
 import android.view.Display;
 import android.view.IWindowManager;
 import android.view.LayoutInflater;
@@ -131,7 +132,10 @@
     protected IDreamManager mDreamManager;
     PowerManager mPowerManager;
     protected int mRowHeight;
-    private boolean mPublicMode = false;
+
+    // public mode, private notifications, etc
+    private boolean mLockscreenPublicMode = false;
+    private final SparseBooleanArray mUsersAllowingPrivateNotifications = new SparseBooleanArray();
 
     // UI-specific methods
 
@@ -159,7 +163,7 @@
         return mDeviceProvisioned;
     }
 
-    private ContentObserver mProvisioningObserver = new ContentObserver(new Handler()) {
+    private final ContentObserver mProvisioningObserver = new ContentObserver(mHandler) {
         @Override
         public void onChange(boolean selfChange) {
             final boolean provisioned = 0 != Settings.Global.getInt(
@@ -171,6 +175,17 @@
         }
     };
 
+    private final ContentObserver mLockscreenSettingsObserver = new ContentObserver(mHandler) {
+        @Override
+        public void onChange(boolean selfChange) {
+            // We don't know which user changed LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+            // so we just dump our cache ...
+            mUsersAllowingPrivateNotifications.clear();
+            // ... and refresh all the notifications
+            updateNotificationIcons();
+        }
+    };
+
     private RemoteViews.OnClickHandler mOnClickHandler = new RemoteViews.OnClickHandler() {
         @Override
         public boolean onClickHandler(View view, PendingIntent pendingIntent, Intent fillInIntent) {
@@ -229,6 +244,12 @@
                 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), true,
                 mProvisioningObserver);
 
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
+                true,
+                mLockscreenSettingsObserver,
+                UserHandle.USER_ALL);
+
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
 
@@ -550,12 +571,35 @@
 
     public abstract void resetHeadsUpDecayTimer();
 
-    public void setPublicMode(boolean publicMode) {
-        mPublicMode = publicMode;
+    /**
+     * Save the current "public" (locked and secure) state of the lockscreen.
+     */
+    public void setLockscreenPublicMode(boolean publicMode) {
+        mLockscreenPublicMode = publicMode;
     }
 
-    public boolean isPublicMode() {
-        return mPublicMode;
+    public boolean isLockscreenPublicMode() {
+        return mLockscreenPublicMode;
+    }
+
+    /**
+     * Has the given user chosen to allow their private (full) notifications to be shown even
+     * when the lockscreen is in "public" (secure & locked) mode?
+     */
+    public boolean userAllowsPrivateNotificationsInPublic(int userHandle) {
+        if (userHandle == UserHandle.USER_ALL) {
+            return true;
+        }
+
+        if (mUsersAllowingPrivateNotifications.indexOfKey(userHandle) < 0) {
+            final boolean allowed = 0 != Settings.Secure.getIntForUser(
+                    mContext.getContentResolver(),
+                    Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, userHandle);
+            mUsersAllowingPrivateNotifications.append(userHandle, allowed);
+            return allowed;
+        }
+
+        return mUsersAllowingPrivateNotifications.get(userHandle);
     }
 
     protected class H extends Handler {
@@ -1136,8 +1180,9 @@
             StatusBarNotification notification, boolean isHeadsUp) {
         final RemoteViews contentView = notification.getNotification().contentView;
         final RemoteViews bigContentView = notification.getNotification().bigContentView;
-        final RemoteViews publicContentView
-                = notification.getNotification().publicVersion.contentView;
+        final Notification publicVersion = notification.getNotification().publicVersion;
+        final RemoteViews publicContentView = publicVersion != null ? publicVersion.contentView
+                : null;
 
         // Reapply the RemoteViews
         contentView.reapply(mContext, entry.expanded, mOnClickHandler);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index e5bdd59..2114991 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1033,8 +1033,10 @@
             if (!notificationIsForCurrentUser(ent.notification)) continue;
             final int vis = ent.notification.getNotification().visibility;
             if (vis != Notification.VISIBILITY_SECRET) {
-                // when isPublicMode() we show the public form of VISIBILITY_PRIVATE notifications
-                ent.row.setShowingPublic(isPublicMode() && vis == Notification.VISIBILITY_PRIVATE);
+                // when isLockscreenPublicMode() we show the public form of VISIBILITY_PRIVATE notifications
+                ent.row.setShowingPublic(isLockscreenPublicMode()
+                        && vis == Notification.VISIBILITY_PRIVATE
+                        && !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId()));
                 toShow.add(ent.row);
             }
         }
@@ -1087,9 +1089,10 @@
             if (!((provisioned && ent.notification.getScore() >= HIDE_ICONS_BELOW_SCORE)
                     || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
             if (!notificationIsForCurrentUser(ent.notification)) continue;
-            if (isPublicMode()
+            if (isLockscreenPublicMode()
                     && ent.notification.getNotification().visibility
-                            == Notification.VISIBILITY_SECRET) {
+                            == Notification.VISIBILITY_SECRET
+                    && !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId())) {
                 // in "public" mode (atop a secure keyguard), secret notifs are totally hidden
                 continue;
             }
@@ -1343,10 +1346,10 @@
         } else if ((diff & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) {
             if ((state & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) {
                 // we are outside a secure keyguard, so we need to switch to "public" mode
-                setPublicMode(true);
+                setLockscreenPublicMode(true);
             } else {
                 // user has authenticated the device; full notifications may be shown
-                setPublicMode(false);
+                setLockscreenPublicMode(false);
             }
             updateNotificationIcons();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
index 11cba7b..48ee1ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
@@ -782,7 +782,6 @@
     void addRemoteDisplayTile(QuickSettingsTileView view, RefreshCallback cb) {
         mRemoteDisplayTile = view;
         mRemoteDisplayCallback = cb;
-        final int[] count = new int[1];
         mRemoteDisplayTile.setOnPrepareListener(new QuickSettingsTileView.OnPrepareListener() {
             @Override
             public void onPrepare() {
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 2c36ab7..0adb32f 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -311,6 +311,8 @@
             }
 
             mUsbStorageNotification.setLatestEventInfo(mContext, title, message, pi);
+            mUsbStorageNotification.visibility = Notification.VISIBILITY_PUBLIC;
+
             final boolean adbOn = 1 == Settings.Global.getInt(
                 mContext.getContentResolver(),
                 Settings.Global.ADB_ENABLED,
@@ -401,6 +403,7 @@
 
             mMediaStorageNotification.icon = icon;
             mMediaStorageNotification.setLatestEventInfo(mContext, title, message, pi);
+            mMediaStorageNotification.visibility = Notification.VISIBILITY_PUBLIC;
         }
 
         final int notificationId = mMediaStorageNotification.icon;
diff --git a/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java b/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java
index 3cc74fc..5602206 100644
--- a/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java
+++ b/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java
@@ -84,9 +84,9 @@
         return exit != null ? exit.getDuration() : 0;
     }
 
-    public void loadSetting() {
+    public void loadSetting(int currentUserId) {
         mConfirmed = false;
-        mCurrentUserId = getCurrentUser();
+        mCurrentUserId = currentUserId;
         if (DEBUG) Slog.d(TAG, String.format("loadSetting() mCurrentUserId=%d resetForPanic=%s",
                 mCurrentUserId, mUserPanicResets.get(mCurrentUserId, false)));
         String value = null;
@@ -159,14 +159,6 @@
         saveSetting();
     }
 
-    private int getCurrentUser() {
-        try {
-            return ActivityManagerNative.getDefault().getCurrentUser().id;
-        } catch (RemoteException e) {
-            throw new IllegalStateException(e); // local call
-        }
-    }
-
     private void handleHide() {
         if (mClingWindow != null) {
             if (DEBUG) Slog.d(TAG, "Hiding immersive mode confirmation");
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index ece4fe7..ada649d 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1168,7 +1168,7 @@
                 updateRotation = true;
             }
             if (mImmersiveModeConfirmation != null) {
-                mImmersiveModeConfirmation.loadSetting();
+                mImmersiveModeConfirmation.loadSetting(mCurrentUserId);
             }
             PolicyControl.reloadFromSetting(mContext);
         }
@@ -2569,7 +2569,8 @@
     @Override
     public void getContentInsetHintLw(WindowManager.LayoutParams attrs, Rect contentInset) {
         final int fl = PolicyControl.getWindowFlags(null, attrs);
-        final int systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
+        final int sysuiVis = PolicyControl.getSystemUiVisibility(null, attrs);
+        final int systemUiVisibility = (sysuiVis | attrs.subtreeSystemUiVisibility);
 
         if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR))
                 == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) {
@@ -2953,7 +2954,7 @@
 
         final int fl = PolicyControl.getWindowFlags(win, attrs);
         final int sim = attrs.softInputMode;
-        final int sysUiFl = PolicyControl.getSystemUiVisibility(win);
+        final int sysUiFl = PolicyControl.getSystemUiVisibility(win, null);
 
         final Rect pf = mTmpParentFrame;
         final Rect df = mTmpDisplayFrame;
@@ -5078,7 +5079,7 @@
             return 0;
         }
 
-        int tmpVisibility = PolicyControl.getSystemUiVisibility(win)
+        int tmpVisibility = PolicyControl.getSystemUiVisibility(win, null)
                 & ~mResettingSystemUiFlags
                 & ~mForceClearedSystemUiFlags;
         if (mForcingShowNavBar && win.getSurfaceLayer() < mForcingShowNavBarLayer) {
diff --git a/policy/src/com/android/internal/policy/impl/PolicyControl.java b/policy/src/com/android/internal/policy/impl/PolicyControl.java
index 4f355dd..ffdb520 100644
--- a/policy/src/com/android/internal/policy/impl/PolicyControl.java
+++ b/policy/src/com/android/internal/policy/impl/PolicyControl.java
@@ -61,16 +61,17 @@
     private static Filter sImmersiveStatusFilter;
     private static Filter sImmersiveNavigationFilter;
 
-    public static int getSystemUiVisibility(WindowState win) {
-        int vis = win.getSystemUiVisibility();
-        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(win)) {
+    public static int getSystemUiVisibility(WindowState win, LayoutParams attrs) {
+        attrs = attrs != null ? attrs : win.getAttrs();
+        int vis = win != null ? win.getSystemUiVisibility() : attrs.systemUiVisibility;
+        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
             vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                     | View.SYSTEM_UI_FLAG_FULLSCREEN
                     | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
             vis &= ~(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                     | View.STATUS_BAR_TRANSLUCENT);
         }
-        if (sImmersiveNavigationFilter != null && sImmersiveNavigationFilter.matches(win)) {
+        if (sImmersiveNavigationFilter != null && sImmersiveNavigationFilter.matches(attrs)) {
             vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                     | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                     | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
@@ -81,20 +82,22 @@
     }
 
     public static int getWindowFlags(WindowState win, LayoutParams attrs) {
-        int flags = (attrs != null ? attrs : win.getAttrs()).flags;
-        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(win)) {
+        attrs = attrs != null ? attrs : win.getAttrs();
+        int flags = attrs.flags;
+        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
             flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
             flags &= ~(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                     | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
         }
-        if (sImmersiveNavigationFilter != null && sImmersiveNavigationFilter.matches(win)) {
+        if (sImmersiveNavigationFilter != null && sImmersiveNavigationFilter.matches(attrs)) {
             flags &= ~WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
         }
         return flags;
     }
 
     public static int adjustClearableFlags(WindowState win, int clearableFlags) {
-        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(win)) {
+        final LayoutParams attrs = win != null ? win.getAttrs() : null;
+        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
             clearableFlags &= ~View.SYSTEM_UI_FLAG_FULLSCREEN;
         }
         return clearableFlags;
@@ -187,9 +190,7 @@
             mBlacklist = blacklist;
         }
 
-        boolean matches(WindowState win) {
-            if (win == null) return false;
-            LayoutParams attrs = win.getAttrs();
+        boolean matches(LayoutParams attrs) {
             if (attrs == null) return false;
             boolean isApp = attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
                     && attrs.type <= WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
diff --git a/rs/java/android/renderscript/AllocationAdapter.java b/rs/java/android/renderscript/AllocationAdapter.java
index 6c1b1ed..3522a52 100644
--- a/rs/java/android/renderscript/AllocationAdapter.java
+++ b/rs/java/android/renderscript/AllocationAdapter.java
@@ -219,7 +219,6 @@
     }
 
     static public AllocationAdapter create2D(RenderScript rs, Allocation a) {
-        android.util.Log.e("rs", "create2d " + a);
         rs.validate();
         AllocationAdapter aa = new AllocationAdapter(0, rs, a);
         aa.mConstrainedLOD = true;
diff --git a/rs/java/android/renderscript/BaseObj.java b/rs/java/android/renderscript/BaseObj.java
index 842aa23..b386dd7 100644
--- a/rs/java/android/renderscript/BaseObj.java
+++ b/rs/java/android/renderscript/BaseObj.java
@@ -122,7 +122,8 @@
             // must include nObjDestroy in the critical section
             ReentrantReadWriteLock.ReadLock rlock = mRS.mRWLock.readLock();
             rlock.lock();
-            if(mRS.isAlive()) {
+            // AllocationAdapters are BaseObjs with an ID of 0 but should not be passed to nObjDestroy
+            if(mRS.isAlive() && mID != 0) {
                 mRS.nObjDestroy(mID);
             }
             rlock.unlock();
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index a4a9070..89dba9f 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -99,6 +99,20 @@
 
     static File mCacheDir;
 
+    // this should be a monotonically increasing ID
+    // used in conjunction with the API version of a device
+    static final long sMinorID = 1;
+
+    /**
+     * Returns an identifier that can be used to identify a particular
+     * minor version of RS.
+     *
+     * @hide
+     */
+    public static long getMinorID() {
+        return sMinorID;
+    }
+
      /**
      * Sets the directory to use as a persistent storage for the
      * renderscript object file cache.
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 9349730..ba08a2e 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2352,7 +2352,7 @@
         if (ConnectivityManager.isNetworkTypeMobile(type)) {
             timeout = Settings.Global.getInt(mContext.getContentResolver(),
                                              Settings.Global.DATA_ACTIVITY_TIMEOUT_MOBILE,
-                                             0);
+                                             5);
             // Canonicalize mobile network type
             type = ConnectivityManager.TYPE_MOBILE;
         } else if (ConnectivityManager.TYPE_WIFI == type) {
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index eebd1c5..fc68205 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -73,6 +73,9 @@
 import com.android.server.location.LocationFudger;
 import com.android.server.location.LocationProviderInterface;
 import com.android.server.location.LocationProviderProxy;
+import com.android.server.location.LocationRequestStatistics;
+import com.android.server.location.LocationRequestStatistics.PackageProviderKey;
+import com.android.server.location.LocationRequestStatistics.PackageStatistics;
 import com.android.server.location.MockProvider;
 import com.android.server.location.PassiveProvider;
 
@@ -178,6 +181,8 @@
     private final HashMap<String, ArrayList<UpdateRecord>> mRecordsByProvider =
             new HashMap<String, ArrayList<UpdateRecord>>();
 
+    private final LocationRequestStatistics mRequestStatistics = new LocationRequestStatistics();
+
     // mapping from provider name to last known location
     private final HashMap<String, Location> mLastLocation = new HashMap<String, Location>();
 
@@ -568,7 +573,7 @@
                     if (isAllowedByCurrentUserSettingsLocked(updateRecord.mProvider)) {
                         requestingLocation = true;
                         LocationProviderInterface locationProvider
-                            = mProvidersByName.get(updateRecord.mProvider);
+                                = mProvidersByName.get(updateRecord.mProvider);
                         ProviderProperties properties = locationProvider != null
                                 ? locationProvider.getProperties() : null;
                         if (properties != null
@@ -813,7 +818,7 @@
                     long identity = Binder.clearCallingIdentity();
                     receiver.decrementPendingBroadcastsLocked();
                     Binder.restoreCallingIdentity(identity);
-               }
+                }
             }
         }
     }
@@ -1288,13 +1293,18 @@
             if (!records.contains(this)) {
                 records.add(this);
             }
+
+            // Update statistics for historical location requests by package/provider
+            mRequestStatistics.startRequesting(
+                    mReceiver.mPackageName, provider, request.getInterval());
         }
 
         /**
-         * Method to be called when a record will no longer be used.  Calling this multiple times
-         * must have the same effect as calling it once.
+         * Method to be called when a record will no longer be used.
          */
         void disposeLocked(boolean removeReceiver) {
+            mRequestStatistics.stopRequesting(mReceiver.mPackageName, mProvider);
+
             // remove from mRecordsByProvider
             ArrayList<UpdateRecord> globalRecords = mRecordsByProvider.get(this.mProvider);
             if (globalRecords != null) {
@@ -1541,6 +1551,7 @@
         if (oldRecords != null) {
             // Call dispose() on the obsolete update records.
             for (UpdateRecord record : oldRecords.values()) {
+                // Update statistics for historical location requests by package/provider
                 record.disposeLocked(false);
             }
             // Accumulate providers
@@ -1762,7 +1773,7 @@
     @Override
     public ProviderProperties getProviderProperties(String provider) {
         if (mProvidersByName.get(provider) == null) {
-          return null;
+            return null;
         }
 
         checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(),
@@ -1965,7 +1976,7 @@
         // Fetch latest status update time
         long newStatusUpdateTime = p.getStatusUpdateTime();
 
-       // Get latest status
+        // Get latest status
         Bundle extras = new Bundle();
         int status = p.getStatus(extras);
 
@@ -2179,7 +2190,7 @@
         }
 
         if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) !=
-            PackageManager.PERMISSION_GRANTED) {
+                PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission");
         }
     }
@@ -2351,13 +2362,20 @@
             for (Receiver receiver : mReceivers.values()) {
                 pw.println("    " + receiver);
             }
-            pw.println("  Records by Provider:");
+            pw.println("  Active Records by Provider:");
             for (Map.Entry<String, ArrayList<UpdateRecord>> entry : mRecordsByProvider.entrySet()) {
                 pw.println("    " + entry.getKey() + ":");
                 for (UpdateRecord record : entry.getValue()) {
                     pw.println("      " + record);
                 }
             }
+            pw.println("  Historical Records by Provider:");
+            for (Map.Entry<PackageProviderKey, PackageStatistics> entry
+                    : mRequestStatistics.statistics.entrySet()) {
+                PackageProviderKey key = entry.getKey();
+                PackageStatistics stats = entry.getValue();
+                pw.println("    " + key.packageName + ": " + key.providerName + ": " + stats);
+            }
             pw.println("  Last Known Locations:");
             for (Map.Entry<String, Location> entry : mLastLocation.entrySet()) {
                 String provider = entry.getKey();
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index e6e4bca..607def6 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -73,13 +73,16 @@
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 
+import org.apache.commons.codec.binary.Hex;
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
 import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
 import java.security.NoSuchAlgorithmException;
 import java.security.spec.InvalidKeySpecException;
 import java.security.spec.KeySpec;
@@ -91,6 +94,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -189,6 +193,12 @@
         public static final int FstrimCompleted                = 700;
     }
 
+    /** List of crypto types.
+      * These must match CRYPT_TYPE_XXX in cryptfs.h AND their
+      * corresponding commands in CommandListener.cpp */
+    public static final String[] CRYPTO_TYPES
+        = { "password", "default", "pattern", "pin" };
+
     private Context mContext;
     private NativeDaemonConnector mConnector;
 
@@ -388,18 +398,37 @@
     }
 
     class ShutdownCallBack extends UnmountCallBack {
-        IMountShutdownObserver observer;
-        ShutdownCallBack(String path, IMountShutdownObserver observer) {
+        MountShutdownLatch mMountShutdownLatch;
+        ShutdownCallBack(String path, final MountShutdownLatch mountShutdownLatch) {
             super(path, true, false);
-            this.observer = observer;
+            mMountShutdownLatch = mountShutdownLatch;
         }
 
         @Override
         void handleFinished() {
             int ret = doUnmountVolume(path, true, removeEncryption);
-            if (observer != null) {
+            Slog.i(TAG, "Unmount completed: " + path + ", result code: " + ret);
+            mMountShutdownLatch.countDown();
+        }
+    }
+
+    static class MountShutdownLatch {
+        private IMountShutdownObserver mObserver;
+        private AtomicInteger mCount;
+
+        MountShutdownLatch(final IMountShutdownObserver observer, int count) {
+            mObserver = observer;
+            mCount = new AtomicInteger(count);
+        }
+
+        void countDown() {
+            boolean sendShutdown = false;
+            if (mCount.decrementAndGet() == 0) {
+                sendShutdown = true;
+            }
+            if (sendShutdown && mObserver != null) {
                 try {
-                    observer.onShutDownComplete(ret);
+                    mObserver.onShutDownComplete(StorageResultCode.OperationSucceeded);
                 } catch (RemoteException e) {
                     Slog.w(TAG, "RemoteException when shutting down");
                 }
@@ -1427,6 +1456,10 @@
 
         Slog.i(TAG, "Shutting down");
         synchronized (mVolumesLock) {
+            // Get all volumes to be unmounted.
+            MountShutdownLatch mountShutdownLatch = new MountShutdownLatch(observer,
+                                                            mVolumeStates.size());
+
             for (String path : mVolumeStates.keySet()) {
                 String state = mVolumeStates.get(path);
 
@@ -1462,19 +1495,16 @@
 
                 if (state.equals(Environment.MEDIA_MOUNTED)) {
                     // Post a unmount message.
-                    ShutdownCallBack ucb = new ShutdownCallBack(path, observer);
+                    ShutdownCallBack ucb = new ShutdownCallBack(path, mountShutdownLatch);
                     mHandler.sendMessage(mHandler.obtainMessage(H_UNMOUNT_PM_UPDATE, ucb));
                 } else if (observer != null) {
                     /*
-                     * Observer is waiting for onShutDownComplete when we are done.
-                     * Since nothing will be done send notification directly so shutdown
-                     * sequence can continue.
+                     * Count down, since nothing will be done. The observer will be
+                     * notified when we are done so shutdown sequence can continue.
                      */
-                    try {
-                        observer.onShutDownComplete(StorageResultCode.OperationSucceeded);
-                    } catch (RemoteException e) {
-                        Slog.w(TAG, "RemoteException when shutting down");
-                    }
+                    mountShutdownLatch.countDown();
+                    Slog.i(TAG, "Unmount completed: " + path +
+                        ", result code: " + StorageResultCode.OperationSucceeded);
                 }
             }
         }
@@ -2036,6 +2066,14 @@
         }
     }
 
+    private String toHex(String password) {
+        if (password == null) {
+            return null;
+        }
+        byte[] bytes = password.getBytes(StandardCharsets.UTF_8);
+        return new String(Hex.encodeHex(bytes));
+    }
+
     @Override
     public int decryptStorage(String password) {
         if (TextUtils.isEmpty(password)) {
@@ -2053,7 +2091,7 @@
 
         final NativeDaemonEvent event;
         try {
-            event = mConnector.execute("cryptfs", "checkpw", new SensitiveArg(password));
+            event = mConnector.execute("cryptfs", "checkpw", new SensitiveArg(toHex(password)));
 
             final int code = Integer.parseInt(event.getMessage());
             if (code == 0) {
@@ -2092,7 +2130,8 @@
         }
 
         try {
-            mConnector.execute("cryptfs", "enablecrypto", "inplace", new SensitiveArg(password));
+            mConnector.execute("cryptfs", "enablecrypto", "inplace",
+                               new SensitiveArg(toHex(password)));
         } catch (NativeDaemonConnectorException e) {
             // Encryption failed
             return e.getCode();
@@ -2101,11 +2140,11 @@
         return 0;
     }
 
-    public int changeEncryptionPassword(String password) {
-        if (TextUtils.isEmpty(password)) {
-            throw new IllegalArgumentException("password cannot be empty");
-        }
-
+    /** Set the password for encrypting the master key.
+     *  @param type One of the CRYPTO_TYPE_XXX consts defined in StorageManager.
+     *  @param password The password to set.
+     */
+    public int changeEncryptionPassword(int type, String password) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
             "no permission to access the crypt keeper");
 
@@ -2117,7 +2156,8 @@
 
         final NativeDaemonEvent event;
         try {
-            event = mConnector.execute("cryptfs", "changepw", new SensitiveArg(password));
+            event = mConnector.execute("cryptfs", "changepw", CRYPTO_TYPES[type],
+                                       new SensitiveArg(toHex(password)));
             return Integer.parseInt(event.getMessage());
         } catch (NativeDaemonConnectorException e) {
             // Encryption failed
@@ -2150,7 +2190,7 @@
 
         final NativeDaemonEvent event;
         try {
-            event = mConnector.execute("cryptfs", "verifypw", new SensitiveArg(password));
+            event = mConnector.execute("cryptfs", "verifypw", new SensitiveArg(toHex(password)));
             Slog.i(TAG, "cryptfs verifypw => " + event.getMessage());
             return Integer.parseInt(event.getMessage());
         } catch (NativeDaemonConnectorException e) {
@@ -2159,6 +2199,29 @@
         }
     }
 
+    /**
+     * Get the type of encryption used to encrypt the master key.
+     * @return The type, one of the CRYPT_TYPE_XXX consts from StorageManager.
+     */
+    @Override
+    public int getPasswordType() throws RemoteException {
+
+        waitForReady();
+
+        final NativeDaemonEvent event;
+        try {
+            event = mConnector.execute("cryptfs", "getpwtype");
+            for (int i = 0; i < CRYPTO_TYPES.length; ++i) {
+                if (CRYPTO_TYPES[i].equals(event.getMessage()))
+                    return i;
+            }
+
+            throw new IllegalStateException("unexpected return from cryptfs");
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
     @Override
     public int mkdirs(String callingPkg, String appPath) {
         final int userId = UserHandle.getUserId(Binder.getCallingUid());
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index ad7ec99..3924fe8 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -82,6 +82,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.StringTokenizer;
@@ -151,6 +152,8 @@
 
     private final Handler mMainHandler = new Handler();
 
+    private IBatteryStats mBatteryStats;
+
     private Thread mThread;
     private CountDownLatch mConnectedSignal = new CountDownLatch(1);
 
@@ -226,6 +229,17 @@
         if (DBG) Slog.d(TAG, "Prepared");
     }
 
+    private IBatteryStats getBatteryStats() {
+        synchronized (this) {
+            if (mBatteryStats != null) {
+                return mBatteryStats;
+            }
+            mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
+                    BatteryStats.SERVICE_NAME));
+            return mBatteryStats;
+        }
+    }
+
     @Override
     public void registerObserver(INetworkManagementEventObserver observer) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
@@ -323,6 +337,10 @@
      * Notify our observers of a change in the data activity state of the interface
      */
     private void notifyInterfaceClassActivity(String label, boolean active) {
+        try {
+            getBatteryStats().noteDataConnectionActive(label, active);
+        } catch (RemoteException e) {
+        }
         final int length = mObservers.beginBroadcast();
         for (int i = 0; i < length; i++) {
             try {
@@ -359,8 +377,7 @@
 
         if (mBandwidthControlEnabled) {
             try {
-                IBatteryStats.Stub.asInterface(ServiceManager.getService(BatteryStats.SERVICE_NAME))
-                        .noteNetworkStatsEnabled();
+                getBatteryStats().noteNetworkStatsEnabled();
             } catch (RemoteException e) {
             }
         }
@@ -1022,6 +1039,15 @@
         }
     }
 
+    private List<InterfaceAddress> excludeLinkLocal(List<InterfaceAddress> addresses) {
+        ArrayList<InterfaceAddress> filtered = new ArrayList<InterfaceAddress>(addresses.size());
+        for (InterfaceAddress ia : addresses) {
+            if (!ia.getAddress().isLinkLocalAddress())
+                filtered.add(ia);
+        }
+        return filtered;
+    }
+
     private void modifyNat(String action, String internalInterface, String externalInterface)
             throws SocketException {
         final Command cmd = new Command("nat", action, internalInterface, externalInterface);
@@ -1031,8 +1057,10 @@
         if (internalNetworkInterface == null) {
             cmd.appendArg("0");
         } else {
-            Collection<InterfaceAddress> interfaceAddresses = internalNetworkInterface
-                    .getInterfaceAddresses();
+            // Don't touch link-local routes, as link-local addresses aren't routable,
+            // kernel creates link-local routes on all interfaces automatically
+            List<InterfaceAddress> interfaceAddresses = excludeLinkLocal(
+                    internalNetworkInterface.getInterfaceAddresses());
             cmd.appendArg(interfaceAddresses.size());
             for (InterfaceAddress ia : interfaceAddresses) {
                 InetAddress addr = NetworkUtils.getNetworkPart(
@@ -1192,6 +1220,8 @@
                 throw e.rethrowAsParcelableException();
             }
             mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, label));
+            // Networks start up.
+            notifyInterfaceClassActivity(label, true);
         }
     }
 
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 699d79e..77f5182 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -37,6 +37,10 @@
 import android.telephony.SignalStrength;
 import android.telephony.CellInfo;
 import android.telephony.TelephonyManager;
+import android.telephony.DisconnectCause;
+import android.telephony.PreciseCallState;
+import android.telephony.PreciseDataConnectionState;
+import android.telephony.PreciseDisconnectCause;
 import android.text.TextUtils;
 import android.util.Slog;
 
@@ -125,6 +129,17 @@
 
     private List<CellInfo> mCellInfo = null;
 
+    private int mRingingCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
+
+    private int mForegroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
+
+    private int mBackgroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
+
+    private PreciseCallState mPreciseCallState = new PreciseCallState();
+
+    private PreciseDataConnectionState mPreciseDataConnectionState =
+                new PreciseDataConnectionState();
+
     static final int PHONE_STATE_PERMISSION_MASK =
                 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
                 PhoneStateListener.LISTEN_CALL_STATE |
@@ -132,6 +147,10 @@
                 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |
                 PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR;
 
+    static final int PRECISE_PHONE_STATE_PERMISSION_MASK =
+                PhoneStateListener.LISTEN_PRECISE_CALL_STATE |
+                PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE;
+
     private static final int MSG_USER_SWITCHED = 1;
 
     private final Handler mHandler = new Handler() {
@@ -305,6 +324,21 @@
                             remove(r.binder);
                         }
                     }
+                    if ((events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
+                        try {
+                            r.callback.onPreciseCallStateChanged(mPreciseCallState);
+                        } catch (RemoteException ex) {
+                            remove(r.binder);
+                        }
+                    }
+                    if ((events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
+                        try {
+                            r.callback.onPreciseDataConnectionStateChanged(
+                                    mPreciseDataConnectionState);
+                        } catch (RemoteException ex) {
+                            remove(r.binder);
+                        }
+                    }
                 }
             }
         } else {
@@ -533,30 +567,47 @@
                 }
                 handleRemoveListLocked();
             }
+            mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType,
+                    apnType, apn, reason, linkProperties, "");
+            for (Record r : mRecords) {
+                if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
+                    try {
+                        r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
+                    } catch (RemoteException ex) {
+                        mRemoveList.add(r.binder);
+                    }
+                }
+            }
+            handleRemoveListLocked();
         }
         broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
                 apnType, linkProperties, linkCapabilities, roaming);
+        broadcastPreciseDataConnectionStateChanged(state, networkType, apnType, apn, reason,
+                linkProperties, "");
     }
 
     public void notifyDataConnectionFailed(String reason, String apnType) {
         if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
             return;
         }
-        /*
-         * This is commented out because there is no onDataConnectionFailed callback
-         * in PhoneStateListener. There should be.
         synchronized (mRecords) {
-            mDataConnectionFailedReason = reason;
-            final int N = mRecords.size();
-            for (int i=N-1; i>=0; i--) {
-                Record r = mRecords.get(i);
-                if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_FAILED) != 0) {
-                    // XXX
+            mPreciseDataConnectionState = new PreciseDataConnectionState(
+                    TelephonyManager.DATA_UNKNOWN,TelephonyManager.NETWORK_TYPE_UNKNOWN,
+                    apnType, "", reason, null, "");
+            for (Record r : mRecords) {
+                if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
+                    try {
+                        r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
+                    } catch (RemoteException ex) {
+                        mRemoveList.add(r.binder);
+                    }
                 }
             }
+            handleRemoveListLocked();
         }
-        */
         broadcastDataConnectionFailed(reason, apnType);
+        broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN,
+                TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, "", reason, null, "");
     }
 
     public void notifyCellLocation(Bundle cellLocation) {
@@ -602,6 +653,81 @@
         }
     }
 
+    public void notifyPreciseCallState(int ringingCallState, int foregroundCallState,
+            int backgroundCallState) {
+        if (!checkNotifyPermission("notifyPreciseCallState()")) {
+            return;
+        }
+        synchronized (mRecords) {
+            mRingingCallState = ringingCallState;
+            mForegroundCallState = foregroundCallState;
+            mBackgroundCallState = backgroundCallState;
+            mPreciseCallState = new PreciseCallState(ringingCallState, foregroundCallState,
+                    backgroundCallState,
+                    DisconnectCause.NOT_VALID,
+                    PreciseDisconnectCause.NOT_VALID);
+            for (Record r : mRecords) {
+                if ((r.events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
+                    try {
+                        r.callback.onPreciseCallStateChanged(mPreciseCallState);
+                    } catch (RemoteException ex) {
+                        mRemoveList.add(r.binder);
+                    }
+                }
+            }
+            handleRemoveListLocked();
+        }
+        broadcastPreciseCallStateChanged(ringingCallState, foregroundCallState, backgroundCallState,
+                DisconnectCause.NOT_VALID,
+                PreciseDisconnectCause.NOT_VALID);
+    }
+
+    public void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause) {
+        if (!checkNotifyPermission("notifyDisconnectCause()")) {
+            return;
+        }
+        synchronized (mRecords) {
+            mPreciseCallState = new PreciseCallState(mRingingCallState, mForegroundCallState,
+                    mBackgroundCallState, disconnectCause, preciseDisconnectCause);
+            for (Record r : mRecords) {
+                if ((r.events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
+                    try {
+                        r.callback.onPreciseCallStateChanged(mPreciseCallState);
+                    } catch (RemoteException ex) {
+                        mRemoveList.add(r.binder);
+                    }
+                }
+            }
+            handleRemoveListLocked();
+        }
+        broadcastPreciseCallStateChanged(mRingingCallState, mForegroundCallState,
+                mBackgroundCallState, disconnectCause, preciseDisconnectCause);
+    }
+
+    public void notifyPreciseDataConnectionFailed(String reason, String apnType,
+            String apn, String failCause) {
+        if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) {
+            return;
+        }
+        synchronized (mRecords) {
+            mPreciseDataConnectionState = new PreciseDataConnectionState(
+                    TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN,
+                    apnType, apn, reason, null, failCause);
+            for (Record r : mRecords) {
+                if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
+                    try {
+                        r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
+                    } catch (RemoteException ex) {
+                        mRemoveList.add(r.binder);
+                    }
+                }
+            }
+            handleRemoveListLocked();
+        }
+        broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN,
+                TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, reason, null, failCause);
+    }
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
@@ -738,6 +864,33 @@
         mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
     }
 
+    private void broadcastPreciseCallStateChanged(int ringingCallState, int foregroundCallState,
+            int backgroundCallState, int disconnectCause, int preciseDisconnectCause) {
+        Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_CALL_STATE_CHANGED);
+        intent.putExtra(TelephonyManager.EXTRA_RINGING_CALL_STATE, ringingCallState);
+        intent.putExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, foregroundCallState);
+        intent.putExtra(TelephonyManager.EXTRA_BACKGROUND_CALL_STATE, backgroundCallState);
+        intent.putExtra(TelephonyManager.EXTRA_DISCONNECT_CAUSE, disconnectCause);
+        intent.putExtra(TelephonyManager.EXTRA_PRECISE_DISCONNECT_CAUSE, preciseDisconnectCause);
+        mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
+                android.Manifest.permission.READ_PRECISE_PHONE_STATE);
+    }
+
+    private void broadcastPreciseDataConnectionStateChanged(int state, int networkType,
+            String apnType, String apn, String reason, LinkProperties linkProperties, String failCause) {
+        Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED);
+        intent.putExtra(PhoneConstants.STATE_KEY, state);
+        intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType);
+        if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason);
+        if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
+        if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
+        if (linkProperties != null) intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
+        if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause);
+
+        mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
+                android.Manifest.permission.READ_PRECISE_PHONE_STATE);
+    }
+
     private boolean checkNotifyPermission(String method) {
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
                 == PackageManager.PERMISSION_GRANTED) {
@@ -766,6 +919,12 @@
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.READ_PHONE_STATE, null);
         }
+
+        if ((events & PRECISE_PHONE_STATE_PERMISSION_MASK) != 0) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.READ_PRECISE_PHONE_STATE, null);
+
+        }
     }
 
     private void handleRemoveListLocked() {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
old mode 100644
new mode 100755
index be2df04..a845127
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -204,6 +204,7 @@
                     Slog.i(TAG, "Waited long enough for: " + r);
                     mStartingBackground.remove(i);
                     N--;
+                    i--;
                 }
             }
             while (mDelayedStartList.size() > 0
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 8a29ac7..059aa2b 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -230,7 +230,14 @@
             mStats.noteUserActivityLocked(uid, event);
         }
     }
-    
+
+    public void noteDataConnectionActive(String label, boolean active) {
+        enforceCallingPermission();
+        synchronized (mStats) {
+            mStats.noteDataConnectionActive(label, active);
+        }
+    }
+
     public void notePhoneOn() {
         enforceCallingPermission();
         synchronized (mStats) {
@@ -330,6 +337,13 @@
         }
     }
 
+    public void noteWifiState(int wifiState, String accessPoint) {
+        enforceCallingPermission();
+        synchronized (mStats) {
+            mStats.noteWifiStateLocked(wifiState, accessPoint);
+        }
+    }
+
     public void noteBluetoothOn() {
         enforceCallingPermission();
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -373,6 +387,13 @@
         }
     }
     
+    public void noteBluetoothState(int bluetoothState) {
+        enforceCallingPermission();
+        synchronized (mStats) {
+            mStats.noteBluetoothStateLocked(bluetoothState);
+        }
+    }
+
     public void noteFullWifiLockAcquired(int uid) {
         enforceCallingPermission();
         synchronized (mStats) {
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 5971737..b233943 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -470,6 +470,7 @@
         mTetheredNotification.defaults &= ~Notification.DEFAULT_SOUND;
         mTetheredNotification.flags = Notification.FLAG_ONGOING_EVENT;
         mTetheredNotification.tickerText = title;
+        mTetheredNotification.visibility = Notification.VISIBILITY_PUBLIC;
         mTetheredNotification.setLatestEventInfo(mContext, title, message, pi);
 
         notificationManager.notifyAsUser(null, mTetheredNotification.icon,
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index f5acc4c..ffb113c 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -18,7 +18,9 @@
 
 import com.android.internal.util.DumpUtils;
 import com.android.server.FgThread;
+import com.android.server.SystemService;
 
+import android.Manifest;
 import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -35,6 +37,8 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.service.dreams.DreamManagerInternal;
+import android.service.dreams.DreamService;
 import android.service.dreams.IDreamManager;
 import android.util.Slog;
 
@@ -50,7 +54,7 @@
  *
  * @hide
  */
-public final class DreamManagerService extends IDreamManager.Stub {
+public final class DreamManagerService extends SystemService {
     private static final boolean DEBUG = false;
     private static final String TAG = "DreamManagerService";
 
@@ -67,6 +71,7 @@
     private boolean mCurrentDreamIsTest;
 
     public DreamManagerService(Context context) {
+        super(context);
         mContext = context;
         mHandler = new DreamHandler(FgThread.get().getLooper());
         mController = new DreamController(context, mHandler, mControllerListener);
@@ -74,27 +79,27 @@
         mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
     }
 
-    public void systemRunning() {
-        mContext.registerReceiver(new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                synchronized (mLock) {
-                    stopDreamLocked();
-                }
-            }
-        }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
+    @Override
+    public void onStart() {
+        publishBinderService(DreamService.DREAM_SERVICE, new BinderService());
+        publishLocalService(DreamManagerInternal.class, new LocalService());
     }
 
     @Override
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
-                != PackageManager.PERMISSION_GRANTED) {
-            pw.println("Permission Denial: can't dump DreamManager from pid="
-                    + Binder.getCallingPid()
-                    + ", uid=" + Binder.getCallingUid());
-            return;
+    public void onBootPhase(int phase) {
+        if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
+            mContext.registerReceiver(new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    synchronized (mLock) {
+                        stopDreamLocked();
+                    }
+                }
+            }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
         }
+    }
 
+    private void dumpInternal(PrintWriter pw) {
         pw.println("DREAM MANAGER (dumpsys dreams)");
         pw.println();
 
@@ -112,156 +117,57 @@
         }, pw, 200);
     }
 
-    @Override // Binder call
-    public ComponentName[] getDreamComponents() {
-        checkPermission(android.Manifest.permission.READ_DREAM_STATE);
-
-        final int userId = UserHandle.getCallingUserId();
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            return getDreamComponentsForUser(userId);
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    @Override // Binder call
-    public void setDreamComponents(ComponentName[] componentNames) {
-        checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
-
-        final int userId = UserHandle.getCallingUserId();
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            Settings.Secure.putStringForUser(mContext.getContentResolver(),
-                    Settings.Secure.SCREENSAVER_COMPONENTS,
-                    componentsToString(componentNames),
-                    userId);
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    @Override // Binder call
-    public ComponentName getDefaultDreamComponent() {
-        checkPermission(android.Manifest.permission.READ_DREAM_STATE);
-
-        final int userId = UserHandle.getCallingUserId();
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            String name = Settings.Secure.getStringForUser(mContext.getContentResolver(),
-                    Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT,
-                    userId);
-            return name == null ? null : ComponentName.unflattenFromString(name);
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    @Override // Binder call
-    public boolean isDreaming() {
-        checkPermission(android.Manifest.permission.READ_DREAM_STATE);
-
+    private boolean isDreamingInternal() {
         synchronized (mLock) {
             return mCurrentDreamToken != null && !mCurrentDreamIsTest;
         }
     }
 
-    @Override // Binder call
-    public void dream() {
-        checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
-
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            // Ask the power manager to nap.  It will eventually call back into
-            // startDream() if/when it is appropriate to start dreaming.
-            // Because napping could cause the screen to turn off immediately if the dream
-            // cannot be started, we keep one eye open and gently poke user activity.
-            long time = SystemClock.uptimeMillis();
-            mPowerManager.userActivity(time, true /*noChangeLights*/);
-            mPowerManager.nap(time);
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
+    private void requestDreamInternal() {
+        // Ask the power manager to nap.  It will eventually call back into
+        // startDream() if/when it is appropriate to start dreaming.
+        // Because napping could cause the screen to turn off immediately if the dream
+        // cannot be started, we keep one eye open and gently poke user activity.
+        long time = SystemClock.uptimeMillis();
+        mPowerManager.userActivity(time, true /*noChangeLights*/);
+        mPowerManager.nap(time);
     }
 
-    @Override // Binder call
-    public void testDream(ComponentName dream) {
-        checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
+    private void requestAwakenInternal() {
+        // Treat an explicit request to awaken as user activity so that the
+        // device doesn't immediately go to sleep if the timeout expired,
+        // for example when being undocked.
+        long time = SystemClock.uptimeMillis();
+        mPowerManager.userActivity(time, false /*noChangeLights*/);
+        stopDreamInternal();
+    }
 
-        if (dream == null) {
-            throw new IllegalArgumentException("dream must not be null");
+    private void finishSelfInternal(IBinder token) {
+        if (DEBUG) {
+            Slog.d(TAG, "Dream finished: " + token);
         }
 
-        final int callingUserId = UserHandle.getCallingUserId();
-        final int currentUserId = ActivityManager.getCurrentUser();
-        if (callingUserId != currentUserId) {
-            // This check is inherently prone to races but at least it's something.
-            Slog.w(TAG, "Aborted attempt to start a test dream while a different "
-                    + " user is active: callingUserId=" + callingUserId
-                    + ", currentUserId=" + currentUserId);
-            return;
-        }
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            synchronized (mLock) {
-                startDreamLocked(dream, true /*isTest*/, callingUserId);
+        // Note that a dream finishing and self-terminating is not
+        // itself considered user activity.  If the dream is ending because
+        // the user interacted with the device then user activity will already
+        // have been poked so the device will stay awake a bit longer.
+        // If the dream is ending on its own for other reasons and no wake
+        // locks are held and the user activity timeout has expired then the
+        // device may simply go to sleep.
+        synchronized (mLock) {
+            if (mCurrentDreamToken == token) {
+                stopDreamLocked();
             }
-        } finally {
-            Binder.restoreCallingIdentity(ident);
         }
     }
 
-    @Override // Binder call
-    public void awaken() {
-        checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
-
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            // Treat an explicit request to awaken as user activity so that the
-            // device doesn't immediately go to sleep if the timeout expired,
-            // for example when being undocked.
-            long time = SystemClock.uptimeMillis();
-            mPowerManager.userActivity(time, false /*noChangeLights*/);
-            stopDream();
-        } finally {
-            Binder.restoreCallingIdentity(ident);
+    private void testDreamInternal(ComponentName dream, int userId) {
+        synchronized (mLock) {
+            startDreamLocked(dream, true /*isTest*/, userId);
         }
     }
 
-    @Override // Binder call
-    public void finishSelf(IBinder token) {
-        // Requires no permission, called by Dream from an arbitrary process.
-        if (token == null) {
-            throw new IllegalArgumentException("token must not be null");
-        }
-
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            if (DEBUG) {
-                Slog.d(TAG, "Dream finished: " + token);
-            }
-
-            // Note that a dream finishing and self-terminating is not
-            // itself considered user activity.  If the dream is ending because
-            // the user interacted with the device then user activity will already
-            // have been poked so the device will stay awake a bit longer.
-            // If the dream is ending on its own for other reasons and no wake
-            // locks are held and the user activity timeout has expired then the
-            // device may simply go to sleep.
-            synchronized (mLock) {
-                if (mCurrentDreamToken == token) {
-                    stopDreamLocked();
-                }
-            }
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    /**
-     * Called by the power manager to start a dream.
-     */
-    public void startDream() {
+    private void startDreamInternal() {
         int userId = ActivityManager.getCurrentUser();
         ComponentName dream = chooseDreamForUser(userId);
         if (dream != null) {
@@ -271,10 +177,7 @@
         }
     }
 
-    /**
-     * Called by the power manager to stop a dream.
-     */
-    public void stopDream() {
+    private void stopDreamInternal() {
         synchronized (mLock) {
             stopDreamLocked();
         }
@@ -305,7 +208,7 @@
 
         // fallback to the default dream component if necessary
         if (validComponents.isEmpty()) {
-            ComponentName defaultDream = getDefaultDreamComponent();
+            ComponentName defaultDream = getDefaultDreamComponentForUser(userId);
             if (defaultDream != null) {
                 Slog.w(TAG, "Falling back to default dream " + defaultDream);
                 validComponents.add(defaultDream);
@@ -314,6 +217,20 @@
         return validComponents.toArray(new ComponentName[validComponents.size()]);
     }
 
+    private void setDreamComponentsForUser(int userId, ComponentName[] componentNames) {
+        Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                Settings.Secure.SCREENSAVER_COMPONENTS,
+                componentsToString(componentNames),
+                userId);
+    }
+
+    private ComponentName getDefaultDreamComponentForUser(int userId) {
+        String name = Settings.Secure.getStringForUser(mContext.getContentResolver(),
+                Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT,
+                userId);
+        return name == null ? null : ComponentName.unflattenFromString(name);
+    }
+
     private boolean serviceExists(ComponentName name) {
         try {
             return name != null && mContext.getPackageManager().getServiceInfo(name, 0) != null;
@@ -423,4 +340,155 @@
             super(looper, null, true /*async*/);
         }
     }
+
+    private final class BinderService extends IDreamManager.Stub {
+        @Override // Binder call
+        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
+                    != PackageManager.PERMISSION_GRANTED) {
+                pw.println("Permission Denial: can't dump DreamManager from from pid="
+                        + Binder.getCallingPid()
+                        + ", uid=" + Binder.getCallingUid());
+                return;
+            }
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                dumpInternal(pw);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override // Binder call
+        public ComponentName[] getDreamComponents() {
+            checkPermission(android.Manifest.permission.READ_DREAM_STATE);
+
+            final int userId = UserHandle.getCallingUserId();
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                return getDreamComponentsForUser(userId);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override // Binder call
+        public void setDreamComponents(ComponentName[] componentNames) {
+            checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
+
+            final int userId = UserHandle.getCallingUserId();
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                setDreamComponentsForUser(userId, componentNames);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override // Binder call
+        public ComponentName getDefaultDreamComponent() {
+            checkPermission(android.Manifest.permission.READ_DREAM_STATE);
+
+            final int userId = UserHandle.getCallingUserId();
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                return getDefaultDreamComponentForUser(userId);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override // Binder call
+        public boolean isDreaming() {
+            checkPermission(android.Manifest.permission.READ_DREAM_STATE);
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                return isDreamingInternal();
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override // Binder call
+        public void dream() {
+            checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                requestDreamInternal();
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override // Binder call
+        public void testDream(ComponentName dream) {
+            if (dream == null) {
+                throw new IllegalArgumentException("dream must not be null");
+            }
+            checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
+
+            final int callingUserId = UserHandle.getCallingUserId();
+            final int currentUserId = ActivityManager.getCurrentUser();
+            if (callingUserId != currentUserId) {
+                // This check is inherently prone to races but at least it's something.
+                Slog.w(TAG, "Aborted attempt to start a test dream while a different "
+                        + " user is active: callingUserId=" + callingUserId
+                        + ", currentUserId=" + currentUserId);
+                return;
+            }
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                testDreamInternal(dream, callingUserId);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override // Binder call
+        public void awaken() {
+            checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                requestAwakenInternal();
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override // Binder call
+        public void finishSelf(IBinder token) {
+            // Requires no permission, called by Dream from an arbitrary process.
+            if (token == null) {
+                throw new IllegalArgumentException("token must not be null");
+            }
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                finishSelfInternal(token);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
+
+    private final class LocalService extends DreamManagerInternal {
+        @Override
+        public void startDream() {
+            startDreamInternal();
+        }
+
+        @Override
+        public void stopDream() {
+            stopDreamInternal();
+        }
+
+        @Override
+        public boolean isDreaming() {
+            return isDreamingInternal();
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/location/LocationRequestStatistics.java b/services/core/java/com/android/server/location/LocationRequestStatistics.java
new file mode 100644
index 0000000..85231bb
--- /dev/null
+++ b/services/core/java/com/android/server/location/LocationRequestStatistics.java
@@ -0,0 +1,205 @@
+package com.android.server.location;
+
+import android.os.SystemClock;
+import android.util.Log;
+
+import java.util.HashMap;
+
+/**
+ * Holds statistics for location requests (active requests by provider).
+ *
+ * <p>Must be externally synchronized.
+ */
+public class LocationRequestStatistics {
+    private static final String TAG = "LocationStats";
+
+    // Maps package name nad provider to location request statistics.
+    public final HashMap<PackageProviderKey, PackageStatistics> statistics
+            = new HashMap<PackageProviderKey, PackageStatistics>();
+
+    /**
+     * Signals that a package has started requesting locations.
+     *
+     * @param packageName Name of package that has requested locations.
+     * @param providerName Name of provider that is requested (e.g. "gps").
+     * @param intervalMs The interval that is requested in ms.
+     */
+    public void startRequesting(String packageName, String providerName, long intervalMs) {
+        PackageProviderKey key = new PackageProviderKey(packageName, providerName);
+        PackageStatistics stats = statistics.get(key);
+        if (stats == null) {
+            stats = new PackageStatistics();
+            statistics.put(key, stats);
+        }
+        stats.startRequesting(intervalMs);
+    }
+
+    /**
+     * Signals that a package has stopped requesting locations.
+     *
+     * @param packageName Name of package that has stopped requesting locations.
+     * @param providerName Provider that is no longer being requested.
+     */
+    public void stopRequesting(String packageName, String providerName) {
+        PackageProviderKey key = new PackageProviderKey(packageName, providerName);
+        PackageStatistics stats = statistics.get(key);
+        if (stats != null) {
+            stats.stopRequesting();
+        } else {
+            // This shouldn't be a possible code path.
+            Log.e(TAG, "Couldn't find package statistics when removing location request.");
+        }
+    }
+
+    /**
+     * A key that holds both package and provider names.
+     */
+    public static class PackageProviderKey {
+        /**
+         * Name of package requesting location.
+         */
+        public final String packageName;
+        /**
+         * Name of provider being requested (e.g. "gps").
+         */
+        public final String providerName;
+
+        public PackageProviderKey(String packageName, String providerName) {
+            this.packageName = packageName;
+            this.providerName = providerName;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof PackageProviderKey)) {
+                return false;
+            }
+
+            PackageProviderKey otherKey = (PackageProviderKey) other;
+            return packageName.equals(otherKey.packageName)
+                    && providerName.equals(otherKey.providerName);
+        }
+
+        @Override
+        public int hashCode() {
+            return packageName.hashCode() + 31 * providerName.hashCode();
+        }
+    }
+
+    /**
+     * Usage statistics for a package/provider pair.
+     */
+    public static class PackageStatistics {
+        // Time when this package first requested location.
+        private final long mInitialElapsedTimeMs;
+        // Number of active location requests this package currently has.
+        private int mNumActiveRequests;
+        // Time when this package most recently went from not requesting location to requesting.
+        private long mLastActivitationElapsedTimeMs;
+        // The fastest interval this package has ever requested.
+        private long mFastestIntervalMs;
+        // The slowest interval this package has ever requested.
+        private long mSlowestIntervalMs;
+        // The total time this app has requested location (not including currently running requests).
+        private long mTotalDurationMs;
+
+        private PackageStatistics() {
+            mInitialElapsedTimeMs = SystemClock.elapsedRealtime();
+            mNumActiveRequests = 0;
+            mTotalDurationMs = 0;
+            mFastestIntervalMs = Long.MAX_VALUE;
+            mSlowestIntervalMs = 0;
+        }
+
+        private void startRequesting(long intervalMs) {
+            if (mNumActiveRequests == 0) {
+                mLastActivitationElapsedTimeMs = SystemClock.elapsedRealtime();
+            }
+
+            if (intervalMs < mFastestIntervalMs) {
+                mFastestIntervalMs = intervalMs;
+            }
+
+            if (intervalMs > mSlowestIntervalMs) {
+                mSlowestIntervalMs = intervalMs;
+            }
+
+            mNumActiveRequests++;
+        }
+
+        private void stopRequesting() {
+            if (mNumActiveRequests <= 0) {
+                // Shouldn't be a possible code path
+                Log.e(TAG, "Reference counting corrupted in usage statistics.");
+                return;
+            }
+
+            mNumActiveRequests--;
+            if (mNumActiveRequests == 0) {
+                long lastDurationMs
+                        = SystemClock.elapsedRealtime() - mLastActivitationElapsedTimeMs;
+                mTotalDurationMs += lastDurationMs;
+            }
+        }
+
+        /**
+         * Returns the duration that this request has been active.
+         */
+        public long getDurationMs() {
+            long currentDurationMs = mTotalDurationMs;
+            if (mNumActiveRequests > 0) {
+                currentDurationMs
+                        += SystemClock.elapsedRealtime() - mLastActivitationElapsedTimeMs;
+            }
+            return currentDurationMs;
+        }
+
+        /**
+         * Returns the time since the initial request in ms.
+         */
+        public long getTimeSinceFirstRequestMs() {
+            return SystemClock.elapsedRealtime() - mInitialElapsedTimeMs;
+        }
+
+        /**
+         * Returns the fastest interval that has been tracked.
+         */
+        public long getFastestIntervalMs() {
+            return mFastestIntervalMs;
+        }
+
+        /**
+         * Returns the slowest interval that has been tracked.
+         */
+        public long getSlowestIntervalMs() {
+            return mSlowestIntervalMs;
+        }
+
+        /**
+         * Returns true if a request is active for these tracked statistics.
+         */
+        public boolean isActive() {
+            return mNumActiveRequests > 0;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder s = new StringBuilder();
+            if (mFastestIntervalMs == mSlowestIntervalMs) {
+                s.append("Interval ").append(mFastestIntervalMs / 1000).append(" seconds");
+            } else {
+                s.append("Min interval ").append(mFastestIntervalMs / 1000).append(" seconds");
+                s.append(": Max interval ").append(mSlowestIntervalMs / 1000).append(" seconds");
+            }
+            s.append(": Duration requested ")
+                    .append((getDurationMs() / 1000) / 60)
+                    .append(" out of the last ")
+                    .append((getTimeSinceFirstRequestMs() / 1000) / 60)
+                    .append(" minutes");
+            if (isActive()) {
+                s.append(": Currently active");
+            }
+            return s.toString();
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 6185e50..ad6eabd 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -221,6 +221,17 @@
         return execute(builder.toString());
     }
 
+    public int idmap(String targetApkPath, String overlayApkPath, int uid) {
+        StringBuilder builder = new StringBuilder("idmap");
+        builder.append(' ');
+        builder.append(targetApkPath);
+        builder.append(' ');
+        builder.append(overlayApkPath);
+        builder.append(' ');
+        builder.append(uid);
+        return execute(builder.toString());
+    }
+
     public int movedex(String srcPath, String dstPath) {
         StringBuilder builder = new StringBuilder("movedex");
         builder.append(' ');
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 6e90bf6..130b94e 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -219,7 +219,8 @@
     static final int SCAN_UPDATE_TIME = 1<<6;
     static final int SCAN_DEFER_DEX = 1<<7;
     static final int SCAN_BOOTING = 1<<8;
-    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<9;
+    static final int SCAN_TRUSTED_OVERLAY = 1<<9;
+    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
 
     static final int REMOVE_CHATTY = 1<<16;
 
@@ -260,9 +261,15 @@
 
     private static final String LIB_DIR_NAME = "lib";
 
+    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
+
     static final String mTempContainerPrefix = "smdl2tmp";
 
     final ServiceThread mHandlerThread;
+
+    private static final String IDMAP_PREFIX = "/data/resource-cache/";
+    private static final String IDMAP_SUFFIX = "@idmap";
+
     final PackageHandler mHandler;
 
     final int mSdkVersion = Build.VERSION.SDK_INT;
@@ -298,6 +305,9 @@
     // This is the object monitoring the system app dir.
     final FileObserver mVendorInstallObserver;
 
+    // This is the object monitoring the vendor overlay package dir.
+    final FileObserver mVendorOverlayInstallObserver;
+
     // This is the object monitoring mAppInstallDir.
     final FileObserver mAppInstallObserver;
 
@@ -344,6 +354,10 @@
     final HashMap<String, PackageParser.Package> mPackages =
             new HashMap<String, PackageParser.Package>();
 
+    // Tracks available target package names -> overlay package paths.
+    final HashMap<String, HashMap<String, PackageParser.Package>> mOverlays =
+        new HashMap<String, HashMap<String, PackageParser.Package>>();
+
     final Settings mSettings;
     boolean mRestoredSettings;
 
@@ -1279,6 +1293,17 @@
                 }
             }
 
+            // Collect vendor overlay packages.
+            // (Do this before scanning any apps.)
+            // For security and version matching reason, only consider
+            // overlay packages if they reside in VENDOR_OVERLAY_DIR.
+            File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
+            mVendorOverlayInstallObserver = new AppDirObserver(
+                vendorOverlayDir.getPath(), OBSERVER_EVENTS, true, false);
+            mVendorOverlayInstallObserver.startWatching();
+            scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
+                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode | SCAN_TRUSTED_OVERLAY, 0);
+
             // Find base frameworks (resource packages without code).
             mFrameworkInstallObserver = new AppDirObserver(
                 frameworkDir.getPath(), OBSERVER_EVENTS, true, false);
@@ -3481,6 +3506,56 @@
         return finalList;
     }
 
+    private void createIdmapsForPackageLI(PackageParser.Package pkg) {
+        HashMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
+        if (overlays == null) {
+            Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
+            return;
+        }
+        for (PackageParser.Package opkg : overlays.values()) {
+            // Not much to do if idmap fails: we already logged the error
+            // and we certainly don't want to abort installation of pkg simply
+            // because an overlay didn't fit properly. For these reasons,
+            // ignore the return value of createIdmapForPackagePairLI.
+            createIdmapForPackagePairLI(pkg, opkg);
+        }
+    }
+
+    private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
+            PackageParser.Package opkg) {
+        if (!opkg.mTrustedOverlay) {
+            Slog.w(TAG, "Skipping target and overlay pair " + pkg.mScanPath + " and " +
+                    opkg.mScanPath + ": overlay not trusted");
+            return false;
+        }
+        HashMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
+        if (overlaySet == null) {
+            Slog.e(TAG, "was about to create idmap for " + pkg.mScanPath + " and " +
+                    opkg.mScanPath + " but target package has no known overlays");
+            return false;
+        }
+        final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
+        if (mInstaller.idmap(pkg.mScanPath, opkg.mScanPath, sharedGid) != 0) {
+            Slog.e(TAG, "Failed to generate idmap for " + pkg.mScanPath + " and " + opkg.mScanPath);
+            return false;
+        }
+        PackageParser.Package[] overlayArray =
+            overlaySet.values().toArray(new PackageParser.Package[0]);
+        Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
+            public int compare(PackageParser.Package p1, PackageParser.Package p2) {
+                return p1.mOverlayPriority - p2.mOverlayPriority;
+            }
+        };
+        Arrays.sort(overlayArray, cmp);
+
+        pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
+        int i = 0;
+        for (PackageParser.Package p : overlayArray) {
+            pkg.applicationInfo.resourceDirs[i++] = p.applicationInfo.sourceDir;
+        }
+        return true;
+    }
+
     private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
         String[] files = dir.list();
         if (files == null) {
@@ -3578,7 +3653,7 @@
         pp.setSeparateProcesses(mSeparateProcesses);
         pp.setOnlyCoreApps(mOnlyCore);
         final PackageParser.Package pkg = pp.parsePackage(scanFile,
-                scanPath, mMetrics, parseFlags);
+                scanPath, mMetrics, parseFlags, (scanMode & SCAN_TRUSTED_OVERLAY) != 0);
 
         if (pkg == null) {
             mLastScanError = pp.getParseError();
@@ -5095,6 +5170,29 @@
             }
 
             pkgSetting.setTimeStamp(scanFileTime);
+
+            // Create idmap files for pairs of (packages, overlay packages).
+            // Note: "android", ie framework-res.apk, is handled by native layers.
+            if (pkg.mOverlayTarget != null) {
+                // This is an overlay package.
+                if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
+                    if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
+                        mOverlays.put(pkg.mOverlayTarget,
+                                new HashMap<String, PackageParser.Package>());
+                    }
+                    HashMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
+                    map.put(pkg.packageName, pkg);
+                    PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
+                    if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
+                        mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
+                        return null;
+                    }
+                }
+            } else if (mOverlays.containsKey(pkg.packageName) &&
+                    !pkg.packageName.equals("android")) {
+                // This is a regular package, with one or more known overlay packages.
+                createIdmapsForPackageLI(pkg);
+            }
         }
 
         return pkg;
diff --git a/services/core/java/com/android/server/power/AutomaticBrightnessController.java b/services/core/java/com/android/server/power/AutomaticBrightnessController.java
new file mode 100644
index 0000000..b24c572
--- /dev/null
+++ b/services/core/java/com/android/server/power/AutomaticBrightnessController.java
@@ -0,0 +1,687 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power;
+
+import com.android.server.twilight.TwilightListener;
+import com.android.server.twilight.TwilightManager;
+import com.android.server.twilight.TwilightState;
+
+import android.content.res.Resources;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.text.format.DateUtils;
+import android.util.MathUtils;
+import android.util.Spline;
+import android.util.Slog;
+import android.util.TimeUtils;
+
+import java.io.PrintWriter;
+import java.util.Arrays;
+
+class AutomaticBrightnessController {
+    private static final String TAG = "AutomaticBrightnessController";
+
+    private static final boolean DEBUG = false;
+    private static final boolean DEBUG_PRETEND_LIGHT_SENSOR_ABSENT = false;
+
+    // If true, enables the use of the screen auto-brightness adjustment setting.
+    private static final boolean USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT =
+            PowerManager.useScreenAutoBrightnessAdjustmentFeature();
+
+    // The maximum range of gamma adjustment possible using the screen
+    // auto-brightness adjustment setting.
+    private static final float SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA = 3.0f;
+
+    // Light sensor event rate in milliseconds.
+    private static final int LIGHT_SENSOR_RATE_MILLIS = 1000;
+
+    // Period of time in which to consider light samples in milliseconds.
+    private static final int AMBIENT_LIGHT_HORIZON = 10000;
+
+    // Stability requirements in milliseconds for accepting a new brightness level.  This is used
+    // for debouncing the light sensor.  Different constants are used to debounce the light sensor
+    // when adapting to brighter or darker environments.  This parameter controls how quickly
+    // brightness changes occur in response to an observed change in light level that exceeds the
+    // hysteresis threshold.
+    private static final long BRIGHTENING_LIGHT_DEBOUNCE = 4000;
+    private static final long DARKENING_LIGHT_DEBOUNCE = 8000;
+
+    // Hysteresis constraints for brightening or darkening.
+    // The recent lux must have changed by at least this fraction relative to the
+    // current ambient lux before a change will be considered.
+    private static final float BRIGHTENING_LIGHT_HYSTERESIS = 0.10f;
+    private static final float DARKENING_LIGHT_HYSTERESIS = 0.20f;
+
+    // The intercept used for the weighting calculation. This is used in order to keep all possible
+    // weighting values positive.
+    private static final int WEIGHTING_INTERCEPT = AMBIENT_LIGHT_HORIZON;
+
+    // How long the current sensor reading is assumed to be valid beyond the current time.
+    // This provides a bit of prediction, as well as ensures that the weight for the last sample is
+    // non-zero, which in turn ensures that the total weight is non-zero.
+    private static final long AMBIENT_LIGHT_PREDICTION_TIME_MILLIS = 100;
+
+    // If true, enables the use of the current time as an auto-brightness adjustment.
+    // The basic idea here is to expand the dynamic range of auto-brightness
+    // when it is especially dark outside.  The light sensor tends to perform
+    // poorly at low light levels so we compensate for it by making an
+    // assumption about the environment.
+    private static final boolean USE_TWILIGHT_ADJUSTMENT =
+            PowerManager.useTwilightAdjustmentFeature();
+
+    // Specifies the maximum magnitude of the time of day adjustment.
+    private static final float TWILIGHT_ADJUSTMENT_MAX_GAMMA = 1.5f;
+
+    // The amount of time after or before sunrise over which to start adjusting
+    // the gamma.  We want the change to happen gradually so that it is below the
+    // threshold of perceptibility and so that the adjustment has maximum effect
+    // well after dusk.
+    private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 2;
+
+    private static final int MSG_UPDATE_AMBIENT_LUX = 1;
+
+    // Callbacks for requesting updates to the the display's power state
+    private final Callbacks mCallbacks;
+
+    // The sensor manager.
+    private final SensorManager mSensorManager;
+
+    // The light sensor, or null if not available or needed.
+    private final Sensor mLightSensor;
+
+    // The twilight service.
+    private final TwilightManager mTwilight;
+
+    // The auto-brightness spline adjustment.
+    // The brightness values have been scaled to a range of 0..1.
+    private final Spline mScreenAutoBrightnessSpline;
+
+    // The minimum and maximum screen brightnesses.
+    private final int mScreenBrightnessRangeMinimum;
+    private final int mScreenBrightnessRangeMaximum;
+
+    // Amount of time to delay auto-brightness after screen on while waiting for
+    // the light sensor to warm-up in milliseconds.
+    // May be 0 if no warm-up is required.
+    private int mLightSensorWarmUpTimeConfig;
+
+    // Set to true if the light sensor is enabled.
+    private boolean mLightSensorEnabled;
+
+    // The time when the light sensor was enabled.
+    private long mLightSensorEnableTime;
+
+    // The currently accepted nominal ambient light level.
+    private float mAmbientLux;
+
+    // True if mAmbientLux holds a valid value.
+    private boolean mAmbientLuxValid;
+
+    // The ambient light level threshold at which to brighten or darken the screen.
+    private float mBrighteningLuxThreshold;
+    private float mDarkeningLuxThreshold;
+
+    // The most recent light sample.
+    private float mLastObservedLux;
+
+    // The time of the most light recent sample.
+    private long mLastObservedLuxTime;
+
+    // The number of light samples collected since the light sensor was enabled.
+    private int mRecentLightSamples;
+
+    // A ring buffer containing all of the recent ambient light sensor readings.
+    private AmbientLightRingBuffer mAmbientLightRingBuffer;
+
+    // The handler
+    private AutomaticBrightnessHandler mHandler;
+
+    // The screen brightness level that has been chosen by the auto-brightness
+    // algorithm.  The actual brightness should ramp towards this value.
+    // We preserve this value even when we stop using the light sensor so
+    // that we can quickly revert to the previous auto-brightness level
+    // while the light sensor warms up.
+    // Use -1 if there is no current auto-brightness value available.
+    private int mScreenAutoBrightness = -1;
+
+    // The screen auto-brightness adjustment factor in the range -1 (dimmer) to 1 (brighter)
+    private float mScreenAutoBrightnessAdjustment = 0.0f;
+
+    // The last screen auto-brightness gamma.  (For printing in dump() only.)
+    private float mLastScreenAutoBrightnessGamma = 1.0f;
+
+    public AutomaticBrightnessController(Callbacks callbacks, Looper looper,
+            TwilightManager twilight, SensorManager sensorManager, Spline autoBrightnessSpline,
+            int lightSensorWarmUpTime, int brightnessMin, int brightnessMax) {
+        mCallbacks = callbacks;
+        mTwilight = twilight;
+        mSensorManager = sensorManager;
+        mScreenAutoBrightnessSpline = autoBrightnessSpline;
+        mScreenBrightnessRangeMinimum = brightnessMin;
+        mScreenBrightnessRangeMaximum = brightnessMax;
+        mLightSensorWarmUpTimeConfig = lightSensorWarmUpTime;
+
+        mHandler = new AutomaticBrightnessHandler(looper);
+        mAmbientLightRingBuffer = new AmbientLightRingBuffer();
+
+        if (!DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
+            mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
+        }
+
+        if (USE_TWILIGHT_ADJUSTMENT) {
+            mTwilight.registerListener(mTwilightListener, mHandler);
+        }
+    }
+
+    public int getAutomaticScreenBrightness() {
+        return mScreenAutoBrightness;
+    }
+
+    public void updatePowerState(DisplayPowerRequest request) {
+        if (setScreenAutoBrightnessAdjustment(request.screenAutoBrightnessAdjustment)
+                || setLightSensorEnabled(request.useAutoBrightness
+                    && DisplayPowerRequest.wantScreenOn(request.screenState))) {
+            updateAutoBrightness(false /*sendUpdate*/);
+        }
+    }
+
+    public void dump(PrintWriter pw) {
+        pw.println();
+        pw.println("Automatic Brightness Controller Configuration:");
+        pw.println("  mScreenAutoBrightnessSpline=" + mScreenAutoBrightnessSpline);
+        pw.println("  mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
+        pw.println("  mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
+        pw.println("  mLightSensorWarmUpTimeConfig=" + mLightSensorWarmUpTimeConfig);
+
+        pw.println();
+        pw.println("Automatic Brightness Controller State:");
+        pw.println("  mLightSensor=" + mLightSensor);
+        pw.println("  mTwilight.getCurrentState()=" + mTwilight.getCurrentState());
+        pw.println("  mLightSensorEnabled=" + mLightSensorEnabled);
+        pw.println("  mLightSensorEnableTime=" + TimeUtils.formatUptime(mLightSensorEnableTime));
+        pw.println("  mAmbientLux=" + mAmbientLux);
+        pw.println("  mBrighteningLuxThreshold=" + mBrighteningLuxThreshold);
+        pw.println("  mDarkeningLuxThreshold=" + mDarkeningLuxThreshold);
+        pw.println("  mLastObservedLux=" + mLastObservedLux);
+        pw.println("  mLastObservedLuxTime=" + TimeUtils.formatUptime(mLastObservedLuxTime));
+        pw.println("  mRecentLightSamples=" + mRecentLightSamples);
+        pw.println("  mAmbientLightRingBuffer=" + mAmbientLightRingBuffer);
+        pw.println("  mScreenAutoBrightness=" + mScreenAutoBrightness);
+        pw.println("  mScreenAutoBrightnessAdjustment=" + mScreenAutoBrightnessAdjustment);
+        pw.println("  mLastScreenAutoBrightnessGamma=" + mLastScreenAutoBrightnessGamma);
+    }
+
+    private boolean setLightSensorEnabled(boolean enable) {
+        if (enable) {
+            if (!mLightSensorEnabled) {
+                mLightSensorEnabled = true;
+                mLightSensorEnableTime = SystemClock.uptimeMillis();
+                mSensorManager.registerListener(mLightSensorListener, mLightSensor,
+                        LIGHT_SENSOR_RATE_MILLIS * 1000, mHandler);
+                return true;
+            }
+        } else {
+            if (mLightSensorEnabled) {
+                mLightSensorEnabled = false;
+                mAmbientLuxValid = false;
+                mRecentLightSamples = 0;
+                mAmbientLightRingBuffer.clear();
+                mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX);
+                mSensorManager.unregisterListener(mLightSensorListener);
+            }
+        }
+        return false;
+    }
+
+    private void handleLightSensorEvent(long time, float lux) {
+        mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX);
+
+        applyLightSensorMeasurement(time, lux);
+        updateAmbientLux(time);
+    }
+
+    private void applyLightSensorMeasurement(long time, float lux) {
+        mRecentLightSamples++;
+        mAmbientLightRingBuffer.prune(time - AMBIENT_LIGHT_HORIZON);
+        mAmbientLightRingBuffer.push(time, lux);
+
+        // Remember this sample value.
+        mLastObservedLux = lux;
+        mLastObservedLuxTime = time;
+    }
+
+    private boolean setScreenAutoBrightnessAdjustment(float adjustment) {
+        if (adjustment != mScreenAutoBrightnessAdjustment) {
+            mScreenAutoBrightnessAdjustment = adjustment;
+            return true;
+        }
+        return false;
+    }
+
+    private void setAmbientLux(float lux) {
+        mAmbientLux = lux;
+        mBrighteningLuxThreshold = mAmbientLux * (1.0f + BRIGHTENING_LIGHT_HYSTERESIS);
+        mDarkeningLuxThreshold = mAmbientLux * (1.0f - DARKENING_LIGHT_HYSTERESIS);
+    }
+
+    private float calculateAmbientLux(long now) {
+        final int N = mAmbientLightRingBuffer.size();
+        if (N == 0) {
+            Slog.e(TAG, "calculateAmbientLux: No ambient light readings available");
+            return -1;
+        }
+        float sum = 0;
+        float totalWeight = 0;
+        long endTime = AMBIENT_LIGHT_PREDICTION_TIME_MILLIS;
+        for (int i = N - 1; i >= 0; i--) {
+            long startTime = (mAmbientLightRingBuffer.getTime(i) - now);
+            float weight = calculateWeight(startTime, endTime);
+            float lux = mAmbientLightRingBuffer.getLux(i);
+            if (DEBUG) {
+                Slog.d(TAG, "calculateAmbientLux: [" +
+                        (startTime) + ", " +
+                        (endTime) + "]: lux=" + lux + ", weight=" + weight);
+            }
+            totalWeight += weight;
+            sum += mAmbientLightRingBuffer.getLux(i) * weight;
+            endTime = startTime;
+        }
+        if (DEBUG) {
+            Slog.d(TAG, "calculateAmbientLux: totalWeight=" + totalWeight +
+                    ", newAmbientLux=" + (sum / totalWeight));
+        }
+        return sum / totalWeight;
+    }
+
+    private static float calculateWeight(long startDelta, long endDelta) {
+        return weightIntegral(endDelta) - weightIntegral(startDelta);
+    }
+
+    // Evaluates the integral of y = x + WEIGHTING_INTERCEPT. This is always positive for the
+    // horizon we're looking at and provides a non-linear weighting for light samples.
+    private static float weightIntegral(long x) {
+        return x * (x * 0.5f + WEIGHTING_INTERCEPT);
+    }
+
+    private long nextAmbientLightBrighteningTransition(long time) {
+        final int N = mAmbientLightRingBuffer.size();
+        long earliestValidTime = time;
+        for (int i = N - 1; i >= 0; i--) {
+            if (mAmbientLightRingBuffer.getLux(i) <= mBrighteningLuxThreshold) {
+                break;
+            }
+            earliestValidTime = mAmbientLightRingBuffer.getTime(i);
+        }
+        return earliestValidTime + BRIGHTENING_LIGHT_DEBOUNCE;
+    }
+
+    private long nextAmbientLightDarkeningTransition(long time) {
+        final int N = mAmbientLightRingBuffer.size();
+        long earliestValidTime = time;
+        for (int i = N - 1; i >= 0; i--) {
+            if (mAmbientLightRingBuffer.getLux(i) >= mDarkeningLuxThreshold) {
+                break;
+            }
+            earliestValidTime = mAmbientLightRingBuffer.getTime(i);
+        }
+        return earliestValidTime + DARKENING_LIGHT_DEBOUNCE;
+    }
+
+    private void updateAmbientLux() {
+        long time = SystemClock.uptimeMillis();
+        mAmbientLightRingBuffer.prune(time - AMBIENT_LIGHT_HORIZON);
+        updateAmbientLux(time);
+    }
+
+    private void updateAmbientLux(long time) {
+        // If the light sensor was just turned on then immediately update our initial
+        // estimate of the current ambient light level.
+        if (!mAmbientLuxValid) {
+            final long timeWhenSensorWarmedUp =
+                mLightSensorWarmUpTimeConfig + mLightSensorEnableTime;
+            if (time < timeWhenSensorWarmedUp) {
+                if (DEBUG) {
+                    Slog.d(TAG, "updateAmbientLux: Sensor not  ready yet: "
+                            + "time=" + time
+                            + ", timeWhenSensorWarmedUp=" + timeWhenSensorWarmedUp);
+                }
+                mHandler.sendEmptyMessageAtTime(MSG_UPDATE_AMBIENT_LUX,
+                        timeWhenSensorWarmedUp);
+                return;
+            }
+            setAmbientLux(calculateAmbientLux(time));
+            mAmbientLuxValid = true;
+            if (DEBUG) {
+                Slog.d(TAG, "updateAmbientLux: Initializing: "
+                        + "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer
+                        + ", mAmbientLux=" + mAmbientLux);
+            }
+            updateAutoBrightness(true);
+        }
+
+        long nextBrightenTransition = nextAmbientLightBrighteningTransition(time);
+        long nextDarkenTransition = nextAmbientLightDarkeningTransition(time);
+        float ambientLux = calculateAmbientLux(time);
+
+        if (ambientLux >= mBrighteningLuxThreshold && nextBrightenTransition <= time
+                || ambientLux <= mDarkeningLuxThreshold && nextDarkenTransition <= time) {
+            setAmbientLux(ambientLux);
+            if (DEBUG) {
+                Slog.d(TAG, "updateAmbientLux: "
+                        + ((ambientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": "
+                        + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold
+                        + ", mAmbientLightRingBuffer=" + mAmbientLightRingBuffer
+                        + ", mAmbientLux=" + mAmbientLux);
+            }
+            updateAutoBrightness(true);
+            nextBrightenTransition = nextAmbientLightBrighteningTransition(time);
+            nextDarkenTransition = nextAmbientLightDarkeningTransition(time);
+        }
+        long nextTransitionTime = Math.min(nextDarkenTransition, nextBrightenTransition);
+        // If one of the transitions is ready to occur, but the total weighted ambient lux doesn't
+        // exceed the necessary threshold, then it's possible we'll get a transition time prior to
+        // now. Rather than continually checking to see whether the weighted lux exceeds the
+        // threshold, schedule an update for when we'd normally expect another light sample, which
+        // should be enough time to decide whether we should actually transition to the new
+        // weighted ambient lux or not.
+        nextTransitionTime =
+                nextTransitionTime > time ? nextTransitionTime : time + LIGHT_SENSOR_RATE_MILLIS;
+        if (DEBUG) {
+            Slog.d(TAG, "updateAmbientLux: Scheduling ambient lux update for "
+                    + nextTransitionTime + TimeUtils.formatUptime(nextTransitionTime));
+        }
+        mHandler.sendEmptyMessageAtTime(MSG_UPDATE_AMBIENT_LUX, nextTransitionTime);
+    }
+
+    private void updateAutoBrightness(boolean sendUpdate) {
+        if (!mAmbientLuxValid) {
+            return;
+        }
+
+        float value = mScreenAutoBrightnessSpline.interpolate(mAmbientLux);
+        float gamma = 1.0f;
+
+        if (USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT
+                && mScreenAutoBrightnessAdjustment != 0.0f) {
+            final float adjGamma = MathUtils.pow(SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA,
+                    Math.min(1.0f, Math.max(-1.0f, -mScreenAutoBrightnessAdjustment)));
+            gamma *= adjGamma;
+            if (DEBUG) {
+                Slog.d(TAG, "updateAutoBrightness: adjGamma=" + adjGamma);
+            }
+        }
+
+        if (USE_TWILIGHT_ADJUSTMENT) {
+            TwilightState state = mTwilight.getCurrentState();
+            if (state != null && state.isNight()) {
+                final long now = System.currentTimeMillis();
+                final float earlyGamma =
+                        getTwilightGamma(now, state.getYesterdaySunset(), state.getTodaySunrise());
+                final float lateGamma =
+                        getTwilightGamma(now, state.getTodaySunset(), state.getTomorrowSunrise());
+                gamma *= earlyGamma * lateGamma;
+                if (DEBUG) {
+                    Slog.d(TAG, "updateAutoBrightness: earlyGamma=" + earlyGamma
+                            + ", lateGamma=" + lateGamma);
+                }
+            }
+        }
+
+        if (gamma != 1.0f) {
+            final float in = value;
+            value = MathUtils.pow(value, gamma);
+            if (DEBUG) {
+                Slog.d(TAG, "updateAutoBrightness: gamma=" + gamma
+                        + ", in=" + in + ", out=" + value);
+            }
+        }
+
+        int newScreenAutoBrightness =
+            clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON));
+        if (mScreenAutoBrightness != newScreenAutoBrightness) {
+            if (DEBUG) {
+                Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness="
+                        + mScreenAutoBrightness + ", newScreenAutoBrightness="
+                        + newScreenAutoBrightness);
+            }
+
+            mScreenAutoBrightness = newScreenAutoBrightness;
+            mLastScreenAutoBrightnessGamma = gamma;
+            if (sendUpdate) {
+                mCallbacks.updateBrightness();
+            }
+        }
+    }
+
+    private int clampScreenBrightness(int value) {
+        return MathUtils.constrain(value,
+                mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
+    }
+
+    private static float getTwilightGamma(long now, long lastSunset, long nextSunrise) {
+        if (lastSunset < 0 || nextSunrise < 0
+                || now < lastSunset || now > nextSunrise) {
+            return 1.0f;
+        }
+
+        if (now < lastSunset + TWILIGHT_ADJUSTMENT_TIME) {
+            return MathUtils.lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
+                    (float)(now - lastSunset) / TWILIGHT_ADJUSTMENT_TIME);
+        }
+
+        if (now > nextSunrise - TWILIGHT_ADJUSTMENT_TIME) {
+            return MathUtils.lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
+                    (float)(nextSunrise - now) / TWILIGHT_ADJUSTMENT_TIME);
+        }
+
+        return TWILIGHT_ADJUSTMENT_MAX_GAMMA;
+    }
+
+    private final class AutomaticBrightnessHandler extends Handler {
+        public AutomaticBrightnessHandler(Looper looper) {
+            super(looper, null, true /*async*/);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_UPDATE_AMBIENT_LUX:
+                    updateAmbientLux();
+                    break;
+            }
+        }
+    }
+
+    private final SensorEventListener mLightSensorListener = new SensorEventListener() {
+        @Override
+        public void onSensorChanged(SensorEvent event) {
+            if (mLightSensorEnabled) {
+                final long time = SystemClock.uptimeMillis();
+                final float lux = event.values[0];
+                handleLightSensorEvent(time, lux);
+            }
+        }
+
+        @Override
+        public void onAccuracyChanged(Sensor sensor, int accuracy) {
+            // Not used.
+        }
+    };
+
+    private final TwilightListener mTwilightListener = new TwilightListener() {
+        @Override
+        public void onTwilightStateChanged() {
+            updateAutoBrightness(true /*sendUpdate*/);
+        }
+    };
+
+    /** Callbacks to request updates to the display's power state. */
+    interface Callbacks {
+        void updateBrightness();
+    }
+
+    private static final class AmbientLightRingBuffer{
+        // Proportional extra capacity of the buffer beyond the expected number of light samples
+        // in the horizon
+        private static final float BUFFER_SLACK = 1.5f;
+        private static final int DEFAULT_CAPACITY =
+            (int) Math.ceil(AMBIENT_LIGHT_HORIZON * BUFFER_SLACK / LIGHT_SENSOR_RATE_MILLIS);
+        private float[] mRingLux;
+        private long[] mRingTime;
+        private int mCapacity;
+
+        // The first valid element and the next open slot.
+        // Note that if mCount is zero then there are no valid elements.
+        private int mStart;
+        private int mEnd;
+        private int mCount;
+
+        public AmbientLightRingBuffer() {
+            this(DEFAULT_CAPACITY);
+        }
+
+        public AmbientLightRingBuffer(int initialCapacity) {
+            mCapacity = initialCapacity;
+            mRingLux = new float[mCapacity];
+            mRingTime = new long[mCapacity];
+        }
+
+        public float getLux(int index) {
+            return mRingLux[offsetOf(index)];
+        }
+
+        public long getTime(int index) {
+            return mRingTime[offsetOf(index)];
+        }
+
+        public void push(long time, float lux) {
+            int next = mEnd;
+            if (mCount == mCapacity) {
+                int newSize = mCapacity * 2;
+
+                float[] newRingLux = new float[newSize];
+                long[] newRingTime = new long[newSize];
+                int length = mCapacity - mStart;
+                System.arraycopy(mRingLux, mStart, newRingLux, 0, length);
+                System.arraycopy(mRingTime, mStart, newRingTime, 0, length);
+                if (mStart != 0) {
+                    System.arraycopy(mRingLux, 0, newRingLux, length, mStart);
+                    System.arraycopy(mRingTime, 0, newRingTime, length, mStart);
+                }
+                mRingLux = newRingLux;
+                mRingTime = newRingTime;
+
+                next = mCapacity;
+                mCapacity = newSize;
+                mStart = 0;
+            }
+            mRingTime[next] = time;
+            mRingLux[next] = lux;
+            mEnd = next + 1;
+            if (mEnd == mCapacity) {
+                mEnd = 0;
+            }
+            mCount++;
+        }
+
+        public void prune(long horizon) {
+            if (mCount == 0) {
+                return;
+            }
+
+            while (mCount > 1) {
+                int next = mStart + 1;
+                if (next >= mCapacity) {
+                    next -= mCapacity;
+                }
+                if (mRingTime[next] > horizon) {
+                    // Some light sensors only produce data upon a change in the ambient light
+                    // levels, so we need to consider the previous measurement as the ambient light
+                    // level for all points in time up until we receive a new measurement. Thus, we
+                    // always want to keep the youngest element that would be removed from the
+                    // buffer and just set its measurement time to the horizon time since at that
+                    // point it is the ambient light level, and to remove it would be to drop a
+                    // valid data point within our horizon.
+                    break;
+                }
+                mStart = next;
+                mCount -= 1;
+            }
+
+            if (mRingTime[mStart] < horizon) {
+                mRingTime[mStart] = horizon;
+            }
+        }
+
+        public int size() {
+            return mCount;
+        }
+
+        public boolean isEmpty() {
+            return mCount == 0;
+        }
+
+        public void clear() {
+            mStart = 0;
+            mEnd = 0;
+            mCount = 0;
+        }
+
+        @Override
+        public String toString() {
+            final int length = mCapacity - mStart;
+            float[] lux = new float[mCount];
+            long[] time = new long[mCount];
+
+            if (mCount <= length) {
+                System.arraycopy(mRingLux, mStart, lux, 0, mCount);
+                System.arraycopy(mRingTime, mStart, time, 0, mCount);
+            } else {
+                System.arraycopy(mRingLux, mStart, lux, 0, length);
+                System.arraycopy(mRingLux, 0, lux, length, mCount - length);
+
+                System.arraycopy(mRingTime, mStart, time, 0, length);
+                System.arraycopy(mRingTime, 0, time, length, mCount - length);
+            }
+            return "AmbientLightRingBuffer{mCapacity=" + mCapacity
+                + ", mStart=" + mStart
+                + ", mEnd=" + mEnd
+                + ", mCount=" + mCount
+                + ", mRingLux=" + Arrays.toString(lux)
+                + ", mRingTime=" + Arrays.toString(time)
+                + "}";
+        }
+
+        private int offsetOf(int index) {
+            if (index >= mCount || index < 0) {
+                throw new ArrayIndexOutOfBoundsException(index);
+            }
+            index += mStart;
+            if (index >= mCapacity) {
+                index -= mCapacity;
+            }
+            return index;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/power/DisplayPowerController.java b/services/core/java/com/android/server/power/DisplayPowerController.java
index b63f625..291bb64 100644
--- a/services/core/java/com/android/server/power/DisplayPowerController.java
+++ b/services/core/java/com/android/server/power/DisplayPowerController.java
@@ -35,7 +35,7 @@
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.text.format.DateUtils;
-import android.util.FloatMath;
+import android.util.MathUtils;
 import android.util.Slog;
 import android.util.Spline;
 import android.util.TimeUtils;
@@ -64,12 +64,11 @@
  * For debugging, you can make the electron beam and brightness animations run
  * slower by changing the "animator duration scale" option in Development Settings.
  */
-final class DisplayPowerController {
+final class DisplayPowerController implements AutomaticBrightnessController.Callbacks {
     private static final String TAG = "DisplayPowerController";
 
     private static boolean DEBUG = false;
     private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
-    private static final boolean DEBUG_PRETEND_LIGHT_SENSOR_ABSENT = false;
 
     // If true, uses the electron beam on animation.
     // We might want to turn this off if we cannot get a guarantee that the screen
@@ -77,13 +76,6 @@
     // screen state returns.  Playing the animation can also be somewhat slow.
     private static final boolean USE_ELECTRON_BEAM_ON_ANIMATION = false;
 
-    // If true, enables the use of the screen auto-brightness adjustment setting.
-    private static final boolean USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT =
-            PowerManager.useScreenAutoBrightnessAdjustmentFeature();
-
-    // The maximum range of gamma adjustment possible using the screen
-    // auto-brightness adjustment setting.
-    private static final float SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA = 3.0f;
 
     // The minimum reduction in brightness when dimmed.
     private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10;
@@ -110,7 +102,6 @@
 
     private static final int MSG_UPDATE_POWER_STATE = 1;
     private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
-    private static final int MSG_LIGHT_SENSOR_DEBOUNCED = 3;
 
     private static final int PROXIMITY_UNKNOWN = -1;
     private static final int PROXIMITY_NEGATIVE = 0;
@@ -123,41 +114,10 @@
     // Trigger proximity if distance is less than 5 cm.
     private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
 
-    // Light sensor event rate in milliseconds.
-    private static final int LIGHT_SENSOR_RATE_MILLIS = 1000;
-
-    // A rate for generating synthetic light sensor events in the case where the light
-    // sensor hasn't reported any new data in a while and we need it to update the
-    // debounce filter.  We only synthesize light sensor measurements when needed.
-    private static final int SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS =
-            LIGHT_SENSOR_RATE_MILLIS * 2;
-
     // Brightness animation ramp rate in brightness units per second.
     private static final int BRIGHTNESS_RAMP_RATE_FAST = 200;
     private static final int BRIGHTNESS_RAMP_RATE_SLOW = 40;
 
-    // IIR filter time constants in milliseconds for computing two moving averages of
-    // the light samples.  One is a long-term average and the other is a short-term average.
-    // We can use these filters to assess trends in ambient brightness.
-    // The short term average gives us a filtered but relatively low latency measurement.
-    // The long term average informs us about the overall trend.
-    private static final long SHORT_TERM_AVERAGE_LIGHT_TIME_CONSTANT = 1000;
-    private static final long LONG_TERM_AVERAGE_LIGHT_TIME_CONSTANT = 5000;
-
-    // Stability requirements in milliseconds for accepting a new brightness
-    // level.  This is used for debouncing the light sensor.  Different constants
-    // are used to debounce the light sensor when adapting to brighter or darker environments.
-    // This parameter controls how quickly brightness changes occur in response to
-    // an observed change in light level that exceeds the hysteresis threshold.
-    private static final long BRIGHTENING_LIGHT_DEBOUNCE = 4000;
-    private static final long DARKENING_LIGHT_DEBOUNCE = 8000;
-
-    // Hysteresis constraints for brightening or darkening.
-    // The recent lux must have changed by at least this fraction relative to the
-    // current ambient lux before a change will be considered.
-    private static final float BRIGHTENING_LIGHT_HYSTERESIS = 0.10f;
-    private static final float DARKENING_LIGHT_HYSTERESIS = 0.20f;
-
     private final Object mLock = new Object();
 
     // Notifier for sending asynchronous notifications.
@@ -181,18 +141,12 @@
     // The lights service.
     private final LightsManager mLights;
 
-    // The twilight service.
-    private final TwilightManager mTwilight;
-
     // The sensor manager.
     private final SensorManager mSensorManager;
 
     // The proximity sensor, or null if not available or needed.
     private Sensor mProximitySensor;
 
-    // The light sensor, or null if not available or needed.
-    private Sensor mLightSensor;
-
     // The dim screen brightness.
     private final int mScreenBrightnessDimConfig;
 
@@ -205,15 +159,6 @@
     // True if auto-brightness should be used.
     private boolean mUseSoftwareAutoBrightnessConfig;
 
-    // The auto-brightness spline adjustment.
-    // The brightness values have been scaled to a range of 0..1.
-    private Spline mScreenAutoBrightnessSpline;
-
-    // Amount of time to delay auto-brightness after screen on while waiting for
-    // the light sensor to warm-up in milliseconds.
-    // May be 0 if no warm-up is required.
-    private int mLightSensorWarmUpTimeConfig;
-
     // True if we should fade the screen while turning it off, false if we should play
     // a stylish electron beam animation instead.
     private boolean mElectronBeamFadesConfig;
@@ -283,67 +228,18 @@
     // The elapsed real time when the screen on was blocked.
     private long mScreenOnBlockStartRealTime;
 
-    // Set to true if the light sensor is enabled.
-    private boolean mLightSensorEnabled;
-
-    // The time when the light sensor was enabled.
-    private long mLightSensorEnableTime;
-
-    // The currently accepted nominal ambient light level.
-    private float mAmbientLux;
-
-    // True if mAmbientLux holds a valid value.
-    private boolean mAmbientLuxValid;
-
-    // The ambient light level threshold at which to brighten or darken the screen.
-    private float mBrighteningLuxThreshold;
-    private float mDarkeningLuxThreshold;
-
-    // The most recent light sample.
-    private float mLastObservedLux;
-
-    // The time of the most light recent sample.
-    private long mLastObservedLuxTime;
-
-    // The number of light samples collected since the light sensor was enabled.
-    private int mRecentLightSamples;
-
-    // The long-term and short-term filtered light measurements.
-    private float mRecentShortTermAverageLux;
-    private float mRecentLongTermAverageLux;
-
-    // The direction in which the average lux is moving relative to the current ambient lux.
-    //    0 if not changing or within hysteresis threshold.
-    //    1 if brightening beyond hysteresis threshold.
-    //   -1 if darkening beyond hysteresis threshold.
-    private int mDebounceLuxDirection;
-
-    // The time when the average lux last changed direction.
-    private long mDebounceLuxTime;
-
-    // The screen brightness level that has been chosen by the auto-brightness
-    // algorithm.  The actual brightness should ramp towards this value.
-    // We preserve this value even when we stop using the light sensor so
-    // that we can quickly revert to the previous auto-brightness level
-    // while the light sensor warms up.
-    // Use -1 if there is no current auto-brightness value available.
-    private int mScreenAutoBrightness = -1;
-
-    // The last screen auto-brightness gamma.  (For printing in dump() only.)
-    private float mLastScreenAutoBrightnessGamma = 1.0f;
-
     // True if the screen auto-brightness value is actually being used to
     // set the display brightness.
     private boolean mUsingScreenAutoBrightness;
 
+    // The controller for the automatic brightness level.
+    private AutomaticBrightnessController mAutomaticBrightnessController;
+
     // Animators.
     private ObjectAnimator mElectronBeamOnAnimator;
     private ObjectAnimator mElectronBeamOffAnimator;
     private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
 
-    // Twilight changed.  We might recalculate auto-brightness values.
-    private boolean mTwilightChanged;
-
     /**
      * Creates the display power controller.
      */
@@ -359,7 +255,6 @@
         mCallbackHandler = callbackHandler;
 
         mLights = lights;
-        mTwilight = twilight;
         mSensorManager = sensorManager;
 
         final Resources resources = context.getResources();
@@ -367,9 +262,11 @@
         mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
                 com.android.internal.R.integer.config_screenBrightnessDim));
 
-        int screenBrightnessMinimum = Math.min(resources.getInteger(
+        int screenBrightnessRangeMinimum = clampAbsoluteBrightness(Math.min(resources.getInteger(
                 com.android.internal.R.integer.config_screenBrightnessSettingMinimum),
-                mScreenBrightnessDimConfig);
+                mScreenBrightnessDimConfig));
+
+        mScreenBrightnessRangeMaximum = PowerManager.BRIGHTNESS_ON;
 
         mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
                 com.android.internal.R.bool.config_automatic_brightness_available);
@@ -378,9 +275,11 @@
                     com.android.internal.R.array.config_autoBrightnessLevels);
             int[] screenBrightness = resources.getIntArray(
                     com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
+            int lightSensorWarmUpTimeConfig = resources.getInteger(
+                    com.android.internal.R.integer.config_lightSensorWarmupTime);
 
-            mScreenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);
-            if (mScreenAutoBrightnessSpline == null) {
+            Spline screenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);
+            if (screenAutoBrightnessSpline == null) {
                 Slog.e(TAG, "Error in config.xml.  config_autoBrightnessLcdBacklightValues "
                         + "(size " + screenBrightness.length + ") "
                         + "must be monotic and have exactly one more entry than "
@@ -389,17 +288,17 @@
                         + "Auto-brightness will be disabled.");
                 mUseSoftwareAutoBrightnessConfig = false;
             } else {
-                if (screenBrightness[0] < screenBrightnessMinimum) {
-                    screenBrightnessMinimum = screenBrightness[0];
+                if (screenBrightness[0] < screenBrightnessRangeMinimum) {
+                    screenBrightnessRangeMinimum = clampAbsoluteBrightness(screenBrightness[0]);
                 }
+                mAutomaticBrightnessController = new AutomaticBrightnessController(this, looper,
+                        twilight, sensorManager, screenAutoBrightnessSpline,
+                        lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum,
+                        mScreenBrightnessRangeMaximum);
             }
-
-            mLightSensorWarmUpTimeConfig = resources.getInteger(
-                    com.android.internal.R.integer.config_lightSensorWarmupTime);
         }
 
-        mScreenBrightnessRangeMinimum = clampAbsoluteBrightness(screenBrightnessMinimum);
-        mScreenBrightnessRangeMaximum = PowerManager.BRIGHTNESS_ON;
+        mScreenBrightnessRangeMinimum = screenBrightnessRangeMinimum;
 
         mElectronBeamFadesConfig = resources.getBoolean(
                 com.android.internal.R.bool.config_animateScreenLights);
@@ -412,39 +311,6 @@
             }
         }
 
-        if (mUseSoftwareAutoBrightnessConfig
-                && !DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
-            mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
-        }
-
-        if (mUseSoftwareAutoBrightnessConfig && USE_TWILIGHT_ADJUSTMENT) {
-            mTwilight.registerListener(mTwilightListener, mHandler);
-        }
-    }
-
-    private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) {
-        try {
-            final int n = brightness.length;
-            float[] x = new float[n];
-            float[] y = new float[n];
-            y[0] = normalizeAbsoluteBrightness(brightness[0]);
-            for (int i = 1; i < n; i++) {
-                x[i] = lux[i - 1];
-                y[i] = normalizeAbsoluteBrightness(brightness[i]);
-            }
-
-            Spline spline = Spline.createMonotoneCubicSpline(x, y);
-            if (DEBUG) {
-                Slog.d(TAG, "Auto-brightness spline: " + spline);
-                for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) {
-                    Slog.d(TAG, String.format("  %7.1f: %7.1f", v, spline.interpolate(v)));
-                }
-            }
-            return spline;
-        } catch (IllegalArgumentException ex) {
-            Slog.e(TAG, "Could not create auto-brightness spline.", ex);
-            return null;
-        }
     }
 
     /**
@@ -566,9 +432,7 @@
         // Update the power state request.
         final boolean mustNotify;
         boolean mustInitialize = false;
-        boolean updateAutoBrightness = mTwilightChanged;
         boolean wasDim = false;
-        mTwilightChanged = false;
 
         synchronized (mLock) {
             mPendingUpdatePowerStateLocked = false;
@@ -583,10 +447,6 @@
                 mPendingRequestChangedLocked = false;
                 mustInitialize = true;
             } else if (mPendingRequestChangedLocked) {
-                if (mPowerRequest.screenAutoBrightnessAdjustment
-                        != mPendingRequestLocked.screenAutoBrightnessAdjustment) {
-                    updateAutoBrightness = true;
-                }
                 wasDim = (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM);
                 mPowerRequest.copyFrom(mPendingRequestLocked);
                 mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
@@ -633,18 +493,19 @@
         }
 
         // Turn on the light sensor if needed.
-        if (mLightSensor != null) {
-            setLightSensorEnabled(mPowerRequest.useAutoBrightness
-                    && wantScreenOn(mPowerRequest.screenState), updateAutoBrightness);
+        if (mAutomaticBrightnessController != null) {
+            mAutomaticBrightnessController.updatePowerState(mPowerRequest);
         }
 
         // Set the screen brightness.
-        if (wantScreenOn(mPowerRequest.screenState)) {
+        if (DisplayPowerRequest.wantScreenOn(mPowerRequest.screenState)) {
             int target;
             boolean slow;
-            if (mScreenAutoBrightness >= 0 && mLightSensorEnabled) {
+            int screenAutoBrightness = mAutomaticBrightnessController != null ?
+                    mAutomaticBrightnessController.getAutomaticScreenBrightness() : -1;
+            if (screenAutoBrightness >= 0) {
                 // Use current auto-brightness value.
-                target = mScreenAutoBrightness;
+                target = screenAutoBrightness;
                 slow = mUsingScreenAutoBrightness;
                 mUsingScreenAutoBrightness = true;
             } else {
@@ -674,7 +535,7 @@
 
         // Animate the screen on or off.
         if (!mScreenOffBecauseOfProximity) {
-            if (wantScreenOn(mPowerRequest.screenState)) {
+            if (DisplayPowerRequest.wantScreenOn(mPowerRequest.screenState)) {
                 // Want screen on.
                 // Wait for previous off animation to complete beforehand.
                 // It is relatively short but if we cancel it and switch to the
@@ -751,6 +612,11 @@
         }
     }
 
+    @Override
+    public void updateBrightness() {
+        sendUpdatePowerState();
+    }
+
     private void blockScreenOn() {
         if (!mScreenOnWasBlocked) {
             mScreenOnWasBlocked = true;
@@ -783,25 +649,8 @@
     }
 
     private int clampScreenBrightness(int value) {
-        return clamp(value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
-    }
-
-    private static int clampAbsoluteBrightness(int value) {
-        return clamp(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
-    }
-
-    private static int clamp(int value, int min, int max) {
-        if (value <= min) {
-            return min;
-        }
-        if (value >= max) {
-            return max;
-        }
-        return value;
-    }
-
-    private static float normalizeAbsoluteBrightness(int value) {
-        return (float)clampAbsoluteBrightness(value) / PowerManager.BRIGHTNESS_ON;
+        return MathUtils.constrain(
+                value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
     }
 
     private void animateScreenBrightness(int target, int rate) {
@@ -902,270 +751,6 @@
         mPendingProximityDebounceTime = debounceTime;
     }
 
-    private void setLightSensorEnabled(boolean enable, boolean updateAutoBrightness) {
-        if (enable) {
-            if (!mLightSensorEnabled) {
-                updateAutoBrightness = true;
-                mLightSensorEnabled = true;
-                mLightSensorEnableTime = SystemClock.uptimeMillis();
-                mSensorManager.registerListener(mLightSensorListener, mLightSensor,
-                        LIGHT_SENSOR_RATE_MILLIS * 1000, mHandler);
-            }
-        } else {
-            if (mLightSensorEnabled) {
-                mLightSensorEnabled = false;
-                mAmbientLuxValid = false;
-                mRecentLightSamples = 0;
-                mHandler.removeMessages(MSG_LIGHT_SENSOR_DEBOUNCED);
-                mSensorManager.unregisterListener(mLightSensorListener);
-            }
-        }
-        if (updateAutoBrightness) {
-            updateAutoBrightness(false);
-        }
-    }
-
-    private void handleLightSensorEvent(long time, float lux) {
-        mHandler.removeMessages(MSG_LIGHT_SENSOR_DEBOUNCED);
-
-        applyLightSensorMeasurement(time, lux);
-        updateAmbientLux(time);
-    }
-
-    private void applyLightSensorMeasurement(long time, float lux) {
-        // Update our filters.
-        mRecentLightSamples += 1;
-        if (mRecentLightSamples == 1) {
-            mRecentShortTermAverageLux = lux;
-            mRecentLongTermAverageLux = lux;
-        } else {
-            final long timeDelta = time - mLastObservedLuxTime;
-            mRecentShortTermAverageLux += (lux - mRecentShortTermAverageLux)
-                    * timeDelta / (SHORT_TERM_AVERAGE_LIGHT_TIME_CONSTANT + timeDelta);
-            mRecentLongTermAverageLux += (lux - mRecentLongTermAverageLux)
-                    * timeDelta / (LONG_TERM_AVERAGE_LIGHT_TIME_CONSTANT + timeDelta);
-        }
-
-        // Remember this sample value.
-        mLastObservedLux = lux;
-        mLastObservedLuxTime = time;
-    }
-
-    private void setAmbientLux(float lux) {
-        mAmbientLux = lux;
-        mBrighteningLuxThreshold = mAmbientLux * (1.0f + BRIGHTENING_LIGHT_HYSTERESIS);
-        mDarkeningLuxThreshold = mAmbientLux * (1.0f - DARKENING_LIGHT_HYSTERESIS);
-    }
-
-    private void updateAmbientLux(long time) {
-        // If the light sensor was just turned on then immediately update our initial
-        // estimate of the current ambient light level.
-        if (!mAmbientLuxValid) {
-            final long timeWhenSensorWarmedUp =
-                mLightSensorWarmUpTimeConfig + mLightSensorEnableTime;
-            if (time < timeWhenSensorWarmedUp) {
-                mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED,
-                        timeWhenSensorWarmedUp);
-                return;
-            }
-            setAmbientLux(mRecentShortTermAverageLux);
-            mAmbientLuxValid = true;
-            mDebounceLuxDirection = 0;
-            mDebounceLuxTime = time;
-            if (DEBUG) {
-                Slog.d(TAG, "updateAmbientLux: Initializing: "
-                        + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
-                        + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
-                        + ", mAmbientLux=" + mAmbientLux);
-            }
-            updateAutoBrightness(true);
-        } else if (mRecentShortTermAverageLux > mBrighteningLuxThreshold
-                && mRecentLongTermAverageLux > mBrighteningLuxThreshold) {
-            // The ambient environment appears to be brightening.
-            if (mDebounceLuxDirection <= 0) {
-                mDebounceLuxDirection = 1;
-                mDebounceLuxTime = time;
-                if (DEBUG) {
-                    Slog.d(TAG, "updateAmbientLux: Possibly brightened, waiting for "
-                            + BRIGHTENING_LIGHT_DEBOUNCE + " ms: "
-                            + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold
-                            + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
-                            + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
-                            + ", mAmbientLux=" + mAmbientLux);
-                }
-            }
-            long debounceTime = mDebounceLuxTime + BRIGHTENING_LIGHT_DEBOUNCE;
-            if (time < debounceTime) {
-                mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED, debounceTime);
-                return;
-            }
-            setAmbientLux(mRecentShortTermAverageLux);
-            if (DEBUG) {
-                Slog.d(TAG, "updateAmbientLux: Brightened: "
-                        + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold
-                        + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
-                        + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
-                        + ", mAmbientLux=" + mAmbientLux);
-            }
-            updateAutoBrightness(true);
-        } else if (mRecentShortTermAverageLux < mDarkeningLuxThreshold
-                && mRecentLongTermAverageLux < mDarkeningLuxThreshold) {
-            // The ambient environment appears to be darkening.
-            if (mDebounceLuxDirection >= 0) {
-                mDebounceLuxDirection = -1;
-                mDebounceLuxTime = time;
-                if (DEBUG) {
-                    Slog.d(TAG, "updateAmbientLux: Possibly darkened, waiting for "
-                            + DARKENING_LIGHT_DEBOUNCE + " ms: "
-                            + "mDarkeningLuxThreshold=" + mDarkeningLuxThreshold
-                            + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
-                            + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
-                            + ", mAmbientLux=" + mAmbientLux);
-                }
-            }
-            long debounceTime = mDebounceLuxTime + DARKENING_LIGHT_DEBOUNCE;
-            if (time < debounceTime) {
-                mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED, debounceTime);
-                return;
-            }
-            // Be conservative about reducing the brightness, only reduce it a little bit
-            // at a time to avoid having to bump it up again soon.
-            setAmbientLux(Math.max(mRecentShortTermAverageLux, mRecentLongTermAverageLux));
-            if (DEBUG) {
-                Slog.d(TAG, "updateAmbientLux: Darkened: "
-                        + "mDarkeningLuxThreshold=" + mDarkeningLuxThreshold
-                        + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
-                        + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
-                        + ", mAmbientLux=" + mAmbientLux);
-            }
-            updateAutoBrightness(true);
-        } else if (mDebounceLuxDirection != 0) {
-            // No change or change is within the hysteresis thresholds.
-            mDebounceLuxDirection = 0;
-            mDebounceLuxTime = time;
-            if (DEBUG) {
-                Slog.d(TAG, "updateAmbientLux: Canceled debounce: "
-                        + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold
-                        + ", mDarkeningLuxThreshold=" + mDarkeningLuxThreshold
-                        + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
-                        + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
-                        + ", mAmbientLux=" + mAmbientLux);
-            }
-        }
-
-        // Now that we've done all of that, we haven't yet posted a debounce
-        // message. So consider the case where current lux is beyond the
-        // threshold. It's possible that the light sensor may not report values
-        // if the light level does not change, so we need to occasionally
-        // synthesize sensor readings in order to make sure the brightness is
-        // adjusted accordingly. Note these thresholds may have changed since
-        // we entered the function because we called setAmbientLux and
-        // updateAutoBrightness along the way.
-        if (mLastObservedLux > mBrighteningLuxThreshold
-                || mLastObservedLux < mDarkeningLuxThreshold) {
-            mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED,
-                    time + SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS);
-        }
-    }
-
-    private void debounceLightSensor() {
-        if (mLightSensorEnabled) {
-            long time = SystemClock.uptimeMillis();
-            if (time >= mLastObservedLuxTime + SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS) {
-                if (DEBUG) {
-                    Slog.d(TAG, "debounceLightSensor: Synthesizing light sensor measurement "
-                            + "after " + (time - mLastObservedLuxTime) + " ms.");
-                }
-                applyLightSensorMeasurement(time, mLastObservedLux);
-            }
-            updateAmbientLux(time);
-        }
-    }
-
-    private void updateAutoBrightness(boolean sendUpdate) {
-        if (!mAmbientLuxValid) {
-            return;
-        }
-
-        float value = mScreenAutoBrightnessSpline.interpolate(mAmbientLux);
-        float gamma = 1.0f;
-
-        if (USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT
-                && mPowerRequest.screenAutoBrightnessAdjustment != 0.0f) {
-            final float adjGamma = FloatMath.pow(SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA,
-                    Math.min(1.0f, Math.max(-1.0f,
-                            -mPowerRequest.screenAutoBrightnessAdjustment)));
-            gamma *= adjGamma;
-            if (DEBUG) {
-                Slog.d(TAG, "updateAutoBrightness: adjGamma=" + adjGamma);
-            }
-        }
-
-        if (USE_TWILIGHT_ADJUSTMENT) {
-            TwilightState state = mTwilight.getCurrentState();
-            if (state != null && state.isNight()) {
-                final long now = System.currentTimeMillis();
-                final float earlyGamma =
-                        getTwilightGamma(now, state.getYesterdaySunset(), state.getTodaySunrise());
-                final float lateGamma =
-                        getTwilightGamma(now, state.getTodaySunset(), state.getTomorrowSunrise());
-                gamma *= earlyGamma * lateGamma;
-                if (DEBUG) {
-                    Slog.d(TAG, "updateAutoBrightness: earlyGamma=" + earlyGamma
-                            + ", lateGamma=" + lateGamma);
-                }
-            }
-        }
-
-        if (gamma != 1.0f) {
-            final float in = value;
-            value = FloatMath.pow(value, gamma);
-            if (DEBUG) {
-                Slog.d(TAG, "updateAutoBrightness: gamma=" + gamma
-                        + ", in=" + in + ", out=" + value);
-            }
-        }
-
-        int newScreenAutoBrightness = clampScreenBrightness(
-                Math.round(value * PowerManager.BRIGHTNESS_ON));
-        if (mScreenAutoBrightness != newScreenAutoBrightness) {
-            if (DEBUG) {
-                Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness="
-                        + mScreenAutoBrightness + ", newScreenAutoBrightness="
-                        + newScreenAutoBrightness);
-            }
-
-            mScreenAutoBrightness = newScreenAutoBrightness;
-            mLastScreenAutoBrightnessGamma = gamma;
-            if (sendUpdate) {
-                sendUpdatePowerState();
-            }
-        }
-    }
-
-    private static float getTwilightGamma(long now, long lastSunset, long nextSunrise) {
-        if (lastSunset < 0 || nextSunrise < 0
-                || now < lastSunset || now > nextSunrise) {
-            return 1.0f;
-        }
-
-        if (now < lastSunset + TWILIGHT_ADJUSTMENT_TIME) {
-            return lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
-                    (float)(now - lastSunset) / TWILIGHT_ADJUSTMENT_TIME);
-        }
-
-        if (now > nextSunrise - TWILIGHT_ADJUSTMENT_TIME) {
-            return lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
-                    (float)(nextSunrise - now) / TWILIGHT_ADJUSTMENT_TIME);
-        }
-
-        return TWILIGHT_ADJUSTMENT_MAX_GAMMA;
-    }
-
-    private static float lerp(float x, float y, float alpha) {
-        return x + (y - x) * alpha;
-    }
-
     private void sendOnStateChangedWithWakelock() {
         mDisplaySuspendBlocker.acquire();
         mCallbackHandler.post(mOnStateChangedRunnable);
@@ -1224,8 +809,6 @@
         pw.println("  mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
         pw.println("  mUseSoftwareAutoBrightnessConfig="
                 + mUseSoftwareAutoBrightnessConfig);
-        pw.println("  mScreenAutoBrightnessSpline=" + mScreenAutoBrightnessSpline);
-        pw.println("  mLightSensorWarmUpTimeConfig=" + mLightSensorWarmUpTimeConfig);
 
         mHandler.runWithScissors(new Runnable() {
             @Override
@@ -1249,25 +832,7 @@
         pw.println("  mPendingProximityDebounceTime="
                 + TimeUtils.formatUptime(mPendingProximityDebounceTime));
         pw.println("  mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
-
-        pw.println("  mLightSensor=" + mLightSensor);
-        pw.println("  mLightSensorEnabled=" + mLightSensorEnabled);
-        pw.println("  mLightSensorEnableTime="
-                + TimeUtils.formatUptime(mLightSensorEnableTime));
-        pw.println("  mAmbientLux=" + mAmbientLux);
-        pw.println("  mAmbientLuxValid=" + mAmbientLuxValid);
-        pw.println("  mLastObservedLux=" + mLastObservedLux);
-        pw.println("  mLastObservedLuxTime="
-                + TimeUtils.formatUptime(mLastObservedLuxTime));
-        pw.println("  mRecentLightSamples=" + mRecentLightSamples);
-        pw.println("  mRecentShortTermAverageLux=" + mRecentShortTermAverageLux);
-        pw.println("  mRecentLongTermAverageLux=" + mRecentLongTermAverageLux);
-        pw.println("  mDebounceLuxDirection=" + mDebounceLuxDirection);
-        pw.println("  mDebounceLuxTime=" + TimeUtils.formatUptime(mDebounceLuxTime));
-        pw.println("  mScreenAutoBrightness=" + mScreenAutoBrightness);
         pw.println("  mUsingScreenAutoBrightness=" + mUsingScreenAutoBrightness);
-        pw.println("  mLastScreenAutoBrightnessGamma=" + mLastScreenAutoBrightnessGamma);
-        pw.println("  mTwilight.getCurrentState()=" + mTwilight.getCurrentState());
 
         if (mElectronBeamOnAnimator != null) {
             pw.println("  mElectronBeamOnAnimator.isStarted()=" +
@@ -1281,6 +846,11 @@
         if (mPowerState != null) {
             mPowerState.dump(pw);
         }
+
+        if (mAutomaticBrightnessController != null) {
+            mAutomaticBrightnessController.dump(pw);
+        }
+
     }
 
     private static String proximityToString(int state) {
@@ -1296,13 +866,37 @@
         }
     }
 
-    private static boolean wantScreenOn(int state) {
-        switch (state) {
-            case DisplayPowerRequest.SCREEN_STATE_BRIGHT:
-            case DisplayPowerRequest.SCREEN_STATE_DIM:
-                return true;
+    private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) {
+        try {
+            final int n = brightness.length;
+            float[] x = new float[n];
+            float[] y = new float[n];
+            y[0] = normalizeAbsoluteBrightness(brightness[0]);
+            for (int i = 1; i < n; i++) {
+                x[i] = lux[i - 1];
+                y[i] = normalizeAbsoluteBrightness(brightness[i]);
+            }
+
+            Spline spline = Spline.createMonotoneCubicSpline(x, y);
+            if (DEBUG) {
+                Slog.d(TAG, "Auto-brightness spline: " + spline);
+                for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) {
+                    Slog.d(TAG, String.format("  %7.1f: %7.1f", v, spline.interpolate(v)));
+                }
+            }
+            return spline;
+        } catch (IllegalArgumentException ex) {
+            Slog.e(TAG, "Could not create auto-brightness spline.", ex);
+            return null;
         }
-        return false;
+    }
+
+    private static float normalizeAbsoluteBrightness(int value) {
+        return (float)clampAbsoluteBrightness(value) / PowerManager.BRIGHTNESS_ON;
+    }
+
+    private static int clampAbsoluteBrightness(int value) {
+        return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
     }
 
     /**
@@ -1329,10 +923,6 @@
                 case MSG_PROXIMITY_SENSOR_DEBOUNCED:
                     debounceProximitySensor();
                     break;
-
-                case MSG_LIGHT_SENSOR_DEBOUNCED:
-                    debounceLightSensor();
-                    break;
             }
         }
     }
@@ -1353,28 +943,4 @@
             // Not used.
         }
     };
-
-    private final SensorEventListener mLightSensorListener = new SensorEventListener() {
-        @Override
-        public void onSensorChanged(SensorEvent event) {
-            if (mLightSensorEnabled) {
-                final long time = SystemClock.uptimeMillis();
-                final float lux = event.values[0];
-                handleLightSensorEvent(time, lux);
-            }
-        }
-
-        @Override
-        public void onAccuracyChanged(Sensor sensor, int accuracy) {
-            // Not used.
-        }
-    };
-
-    private final TwilightListener mTwilightListener = new TwilightListener() {
-        @Override
-        public void onTwilightStateChanged() {
-            mTwilightChanged = true;
-            updatePowerState();
-        }
-    };
 }
diff --git a/services/core/java/com/android/server/power/DisplayPowerRequest.java b/services/core/java/com/android/server/power/DisplayPowerRequest.java
index 22f17d7..7626f76 100644
--- a/services/core/java/com/android/server/power/DisplayPowerRequest.java
+++ b/services/core/java/com/android/server/power/DisplayPowerRequest.java
@@ -114,4 +114,13 @@
                 + ", useAutoBrightness=" + useAutoBrightness
                 + ", blockScreenOn=" + blockScreenOn;
     }
+
+    public static boolean wantScreenOn(int state) {
+        switch(state) {
+            case SCREEN_STATE_DIM:
+            case SCREEN_STATE_BRIGHT:
+                return true;
+        }
+        return false;
+    }
 }
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index b2344e6..ecde184 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -20,12 +20,12 @@
 import com.android.internal.app.IBatteryStats;
 import com.android.server.BatteryService;
 import com.android.server.EventLogTags;
+import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
 import com.android.server.lights.Light;
 import com.android.server.lights.LightsManager;
 import com.android.server.twilight.TwilightManager;
 import com.android.server.Watchdog;
-import com.android.server.dreams.DreamManagerService;
 
 import android.Manifest;
 import android.content.BroadcastReceiver;
@@ -57,6 +57,7 @@
 import android.os.UserHandle;
 import android.os.WorkSource;
 import android.provider.Settings;
+import android.service.dreams.DreamManagerInternal;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
@@ -181,7 +182,7 @@
     private DisplayPowerController mDisplayPowerController;
     private WirelessChargerDetector mWirelessChargerDetector;
     private SettingsObserver mSettingsObserver;
-    private DreamManagerService mDreamManager;
+    private DreamManagerInternal mDreamManager;
     private Light mAttentionLight;
 
     private final Object mLock = new Object();
@@ -433,10 +434,10 @@
         }
     }
 
-    public void systemReady(TwilightManager twilight, DreamManagerService dreamManager) {
+    public void systemReady() {
         synchronized (mLock) {
             mSystemReady = true;
-            mDreamManager = dreamManager;
+            mDreamManager = LocalServices.getService(DreamManagerInternal.class);
 
             PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
             mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
@@ -454,7 +455,8 @@
             // The display power controller runs on the power manager service's
             // own handler thread to ensure timely operation.
             mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(),
-                    mContext, mNotifier, mLightsManager, twilight, sensorManager,
+                    mContext, mNotifier, mLightsManager,
+                    LocalServices.getService(TwilightManager.class), sensorManager,
                     mDisplaySuspendBlocker, mDisplayBlanker,
                     mDisplayPowerControllerCallbacks, mHandler);
 
diff --git a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
index 43a99e0..260e97a 100644
--- a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
+++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
@@ -454,6 +454,7 @@
         notification.tickerText = title;
         notification.flags |= Notification.FLAG_NO_CLEAR;
         notification.setLatestEventInfo(context, title, details, intent);
+        notification.visibility = Notification.VISIBILITY_PUBLIC;
         mNotificationMgr.notifyAsUser(null, LOW_MEMORY_NOTIFICATION_ID, notification,
                 UserHandle.ALL);
         context.sendStickyBroadcastAsUser(mStorageLowIntent, UserHandle.ALL);
diff --git a/services/core/java/com/android/server/usb/UsbDeviceManager.java b/services/core/java/com/android/server/usb/UsbDeviceManager.java
index c1a3646..2312288 100644
--- a/services/core/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/core/java/com/android/server/usb/UsbDeviceManager.java
@@ -697,6 +697,7 @@
                     PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0,
                             intent, 0, null, UserHandle.CURRENT);
                     notification.setLatestEventInfo(mContext, title, message, pi);
+                    notification.visibility = Notification.VISIBILITY_PUBLIC;
                     mNotificationManager.notifyAsUser(null, id, notification,
                             UserHandle.ALL);
                     mUsbNotificationId = id;
@@ -732,6 +733,7 @@
                     PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0,
                             intent, 0, null, UserHandle.CURRENT);
                     notification.setLatestEventInfo(mContext, title, message, pi);
+                    notification.visibility = Notification.VISIBILITY_PUBLIC;
                     mAdbNotificationShown = true;
                     mNotificationManager.notifyAsUser(null, id, notification,
                             UserHandle.ALL);
diff --git a/services/core/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java
index 574ae2d..aa7d485 100644
--- a/services/core/java/com/android/server/wm/DimLayer.java
+++ b/services/core/java/com/android/server/wm/DimLayer.java
@@ -127,6 +127,11 @@
 
     void setBounds(Rect bounds) {
         mBounds.set(bounds);
+        if (isDimming() && !mLastBounds.equals(bounds)) {
+            // Clearing mAlpha forces show to redisplay with new size. 
+            mAlpha = 0;
+            show();
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 415a06b..68834d8 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -170,22 +170,13 @@
     }
 
     void updateDisplayInfo() {
-        // Save old size.
-        int oldWidth = mDisplayInfo.logicalWidth;
-        int oldHeight = mDisplayInfo.logicalHeight;
         mDisplay.getDisplayInfo(mDisplayInfo);
-
         for (int i = mStacks.size() - 1; i >= 0; --i) {
-            final TaskStack stack = mStacks.get(i);
-            if (!stack.isFullscreen()) {
-                stack.resizeBounds(oldWidth, oldHeight, mDisplayInfo.logicalWidth,
-                        mDisplayInfo.logicalHeight);
-            }
+            mStacks.get(i).updateDisplayInfo();
         }
     }
 
     void getLogicalDisplayRect(Rect out) {
-        updateDisplayInfo();
         // Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked.
         final int orientation = mDisplayInfo.rotation;
         boolean rotated = (orientation == Surface.ROTATION_90
@@ -291,11 +282,12 @@
     }
 
     boolean isDimming() {
-        boolean result = false;
         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            result |= mStacks.get(stackNdx).isDimming();
+            if (mStacks.get(stackNdx).isDimming()) {
+                return true;
+            }
         }
-        return result;
+        return false;
     }
 
     void stopDimmingIfNeeded() {
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 7d8cff4..c70bc62 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -47,12 +47,17 @@
      * mTaskHistory in the ActivityStack with the same mStackId */
     private final ArrayList<Task> mTasks = new ArrayList<Task>();
 
-    /** Content limits relative to the DisplayContent this sits in. Empty indicates fullscreen,
-     * Nonempty is size of this TaskStack but is also used to scale if DisplayContent changes. */
-    Rect mBounds = new Rect();
+    /** For comparison with DisplayContent bounds. */
+    private Rect mTmpRect = new Rect();
+
+    /** Content limits relative to the DisplayContent this sits in. */
+    private Rect mBounds = new Rect();
+
+    /** Whether mBounds is fullscreen */
+    private boolean mFullscreen = true;
 
     /** Used to support {@link android.view.WindowManager.LayoutParams#FLAG_DIM_BEHIND} */
-    DimLayer mDimLayer;
+    private DimLayer mDimLayer;
 
     /** The particular window with FLAG_DIM_BEHIND set. If null, hide mDimLayer. */
     WindowStateAnimator mDimWinAnimator;
@@ -86,7 +91,7 @@
         return mTasks;
     }
 
-    private void resizeWindows() {
+    void resizeWindows() {
         final boolean underStatusBar = mBounds.top == 0;
 
         final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
@@ -108,7 +113,13 @@
     }
 
     boolean setBounds(Rect bounds) {
-        if (mBounds.equals(bounds)) {
+        boolean oldFullscreen = mFullscreen;
+        if (mDisplayContent != null) {
+            mDisplayContent.getLogicalDisplayRect(mTmpRect);
+            mFullscreen = mTmpRect.equals(bounds);
+        }
+
+        if (mBounds.equals(bounds) && oldFullscreen == mFullscreen) {
             return false;
         }
 
@@ -116,25 +127,22 @@
         mAnimationBackgroundSurface.setBounds(bounds);
         mBounds.set(bounds);
 
-        resizeWindows();
         return true;
     }
 
     void getBounds(Rect out) {
-        if (mDisplayContent != null) {
-            if (mBounds.isEmpty()) {
-                mDisplayContent.getLogicalDisplayRect(out);
-            } else {
-                out.set(mBounds);
-            }
-            out.intersect(mDisplayContent.mContentRect);
-        } else {
-            out.set(mBounds);
+        out.set(mBounds);
+    }
+
+    void updateDisplayInfo() {
+        if (mFullscreen && mDisplayContent != null) {
+            mDisplayContent.getLogicalDisplayRect(mTmpRect);
+            setBounds(mTmpRect);
         }
     }
 
     boolean isFullscreen() {
-        return mBounds.isEmpty();
+        return mFullscreen;
     }
 
     boolean isAnimating() {
@@ -152,19 +160,6 @@
         return false;
     }
 
-    void resizeBounds(float oldWidth, float oldHeight, float newWidth, float newHeight) {
-        if (oldWidth == newWidth && oldHeight == newHeight) {
-            return;
-        }
-        float widthScale = newWidth / oldWidth;
-        float heightScale = newHeight / oldHeight;
-        mBounds.left = (int)(mBounds.left * widthScale + 0.5);
-        mBounds.top = (int)(mBounds.top * heightScale + 0.5);
-        mBounds.right = (int)(mBounds.right * widthScale + 0.5);
-        mBounds.bottom = (int)(mBounds.bottom * heightScale + 0.5);
-        resizeWindows();
-    }
-
     /**
      * Put a Task in this stack. Used for adding and moving.
      * @param task The task to add.
@@ -233,6 +228,7 @@
         mDisplayContent = displayContent;
         mDimLayer = new DimLayer(mService, this, displayContent);
         mAnimationBackgroundSurface = new DimLayer(mService, this, displayContent);
+        updateDisplayInfo();
     }
 
     void detachDisplay() {
@@ -371,11 +367,11 @@
                 (mDisplayContent.mDeferredActions & DisplayContent.DEFER_DETACH) != 0 &&
                 !isAnimating()) {
             mDisplayContent.mDeferredActions &= ~DisplayContent.DEFER_DETACH;
-            mService.detachStack(mStackId);
             if ((mDisplayContent.mDeferredActions & DisplayContent.DEFER_REMOVAL) != 0) {
                 mDisplayContent.mDeferredActions &= ~DisplayContent.DEFER_REMOVAL;
                 mService.onDisplayRemoved(mDisplayContent.getDisplayId());
             }
+            mService.detachStack(mStackId);
         }
         for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
             final Task task = mTasks.get(taskNdx);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 8f07e27..bf88d9f 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4537,6 +4537,10 @@
         final Task task = mTaskIdToTask.get(wtoken.groupId);
         if (task != null) {
             task.removeAppToken(wtoken);
+            // Remove after bug resolved.
+            Slog.d(TAG, "removeAppFromTaskLocked: wtoken=" + wtoken
+                    + " numTokens left=" + task.mAppTokens.size()
+                    + " Callers=" + Debug.getCallers(5));
         }
     }
 
@@ -4984,6 +4988,7 @@
                         + " not found.");
             }
             if (stack.setBounds(bounds)) {
+                stack.resizeWindows();
                 stack.getDisplayContent().layoutNeeded = true;
                 performLayoutAndPlaceSurfacesLocked();
             }
@@ -8065,6 +8070,9 @@
                 final int numTokens = tokens.size();
                 for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
                     final AppWindowToken wtoken = tokens.get(tokenNdx);
+                    if (wtoken.mDeferRemoval) {
+                        continue;
+                    }
                     i = reAddAppWindowsLocked(displayContent, i, wtoken);
                 }
             }
@@ -9952,6 +9960,7 @@
             }
 
             // TODO(multidisplay): rotation on main screen only.
+            displayContent.updateDisplayInfo();
             screenRotationAnimation = new ScreenRotationAnimation(mContext, displayContent,
                     mFxSession, inTransaction, mPolicy.isDefaultOrientationForced());
             mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
diff --git a/services/core/jni/com_android_server_UsbHostManager.cpp b/services/core/jni/com_android_server_UsbHostManager.cpp
index f1fa6cf..fc6de60 100644
--- a/services/core/jni/com_android_server_UsbHostManager.cpp
+++ b/services/core/jni/com_android_server_UsbHostManager.cpp
@@ -163,8 +163,10 @@
         return NULL;
 
     int fd = usb_device_get_fd(device);
-    if (fd < 0)
+    if (fd < 0) {
+        usb_device_close(device);
         return NULL;
+    }
     int newFD = dup(fd);
     usb_device_close(device);
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index bb96544..12f0114 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -2830,6 +2830,14 @@
             return false;
         }
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
+
+        UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        if (um.getUserInfo(userHandle) == null) {
+            // User doesn't exist.
+            throw new IllegalArgumentException(
+                    "Attempted to set profile owner for invalid userId: " + userHandle);
+        }
+
         if (packageName == null
                 || !DeviceOwner.isInstalledForUser(packageName, userHandle)) {
             throw new IllegalArgumentException("Package name " + packageName
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 85e5e23..5221f1f 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -74,7 +74,6 @@
 import com.android.server.search.SearchManagerService;
 import com.android.server.statusbar.StatusBarManagerService;
 import com.android.server.storage.DeviceStorageMonitorService;
-import com.android.server.twilight.TwilightManager;
 import com.android.server.twilight.TwilightService;
 import com.android.server.usb.UsbService;
 import com.android.server.wallpaper.WallpaperManagerService;
@@ -303,7 +302,6 @@
         DockObserver dock = null;
         UsbService usb = null;
         SerialService serial = null;
-        TwilightManager twilight = null;
         RecognitionManagerService recognition = null;
         NetworkTimeUpdateService networkTimeUpdater = null;
         CommonTimeManagementService commonTimeMgmtService = null;
@@ -460,7 +458,6 @@
         CountryDetectorService countryDetector = null;
         TextServicesManagerService tsms = null;
         LockSettingsService lockSettings = null;
-        DreamManagerService dreamy = null;
         AssetAtlasService atlas = null;
         MediaRouterService mediaRouter = null;
 
@@ -532,7 +529,7 @@
                 }
 
                 try {
-                    if (pm.hasSystemFeature("android.software.device_admin")) {
+                    if (pm.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) {
                         mSystemServiceManager.startServiceIfExists(
                                 DEVICE_POLICY_MANAGER_SERVICE_CLASS);
                     }
@@ -776,13 +773,12 @@
             }
 
             mSystemServiceManager.startService(TwilightService.class);
-            twilight = LocalServices.getService(TwilightManager.class);
 
             mSystemServiceManager.startService(UiModeManagerService.class);
 
             if (!disableNonCoreServices) {
                 try {
-                    if (pm.hasSystemFeature("android.software.backup")) {
+                    if (pm.hasSystemFeature(PackageManager.FEATURE_BACKUP)) {
                         mSystemServiceManager.startServiceIfExists(BACKUP_MANAGER_SERVICE_CLASS);
                     }
                 } catch (Throwable e) {
@@ -790,7 +786,7 @@
                 }
 
                 try {
-                    if (pm.hasSystemFeature("android.software.app_widgets")) {
+                    if (pm.hasSystemFeature(PackageManager.FEATURE_APP_WIDGETS)) {
                         mSystemServiceManager.startServiceIfExists(APPWIDGET_SERVICE_CLASS);
                     }
                 } catch (Throwable e) {
@@ -852,16 +848,10 @@
                 }
             }
 
-            if (!disableNonCoreServices &&
-                context.getResources().getBoolean(R.bool.config_dreamsSupported)) {
-                try {
-                    Slog.i(TAG, "Dreams Service");
-                    // Dreams (interactive idle-time views, a/k/a screen savers)
-                    dreamy = new DreamManagerService(context);
-                    ServiceManager.addService(DreamService.DREAM_SERVICE, dreamy);
-                } catch (Throwable e) {
-                    reportWtf("starting DreamManagerService", e);
-                }
+            if (!disableNonCoreServices
+                    && context.getResources().getBoolean(R.bool.config_dreamsSupported)) {
+                // Dreams (interactive idle-time views, a/k/a screen savers)
+                mSystemServiceManager.startService(DreamManagerService.class);
             }
 
             if (!disableNonCoreServices) {
@@ -882,7 +872,7 @@
             }
 
             try {
-                if (pm.hasSystemFeature("android.software.print")) {
+                if (pm.hasSystemFeature(PackageManager.FEATURE_PRINTING)) {
                     mSystemServiceManager.startServiceIfExists(PRINT_MANAGER_SERVICE_CLASS);
                 }
             } catch (Throwable e) {
@@ -956,7 +946,7 @@
 
         try {
             // TODO: use boot phase
-            mPowerManagerService.systemReady(twilight, dreamy);
+            mPowerManagerService.systemReady();
         } catch (Throwable e) {
             reportWtf("making Power Manager Service ready", e);
         }
@@ -993,7 +983,6 @@
         final CommonTimeManagementService commonTimeMgmtServiceF = commonTimeMgmtService;
         final TextServicesManagerService textServiceManagerServiceF = tsms;
         final StatusBarManagerService statusBarF = statusBar;
-        final DreamManagerService dreamyF = dreamy;
         final AssetAtlasService atlasF = atlas;
         final InputManagerService inputManagerF = inputManager;
         final TelephonyRegistry telephonyRegistryF = telephonyRegistry;
@@ -1106,11 +1095,6 @@
                     reportWtf("Notifying TextServicesManagerService running", e);
                 }
                 try {
-                    if (dreamyF != null) dreamyF.systemRunning();
-                } catch (Throwable e) {
-                    reportWtf("Notifying DreamManagerService running", e);
-                }
-                try {
                     if (atlasF != null) atlasF.systemRunning();
                 } catch (Throwable e) {
                     reportWtf("Notifying AssetAtlasService running", e);
diff --git a/services/tests/servicestests/src/com/android/server/location/LocationRequestStatisticsTest.java b/services/tests/servicestests/src/com/android/server/location/LocationRequestStatisticsTest.java
new file mode 100644
index 0000000..33f604d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/location/LocationRequestStatisticsTest.java
@@ -0,0 +1,175 @@
+package com.android.server.location;
+
+import com.android.server.location.LocationRequestStatistics.PackageProviderKey;
+import com.android.server.location.LocationRequestStatistics.PackageStatistics;
+
+import android.os.SystemClock;
+import android.test.AndroidTestCase;
+
+/**
+ * Unit tests for {@link LocationRequestStatistics}.
+ */
+public class LocationRequestStatisticsTest extends AndroidTestCase {
+    private static final String PACKAGE1 = "package1";
+    private static final String PACKAGE2 = "package2";
+    private static final String PROVIDER1 = "provider1";
+    private static final String PROVIDER2 = "provider2";
+    private static final long INTERVAL1 = 5000;
+    private static final long INTERVAL2 = 100000;
+
+    private LocationRequestStatistics mStatistics;
+    private long mStartElapsedRealtimeMs;
+
+    @Override
+    public void setUp() {
+        mStatistics = new LocationRequestStatistics();
+        mStartElapsedRealtimeMs = SystemClock.elapsedRealtime();
+    }
+
+    /**
+     * Tests that adding a single package works correctly.
+     */
+    public void testSinglePackage() {
+        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
+
+        assertEquals(1, mStatistics.statistics.size());
+        PackageProviderKey key = mStatistics.statistics.keySet().iterator().next();
+        assertEquals(PACKAGE1, key.packageName);
+        assertEquals(PROVIDER1, key.providerName);
+        PackageStatistics stats = mStatistics.statistics.values().iterator().next();
+        verifyStatisticsTimes(stats);
+        assertEquals(INTERVAL1, stats.getFastestIntervalMs());
+        assertEquals(INTERVAL1, stats.getSlowestIntervalMs());
+        assertTrue(stats.isActive());
+    }
+
+    /**
+     * Tests that adding a single package works correctly when it is stopped and restarted.
+     */
+    public void testSinglePackage_stopAndRestart() {
+        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
+        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
+
+        assertEquals(1, mStatistics.statistics.size());
+        PackageProviderKey key = mStatistics.statistics.keySet().iterator().next();
+        assertEquals(PACKAGE1, key.packageName);
+        assertEquals(PROVIDER1, key.providerName);
+        PackageStatistics stats = mStatistics.statistics.values().iterator().next();
+        verifyStatisticsTimes(stats);
+        assertEquals(INTERVAL1, stats.getFastestIntervalMs());
+        assertEquals(INTERVAL1, stats.getSlowestIntervalMs());
+        assertTrue(stats.isActive());
+
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
+        assertFalse(stats.isActive());
+    }
+
+    /**
+     * Tests that adding a single package works correctly when multiple intervals are used.
+     */
+    public void testSinglePackage_multipleIntervals() {
+        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
+        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL2);
+
+        assertEquals(1, mStatistics.statistics.size());
+        PackageProviderKey key = mStatistics.statistics.keySet().iterator().next();
+        assertEquals(PACKAGE1, key.packageName);
+        assertEquals(PROVIDER1, key.providerName);
+        PackageStatistics stats = mStatistics.statistics.values().iterator().next();
+        verifyStatisticsTimes(stats);
+        assertEquals(INTERVAL1, stats.getFastestIntervalMs());
+        assertTrue(stats.isActive());
+
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
+        assertTrue(stats.isActive());
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
+        assertFalse(stats.isActive());
+    }
+
+    /**
+     * Tests that adding a single package works correctly when multiple providers are used.
+     */
+    public void testSinglePackage_multipleProviders() {
+        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
+        mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL2);
+
+        assertEquals(2, mStatistics.statistics.size());
+        PackageProviderKey key1 = new PackageProviderKey(PACKAGE1, PROVIDER1);
+        PackageStatistics stats1 = mStatistics.statistics.get(key1);
+        verifyStatisticsTimes(stats1);
+        assertEquals(INTERVAL1, stats1.getSlowestIntervalMs());
+        assertEquals(INTERVAL1, stats1.getFastestIntervalMs());
+        assertTrue(stats1.isActive());
+        PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, PROVIDER2);
+        PackageStatistics stats2 = mStatistics.statistics.get(key2);
+        verifyStatisticsTimes(stats2);
+        assertEquals(INTERVAL2, stats2.getSlowestIntervalMs());
+        assertEquals(INTERVAL2, stats2.getFastestIntervalMs());
+        assertTrue(stats2.isActive());
+
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
+        assertFalse(stats1.isActive());
+        assertTrue(stats2.isActive());
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER2);
+        assertFalse(stats1.isActive());
+        assertFalse(stats2.isActive());
+    }
+
+    /**
+     * Tests that adding multiple packages works correctly.
+     */
+    public void testMultiplePackages() {
+        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
+        mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL1);
+        mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL2);
+        mStatistics.startRequesting(PACKAGE2, PROVIDER1, INTERVAL1);
+
+        assertEquals(3, mStatistics.statistics.size());
+        PackageProviderKey key1 = new PackageProviderKey(PACKAGE1, PROVIDER1);
+        PackageStatistics stats1 = mStatistics.statistics.get(key1);
+        verifyStatisticsTimes(stats1);
+        assertEquals(INTERVAL1, stats1.getSlowestIntervalMs());
+        assertEquals(INTERVAL1, stats1.getFastestIntervalMs());
+        assertTrue(stats1.isActive());
+
+        PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, PROVIDER2);
+        PackageStatistics stats2 = mStatistics.statistics.get(key2);
+        verifyStatisticsTimes(stats2);
+        assertEquals(INTERVAL2, stats2.getSlowestIntervalMs());
+        assertEquals(INTERVAL1, stats2.getFastestIntervalMs());
+        assertTrue(stats2.isActive());
+
+        PackageProviderKey key3 = new PackageProviderKey(PACKAGE2, PROVIDER1);
+        PackageStatistics stats3 = mStatistics.statistics.get(key3);
+        verifyStatisticsTimes(stats3);
+        assertEquals(INTERVAL1, stats3.getSlowestIntervalMs());
+        assertEquals(INTERVAL1, stats3.getFastestIntervalMs());
+        assertTrue(stats3.isActive());
+
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
+        assertFalse(stats1.isActive());
+        assertTrue(stats2.isActive());
+        assertTrue(stats3.isActive());
+
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER2);
+        assertFalse(stats1.isActive());
+        assertTrue(stats2.isActive());
+        assertTrue(stats3.isActive());
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER2);
+        assertFalse(stats2.isActive());
+
+        mStatistics.stopRequesting(PACKAGE2, PROVIDER1);
+        assertFalse(stats1.isActive());
+        assertFalse(stats2.isActive());
+        assertFalse(stats3.isActive());
+    }
+
+    private void verifyStatisticsTimes(PackageStatistics stats) {
+        long durationMs = stats.getDurationMs();
+        long timeSinceFirstRequestMs = stats.getTimeSinceFirstRequestMs();
+        long maxDeltaMs = SystemClock.elapsedRealtime() - mStartElapsedRealtimeMs;
+        assertTrue("Duration is too large", durationMs <= maxDeltaMs);
+        assertTrue("Time since first request is too large", timeSinceFirstRequestMs <= maxDeltaMs);
+    }
+}
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
new file mode 100644
index 0000000..323e0ac
--- /dev/null
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 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.telephony;
+
+/**
+ * Contains disconnect call causes generated by the
+ * framework and the RIL.
+ *
+ * @hide
+ */
+public class DisconnectCause {
+
+    /** The disconnect cause is not valid (Not received a disconnect cause) */
+    public static final int NOT_VALID                      = -1;
+    /** Has not yet disconnected */
+    public static final int NOT_DISCONNECTED               = 0;
+    /** An incoming call that was missed and never answered */
+    public static final int INCOMING_MISSED                = 1;
+    /** Normal; Remote hangup*/
+    public static final int NORMAL                         = 2;
+    /** Normal; Local hangup */
+    public static final int LOCAL                          = 3;
+    /** Outgoing call to busy line */
+    public static final int BUSY                           = 4;
+    /** Outgoing call to congested network */
+    public static final int CONGESTION                     = 5;
+    /** Not presently used */
+    public static final int MMI                            = 6;
+    /** Invalid dial string */
+    public static final int INVALID_NUMBER                 = 7;
+    /** Cannot reach the peer */
+    public static final int NUMBER_UNREACHABLE             = 8;
+    /** Cannot reach the server */
+    public static final int SERVER_UNREACHABLE             = 9;
+    /** Invalid credentials */
+    public static final int INVALID_CREDENTIALS            = 10;
+    /** Calling from out of network is not allowed */
+    public static final int OUT_OF_NETWORK                 = 11;
+    /** Server error */
+    public static final int SERVER_ERROR                   = 12;
+    /** Client timed out */
+    public static final int TIMED_OUT                      = 13;
+    /** Client went out of network range */
+    public static final int LOST_SIGNAL                    = 14;
+    /** GSM or CDMA ACM limit exceeded */
+    public static final int LIMIT_EXCEEDED                 = 15;
+    /** An incoming call that was rejected */
+    public static final int INCOMING_REJECTED              = 16;
+    /** Radio is turned off explicitly */
+    public static final int POWER_OFF                      = 17;
+    /** Out of service */
+    public static final int OUT_OF_SERVICE                 = 18;
+    /** No ICC, ICC locked, or other ICC error */
+    public static final int ICC_ERROR                      = 19;
+    /** Call was blocked by call barring */
+    public static final int CALL_BARRED                    = 20;
+    /** Call was blocked by fixed dial number */
+    public static final int FDN_BLOCKED                    = 21;
+    /** Call was blocked by restricted all voice access */
+    public static final int CS_RESTRICTED                  = 22;
+    /** Call was blocked by restricted normal voice access */
+    public static final int CS_RESTRICTED_NORMAL           = 23;
+    /** Call was blocked by restricted emergency voice access */
+    public static final int CS_RESTRICTED_EMERGENCY        = 24;
+    /** Unassigned number */
+    public static final int UNOBTAINABLE_NUMBER            = 25;
+    /** MS is locked until next power cycle */
+    public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE  = 26;
+    /** Drop call*/
+    public static final int CDMA_DROP                      = 27;
+    /** INTERCEPT order received, MS state idle entered */
+    public static final int CDMA_INTERCEPT                 = 28;
+    /** MS has been redirected, call is cancelled */
+    public static final int CDMA_REORDER                   = 29;
+    /** Service option rejection */
+    public static final int CDMA_SO_REJECT                 = 30;
+    /** Requested service is rejected, retry delay is set */
+    public static final int CDMA_RETRY_ORDER               = 31;
+    /** Unable to obtain access to the CDMA system */
+    public static final int CDMA_ACCESS_FAILURE            = 32;
+    /** Not a preempted call */
+    public static final int CDMA_PREEMPTED                 = 33;
+    /** Not an emergency call */
+    public static final int CDMA_NOT_EMERGENCY             = 34;
+    /** Access Blocked by CDMA network */
+    public static final int CDMA_ACCESS_BLOCKED            = 35;
+    /** Unknown error or not specified */
+    public static final int ERROR_UNSPECIFIED              = 36;
+
+    /** Private constructor to avoid class instantiation. */
+    private DisconnectCause() {
+        // Do nothing.
+    }
+}
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index d34c55c..bb3f132 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -23,6 +23,9 @@
 import android.telephony.SignalStrength;
 import android.telephony.CellLocation;
 import android.telephony.CellInfo;
+import android.telephony.Rlog;
+import android.telephony.PreciseCallState;
+import android.telephony.PreciseDataConnectionState;
 
 import com.android.internal.telephony.IPhoneStateListener;
 
@@ -164,6 +167,27 @@
      */
     public static final int LISTEN_CELL_INFO = 0x00000400;
 
+    /**
+     * Listen for precise changes and fails to the device calls (cellular).
+     * {@more}
+     * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
+     * READ_PRECISE_PHONE_STATE}
+     *
+     * @hide
+     */
+    public static final int LISTEN_PRECISE_CALL_STATE                       = 0x00000800;
+
+    /**
+     * Listen for precise changes and fails on the data connection (cellular).
+     * {@more}
+     * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
+     * READ_PRECISE_PHONE_STATE}
+     *
+     * @see #onPreciseDataConnectionStateChanged
+     * @hide
+     */
+    public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE            = 0x00001000;
+
     public PhoneStateListener() {
     }
 
@@ -292,6 +316,25 @@
     }
 
     /**
+     * Callback invoked when precise device call state changes.
+     *
+     * @hide
+     */
+    public void onPreciseCallStateChanged(PreciseCallState callState) {
+        // default implementation empty
+    }
+
+    /**
+     * Callback invoked when data connection state changes with precise information.
+     *
+     * @hide
+     */
+    public void onPreciseDataConnectionStateChanged(
+            PreciseDataConnectionState dataConnectionState) {
+        // default implementation empty
+    }
+
+    /**
      * The callback methods need to be called on the handler thread where
      * this object was created.  If the binder did that for us it'd be nice.
      */
@@ -343,6 +386,16 @@
         public void onCellInfoChanged(List<CellInfo> cellInfo) {
             Message.obtain(mHandler, LISTEN_CELL_INFO, 0, 0, cellInfo).sendToTarget();
         }
+
+        public void onPreciseCallStateChanged(PreciseCallState callState) {
+            Message.obtain(mHandler, LISTEN_PRECISE_CALL_STATE, 0, 0, callState).sendToTarget();
+        }
+
+        public void onPreciseDataConnectionStateChanged(
+                PreciseDataConnectionState dataConnectionState) {
+            Message.obtain(mHandler, LISTEN_PRECISE_DATA_CONNECTION_STATE, 0, 0,
+                    dataConnectionState).sendToTarget();
+        }
     };
 
     Handler mHandler = new Handler() {
@@ -382,6 +435,12 @@
                     break;
                 case LISTEN_CELL_INFO:
                     PhoneStateListener.this.onCellInfoChanged((List<CellInfo>)msg.obj);
+                    break;
+                case LISTEN_PRECISE_CALL_STATE:
+                    PhoneStateListener.this.onPreciseCallStateChanged((PreciseCallState)msg.obj);
+                    break;
+                case LISTEN_PRECISE_DATA_CONNECTION_STATE:
+                    PhoneStateListener.this.onPreciseDataConnectionStateChanged((PreciseDataConnectionState)msg.obj);
             }
         }
     };
diff --git a/telephony/java/android/telephony/PreciseCallState.aidl b/telephony/java/android/telephony/PreciseCallState.aidl
new file mode 100644
index 0000000..447f29b
--- /dev/null
+++ b/telephony/java/android/telephony/PreciseCallState.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** Copyright 2014, 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.telephony;
+
+parcelable PreciseCallState;
\ No newline at end of file
diff --git a/telephony/java/android/telephony/PreciseCallState.java b/telephony/java/android/telephony/PreciseCallState.java
new file mode 100644
index 0000000..a85df15
--- /dev/null
+++ b/telephony/java/android/telephony/PreciseCallState.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2014 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.telephony;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.Rlog;
+import android.telephony.DisconnectCause;
+import android.telephony.PreciseDisconnectCause;
+
+/**
+ * Contains precise call state and call fail causes generated by the
+ * framework and the RIL.
+ *
+ * The following call information is included in returned PreciseCallState:
+ *
+ * <ul>
+ *   <li>Ringing call state.
+ *   <li>Foreground call state.
+ *   <li>Background call state.
+ *   <li>Disconnect cause; generated by the framework.
+ *   <li>Precise disconnect cause; generated by the RIL.
+ * </ul>
+ *
+ * @hide
+ */
+public class PreciseCallState implements Parcelable {
+
+    /** Call state is not valid (Not received a call state). */
+    public static final int PRECISE_CALL_STATE_NOT_VALID =      -1;
+    /** Call state: No activity. */
+    public static final int PRECISE_CALL_STATE_IDLE =           0;
+    /** Call state: Active. */
+    public static final int PRECISE_CALL_STATE_ACTIVE =         1;
+    /** Call state: On hold. */
+    public static final int PRECISE_CALL_STATE_HOLDING =        2;
+    /** Call state: Dialing. */
+    public static final int PRECISE_CALL_STATE_DIALING =        3;
+    /** Call state: Alerting. */
+    public static final int PRECISE_CALL_STATE_ALERTING =       4;
+    /** Call state: Incoming. */
+    public static final int PRECISE_CALL_STATE_INCOMING =       5;
+    /** Call state: Waiting. */
+    public static final int PRECISE_CALL_STATE_WAITING =        6;
+    /** Call state: Disconnected. */
+    public static final int PRECISE_CALL_STATE_DISCONNECTED =   7;
+    /** Call state: Disconnecting. */
+    public static final int PRECISE_CALL_STATE_DISCONNECTING =  8;
+
+    private int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID;
+    private int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID;
+    private int mBackgroundCallState = PRECISE_CALL_STATE_NOT_VALID;
+    private int mDisconnectCause = DisconnectCause.NOT_VALID;
+    private int mPreciseDisconnectCause = PreciseDisconnectCause.NOT_VALID;
+
+    /**
+     * Constructor
+     *
+     * @hide
+     */
+    public PreciseCallState(int ringingCall, int foregroundCall, int backgroundCall,
+            int disconnectCause, int preciseDisconnectCause) {
+        mRingingCallState = ringingCall;
+        mForegroundCallState = foregroundCall;
+        mBackgroundCallState = backgroundCall;
+        mDisconnectCause = disconnectCause;
+        mPreciseDisconnectCause = preciseDisconnectCause;
+    }
+
+    /**
+     * Empty Constructor
+     *
+     * @hide
+     */
+    public PreciseCallState() {
+    }
+
+    /**
+     * Construct a PreciseCallState object from the given parcel.
+     */
+    private PreciseCallState(Parcel in) {
+        mRingingCallState = in.readInt();
+        mForegroundCallState = in.readInt();
+        mBackgroundCallState = in.readInt();
+        mDisconnectCause = in.readInt();
+        mPreciseDisconnectCause = in.readInt();
+    }
+
+    /**
+     * Get precise ringing call state
+     *
+     * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
+     * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
+     * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
+     * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
+     * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
+     * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
+     * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
+     * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
+     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
+     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
+     */
+    public int getRingingCallState() {
+        return mRingingCallState;
+    }
+
+    /**
+     * Get precise foreground call state
+     *
+     * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
+     * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
+     * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
+     * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
+     * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
+     * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
+     * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
+     * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
+     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
+     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
+     */
+    public int getForegroundCallState() {
+        return mForegroundCallState;
+    }
+
+    /**
+     * Get precise background call state
+     *
+     * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
+     * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
+     * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
+     * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
+     * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
+     * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
+     * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
+     * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
+     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
+     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
+     */
+    public int getBackgroundCallState() {
+        return mBackgroundCallState;
+    }
+
+    /**
+     * Get disconnect cause generated by the framework
+     *
+     * @see DisconnectCause#NOT_VALID
+     * @see DisconnectCause#NOT_DISCONNECTED
+     * @see DisconnectCause#INCOMING_MISSED
+     * @see DisconnectCause#NORMAL
+     * @see DisconnectCause#LOCAL
+     * @see DisconnectCause#BUSY
+     * @see DisconnectCause#CONGESTION
+     * @see DisconnectCause#MMI
+     * @see DisconnectCause#INVALID_NUMBER
+     * @see DisconnectCause#NUMBER_UNREACHABLE
+     * @see DisconnectCause#SERVER_UNREACHABLE
+     * @see DisconnectCause#INVALID_CREDENTIALS
+     * @see DisconnectCause#OUT_OF_NETWORK
+     * @see DisconnectCause#SERVER_ERROR
+     * @see DisconnectCause#TIMED_OUT
+     * @see DisconnectCause#LOST_SIGNAL
+     * @see DisconnectCause#LIMIT_EXCEEDED
+     * @see DisconnectCause#INCOMING_REJECTED
+     * @see DisconnectCause#POWER_OFF
+     * @see DisconnectCause#OUT_OF_SERVICE
+     * @see DisconnectCause#ICC_ERROR
+     * @see DisconnectCause#CALL_BARRED
+     * @see DisconnectCause#FDN_BLOCKED
+     * @see DisconnectCause#CS_RESTRICTED
+     * @see DisconnectCause#CS_RESTRICTED_NORMAL
+     * @see DisconnectCause#CS_RESTRICTED_EMERGENCY
+     * @see DisconnectCause#UNOBTAINABLE_NUMBER
+     * @see DisconnectCause#CDMA_LOCKED_UNTIL_POWER_CYCLE
+     * @see DisconnectCause#CDMA_DROP
+     * @see DisconnectCause#CDMA_INTERCEPT
+     * @see DisconnectCause#CDMA_REORDER
+     * @see DisconnectCause#CDMA_SO_REJECT
+     * @see DisconnectCause#CDMA_RETRY_ORDER
+     * @see DisconnectCause#CDMA_ACCESS_FAILURE
+     * @see DisconnectCause#CDMA_PREEMPTED
+     * @see DisconnectCause#CDMA_NOT_EMERGENCY
+     * @see DisconnectCause#CDMA_ACCESS_BLOCKED
+     * @see DisconnectCause#ERROR_UNSPECIFIED
+     */
+    public int getDisconnectCause() {
+        return mDisconnectCause;
+    }
+
+    /**
+     * Get disconnect cause generated by the RIL
+     *
+     * @see PreciseDisconnectCause#NOT_VALID
+     * @see PreciseDisconnectCause#NO_DISCONNECT_CAUSE_AVAILABLE
+     * @see PreciseDisconnectCause#UNOBTAINABLE_NUMBER
+     * @see PreciseDisconnectCause#NORMAL
+     * @see PreciseDisconnectCause#BUSY
+     * @see PreciseDisconnectCause#NUMBER_CHANGED
+     * @see PreciseDisconnectCause#STATUS_ENQUIRY
+     * @see PreciseDisconnectCause#NORMAL_UNSPECIFIED
+     * @see PreciseDisconnectCause#NO_CIRCUIT_AVAIL
+     * @see PreciseDisconnectCause#TEMPORARY_FAILURE
+     * @see PreciseDisconnectCause#SWITCHING_CONGESTION
+     * @see PreciseDisconnectCause#CHANNEL_NOT_AVAIL
+     * @see PreciseDisconnectCause#QOS_NOT_AVAIL
+     * @see PreciseDisconnectCause#BEARER_NOT_AVAIL
+     * @see PreciseDisconnectCause#ACM_LIMIT_EXCEEDED
+     * @see PreciseDisconnectCause#CALL_BARRED
+     * @see PreciseDisconnectCause#FDN_BLOCKED
+     * @see PreciseDisconnectCause#IMSI_UNKNOWN_IN_VLR
+     * @see PreciseDisconnectCause#IMEI_NOT_ACCEPTED
+     * @see PreciseDisconnectCause#CDMA_LOCKED_UNTIL_POWER_CYCLE
+     * @see PreciseDisconnectCause#CDMA_DROP
+     * @see PreciseDisconnectCause#CDMA_INTERCEPT
+     * @see PreciseDisconnectCause#CDMA_REORDER
+     * @see PreciseDisconnectCause#CDMA_SO_REJECT
+     * @see PreciseDisconnectCause#CDMA_RETRY_ORDER
+     * @see PreciseDisconnectCause#CDMA_ACCESS_FAILURE
+     * @see PreciseDisconnectCause#CDMA_PREEMPTED
+     * @see PreciseDisconnectCause#CDMA_NOT_EMERGENCY
+     * @see PreciseDisconnectCause#CDMA_ACCESS_BLOCKED
+     * @see PreciseDisconnectCause#ERROR_UNSPECIFIED
+     */
+    public int getPreciseDisconnectCause() {
+        return mPreciseDisconnectCause;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mRingingCallState);
+        out.writeInt(mForegroundCallState);
+        out.writeInt(mBackgroundCallState);
+        out.writeInt(mDisconnectCause);
+        out.writeInt(mPreciseDisconnectCause);
+    }
+
+    public static final Parcelable.Creator<PreciseCallState> CREATOR
+            = new Parcelable.Creator<PreciseCallState>() {
+
+        public PreciseCallState createFromParcel(Parcel in) {
+            return new PreciseCallState(in);
+        }
+
+        public PreciseCallState[] newArray(int size) {
+            return new PreciseCallState[size];
+        }
+    };
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + mRingingCallState;
+        result = prime * result + mForegroundCallState;
+        result = prime * result + mBackgroundCallState;
+        result = prime * result + mDisconnectCause;
+        result = prime * result + mPreciseDisconnectCause;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        PreciseCallState other = (PreciseCallState) obj;
+        return (mRingingCallState != other.mRingingCallState &&
+            mForegroundCallState != other.mForegroundCallState &&
+            mBackgroundCallState != other.mBackgroundCallState &&
+            mDisconnectCause != other.mDisconnectCause &&
+            mPreciseDisconnectCause != other.mPreciseDisconnectCause);
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("Ringing call state: " + mRingingCallState);
+        sb.append(", Foreground call state: " + mForegroundCallState);
+        sb.append(", Background call state: " + mBackgroundCallState);
+        sb.append(", Disconnect cause: " + mDisconnectCause);
+        sb.append(", Precise disconnect cause: " + mPreciseDisconnectCause);
+
+        return sb.toString();
+    }
+}
diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.aidl b/telephony/java/android/telephony/PreciseDataConnectionState.aidl
new file mode 100644
index 0000000..07ad762
--- /dev/null
+++ b/telephony/java/android/telephony/PreciseDataConnectionState.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** Copyright 2014, 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.telephony;
+
+parcelable PreciseDataConnectionState;
\ No newline at end of file
diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java
new file mode 100644
index 0000000..87529fe
--- /dev/null
+++ b/telephony/java/android/telephony/PreciseDataConnectionState.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2014 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.telephony;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.Rlog;
+import android.telephony.TelephonyManager;
+import android.net.LinkProperties;
+
+/**
+ * Contains precise data connection state.
+ *
+ * The following data connection information is included in returned PreciseDataConnectionState:
+ *
+ * <ul>
+ *   <li>Data connection state.
+ *   <li>Network type of the connection.
+ *   <li>APN type.
+ *   <li>APN.
+ *   <li>Data connection change reason.
+ *   <li>The properties of the network link.
+ *   <li>Data connection fail cause.
+ * </ul>
+ *
+ * @hide
+ */
+public class PreciseDataConnectionState implements Parcelable {
+
+    private int mState = TelephonyManager.DATA_UNKNOWN;
+    private int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
+    private String mAPNType = "";
+    private String mAPN = "";
+    private String mReason = "";
+    private LinkProperties mLinkProperties = null;
+    private String mFailCause = "";
+
+    /**
+     * Constructor
+     *
+     * @hide
+     */
+    public PreciseDataConnectionState(int state, int networkType,
+            String apnType, String apn, String reason,
+            LinkProperties linkProperties, String failCause) {
+        mState = state;
+        mNetworkType = networkType;
+        mAPNType = apnType;
+        mAPN = apn;
+        mReason = reason;
+        mLinkProperties = linkProperties;
+        mFailCause = failCause;
+    }
+
+    /**
+     * Empty Constructor
+     *
+     * @hide
+     */
+    public PreciseDataConnectionState() {
+    }
+
+    /**
+     * Construct a PreciseDataConnectionState object from the given parcel.
+     */
+    private PreciseDataConnectionState(Parcel in) {
+        mState = in.readInt();
+        mNetworkType = in.readInt();
+        mAPNType = in.readString();
+        mAPN = in.readString();
+        mReason = in.readString();
+        mLinkProperties = (LinkProperties)in.readParcelable(null);
+        mFailCause = in.readString();
+    }
+
+    /**
+     * Get data connection state
+     *
+     * @see TelephonyManager#DATA_UNKNOWN
+     * @see TelephonyManager#DATA_DISCONNECTED
+     * @see TelephonyManager#DATA_CONNECTING
+     * @see TelephonyManager#DATA_CONNECTED
+     * @see TelephonyManager#DATA_SUSPENDED
+     */
+    public int getDataConnectionState() {
+        return mState;
+    }
+
+    /**
+     * Get data connection network type
+     *
+     * @see TelephonyManager#NETWORK_TYPE_UNKNOWN
+     * @see TelephonyManager#NETWORK_TYPE_GPRS
+     * @see TelephonyManager#NETWORK_TYPE_EDGE
+     * @see TelephonyManager#NETWORK_TYPE_UMTS
+     * @see TelephonyManager#NETWORK_TYPE_CDMA
+     * @see TelephonyManager#NETWORK_TYPE_EVDO_0
+     * @see TelephonyManager#NETWORK_TYPE_EVDO_A
+     * @see TelephonyManager#NETWORK_TYPE_1xRTT
+     * @see TelephonyManager#NETWORK_TYPE_HSDPA
+     * @see TelephonyManager#NETWORK_TYPE_HSUPA
+     * @see TelephonyManager#NETWORK_TYPE_HSPA
+     * @see TelephonyManager#NETWORK_TYPE_IDEN
+     * @see TelephonyManager#NETWORK_TYPE_EVDO_B
+     * @see TelephonyManager#NETWORK_TYPE_LTE
+     * @see TelephonyManager#NETWORK_TYPE_EHRPD
+     * @see TelephonyManager#NETWORK_TYPE_HSPAP
+     */
+    public int getDataConnectionNetworkType() {
+        return mNetworkType;
+    }
+
+    /**
+     * Get data connection APN type
+     */
+    public String getDataConnectionAPNType() {
+        return mAPNType;
+    }
+
+    /**
+     * Get data connection APN.
+     */
+    public String getDataConnectionAPN() {
+        return mAPN;
+    }
+
+    /**
+     * Get data connection change reason.
+     */
+    public String getDataConnectionChangeReason() {
+        return mReason;
+    }
+
+    /**
+     * Get the properties of the network link.
+     */
+    public LinkProperties getDataConnectionLinkProperties() {
+        return mLinkProperties;
+    }
+
+    /**
+     * Get data connection fail cause, in case there was a failure.
+     */
+    public String getDataConnectionFailCause() {
+        return mFailCause;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mState);
+        out.writeInt(mNetworkType);
+        out.writeString(mAPNType);
+        out.writeString(mAPN);
+        out.writeString(mReason);
+        out.writeParcelable(mLinkProperties, flags);
+        out.writeString(mFailCause);
+    }
+
+    public static final Parcelable.Creator<PreciseDataConnectionState> CREATOR
+            = new Parcelable.Creator<PreciseDataConnectionState>() {
+
+        public PreciseDataConnectionState createFromParcel(Parcel in) {
+            return new PreciseDataConnectionState(in);
+        }
+
+        public PreciseDataConnectionState[] newArray(int size) {
+            return new PreciseDataConnectionState[size];
+        }
+    };
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + mState;
+        result = prime * result + mNetworkType;
+        result = prime * result + ((mAPNType == null) ? 0 : mAPNType.hashCode());
+        result = prime * result + ((mAPN == null) ? 0 : mAPN.hashCode());
+        result = prime * result + ((mReason == null) ? 0 : mReason.hashCode());
+        result = prime * result + ((mLinkProperties == null) ? 0 : mLinkProperties.hashCode());
+        result = prime * result + ((mFailCause == null) ? 0 : mFailCause.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        PreciseDataConnectionState other = (PreciseDataConnectionState) obj;
+        if (mAPN == null) {
+            if (other.mAPN != null) {
+                return false;
+            }
+        } else if (!mAPN.equals(other.mAPN)) {
+            return false;
+        }
+        if (mAPNType == null) {
+            if (other.mAPNType != null) {
+                return false;
+            }
+        } else if (!mAPNType.equals(other.mAPNType)) {
+            return false;
+        }
+        if (mFailCause == null) {
+            if (other.mFailCause != null) {
+                return false;
+            }
+        } else if (!mFailCause.equals(other.mFailCause)) {
+            return false;
+        }
+        if (mLinkProperties == null) {
+            if (other.mLinkProperties != null) {
+                return false;
+            }
+        } else if (!mLinkProperties.equals(other.mLinkProperties)) {
+            return false;
+        }
+        if (mNetworkType != other.mNetworkType) {
+            return false;
+        }
+        if (mReason == null) {
+            if (other.mReason != null) {
+                return false;
+            }
+        } else if (!mReason.equals(other.mReason)) {
+            return false;
+        }
+        if (mState != other.mState) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append("Data Connection state: " + mState);
+        sb.append(", Network type: " + mNetworkType);
+        sb.append(", APN type: " + mAPNType);
+        sb.append(", APN: " + mAPN);
+        sb.append(", Change reason: " + mReason);
+        sb.append(", Link properties: " + mLinkProperties);
+        sb.append(", Fail cause: " + mFailCause);
+
+        return sb.toString();
+    }
+}
diff --git a/telephony/java/android/telephony/PreciseDisconnectCause.java b/telephony/java/android/telephony/PreciseDisconnectCause.java
new file mode 100644
index 0000000..54ab19d
--- /dev/null
+++ b/telephony/java/android/telephony/PreciseDisconnectCause.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2014 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.telephony;
+
+/**
+ * Contains precise disconnect call causes generated by the
+ * framework and the RIL.
+ *
+ * @hide
+ */
+public class PreciseDisconnectCause {
+
+    /** The disconnect cause is not valid (Not received a disconnect cause)*/
+    public static final int NOT_VALID                      = -1;
+    /** No disconnect cause provided. Generally a local disconnect or an incoming missed call */
+    public static final int NO_DISCONNECT_CAUSE_AVAILABLE  = 0;
+    /**
+     * The destination cannot be reached because the number, although valid,
+     * is not currently assigned
+     */
+    public static final int UNOBTAINABLE_NUMBER            = 1;
+    /** One of the users involved in the call has requested that the call is cleared */
+    public static final int NORMAL                         = 16;
+    /** The called user is unable to accept another call */
+    public static final int BUSY                           = 17;
+    /** The called number is no longer assigned */
+    public static final int NUMBER_CHANGED                 = 22;
+    /** Provided in response to a STATUS ENQUIRY message */
+    public static final int STATUS_ENQUIRY                 = 30;
+    /** Reports a normal disconnect only when no other normal cause applies */
+    public static final int NORMAL_UNSPECIFIED             = 31;
+    /** There is no channel presently available to handle the call */
+    public static final int NO_CIRCUIT_AVAIL               = 34;
+    /**
+     * The network is not functioning correctly and the condition is not likely to last
+     * a long period of time
+     */
+    public static final int TEMPORARY_FAILURE              = 41;
+    /** The switching equipment is experiencing a period of high traffic */
+    public static final int SWITCHING_CONGESTION           = 42;
+    /** The channel cannot be provided */
+    public static final int CHANNEL_NOT_AVAIL              = 44;
+    /** The requested quality of service (ITU-T X.213) cannot be provided */
+    public static final int QOS_NOT_AVAIL                  = 49;
+    /** The requested bearer capability is not available at this time */
+    public static final int BEARER_NOT_AVAIL               = 58;
+    /** The call clearing is due to ACM being greater than or equal to ACMmax */
+    public static final int ACM_LIMIT_EXCEEDED             = 68;
+    /** The call is restricted */
+    public static final int CALL_BARRED                    = 240;
+    /** The call is blocked by the Fixed Dialing Number list */
+    public static final int FDN_BLOCKED                    = 241;
+    /** The given IMSI is not known at the VLR */
+    /** TS 24.008 cause 4 */
+    public static final int IMSI_UNKNOWN_IN_VLR            = 242;
+    /**
+     * The network does not accept emergency call establishment using an IMEI or not accept attach
+     * procedure for emergency services using an IMEI
+     */
+    public static final int IMEI_NOT_ACCEPTED              = 243;
+    /** MS is locked until next power cycle */
+    public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE  = 1000;
+    /** Drop call*/
+    public static final int CDMA_DROP                      = 1001;
+    /** INTERCEPT order received, MS state idle entered */
+    public static final int CDMA_INTERCEPT                 = 1002;
+    /** MS has been redirected, call is cancelled */
+    public static final int CDMA_REORDER                   = 1003;
+    /** Service option rejection */
+    public static final int CDMA_SO_REJECT                 = 1004;
+    /** Requested service is rejected, retry delay is set */
+    public static final int CDMA_RETRY_ORDER               = 1005;
+    /** Unable to obtain access to the CDMA system */
+    public static final int CDMA_ACCESS_FAILURE            = 1006;
+    /** Not a preempted call */
+    public static final int CDMA_PREEMPTED                 = 1007;
+    /** Not an emergency call */
+    public static final int CDMA_NOT_EMERGENCY             = 1008;
+    /** Access Blocked by CDMA network */
+    public static final int CDMA_ACCESS_BLOCKED            = 1009;
+    /** Disconnected due to unspecified reasons */
+    public static final int ERROR_UNSPECIFIED              = 0xffff;
+
+    /** Private constructor to avoid class instantiation. */
+    private PreciseDisconnectCause() {
+        // Do nothing.
+    }
+}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 3d416fb..23e4d77 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -210,6 +210,267 @@
      */
     public static final String EXTRA_INCOMING_NUMBER = "incoming_number";
 
+    /**
+     * Broadcast intent action indicating that a precise call state
+     * (cellular) on the device has changed.
+     *
+     * <p>
+     * The {@link #EXTRA_RINGING_CALL_STATE} extra indicates the ringing call state.
+     * The {@link #EXTRA_FOREGROUND_CALL_STATE} extra indicates the foreground call state.
+     * The {@link #EXTRA_BACKGROUND_CALL_STATE} extra indicates the background call state.
+     * The {@link #EXTRA_DISCONNECT_CAUSE} extra indicates the disconnect cause.
+     * The {@link #EXTRA_PRECISE_DISCONNECT_CAUSE} extra indicates the precise disconnect cause.
+     *
+     * <p class="note">
+     * Requires the READ_PRECISE_PHONE_STATE permission.
+     *
+     * @see #EXTRA_RINGING_CALL_STATE
+     * @see #EXTRA_FOREGROUND_CALL_STATE
+     * @see #EXTRA_BACKGROUND_CALL_STATE
+     * @see #EXTRA_DISCONNECT_CAUSE
+     * @see #EXTRA_PRECISE_DISCONNECT_CAUSE
+     *
+     * <p class="note">
+     * Requires the READ_PRECISE_PHONE_STATE permission.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_PRECISE_CALL_STATE_CHANGED =
+            "android.intent.action.PRECISE_CALL_STATE";
+
+    /**
+     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
+     * for an integer containing the state of the current ringing call.
+     *
+     * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
+     * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
+     * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
+     * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
+     * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
+     * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
+     * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
+     * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
+     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
+     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
+     *
+     * <p class="note">
+     * Retrieve with
+     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
+     *
+     * @hide
+     */
+    public static final String EXTRA_RINGING_CALL_STATE = "ringing_state";
+
+    /**
+     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
+     * for an integer containing the state of the current foreground call.
+     *
+     * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
+     * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
+     * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
+     * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
+     * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
+     * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
+     * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
+     * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
+     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
+     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
+     *
+     * <p class="note">
+     * Retrieve with
+     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
+     *
+     * @hide
+     */
+    public static final String EXTRA_FOREGROUND_CALL_STATE = "foreground_state";
+
+    /**
+     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
+     * for an integer containing the state of the current background call.
+     *
+     * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
+     * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
+     * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
+     * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
+     * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
+     * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
+     * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
+     * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
+     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
+     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
+     *
+     * <p class="note">
+     * Retrieve with
+     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
+     *
+     * @hide
+     */
+    public static final String EXTRA_BACKGROUND_CALL_STATE = "background_state";
+
+    /**
+     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
+     * for an integer containing the disconnect cause.
+     *
+     * @see DisconnectCause
+     *
+     * <p class="note">
+     * Retrieve with
+     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
+     *
+     * @hide
+     */
+    public static final String EXTRA_DISCONNECT_CAUSE = "disconnect_cause";
+
+    /**
+     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
+     * for an integer containing the disconnect cause provided by the RIL.
+     *
+     * @see PreciseDisconnectCause
+     *
+     * <p class="note">
+     * Retrieve with
+     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
+     *
+     * @hide
+     */
+    public static final String EXTRA_PRECISE_DISCONNECT_CAUSE = "precise_disconnect_cause";
+
+    /**
+     * Broadcast intent action indicating a data connection has changed,
+     * providing precise information about the connection.
+     *
+     * <p>
+     * The {@link #EXTRA_DATA_STATE} extra indicates the connection state.
+     * The {@link #EXTRA_DATA_NETWORK_TYPE} extra indicates the connection network type.
+     * The {@link #EXTRA_DATA_APN_TYPE} extra indicates the APN type.
+     * The {@link #EXTRA_DATA_APN} extra indicates the APN.
+     * The {@link #EXTRA_DATA_CHANGE_REASON} extra indicates the connection change reason.
+     * The {@link #EXTRA_DATA_IFACE_PROPERTIES} extra indicates the connection interface.
+     * The {@link #EXTRA_DATA_FAILURE_CAUSE} extra indicates the connection fail cause.
+     *
+     * <p class="note">
+     * Requires the READ_PRECISE_PHONE_STATE permission.
+     *
+     * @see #EXTRA_DATA_STATE
+     * @see #EXTRA_DATA_NETWORK_TYPE
+     * @see #EXTRA_DATA_APN_TYPE
+     * @see #EXTRA_DATA_APN
+     * @see #EXTRA_DATA_CHANGE_REASON
+     * @see #EXTRA_DATA_IFACE
+     * @see #EXTRA_DATA_FAILURE_CAUSE
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED =
+            "android.intent.action.PRECISE_DATA_CONNECTION_STATE_CHANGED";
+
+    /**
+     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
+     * for an integer containing the state of the current data connection.
+     *
+     * @see TelephonyManager#DATA_UNKNOWN
+     * @see TelephonyManager#DATA_DISCONNECTED
+     * @see TelephonyManager#DATA_CONNECTING
+     * @see TelephonyManager#DATA_CONNECTED
+     * @see TelephonyManager#DATA_SUSPENDED
+     *
+     * <p class="note">
+     * Retrieve with
+     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
+     *
+     * @hide
+     */
+    public static final String EXTRA_DATA_STATE = PhoneConstants.STATE_KEY;
+
+    /**
+     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
+     * for an integer containing the network type.
+     *
+     * @see TelephonyManager#NETWORK_TYPE_UNKNOWN
+     * @see TelephonyManager#NETWORK_TYPE_GPRS
+     * @see TelephonyManager#NETWORK_TYPE_EDGE
+     * @see TelephonyManager#NETWORK_TYPE_UMTS
+     * @see TelephonyManager#NETWORK_TYPE_CDMA
+     * @see TelephonyManager#NETWORK_TYPE_EVDO_0
+     * @see TelephonyManager#NETWORK_TYPE_EVDO_A
+     * @see TelephonyManager#NETWORK_TYPE_1xRTT
+     * @see TelephonyManager#NETWORK_TYPE_HSDPA
+     * @see TelephonyManager#NETWORK_TYPE_HSUPA
+     * @see TelephonyManager#NETWORK_TYPE_HSPA
+     * @see TelephonyManager#NETWORK_TYPE_IDEN
+     * @see TelephonyManager#NETWORK_TYPE_EVDO_B
+     * @see TelephonyManager#NETWORK_TYPE_LTE
+     * @see TelephonyManager#NETWORK_TYPE_EHRPD
+     * @see TelephonyManager#NETWORK_TYPE_HSPAP
+     *
+     * <p class="note">
+     * Retrieve with
+     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
+     *
+     * @hide
+     */
+    public static final String EXTRA_DATA_NETWORK_TYPE = PhoneConstants.DATA_NETWORK_TYPE_KEY;
+
+    /**
+     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
+     * for an String containing the data APN type.
+     *
+     * <p class="note">
+     * Retrieve with
+     * {@link android.content.Intent#getStringExtra(String name)}.
+     *
+     * @hide
+     */
+    public static final String EXTRA_DATA_APN_TYPE = PhoneConstants.DATA_APN_TYPE_KEY;
+
+    /**
+     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
+     * for an String containing the data APN.
+     *
+     * <p class="note">
+     * Retrieve with
+     * {@link android.content.Intent#getStringExtra(String name)}.
+     *
+     * @hide
+     */
+    public static final String EXTRA_DATA_APN = PhoneConstants.DATA_APN_KEY;
+
+    /**
+     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
+     * for an String representation of the change reason.
+     *
+     * <p class="note">
+     * Retrieve with
+     * {@link android.content.Intent#getStringExtra(String name)}.
+     *
+     * @hide
+     */
+    public static final String EXTRA_DATA_CHANGE_REASON = PhoneConstants.STATE_CHANGE_REASON_KEY;
+
+    /**
+     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
+     * for an String representation of the data interface.
+     *
+     * <p class="note">
+     * Retrieve with
+     * {@link android.content.Intent#getParcelableExtra(String name)}.
+     *
+     * @hide
+     */
+    public static final String EXTRA_DATA_LINK_PROPERTIES_KEY = PhoneConstants.DATA_LINK_PROPERTIES_KEY;
+
+    /**
+     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
+     * for the data connection fail cause.
+     *
+     * <p class="note">
+     * Retrieve with
+     * {@link android.content.Intent#getStringExtra(String name)}.
+     *
+     * @hide
+     */
+    public static final String EXTRA_DATA_FAILURE_CAUSE = PhoneConstants.DATA_FAILURE_CAUSE_KEY;
 
     //
     //
diff --git a/telephony/java/android/telephony/ThirdPartyCallListener.java b/telephony/java/android/telephony/ThirdPartyCallListener.java
deleted file mode 100644
index 00265f8..0000000
--- a/telephony/java/android/telephony/ThirdPartyCallListener.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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.telephony;
-
-import android.os.RemoteException;
-
-import com.android.internal.telephony.IThirdPartyCallListener;
-
-/**
- * Interface provided to {@link android.telephony.ThirdPartyCallService}. The service can use this
- * to notify the listener of changes to the call state.
- */
-public class ThirdPartyCallListener {
-    private final IThirdPartyCallListener mListener;
-
-    // Call end reason. TODO: rename this to DisconnectCause once they are public.
-    public static final int CALL_END_NORMAL = 1;
-    public static final int CALL_END_INCOMING_MISSED = 2;
-    public static final int CALL_END_OTHER = 3;
-
-    public ThirdPartyCallListener(IThirdPartyCallListener listener) {
-        if (listener == null) {
-            throw new IllegalArgumentException("Invalid listener");
-        }
-        mListener = listener;
-    }
-
-    /**
-     * Called by the service when a call provider is available to perform the outgoing or incoming
-     * call.
-     */
-    public void onCallProviderAttached(ThirdPartyCallProvider callProvider) {
-        try {
-            mListener.onCallProviderAttached(callProvider.getCallback());
-        } catch (RemoteException e) {
-        }
-    }
-
-    /**
-     * Notifies the listener that ringing has started for this call.
-     */
-    public void onRingingStarted() {
-        try {
-            mListener.onRingingStarted();
-        } catch (RemoteException e) {
-        }
-    }
-
-    /**
-     * Notifies the listener that the call has been successfully established.
-     */
-    public void onCallEstablished() {
-        try {
-            mListener.onCallEstablished();
-        } catch (RemoteException e) {
-        }
-    }
-
-    /**
-     * Notifies the listener that the call has ended.
-     */
-    public void onCallEnded(int reason) {
-        try {
-            mListener.onCallEnded(reason);
-        } catch (RemoteException e) {
-        }
-    }
-}
diff --git a/telephony/java/android/telephony/ThirdPartyCallProvider.java b/telephony/java/android/telephony/ThirdPartyCallProvider.java
deleted file mode 100644
index bd8a1ea..0000000
--- a/telephony/java/android/telephony/ThirdPartyCallProvider.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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.telephony;
-
-import android.os.Handler;
-import android.os.Message;
-
-import com.android.internal.telephony.IThirdPartyCallProvider;
-
-/**
- * Interface sent to {@link android.telephony.ThirdPartyCallListener#onCallProviderAttached
- * onCallProviderAttached}. This is used to control an outgoing or an incoming call.
- */
-public class ThirdPartyCallProvider {
-    private static final int MSG_MUTE = 1;
-    private static final int MSG_HANGUP = 2;
-    private static final int MSG_INCOMING_CALL_ACCEPT = 3;
-    private static final int MSG_SEND_DTMF = 4;
-
-    /**
-     * Mutes or unmutes the call.
-     */
-    public void mute(boolean shouldMute) {
-        // default implementation empty
-    }
-
-    /**
-     * Ends the current call. If this is an unanswered incoming call then the call is rejected.
-     */
-    public void hangup() {
-        // default implementation empty
-    }
-
-   /**
-     * Accepts the incoming call.
-     */
-    public void incomingCallAccept() {
-        // default implementation empty
-    }
-
-    /**
-     * Sends the given DTMF code. The code can be '0'-'9', 'A'-'D', '#', or '*'.
-     */
-    public void sendDtmf(char c) {
-        // default implementation empty
-    }
-
-    IThirdPartyCallProvider getCallback() {
-        return mCallback;
-    }
-
-    private final IThirdPartyCallProvider mCallback = new IThirdPartyCallProvider.Stub() {
-        @Override
-        public void mute(boolean shouldMute) {
-            Message.obtain(mHandler, MSG_MUTE, shouldMute ? 1 : 0, 0).sendToTarget();
-        }
-
-        @Override
-        public void hangup() {
-            Message.obtain(mHandler, MSG_HANGUP).sendToTarget();
-        }
-
-        @Override
-        public void incomingCallAccept() {
-            Message.obtain(mHandler, MSG_INCOMING_CALL_ACCEPT).sendToTarget();
-        }
-
-        @Override
-        public void sendDtmf(char c) {
-            Message.obtain(mHandler, MSG_SEND_DTMF, (int) c, 0).sendToTarget();
-        }
-    };
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_MUTE:
-                    mute(msg.arg1 != 0);
-                    break;
-                case MSG_HANGUP:
-                    hangup();
-                    break;
-                case MSG_INCOMING_CALL_ACCEPT:
-                    incomingCallAccept();
-                    break;
-                case MSG_SEND_DTMF:
-                    sendDtmf((char) msg.arg1);
-                    break;
-            }
-        }
-    };
-}
diff --git a/telephony/java/android/telephony/ThirdPartyCallService.java b/telephony/java/android/telephony/ThirdPartyCallService.java
deleted file mode 100644
index 6eddb43..0000000
--- a/telephony/java/android/telephony/ThirdPartyCallService.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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.telephony;
-
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.util.Pair;
-
-import com.android.internal.telephony.IThirdPartyCallListener;
-import com.android.internal.telephony.IThirdPartyCallService;
-
-/**
- * Interface provided by a service to start outgoing calls and attach to incoming calls.
- */
-public class ThirdPartyCallService {
-    private static final int MSG_OUTGOING_CALL_INITIATE = 1;
-    private static final int MSG_INCOMING_CALL_ATTACH = 2;
-
-    /**
-     * Call to start a new outgoing call.
-     */
-    public void outgoingCallInitiate(ThirdPartyCallListener listener, String number) {
-        // default implementation empty
-    }
-
-    /**
-     * Call to attach to an incoming call.
-     */
-    public void incomingCallAttach(ThirdPartyCallListener listener, String callId) {
-        // default implementation empty
-    }
-
-    /**
-     * Returns an IBinder instance that can returned from the service's onBind function.
-     */
-    public IBinder getBinder() {
-        return mCallback;
-    }
-
-    private final IThirdPartyCallService.Stub mCallback = new IThirdPartyCallService.Stub() {
-        @Override
-        public void outgoingCallInitiate(IThirdPartyCallListener listener, String number) {
-            Rlog.w("ThirdPartyPhone", "ThirdPartyCallService.IThirdPartyCallService.out");
-            Message.obtain(mHandler, MSG_OUTGOING_CALL_INITIATE,
-                    Pair.create(listener, number)).sendToTarget();
-        }
-
-        @Override
-        public void incomingCallAttach(IThirdPartyCallListener listener, String callId) {
-            Rlog.w("ThirdPartyPhone", "ThirdPartyCallService.IThirdPartyCallService.in");
-            Message.obtain(mHandler, MSG_INCOMING_CALL_ATTACH,
-                    Pair.create(listener, callId)).sendToTarget();
-        }
-    };
-
-    private final Handler mHandler = new Handler() {
-        public void handleMessage(Message msg) {
-            Rlog.w("ThirdPartyPhone", "ThirdPartyCallService.handleMessage: " + msg.what);
-            switch (msg.what) {
-                case MSG_OUTGOING_CALL_INITIATE: {
-                    Rlog.w("ThirdPartyPhone", "ThirdPartyCallService.handleMessage out");
-                    Pair<IThirdPartyCallListener, String> pair =
-                            (Pair<IThirdPartyCallListener, String>) msg.obj;
-                    ThirdPartyCallListener listener = new ThirdPartyCallListener(pair.first);
-                    outgoingCallInitiate(listener, pair.second);
-                    break;
-                }
-                case MSG_INCOMING_CALL_ATTACH: {
-                    Rlog.w("ThirdPartyPhone", "ThirdPartyCallService.handleMessage in");
-                    Pair<IThirdPartyCallListener, String> pair =
-                            (Pair<IThirdPartyCallListener, String>) msg.obj;
-                    ThirdPartyCallListener listener = new ThirdPartyCallListener(pair.first);
-                    incomingCallAttach(listener, pair.second);
-                    break;
-                }
-            }
-        }
-    };
-}
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index 4be11b8..59bdf64 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -97,6 +97,7 @@
     public static final int CMD_ENABLE_MOBILE_PROVISIONING = BASE + 37;
     public static final int CMD_IS_PROVISIONING_APN = BASE + 38;
     public static final int EVENT_PROVISIONING_APN_ALARM = BASE + 39;
+    public static final int CMD_NET_STAT_POLL = BASE + 40;
 
     /***** Constants *****/
 
diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
index 3a04ceb..f228d4e 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -20,6 +20,8 @@
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.CellInfo;
+import android.telephony.PreciseCallState;
+import android.telephony.PreciseDataConnectionState;
 
 oneway interface IPhoneStateListener {
     void onServiceStateChanged(in ServiceState serviceState);
@@ -35,5 +37,7 @@
     void onSignalStrengthsChanged(in SignalStrength signalStrength);
     void onOtaspChanged(in int otaspMode);
     void onCellInfoChanged(in List<CellInfo> cellInfo);
+    void onPreciseCallStateChanged(in PreciseCallState callState);
+    void onPreciseDataConnectionStateChanged(in PreciseDataConnectionState dataConnectionState);
 }
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 59c8472..546ce17 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -41,4 +41,9 @@
     void notifyCellLocation(in Bundle cellLocation);
     void notifyOtaspChanged(in int otaspMode);
     void notifyCellInfo(in List<CellInfo> cellInfo);
+    void notifyPreciseCallState(int ringingCallState, int foregroundCallState,
+            int backgroundCallState);
+    void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause);
+    void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn,
+            String failCause);
 }
diff --git a/telephony/java/com/android/internal/telephony/IThirdPartyCallListener.aidl b/telephony/java/com/android/internal/telephony/IThirdPartyCallListener.aidl
deleted file mode 100644
index bcf2d81..0000000
--- a/telephony/java/com/android/internal/telephony/IThirdPartyCallListener.aidl
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.internal.telephony;
-
-import com.android.internal.telephony.IThirdPartyCallProvider;
-
-/**
- * Interface provided to ThirdPartyCallService. The service can use this to notify the listener of
- * changes to the call state.
- */
-oneway interface IThirdPartyCallListener {
-    /**
-     * Called by the service when a call provider is available to perform the outgoing or incoming
-     * call.
-     */
-    void onCallProviderAttached(IThirdPartyCallProvider callProvider);
-
-    /**
-     * Notifies the listener that ringing has started for this call.
-     */
-    void onRingingStarted();
-
-    /**
-     * Notifies the listener that the call has been successfully established.
-     */
-    void onCallEstablished();
-
-    /**
-     * Notifies the listener that the call has ended.
-     */
-    void onCallEnded(int reason);
-}
diff --git a/telephony/java/com/android/internal/telephony/IThirdPartyCallProvider.aidl b/telephony/java/com/android/internal/telephony/IThirdPartyCallProvider.aidl
deleted file mode 100644
index a9d67a4..0000000
--- a/telephony/java/com/android/internal/telephony/IThirdPartyCallProvider.aidl
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.internal.telephony;
-
-import com.android.internal.telephony.IThirdPartyCallListener;
-
-/**
- * Interface sent to ThirdPartyCallListener.onCallProviderAttached. This is used to control an
- * outgoing or incoming call.
- */
-oneway interface IThirdPartyCallProvider {
-    /**
-     * Mutes or unmutes the call.
-     */
-    void mute(boolean shouldMute);
-
-    /**
-     * Ends the current call. If this is an unanswered incoming call then the call is rejected (for
-     * example, a notification is sent to a server that the user declined the call).
-     */
-    void hangup();
-
-    /**
-     * Accepts the incoming call.
-     */
-    void incomingCallAccept();
-
-    /**
-     * Sends the given DTMF code. The code can be '0'-'9', 'A'-'D', '#', or '*'.
-     */
-    void sendDtmf(char c);
-}
diff --git a/telephony/java/com/android/internal/telephony/IThirdPartyCallService.aidl b/telephony/java/com/android/internal/telephony/IThirdPartyCallService.aidl
deleted file mode 100644
index c9ee4ed..0000000
--- a/telephony/java/com/android/internal/telephony/IThirdPartyCallService.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.internal.telephony;
-
-import com.android.internal.telephony.IThirdPartyCallListener;
-
-/**
- * Interface provided by a service to start outgoing calls and attach to incoming calls.
- */
-oneway interface IThirdPartyCallService {
-    /**
-     * Call to start a new outgoing call.
-     */
-    void outgoingCallInitiate(IThirdPartyCallListener listener, String number);
-
-    /**
-     * Call to attach to an incoming call.
-     */
-    void incomingCallAttach(IThirdPartyCallListener listener, String callId);
-}
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index fc6c997..8c42d25 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -73,6 +73,8 @@
     public static final String PHONE_NAME_KEY = "phoneName";
     public static final String FAILURE_REASON_KEY = "reason";
     public static final String STATE_CHANGE_REASON_KEY = "reason";
+    public static final String DATA_NETWORK_TYPE_KEY = "networkType";
+    public static final String DATA_FAILURE_CAUSE_KEY = "failCause";
     public static final String DATA_APN_TYPE_KEY = "apnType";
     public static final String DATA_APN_KEY = "apn";
     public static final String DATA_LINK_PROPERTIES_KEY = "linkProperties";
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
index 446d139..cfe7525 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
@@ -58,7 +58,7 @@
 
     public BridgeTypedArray(BridgeResources resources, BridgeContext context, int len,
             boolean platformFile) {
-        super(null, null, null, 0);
+        super(resources, null, null, 0);
         mBridgeResources = resources;
         mContext = context;
         mPlatformFile = platformFile;
diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
new file mode 100644
index 0000000..112250d
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.content.res;
+
+import java.util.Locale;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+import com.ibm.icu.util.ULocale;
+
+/**
+ * Delegate used to provide new implementation of a select few methods of {@link Resources}
+ *
+ * Through the layoutlib_create tool, the original  methods of Resources have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ */
+public class Resources_Delegate {
+
+    @LayoutlibDelegate
+    /*package*/ static String localeToLanguageTag(Resources res, Locale locale)  {
+        return ULocale.forLocale(locale).toLanguageTag();
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
index 38174f1..bf03a5e 100644
--- a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
@@ -56,7 +56,7 @@
     // ---- native methods ----
 
     @LayoutlibDelegate
-    /*package*/ static void destroyFilter(long native_instance, long nativeColorFilter) {
+    /*package*/ static void destroyFilter(long native_instance) {
         sManager.removeJavaReferenceFor(native_instance);
     }
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
index ca8f450..9aac2bd 100644
--- a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
@@ -60,11 +60,5 @@
         return sManager.addNewDelegate(newDelegate);
     }
 
-    @LayoutlibDelegate
-    /*package*/ static long nColorMatrixFilter(long nativeFilter, float[] array) {
-        // pass
-        return 0;
-    }
-
     // ---- Private delegate/helper methods ----
 }
diff --git a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
index defaac3..501d55c 100644
--- a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
@@ -60,11 +60,5 @@
         return sManager.addNewDelegate(newDelegate);
     }
 
-    @LayoutlibDelegate
-    /*package*/ static int nCreateLightingFilter(long nativeFilter, int mul, int add) {
-        // pass
-        return 0;
-    }
-
     // ---- Private delegate/helper methods ----
 }
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
index 49f314c..77468ec 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
@@ -490,20 +490,6 @@
         return new float[0];
     }
 
-    @LayoutlibDelegate
-    /*package*/ static long native_trim(long nPath, long nTargetPath, long nPathMeasure,
-            float trimStart, float trimEnd, float trimOffset) {
-        // TODO: add trim.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "Path.trim() not supported", null);
-        return nPathMeasure;
-
-    }
-
-    @LayoutlibDelegate
-    private static void native_destroyMeasure(long nPathMeasure) {
-        // Do nothing.
-    }
-
     // ---- Private helper methods ----
 
     private void set(Path_Delegate delegate) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
index 6049919..1bc3033 100644
--- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
@@ -60,12 +60,5 @@
         return sManager.addNewDelegate(newDelegate);
     }
 
-    @LayoutlibDelegate
-    /*package*/ static long nCreatePorterDuffFilter(long nativeFilter, int srcColor,
-            int porterDuffMode) {
-        // pass
-        return 0;
-    }
-
     // ---- Private delegate/helper methods ----
 }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 79aa642..4236038 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -125,6 +125,7 @@
         "android.app.Fragment#instantiate", //(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Landroid/app/Fragment;",
         "android.content.res.Resources$Theme#obtainStyledAttributes",
         "android.content.res.Resources$Theme#resolveAttribute",
+        "android.content.res.Resources#localeToLanguageTag",
         "android.content.res.TypedArray#getValueAt",
         "android.graphics.BitmapFactory#finishDecode",
         "android.os.Handler#sendMessageAtTime",